Node.js

Here are the articles in this section:

Quick start guide

Changing Network

Offline Build/Sign Transaction

All Account methods

All utility methods

Auxiliary Scripts

Quick Start guide

Before calling any methods, you should call utils.setProviders(providers) to set the network providers.

Common flow example:

import { Account, TransactionType } from "@klever/sdk-node";

const payload = {
  amount,
  receiver,
  kda,
};

const privateKey = "yourPrivateKey";

const account = new Account(privateKey);
await account.ready;

const unsignedTx = await account.buildTransaction([
  {
    payload,
    type: TransactionType.Transfer,
  },
]);

const signedTx = await account.signTransaction(unsignedTx);

const broadcastRes = await account.broadcastTransactions([signedTx]);

console.log(broadcastRes);

Quick send example:

import { Account, TransactionType } from "@klever/sdk-node";

const payload = {
  amount,
  receiver,
  kda,
};

const privateKey = "yourPrivateKey";

const account = new Account(privateKey);
await account.ready;

const broadcastRes = await account.quickSend([
  {
    payload,
    type: TransactionType.Transfer,
  },
]); //the same as buildTransaction + signTransaction + broadcastTransactions

console.log(broadcastRes);

Changing Network

The default network is the Kleverchain Mainnet, but if you want to use the Kleverchain Testnet or a local version of the Kleverchain, you can change the provider object by setting it before calling other methods.

import { utils, IProvider } from "@klever/sdk-node";
...
  const provider: IProvider = {
    api: "https://api.testnet.klever.finance",
    node: "https://node.testnet.klever.finance",
  };

  utils.setProviders(provider);
...

Offline Build/Sign Transaction

If you need to build the transaction by hand, we provide methods for you to do it offline as follows:

import { Transaction, Contracts, TXContract_ContractType, utils } from "@klever/sdk-node";
...
  // text encoder UTF-8
  const enc = new TextEncoder();

  const privateKey = "001122..."; // sender`s private key 32 bytes hex format
  // decode addresses sender/receiver
  const senderDecoded = await utils.decodeAddress("klv1vq9f7xtazuk9y3n46ukthgf2l30ev2s0qxvs6dfp4f2e76sfu3xshpmjsr");
  const receiverDecoded = await utils.decodeAddress("klv1fpwjz234gy8aaae3gx0e8q9f52vymzzn3z5q0s5h60pvktzx0n0qwvtux5");
  const accountNonce = 100

  // create transfer contract
  const transfer = Contracts.TransferContract.fromPartial({
      ToAddress: receiverDecoded,
      AssetID: enc.encode("KLV"),
      Amount: 100 * 10 ** 6, // Must be in units (check asset precision) -> 100 KLV = 100 * 10^6
    });

  // create base transaction
  const tx  = new Transaction({
      Sender: senderDecoded,
      Nonce: accountNonce,
      BandwidthFee: 1000000,
      KAppFee: 500000,
      Version: 1,
      ChainID: enc.encode("100420")
    });

  // add contract to transaction
  tx.addContract(TXContract_ContractType.TransferContractType, transfer);

  // signature transaction
  await tx.sign(privateKey);

  console.log("Transaction Info", {
      "Wired Proto": tx.hex(),
      "To Broadcast Format": tx.toBroadcast(),
      "Json Format": tx.toJSON(),
    });
...

All Account methods

All methods that can be called by an account instance.

MethodParametersReturnDescription
getBalance()numberGets that account instance's balance
getNonce()numberGets that account instance's nonce
getAddress()stringGets that account instance's address
sync()Promise<void>Syncs that account instance's balance and nonce with the provided node.
getInfo()Promise<IAccountInfo>Returns that address' info from the provided node.
buildTransaction(contracts: IContractRequest[], txData?: string[], options?: ITxOptionsRequest)Promise<ITransaction>Builds a simplified transaction into a transaction ready to be signed.
signMessage(message: string)Promise<string>Uses the account instance private key to sign any message.
signTransaction(tx: ITransaction)Promise<ITransaction>Uses the account instance private key to sign a transaction.
quickSend(contracts: IContractRequest[], txData?: string[], options?: ITxOptionsRequest)Promise<IBroadcastResponse>Simplifies the build/sign/broadcast flow into a single method.
downloadAsPem(path?: string)Promise<void>Saves the .pem file for that account instance private key and address.
broadcastTransactions(txs: string[] | ITransaction[])Promise<IBroadcastResponse>Broadcasts an array of transactions to the provided node.
validateSignature(message: string, signature: string)Promise<boolean>Checks if a signature is compatible with a given address and message.

