KANALABS WALLET SDK
please refer setup and contribution for development and contributions
Supported Networks
Testnet :
1. Goerli
2. BscTest
3. Mumbai
Mainnet :
1. Mainnet (Ethereum)
2. Bsc
3. Matic
4. Avalanche
5. Arbitrum
6. klaytn
7. Aptos
Available Functions (core functions)
1 . initialize() => initialize SDK instance for multiple network or specific network if provided
2 . destroyInstances() => detroy all SDK instance or network or specific network if provided
3 . addToBundle() => batch multiple transaction into one
4 . estimate() => estimate the gas cost before submitting the transaction
5 . submit() => submit the batch transaction
USAGE
Social Login Setup
For social login setup we can use https://web3auth.io/docs/sdk/web/ sdk which provides us the login for Gmail,facebook,discord etc ..,
This Provider will return the key for us to initialize the kana-wallet-sdk
Installation
npm i @kanalabs/kana-wallet-sdk
Using with metamask on react
To avoid multiple signing invoke in metamask while initializing please use sessions
in session.ts (or in file of your choice)
import { SessionStorage } from '@kanalabs/kana-wallet-sdk';
const storageVersion = 1;
const setItem = (key: string, value: string) =>
localStorage.setItem(`@kanaTransactionBuilder-storage-v${storageVersion}:${key}`, value);
const getItem = (key: string): string | null =>
localStorage.getItem(`@kanaTransactionBuilder-storage-v${storageVersion}:${key}`);
class LocalSessionStorage extends SessionStorage {
constructor() {
super();
}
setSession = async (walletAddress: string, session: Object) => {
if (walletAddress) {
setItem(`session-${walletAddress}`, JSON.stringify(session));
}
};
getSession = (walletAddress: string) => {
let result = null;
try {
const raw = getItem(`session-${walletAddress}`);
result = raw ? JSON.parse(raw) : null;
} catch (err) {
//
}
return result;
};
resetSession = (walletAddress: string) => {
setItem(`session-${walletAddress}`, '');
};
}
export const sessionStorageInstance = new LocalSessionStorage();
Once the session is set up is done, please pass the sessionStorageInstance while initializing the SDK
if (!MetaMaskWalletProvider.detect()) {
console.log('MetaMask not detected');
return;
}
const walletProvider = await MetaMaskWalletProvider.connect();
const sdk = await initializeWalletSdk(walletProvider, undefined, {
sessionStorage: sessionStorageInstance,
omitWalletProviderNetworkCheck: true,
});
Initialize SDK
import { initializeWalletSdk, NetworkNames, EnvNames } from '@kanalabs/kana-wallet-sdk'
const privateKey = '0x33........;
const erc20Address = '0x2d7882beDcbfDDce29Ba99965dd3cdF7fcB10A1e'; //plasma (pos)
const main async () =>{
//Initializes all available networks
const sdk = await initializeWalletSdk(privateKey); //to uses test net pass the env as TestNets
const currentSdkInstance = sdk.setCurrentInstance(NetworkNames.Matic); // if currentinstance is not set, optionally you can pass network as a param to each function
const matic_balance = await currentSdkInstance.getAccountBalances();
console.log(matic_balance)
const address = sdk.contractAddress //retuns the the smart wallet address
//transfer tokens
const transfer = await sdk.erc20().tokenTransfer(erc20Address, '0x45A618c24B35413946cbaB218B56b28EA79b9C11', 10000);//Adding transactions to batch and estimation in done inside the function
const submit = await sdk.erc20().walletTransactions().submit();
console.log(submit)
}
main()
TOKEN LIST
await sdk.getTokenList('tokenListToken', NetworkNames.Avalanche);
TOKEN DETAILS
await sdk.getTokenDetails({
tokenAddress: 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174,
chainId: 137,
provider?: // optional,
});
NFT LIST
await sdk.getNftList({
account: 'account address',
});
Get Account Members
await sdk.getAccountMembers();
//Returns
{
"items": [
{
"member": {
"address": "0x6bd1fE6323c29B4f4Ea5Aa12D9A372182ADa20Eb", //key based account
"type": "Key",
"state": null,
"store": null,
"createdAt": "[Date] 2023-06-02 12:39:05",
"updatedAt": "[Date] 2023-06-02 12:39:05"
},
"type": "Owner",
"state": "Added",
"store": "PersonalAccountRegistry",
"createdAt": "[Date] 2023-06-02 12:39:08",
"updatedAt": "[Date] 2023-06-02 12:39:08"
}
],
"currentPage": 1,
"nextPage": null
}
{
"items": []
}
BATCH TRANSACTIONS
Adding your transaction to a batch
When using kana-wallet-sdk to send transactions, we first add the transaction to a "batch". A batch can contain many transactions for a more gas-efficient operation, but in this example - we're just going to add one transaction to the batch. It will behave as if we are just sending a single transaction.
//Initialize the SDK as mentioned above
import { NetworkNames } from '@kanalabs/kana-wallet-sdk';
const batch = await sdk.walletTransactions().addToBundle({
to: '0x0fd7508903376dab743a02743cadfdc2d92fceb8', // Destination Ethereum address
value: 100, // This value is in wei
data: null, // Optional contract data payload
});
Once the above method, addToBundle has been executed, the instruction to send 100 wer to the Ethereum address 0x0fd7508903376dab743a02743cadfdc2d92fceb8. has been added into the batch. You can choose to continue adding more transactions to this batch.
Estimating your batch
At this point, your batch is ready to have the gas cost estimated. This gives you, or your users, the opportunity to see how much this transaction may cost on the chain that you have instantiated the SDK on.
const estimate = await sdk.walletTransactions().estimate();
console.log('Gas estimated at:', estimate);
Submitting your batch
The final step is to submit your batch, containing your one or more transactions, to wallet-sdk. The wallet-sdk will queue and manage your batch, and endeavour to do everything it can to get your transaction onto your chosen blockchain.
const submit = await sdk.walletTransactions().submit();
Getting transaction history
const transactions = await sdk.walletTransactions().getTransactions({
account: 'account address',
});
Getting transaction info for an hash
const transactions = await sdk.walletTransactions().getTransaction({
hash: 'transaction hash',
});
SWAP
Supported chains and exchanges
Currently, we support following chains and exchanges.
MAINNET
1 . 1inch
2 . Synethetix
3 . Uniswap
4 . Sushiswap
POLYGON, formerly known as MATIC:
1 . 1inch
2 . Sushiswap
BINANCE SMART CHAIN
1 . 1inch
2 . Sushiswap
Searching for swap offers
To start a search for token swap offers, we need to call the swapOffers method with our desired token and amount parameters as illustrated below.
import { utils as EthersUtils } from 'ethers';
// usdc(pos)
const fromToken = {
address: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
decimals: 6,
};
// USDC(so)
const toToken = {
address: '0x576Cf361711cd940CD9C397BB98C4C896cBd38De',
decimals: 6,
};
// Amount requested to swap
const fromAmountEthers = EthersUtils.parseUnits(
'0.01', // Amount in ethers
fromToken.decimals,
);
const swapParams = {
fromTokenAddress: fromToken.address,
toTokenAddress: toToken.address,
fromAmount: fromAmountEthers,
};
const swapOffers = await sdk.swapOffers(swapParams);
const transactionData = swapOffers[0].transactions;
transactionData.map(async (transactiondata) => {
sdk.walletTransactions().addToBundle(transactiondata);
});
const estimate = await sdk.walletTransactions().estimate();
const submit = await sdk.walletTransactions().submit();
When swapOffers is executed, you will receive an array of 0 or more offers based on your swap request. For each item in the array,this data object is returned:
Property | Meaning |
---|---|
exchangeRate | The rate that is being returned by the exchange |
provider | Who is providing this swap offer |
receiveAmount | The total amount due to be received |
transactions | An array of required transactions to execute this swap |