Posting transactions with Lisk Service

How to send transactions to a blockchain node via Lisk Service.

Prepare the transaction object

To prepare the transaction, create the desired transaction object. This is made possible by using either the Lisk Core CLI, or alternatively using the API client:

Via CLI

Any node which is connected to the respective blockchain network can be used to create a sendable transaction object.

$ lisk-core transaction:create 2 0 100000000
? Please enter: amount:  1000000000
? Please enter: recipientAddress:  ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815
? Please enter: data:  send tokens
? Please enter passphrase:  [hidden]
? Please re-enter passphrase:  [hidden]

After all relevant information about the transaction is given, the already encoded transaction object is returned:

{"transaction":"0802100018022080c2d72f2a20e03c09bdc8c023d94cf66a5d352e6258380210d97d545abbf75668ea3736e3123229088094ebdc031214ab0041a7d3f7b2c290b5b834d46bdc7b7eb858151a0b73656e6420746f6b656e733a40faa2626d7306506b1999f48aa2f4b1ffdee01e641fa76d37a9d1d6fd8c225a81065c856ea625c52d138a7e3ba86b62913dc8e5aef8b5e307641ab66e0277a60b"}

To also see the decoded transaction object on creation, add the --json parameter:

$ lisk-core transaction:create 2 0 100000000 --json --pretty
? Please enter: amount:  1000000000
? Please enter: recipientAddress:  ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815
? Please enter: data:  send tokens
? Please enter passphrase:  [hidden]
? Please re-enter passphrase:  [hidden]
{
  "transaction": "0802100018022080c2d72f2a20e03c09bdc8c023d94cf66a5d352e6258380210d97d545abbf75668ea3736e3123229088094ebdc031214ab0041a7d3f7b2c290b5b834d46bdc7b7eb858151a0b73656e6420746f6b656e733a40faa2626d7306506b1999f48aa2f4b1ffdee01e641fa76d37a9d1d6fd8c225a81065c856ea625c52d138a7e3ba86b62913dc8e5aef8b5e307641ab66e0277a60b"
}
{
  "transaction": {
    "moduleID": 2,
    "assetID": 0,
    "nonce": "2",
    "fee": "100000000",
    "senderPublicKey": "e03c09bdc8c023d94cf66a5d352e6258380210d97d545abbf75668ea3736e312",
    "signatures": [
      "faa2626d7306506b1999f48aa2f4b1ffdee01e641fa76d37a9d1d6fd8c225a81065c856ea625c52d138a7e3ba86b62913dc8e5aef8b5e307641ab66e0277a60b"
    ],
    "asset": {
      "amount": "1000000000",
      "recipientAddress": "ab0041a7d3f7b2c290b5b834d46bdc7b7eb85815",
      "data": "send tokens"
    }
  }
}

Via API client

The API client allows to connect to a particular node API, and enables to get and post data to the node. It is part of the lisk-api-client package and is also included in the lisk-client and lisk-sdk packages.

An example script how to create a transaction object is described in the code snippet below:

const { apiClient, cryptography, transactions } = require('@liskhq/lisk-client');
const RPC_ENDPOINT = 'ws://localhost:8080/ws';

let clientCache;

// Replace with the sender address
const senderAddress = "lskt8ovj2shbxrtno8xqqt7cnmzzygdkbt6brnvmj";
// Replace with the sender passphrase
const passphrase = "The 12 word mnemonic passphrase of the sender account"

const getClient = async () => {
    if (!clientCache) {
        clientCache = await apiClient.createWSClient(RPC_ENDPOINT);
    }
    return clientCache;
};

const client = await getClient();
const address = cryptography.getAddressFromBase32Address(senderAddress);
const tx = await client.transaction.create({
    moduleID: 2,
    assetID: 0,
    fee: BigInt(transactions.convertLSKToBeddows('0.01')),
    asset: {
        amount: BigInt(transactions.convertLSKToBeddows(8)),
        recipientAddress: address,
        data: 'Happy birthday!'
    }
}, passphrase);

console.log(tx);

Sending the transaction

An existing transaction object in its binary encoded format can be posted to Lisk Core via the Lisk Service either by using its HTTP or WebSocket APIs.

Via HTTP API

cURL is one of the tools that can be used to send HTTP API requests to Lisk Service:

curl -X POST -H "Content-Type: application/json" -d '{ "transaction": "0802100018022080c2d72f2a20e03c09bdc8c023d94cf66a5d352e6258380210d97d545abbf75668ea3736e3123229088094ebdc031214ab0041a7d3f7b2c290b5b834d46bdc7b7eb858151a0b73656e6420746f6b656e733a40faa2626d7306506b1999f48aa2f4b1ffdee01e641fa76d37a9d1d6fd8c225a81065c856ea625c52d138a7e3ba86b62913dc8e5aef8b5e307641ab66e0277a60b"}' "http://localhost:9901/api/v2/transactions"

The following response will be displayed, if the transaction was posted successfully.

{"message":"Transaction payload was successfully passed to the network node","transactionId":"8a503843942e7d47ba0bef83fe735d26381f32a6ca6c96fb1cde902315f6220c"}

Via WebSocket API

If you prefer to use the RPC WebSocket API of Lisk Service to post transactions, this can be achieved for example by writing a small JS script, and using the API client of the socket.io-client package:

// 1. Require the dependencies
const io = require('socket.io-client'); // The socket.io client
const jsome = require('jsome'); // Prettifies the JSON output

jsome.params.colored = true;

// Use local Service node
const WS_RPC_ENDPOINT = 'ws://localhost:9901/rpc-v2';
//Use public Service node
//const WS_RPC_ENDPOINT = "wss://service.lisk.com/rpc-v2";

// 2. Connect to Lisk Service via WebSockets
const socket = io(WS_RPC_ENDPOINT, {
  forceNew: true,
  transports: ['websocket']
});

// 3. Emit the remote procedure call
socket.emit('request', {
  jsonrpc: '2.0',
  method: 'post.transactions',
  payload: {"transaction":"08021000180d2080c2d72f2a200fe9a3f1a21b5530f27f87a414b549e79a940bf24fdf2b2f05e7f22aeeecc86a32270880c2d72f12144fd8cc4e27a3489b57ed986efe3d327d3de40d921a0a73656e6420746f6b656e3a4069242925e0e377906364fe6c2eed67f419dfc1a757f73e848ff2f1ff97477f90263487d20aedf538edffe2ce5b3e7601a8528e5cd63845272e9d79c294a6590a"}
},
  answer => {
    // console.log(answer);
    jsome(answer);
    process.exit(0);
});