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 Klever Blockchain Mainnet, but if you want to use the Klever Blockchain Testnet or a local version of the Klever Blockchain, 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.org",
node: "https://node.testnet.klever.org",
};
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("109")
});
// 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. |
fromHex | (hex: string) | Uint8Array | Helper method to convert a hex string to a Uint8Array. |
validateAddress | (address: string) | Promise<boolean> | Checks if an address is valid for the Klever Blockchain standard. |
Auxiliary Scripts
In this section, we provide scripts to automate the most commonly executed transaction patterns in Klever Blockchain.
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.org',
node: 'https://node.devnet.klever.org',
})
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}`)
})