<img src="https://user-images.githubusercontent.com/1866848/46092827-535d5880-c1e8-11e8-8a65-f5d9d74df96e.png" width="250" align=center />

A general library wrapped in javascript for interacting with Ultrain.

中文文档看这里

Apply Environment

Browser(ES6)or NodeJS

If you want to integrate u3.js into a react native environment, there is a workable way to do this with rn-nodeify, see the example U3RNDemo

Usage

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>test</title>
            <script src="../dist/u3.js"></script>
            <script>
        
              let u3 = U3.createU3({
                httpEndpoint: 'http://127.0.0.1:8888',
                httpEndpoint_history: 'http://127.0.0.1:3000',
                broadcast: true,
                debug: false,
                sign: true,
                logger: {
                  log: console.log,
                  error: console.error,
                  debug: console.log
                },
                chainId:'0eaaff4003d4e08a541332c62827c0ac5d96766c712316afe7ade6f99b8d70fe',
                symbol: 'UGAS'
              });
        
              u3.getChainInfo((err, info) => {
                if (err) {throw err;}
                console.log(info);
              });
            </script>
        </head>
        <body>
        </body>
    </html>
  • Installation

npm install u3.jsyarn add u3.js

  • Initialization

const { createU3 } = require('u3.js/src');
let config = {
  httpEndpoint: 'http://127.0.0.1:8888',
  httpEndpoint_history: 'http://127.0.0.1:3000',
  chainId: '0eaaff4003d4e08a541332c62827c0ac5d96766c712316afe7ade6f99b8d70fe',
  keyProvider: ['PrivateKeys...'],
  broadcast: true,
  sign: true
}
let u3 = createU3(config);

u3.getChainInfo((err, info) => {
  if (err) {throw err;}
  console.log(info);
});

  • Local environment running

Running u3 locally requires relying on docker.

1.Download docker from here and install it;

2.Then add the Chinese mirror address:https://registry.docker-cn.com;

3.Click on "Apply & Restart";

<img src="https://user-images.githubusercontent.com/1866848/46121838-3d7f8000-c248-11e8-933a-fbcf30cfc443.png" width="500" hegiht="700" align=center />

4.Go to u3.js/docker && ./start.sh

Configuration

Global configuration

  • <b>httpEndpoint</b> string - http or https location of a ultrain providing a chain API. When using u3.js from a browser remember to configure the same origin policy in nodultrain or proxy server. For testing, nodultrain configuration access-control-allow-origin = * could be used.
  • <b>httpEndpoint_history</b> string - http or https location of a ultrain providing a chain history API. When using u3.js from a browser remember to configure the same origin policy in nodultrain or proxy server. .
  • <b>chainId</b> Unique ID for the blockchain you're connecting to. This is required for valid transaction signing. The chainId is provided via the get_chain_info API call.
  • <b>keyProvider</b> [array<string>|string|function] - Provides private keys used to sign transactions. If multiple private keys are found, the API get_required_keys is called to discover which signing keys to use. If a function is provided, this function is called for each transaction.
    If a keyProvider is not provided here, you should provided on a per-action or per-transaction basis in Options.
  • <b>expireInSeconds</b> number - number of seconds before the transaction will expire. The time is based on the nodultrain's clock. An unexpired transaction that may have had an error is a liability until the expiration is reached, this time should be brief.
  • <b>broadcast</b> [boolean=true] - post the transaction to the blockchain. Use false to obtain a fully signed transaction and it will not push to the blockchain.
  • <b>verbose</b> [boolean=false] - verbose logging such as API activity.
  • <b>debug</b> [boolean=false] - low level debug logging (serialization).
  • <b>sign</b> [boolean=true] - sign the transaction with a private key. Leaving a transaction unsigned avoids the need to provide a private key.
  • <b>logger</b> - default logging configuration.
logger: {
  log: config.verbose ? console.log : null,  // null to disable
  error: config.verbose ? console.error : null,
}

Options configuration

Options may be provided after parameters. Authorization is for individual actions.eg:

options = {
  authorization: 'alice@active',
  broadcast: true,
  sign: true
}

u3.transfer('alice', 'bob', '1.0000 UGAS', '', options)
  • <b>authorization</b> [array<auth>|auth] - identifies the signing account and permission typically in a multisig configuration. Authorization may be a string formatted as account@permission.
  • <b>broadcast</b> [boolean=true] - post the transaction to the blockchain. Use false to obtain a fully signed transaction.
  • <b>sign</b> [boolean=true] - sign the transaction with a private key. Leaving a transaction unsigned avoids the need to provide a private key.
  • <b>keyProvider</b> [array<string>|string|function] - just like the global keyProvider except this provides a temporary key for a single action or transaction.