All utility methods

All method packed into the utils object.

MethodParametersReturnDescription
getAddressFromPrivateKey(privatekey: string)Promise<string>Gets the address for the given РК based on the ED25519 curve and bech32 address conversion.
generateKeyPair()Promise<{ privatekey: string; address: string; }>Generates a new private key/address pair, based on the ED25519 curve and bech32 address conversion.
getProviders()IProviderGets the current provider object.
setProviders(providers: IProvider)voidSets the provider object.
broadcastTransactions(txs: ITransaction[])Promise<IBroadcastResponse>Broadcasts an array of transactions to the provided node.
decodeTransaction(tx: ITransaction)Promise<IDecodedTransaction>Decodes a built transaction to a more human-readable JSON.
transactionsProcessed(txs: Promise[], tries?: number)Promise<IDecodedTransaction[]>Resolves when all the broadcasted transactions are processed on chain, rejects when the try limit is reached.
accountsReady(accounts: Account[])Promise<void>Resolves when all the accounts in the array are initialized.
validateSignature(message: string, signature: string, address: string)Promise<boolean>Checks if a signature is compatible with a given address and message.
decodeAddress(address: string)Promise<Uint8Array>Decodes an address to a Uint8Array.
toHex(data: Uint8Array)stringHelper method to convert Uint8Array to a hex string.

Auxiliary Scripts

In this section, we provide scripts to automate the most commonly executed transaction patterns in KleverChain.

Mint + UpdateMetadata

Each Update Metadata has a Kapp Fee of 2KLV, and the Bandwidth Fee depends on the size of the metadata

metadataScript.js

import { Account, utils, TransactionType } from "@klever/sdk-node";

utils.setProviders({
  api: "https://api.devnet.klever.finance",
  node: "https://node.devnet.klever.finance",
});

const privateKey = "Your PrivateKey";
const mainAccount = new Account(privateKey);
await mainAccount.ready;
const receiverAccount = mainAccount.getAddress(); // the account receiver of the NFTs

const assetTriggerMint = {
  amount: 50, // any amount you want, up to 50
  assetId: "Your AssetId",
  triggerType: 0, // Mint
};

const contracts = [
  {
    type: TransactionType.AssetTrigger,
    payload: {
      ...assetTriggerMint,
      receiver: receiverAccount,
    },
  },
];

const transactionRes = [mainAccount.quickSend(contracts)];
const result = await utils.transactionsProcessed(transactionRes);
const arrayAssetId = [];

if (result[0].transaction.status !== 'success') {
  throw new Error(`Transaction failed: ${result[0].transaction.resultCode}`);
}

result[0].transaction.receipts.slice(2).forEach((element) => {
  if (!element.assetId.includes('/')) {
    throw new Error(`${element.assetId} is not a NFT. The amount was minted but the metadata can't be updated`);
  }
  arrayAssetId.push(element.assetId);
});

const updateMetaDataContracts = [];
const updateMetaDataDatas = [];
arrayAssetId.forEach((assetId) => {
  updateMetaDataContracts.push({
    type: TransactionType.AssetTrigger,
    payload: {
      triggerType: 8,
      assetId: assetId,
      mime: "application/json", // You can use any MIME type.
      // Here is a list of the most common ones: 
      // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
      receiver: receiverAccount,
    },
  });
  updateMetaDataDatas.push(JSON.stringify({assetId})); // You can send any metadata for the given assetId here
});

const requestArray = [];
for (
  let index = 0;
  index < updateMetaDataContracts.length;
  index = index + 20 // The amount of contracts per transaction is limited to 20
) {
  const request = await mainAccount.quickSend(
    updateMetaDataContracts.slice(
      index,
      index + 20 < updateMetaDataContracts.length
        ? index + 20
        : updateMetaDataContracts.length
    ),
    updateMetaDataDatas.slice(
      index,
      index + 20 < updateMetaDataContracts.length
        ? index + 20
        : updateMetaDataContracts.length
    )
  );
  requestArray.push(request);
}

const resultUpdateMetaData = await utils.transactionsProcessed(requestArray);
resultUpdateMetaData.forEach((element, index) => {
  console.log(`Hash ${index}: ${element.transaction.hash}`)
});

Was this page helpful?