Node.js
Here are the articles in this section:
Offline Build/Sign Transaction
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.
Method | Parameters | Return | Description |
---|---|---|---|
getBalance | () | number | Gets that account instance's balance |
getNonce | () | number | Gets that account instance's nonce |
getAddress | () | string | Gets 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.
Method | Parameters | Return | Description |
---|---|---|---|
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 | () | IProvider | Gets the current provider object. |
setProviders | (providers: IProvider) | void | Sets 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) | string | Helper 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}`)
});