By default Account.getDefaultGiver() is Evernode SE giver. It is integrated into Account module. We will use it. But you can always re-define it with method Account.giver(newGiver: AccountGiver) with the following signature:
/** * Object that can be used to send some value to an address */exporttypeAccountGiver= (address:string, value:number) =>Promise<void>;
This guide will help you to implement and configure your custom giver. In the example implementation we will use the same Evernode SE giver with its address, keys and ABI, but you can simply substitute them with your own.
First of all, let's declare our Giver's address, keys and ABI:
constgiverSendTo=async (address, value) => {// Run method `sendTransaction` for the Giver. You can use your custom account,// in this case, method name and arguments might vary:returnawaitgiverAccount.run("sendTransaction", { dest: address, value, bounce:false, });};// In order to implement giver's logics, we must implement `AccountGiver` interfaceconstgiver= { address: giverAddress,sendTo:async (address, value) =>giverSendTo(address, value),};
In this example, we created separated giverSendTo function in order to be able get result of sendTransaction execution, because AccountGiver.sendTo doesn't return any value.
Configure AppKit to use our Giver:
// Set Giver for a clientAccount.setGiverForClient(client, giver);
Thats it. Now any contracts deployment using this client will lead to using your configured Giver.
Usage examples:
Example 1. Contract deployment
In this example we will deploy test HelloWallet contract.
// Generate an ed25519 key pair for new accountconsthelloAccKeys=awaitclient.crypto.generate_random_sign_keys();// Create test contractconsthelloAcc=newAccount(HelloWallet, { signer:signerKeys(helloAccKeys), client,});// Get the future address of the contract:constaddress=awaithelloAcc.getAddress();// Request contract deployment funds form the Giver and deploy `HelloWallet` contract.awaithelloAcc.deploy({ useGiver:true });console.log(`HelloWallet contract was deployed at address: ${address}`);
Example 2. Sending some funds from the Giver to a random address
In this example we will send 10 tokens from our Giver to a random address and check messages and transactions, which were created during the operation.
// Generate new random keypair:consthelloAcc2Keys=awaitclient.crypto.generate_random_sign_keys();// Create account object without client's connection. We don't need to deploy it, we just want to obtain it's future address:
consthelloAcc2=newAccount(HelloWallet, { signer:signerKeys(helloAcc2Keys),});// Get address for the contract:constaddress2=awaithelloAcc2.getAddress();console.log("Sending funds to address:", address2);// Send funds using our separated function in order to obtain result message `id`:constresult=awaitgiverSendTo(address2,10000000000);// Wait and get all messages and transactions, which were created during the whole operation:consttransaction_tree=awaitclient.net.query_transaction_tree({ in_msg:result.transaction.in_msg,});// Do some checks in order to assure, that funds are received:assert.equal(transaction_tree.messages.length,2,"There must be 2 messages");assert(!transaction_tree.messages[1].bounce,"Expected 2nd message to be not-bounceable");assert.equal(transaction_tree.messages[1].value,'0x2540be400'/*10 000 000 000*/,"2nd message must have a value of 10 000 000 000",);assert.equal(transaction_tree.messages[1].dst, address2,"2nd message's destination must be "+ address2);assert.equal(transaction_tree.transactions.length,2,"There must be 2 transactions");assert.equal(transaction_tree.transactions[1].account_addr, address2,"2nd transaction's account address must be "+ address2,);assert(transaction_tree.transactions[1].aborted,"2nd transaction must be aborted because of uninitialized account",);console.log("Funds transferred.");