The SDK module provides a quick and easy way to make contract calls to the blockchain node api directly.
For a more detailed and organized documentation, please visit the official Kleverchain SDK Documentation website.
$ npm install @klever/sdk-node
or
$ yarn add @klever/sdk-node
If you are using Node.js, 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);
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 kleverWeb provider object by setting it before calling the initialize function.
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);
...
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(),
});
// decode TX will encode address in bech32 format and Uint8Array data into utf-8 string array
console.log(tx.decode())
...
once transaction is signed, it can be broadcasted into network using node endpoint: http://localhost:8080/transcation/broadcast
, or using await utils.broadcastTransactions([tx.toBroadcast()])
.
Using the SDK you can generate and import accounts using the following methods from the utils
object:
- generateKeyPair
- getAddressFromPrivateKey
Generating a key pair:
import { utils } from '@klever/sdk-node';
...
const { privateKey, address } = await utils.generateKeyPair();
...
Importing an account:
import { utils } from '@klever/sdk-node';
...
const privateKey; // your private key
const address = await utils.getAddressFromPrivateKey(privateKey);
...
Also, when you create an instance of an account with no private key, the SDK will generate a new key pair for you. Be sure to use the downloadAsPem
account method to save the private key.
All available transactions:
Transfer
Freeze
Unfreeze
Delegate
Undelegate
Claim
Withdraw
CreateAsset
AssetTrigger
ConfigITO
CreateMarketplace
ConfigMarketplace
Sell
Buy
CancelMarketOrder
Proposal
Vote
CreateValidator
ConfigValidator
Unjail
SetAccountName
UpdateAccountPermission
If you want a global instance of your account to use throughout your app, you can create a custom hook to help you with that. Using React as an example, you can create a MyCustomHook.tsx file and create your provider as follows:
import { useState, createContext, useContext } from "react";
import { Account, utils } from "@klever/sdk-node";
interface ISdkContext {
isLoaded(): Promise<boolean>;
getAccount(): Account | null;
setAccount(account: Account): void;
}
const SdkContext = createContext({} as ISdkContext);
const SdkProvider: React.FC = ({ children }) => {
const [acc, setAcc] = useState<Account | null>(null);
const values: ISdkContext = {
isLoaded: () => utils.isKleverWebLoaded(),
getAccount: () => acc,
setAccount: (account) => setAcc(account),
};
return <SdkContext.Provider value={values}>{children}</SdkContext.Provider>;
};
const useSdk = () => useContext(SdkContext);
export { SdkContext, SdkProvider, useSdk };
And wrap your entire App.tsx in it:
import { SdkProvider } from './MyCustomHook';
...
<SdkProvider>
...
<App /> // or <Router /> or <Component />
...
</SdkProvider>
...
With that, you can use it on any child component you want, without the need to instantiate an account every time:
import { useSdk } from './MyCustomHook';
...
const sdk = useSdk();
const account = sdk.getAccount();
...
await account.buildTransaction([
{
payload,
type: TransactionType.Transfer,
},
]);
...
The same pattern of global provider can be achieved in any framework you want, not only React.