await u3.anyAction('args', {keyProvider})
await u3.transaction(tr => { tr.anyAction() }, {keyProvider})

create Account

create accounts will need some staked tokens for RAM and bandwidth.

const u3 = createU3(config);
const name = 'abcdefg12345'; //common account should satisfy rule: Must be 12 bit in 12345abcdefghijklmnopqrstuvwxyz
let params = {
   creator: 'ben',
   name: name,
   owner: pubkey,
   active: pubkey,
   updateable: 1,//[optional]whether the account can be updated( update contract)
};
await u3.createUser(params);
 

Transfer(UGAS)

transfer functions are used more frequently.

  • transfer(from,to,content,memo) the content param should be using strict format with right decimal and symbol, eg '1.0000 UGAS'
const u3 = createU3(config);
const c = await u3.contract('utrio.token')

// with positional parameters
await c.transfer('ben', 'bob', '1.2000 UGAS', '')
// or with named parameters
await c.transfer({from: 'bob', to: 'ben', quantity: '1.3000 UGAS', memo: ''})

Sign

send unsigned_transaction

Using { sign: false, broadcast: false } to create a U3 instance and do some action.
And Then send the unsigned_transaction object to the ultrain-chain wallet.

  const u3_offline = createU3({ sign: false, broadcast: false });
  const c = u3_offline.contract('utrio.token');
  let unsigned_transaction = await c.transfer('ultrainio', 'ben', '1 UGAS', 'uu');

sign and push signed_transaction

In the wallet you can provide your privateKey or mnemonic to make a signature.
And then push the signedTransaction to the ultrain-chain.

  const u3_online = createU3();
  let signature = await u3_online.sign(unsigned_transaction, privateKeyOrMnemonic, chainId);
  if (signature) {
     let signedTransaction = Object.assign({}, unsigned_transaction.transaction, { signatures: [signature] });
     let processedTransaction = await u3_online.pushTx(signedTransaction);
  }

Resource

Calling a contract will only spend the contract owner's resource. So if your want to deploy
a contract, buy some resource before.

  • resourcelease(payer,receiver,slot,days)
const u3 = createU3(config);
const c = await u3.contract('ultrainio')

await c.resourcelease('ben', 'bob', 1, 10);// 1 slot for 10 days

And querying resource detail through the method below.

const resource = await u3.queryResource('abcdefg12345');
console.log(resource)

Contracts

deploy

Deploy and call smart contracts. Before you deploy the smart contract, you need to compile the typescript source files
to webassembly targets, which are .abi,.wast,*.wasm.

  • deploy(contracts_files_path, deploy_account) the contracts_files_path param is the absolute path of .abi,.wast,*.wasm.
    and the deploy_account is the one who will deploy the smart contract.
  const u3 = createU3(config);
  await u3.deploy(path.resolve(__dirname, '../contracts/token/token'), 'bob');

call actions

const u3 = createU3(config);
const tr = await u3.contract('ben');
await tr.transfer('bob', 'ben', '1.0000 UGAS','');

//or maybe like this
await u3.contract('ben').then(sm => sm.transfer('bob', 'ben', '1.0000 UGAS',''))

// Transaction with multiple contracts
await u3.transaction(['ben', 'bob'], ({sm1, sm2}) => {
   sm1.myaction(..)
   sm2.myaction(..)
})

custom Token

const u3 = createU3(config);
const account = 'bob';
await u3.transaction(account, token => {
    token.create(account, '10000000.0000 DDD');
    token.issue(account, '10000000.0000 DDD', 'issue');
});

const balance = await u3.getCurrencyBalance(account, account, 'DDD')
console.log('currency balance', balance)

Event

Ultrain provides an event registration and listening mechanism for asynchronous scenarios that trigger another action in the contract.The client needs to first register a listener address to the ultrain, then trigger the event via the emit method in the contract, and Ultrain will push the message to the registered listener address.

register/unregister

  • registerEvent(deployer, listen_url)
  • unregisterEvent(deployer, listen_url)

deployer : the account who deploy the contract

listen_url : the listening url which will receive the message

note: If you are testing in a docker envirnment, make sure the listening address is a local IP and can be access from docker.

const u3 = createU3(config);
const subscribe = await u3.registerEvent('ben', 'http://192.168.1.5:3002');

//or
const unsubscribe = await u3.unregisterEvent('ben', 'http://192.168.1.5:3002');

listen

const { createU3 listener } = require('u3.js/src');
listener(function(data) {
   // do callback logic
   console.log(data);
});

U3Utils.test.wait(2000);

//must call listener function before emit event
const contract = await u3.contract(account);
contract.hi('ben', 30, 'It is a test', { authorization: [`ben@active`] });