How to Transfer BTS Assets on BitShares Blockchain using Node.Js?


Node/Javascript Function to Transfer BTS Assets on BitShares Blockchain

To make a transfer on the BitShares blockchain, you need to create and broadcast a transfer operation. This operation includes details such as the sender, receiver, amount, and asset to transfer.

Here is a basic example of how you can make a transfer with the bitsharesjs library in Node.js. This example assumes that you already have the private key of the sender’s account.

The following code has been tested – which can be used to transfer funds from one account to another on the BitShares Blockchain.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
const { Apis, ChainConfig } = require("bitsharesjs-ws");
const { Aes, ChainStore, FetchChain, PrivateKey, TransactionBuilder, TransactionHelper } = require('bitsharesjs');
 
const https = require("https");
const agent = new https.Agent({
    rejectUnauthorized: false
});
 
BTS_TEST_NODE = "wss://api-us-testnet.61bts.com/ws";
BTS_NODE = "wss://api.61bts.com";
 
async function transferBTS(fromAccountName, toAccountName, amount, asset, memo, privateKeyWif, privateMemoKey, apiNode) {
    return new Promise(async (resolve, reject) => {
        try {
            await Apis.instance(apiNode, true,  4000, undefined, agent).init_promise;
            ChainConfig.setPrefix('BTS');
 
            await new Promise(resolve => setTimeout(resolve, 1000));
 
            const fromAccount = await FetchChain("getAccount", fromAccountName);
            const toAccount = await FetchChain("getAccount", toAccountName);
            const sendAsset = await FetchChain("getAsset", asset);
 
            if (!fromAccount) {
                throw new Error(`Unable to find account: ${fromAccountName}`);
            }
 
            if (!toAccount) {
                throw new Error(`Unable to find account: ${toAccountName}`);
            }
 
            if (!sendAsset) {
                throw new Error(`Unable to find asset: ${asset}`);
            }
 
            let memoObj;
            if (memo) {
                const nonce = TransactionHelper.unique_nonce_uint64();
                memoObj = {
                    from: fromAccount.get("options").get("memo_key"),
                    to: toAccount.get("options").get("memo_key"),
                    nonce: nonce,
                    message: Aes.encrypt_with_checksum(
                        PrivateKey.fromWif(privateMemoKey),
                        toAccount.get('options').get('memo_key'),
                        nonce,
                        new Buffer.from(memo, 'utf-8')
                    )
                };
            }
 
            const tr = new TransactionBuilder();
            const transferOp = tr.get_type_operation("transfer", {
                fee: {
                    amount: 0,
                    asset_id: "1.3.0"
                },
                from: fromAccount.get("id"),
                to: toAccount.get("id"),
                amount: {
                    amount: amount * Math.pow(10, sendAsset.get("precision")),
                    asset_id: sendAsset.get("id")
                },
                memo: memoObj
            });
 
            await tr.add_operation(transferOp);
            await tr.set_required_fees();
            tr.add_signer(PrivateKey.fromWif(privateKeyWif));
            const result = await tr.broadcast();
            resolve(result);
        } catch (error) {
            reject(error);
        }
    });
}
const { Apis, ChainConfig } = require("bitsharesjs-ws");
const { Aes, ChainStore, FetchChain, PrivateKey, TransactionBuilder, TransactionHelper } = require('bitsharesjs');

const https = require("https");
const agent = new https.Agent({
    rejectUnauthorized: false
});

BTS_TEST_NODE = "wss://api-us-testnet.61bts.com/ws";
BTS_NODE = "wss://api.61bts.com";

async function transferBTS(fromAccountName, toAccountName, amount, asset, memo, privateKeyWif, privateMemoKey, apiNode) {
    return new Promise(async (resolve, reject) => {
        try {
            await Apis.instance(apiNode, true,  4000, undefined, agent).init_promise;
            ChainConfig.setPrefix('BTS');

            await new Promise(resolve => setTimeout(resolve, 1000));

            const fromAccount = await FetchChain("getAccount", fromAccountName);
            const toAccount = await FetchChain("getAccount", toAccountName);
            const sendAsset = await FetchChain("getAsset", asset);

            if (!fromAccount) {
                throw new Error(`Unable to find account: ${fromAccountName}`);
            }

            if (!toAccount) {
                throw new Error(`Unable to find account: ${toAccountName}`);
            }

            if (!sendAsset) {
                throw new Error(`Unable to find asset: ${asset}`);
            }

            let memoObj;
            if (memo) {
                const nonce = TransactionHelper.unique_nonce_uint64();
                memoObj = {
                    from: fromAccount.get("options").get("memo_key"),
                    to: toAccount.get("options").get("memo_key"),
                    nonce: nonce,
                    message: Aes.encrypt_with_checksum(
                        PrivateKey.fromWif(privateMemoKey),
                        toAccount.get('options').get('memo_key'),
                        nonce,
                        new Buffer.from(memo, 'utf-8')
                    )
                };
            }

            const tr = new TransactionBuilder();
            const transferOp = tr.get_type_operation("transfer", {
                fee: {
                    amount: 0,
                    asset_id: "1.3.0"
                },
                from: fromAccount.get("id"),
                to: toAccount.get("id"),
                amount: {
                    amount: amount * Math.pow(10, sendAsset.get("precision")),
                    asset_id: sendAsset.get("id")
                },
                memo: memoObj
            });

            await tr.add_operation(transferOp);
            await tr.set_required_fees();
            tr.add_signer(PrivateKey.fromWif(privateKeyWif));
            const result = await tr.broadcast();
            resolve(result);
        } catch (error) {
            reject(error);
        }
    });
}

A few points about the code:

  • Instead of creating a nested async function inside the Promise executor, I’ve directly made the executor function async. This allows you to use await directly in the executor function.
  • I’ve added error handling within the Promise. If any of the await statements fail, the error will be caught and passed to reject, causing the Promise to be rejected.
  • For the Aes.encrypt_with_checksum function, the nonce value wasn’t defined before, so I’ve created a nonce constant and used it.
  • new Buffer(memo, ‘utf-8’) is replaced with new Buffer.from(memo, ‘utf-8’) as new Buffer has been deprecated and it’s recommended to use Buffer.from() or Buffer.alloc() for newer versions of Node.js.

To view the balance of a BTS Account: NodeJs code to check the balance of a BTS account (BitShares Blockchain)

BitShares Blockchain API (bitsharesjs and bitsharesjs-ws) are based on Web Sockets, and thus, the usage is a bit different from SteemJs.

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
679 words
Last Post: Teaching Kids Programming - Algorithms to Find Neither Minimum nor Maximum
Next Post: What is Grid Computing, and how is it different from Cloud Computing?

The Permanent URL is: How to Transfer BTS Assets on BitShares Blockchain using Node.Js?

Leave a Reply