Complementary Examples
Prerequisites
Before we get started we need to make sure that all of the required dependencies are installed. These dependencies are the Crypto SDK and Client SDK. You can head on over to their documentations to read more about them but for now we are only concerned with installing them to get up and running.
Open your project and execute the following commands to install both SDKs. Make sure that those complete without any errors. If you encounter any errors, please open an issue with as much information as you can provide so that our developers can have a look and get to the bottom of the issue.
yarn
1yarn add @arkecosystem/crypto2yarn add @arkecosystem/client
pnpm
1pnpm add @arkecosystem/crypto2pnpm add @arkecosystem/client
npm
1npm install @arkecosystem/crypto2npm install @arkecosystem/client
Now that we’re setup and ready to go we’ll look into some examples for the most common tasks you’ll encounter when wanting to interact with the ARK Blockchain.
Persisting your transaction on the blockchain
The process of getting your transaction verified and persisted on the ARK Blockchain involves a few steps with which our SDKs will help you but lets break them down to get a better idea of what is happening.
- Install the Client SDK and configure it to use a node of your choosing to broadcast your transactions to. Always make sure that you have a fallback node that you can use for broadcasting in case your primary node goes offline or acts strange otherwise.
- Install the Crypto SDK and configure it to match the configuration of the network. This is the most important part as misconfiguration can lead to a myriad of issues as Core will reject your transactions.
- Retrieve the nonce of the sender wallet and increase it by 1. You can read about what a sequential nonce is and why it is important here.
- Create an instance of the builder for the type of transaction you want to create. This is the step where we actually create a transaction and sign it so that the ARK Blockchain can later on verify it and decide if it will be accepted, forged and finally. You can read the relevant API documentation if you want more detailed information about the design and usage.
- Turn the newly created transaction into JSON and broadcast it to the network through the Client SDK. You can read the relevant API documentation if you want more detailed information about the design and usage.
- Process the API response and verify that your transaction was accepted. If the network rejects your transaction you’ll receive the reason as to why that is the case in the response which might mean that you need to create a new transaction and broadcast it.
Troubleshooting
A common issue when trying to get your transaction onto the blockchain is that you’ll receive an error to the effect of Transaction Version 2 is not supported which indicates that your Crypto SDK configuration might be wrong.
The solution to this is to make sure that your Crypto SDK instance is properly configured. This includes both the network preset and the height it’s configured to assume the network has passed, if any of those don’t match up you’ll encounter the aforementioned issue with the version of your transactions.
Mainnet
1Managers.configManager.setFromPreset("mainnet");2Managers.configManager.setHeight(11273000);
Devnet
1Managers.configManager.setFromPreset("devnet");2Managers.configManager.setHeight(4006000);
Creating and Broadcasting a Transfer
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.transfer()18 .version(2)19 .nonce(senderNonce.toFixed())20 .recipientId("Address of Recipient")21 .amount(1 * 1e8)22 .vendorField("Hello World")23 .sign("this is a top secret passphrase");24 25 // Step 4: Broadcast the transaction26 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });27 28 // Step 5: Log the response29 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))30})();
Information
The vendorField is optional and limited to a length of 255 characters. It can be a good idea to add a vendor field to your transactions if you want to be able to easily track them in the future.
Creating and Broadcasting a Second Signature
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.secondSignature()18 .version(2)19 .nonce(senderNonce.toFixed())20 .signatureAsset("this is a top secret second passphrase")21 .sign("this is a top secret passphrase");22 23 // Step 4: Broadcast the transaction24 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });25 26 // Step 5: Log the response27 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))28})();
Creating and Broadcasting a Delegate Registration
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.delegateRegistration()18 .version(2)19 .nonce(senderNonce.toFixed())20 .usernameAsset("johndoe")21 .sign("this is a top secret passphrase");22 23 // Step 4: Broadcast the transaction24 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });25 26 // Step 5: Log the response27 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))28})();
Creating and Broadcasting a Vote
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.vote()18 .version(2)19 .nonce(senderNonce.toFixed())20 .votesAsset(["+public_key_of_a_delegate_wallet"])21 .sign("this is a top secret passphrase");22 23 // Step 4: Broadcast the transaction24 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });25 26 // Step 5: Log the response27 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))28})();
Information
Note the plus prefix for the public key that is passed to the votesAsset function. This prefix denotes that this is a transaction to remove a vote from the given delegate.
Creating and Broadcasting an Unvote
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.vote()18 .version(2)19 .nonce(senderNonce.toFixed())20 .votesAsset(["-public_key_of_a_delegate_wallet"])21 .sign("this is a top secret passphrase");22 23 // Step 4: Broadcast the transaction24 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });25 26 // Step 5: Log the response27 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))28})();
Information
Note the minus prefix for the public key that is passed to the votesAsset function. This prefix denotes that this is a transaction to add a vote to the given delegate.
Creating and Broadcasting a Multi Signature
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.multiSignature()18 .version(2)19 .nonce(senderNonce.toFixed())20 .multiSignatureAsset({21 publicKeys: [22 "039180ea4a8a803ee11ecb462bb8f9613fcdb5fe917e292dbcc73409f0e98f8f22",23 "028d3611c4f32feca3e6713992ae9387e18a0e01954046511878fe078703324dc0",24 "021d3932ab673230486d0f956d05b9e88791ee298d9af2d6df7d9ed5bb861c92dd",25 ],26 min: 2,27 })28 .senderPublicKey("039180ea4a8a803ee11ecb462bb8f9613fcdb5fe917e292dbcc73409f0e98f8f22")29 .multiSign("this is a top secret passphrase 1", 0)30 .multiSign("this is a top secret passphrase 2", 1)31 .multiSign("this is a top secret passphrase 3", 2)32 .sign("this is a top secret passphrase");33 34 // Step 4: Broadcast the transaction35 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });36 37 // Step 5: Log the response38 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))39})();
Creating and Broadcasting a IPFS
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.ipfs()18 .version(2)19 .nonce(senderNonce.toFixed())20 .ipfsAsset("QmR45FmbVVrixReBwJkhEKde2qwHYaQzGxu4ZoDeswuF9w")21 .sign("this is a top secret passphrase");22 23 // Step 4: Broadcast the transaction24 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });25 26 // Step 5: Log the response27 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))28})();
Creating and Broadcasting a Multi Payment
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.multiPayment()18 .version(2)19 .nonce(senderNonce.toFixed())20 .addPayment("Address of Recipient Wallet 1", 1 * 1e8)21 .addPayment("Address of Recipient Wallet 2", 1 * 1e8)22 .addPayment("Address of Recipient Wallet 3", 1 * 1e8)23 .sign("this is a top secret passphrase");24 25 // Step 4: Broadcast the transaction26 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });27 28 // Step 5: Log the response29 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))30})();
Creating and Broadcasting a Delegate Resignation
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.delegateResignation()18 .version(2)19 .nonce(senderNonce.toFixed())20 .sign("this is a top secret passphrase");21 22 // Step 4: Broadcast the transaction23 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });24 25 // Step 5: Log the response26 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))27})();
Information
A delegate resignation has to be sent from the delegate wallet itself to verify its identity.
Creating and Broadcasting a HTLC Lock
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.htlcLock()18 .version(2)19 .nonce(senderNonce.toFixed())20 .htlcLockAsset({21 secretHash: "0f128d401958b1b30ad0d10406f47f9489321017b4614e6cb993fc63913c5454",22 expiration: {23 type: 1,24 value: Math.floor(Date.now() / 1000),25 },26 })27 .amount(1 * 1e8)28 .sign("this is a top secret passphrase");29 30 // Step 4: Broadcast the transaction31 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });32 33 // Step 5: Log the response34 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))35})();
Creating and Broadcasting a HTLC Claim
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.htlcClaim()18 .version(2)19 .nonce(senderNonce.toFixed())20 .htlcClaimAsset({21 lockTransactionId: "943c220691e711c39c79d437ce185748a0018940e1a4144293af9d05627d2eb4",22 unlockSecret: "c27f1ce845d8c29eebc9006be932b604fd06755521b1a8b0be4204c65377151a",23 })24 .sign("this is a top secret passphrase");25 26 // Step 4: Broadcast the transaction27 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });28 29 // Step 5: Log the response30 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))31})();
Information
The unlockSecret has to be a SHA256 hash of the plain text secret that you shared with the person that is allowed to claim the transaction.
Creating and Broadcasting a HTLC Refund
1const { Transactions, Managers, Utils } = require("@arkecosystem/crypto"); 2const { Connection } = require("@arkecosystem/client"); 3 4// Configure our API client 5const client = new Connection("https://dexplorer.ark.io/api"); 6 7// Ensure AIP11 is enabled for the Crypto SDK 8Managers.configManager.setFromPreset("devnet"); 9Managers.configManager.setHeight(4006000);10 11(async () => {12 // Step 1: Retrieve the incremental nonce of the sender wallet13 const senderWallet = await client.api("wallets").get("YOUR_SENDER_WALLET_ADDRESS");14 const senderNonce = Utils.BigNumber.make(senderWallet.body.data.nonce).plus(1);15 16 // Step 2: Create the transaction17 const transaction = Transactions.BuilderFactory.htlcRefund()18 .version(2)19 .nonce(senderNonce.toFixed())20 .htlcRefundAsset({21 lockTransactionId: "943c220691e711c39c79d437ce185748a0018940e1a4144293af9d05627d2eb4",22 })23 .sign("this is a top secret passphrase");24 25 // Step 4: Broadcast the transaction26 const broadcastResponse = await client.api("transactions").create({ transactions: [transaction.build().toJson()] });27 28 // Step 5: Log the response29 console.log(JSON.stringify(broadcastResponse.body.data, null, 4))30})();