@hosokawa-dev/axelar-local-dev v1.0.2
Axelar Local Development Environment
This environment allows you to set up a local instances of the Axelar Gateways, instantiate your application-level executor contracts on the source/destination chains, and simulate message relaying between them.
Installation and simple use.
To install on simply run:
npm install axelarnetwork/axelar-local-devThe following script shows a simple example of how to use this module to create two test blockchains and send some UST from one to the other.
// axelarTest.js
const axelar = require('@axelar-network/axelar-local-dev');
(async () => {
const chain1 = await axelar.createNetwork();
const [ user1 ] = chain1.userWallets;
const chain2 = await axelar.createNetwork();
const [ user2 ] = chain2.userWallets;
await chain1.giveToken(user1.address, 'UST', 1000);
console.log(`user1 has ${await chain1.ust.balanceOf(user1.address)} UST.`);
console.log(`user2 has ${await chain2.ust.balanceOf(user2.address)} UST.`);
// Approve the AxelarGateway to use our UST on chain1.
await (await chain1.ust.connect(user1).approve(chain1.gateway.address, 100)).wait();
// And have it send it to chain2.
await (await chain1.gateway.connect(user1).sendToken(chain2.name, user2.address, 'UST', 100)).wait();
// Have axelar relay the tranfer to chain2.
await axelar.relay();
console.log(`user1 has ${await chain1.ust.balanceOf(user1.address)} UST.`);
console.log(`user2 has ${await chain2.ust.balanceOf(user2.address)} UST.`);
})();Simply run node <path to the above script> to test it. Additional examples are present in the examples directory and can be run with:
node node_modules/@axelar-network/axelar-local-dev/examples/<example_dir>/<file_name>.jsFunctionality
This module exports the following functionality:
Network: This object type is used to handle most functionality within the module. It has the following properties: -name: The name of the network. -chainId: The chainId of the network. -provider: Theethers.Providerfor the network. -userWallets: A list of fundedethers.Walletobjects. -gateway: Anethets.Contractobject corresponding to the Axelar Gateway on the network. -gasReceiver: Anethets.Contractobject corresponding to the AxelarGasReceiver that receives gas for remote execution. It expects gas between the same tworelay()s to funtion properly. -ust: Anethets.Contractobject corresponding to the IERC20 of the Axelar Wrapped UST on this network. -ownerWallet,operatorWallet,relayerWallet,adminWalletsthresholdlastRelayedBlock: These are for configuring the gateway and relaying. -deployToken(name, symbol, decimals, cap): Deploys a new token on the network. For a token to be supported properly it needs to be deployed on all created networks. -getTokenContract(sybmol): Returns anethers.Contractlinked to the ERC20 token represented bysymbol. -giveToken(address, symbol, amount): Givesamountofsymboltoken toaddress. -getInfo(): Returns an object with all the information about theNetwork. -relay(): This method is either equivalent to calling the local instance of this module'srelay()(see below) or, for remote networks, the host's instance ofrelay().createNetwork(options): Creates a newNetwork. Alloptionsare optional here but the following can be used:name: The name to give theNetwork. Defaults to`Chain ${n}`chainId: The chainId of the created network. Defaults ton.seed: A string used to create the prefunded accounts. Different seeds will result in different contract addresses as well.port: If specified the created blockchain will be served onport. Additionally, accessing/axelarwill result in the same output asNetwork.getInfo()and accessing/relaywill cause the networks present in the instance serving this blockchain torelay().dbPath: A path to a folder to save this network. If specified and the network has been saved all other options are ignored and the network is loaded from the database.
getNetwork(urlOrProvider, info=null): ReturnNetworkhosted elsewhere into this instance.infoif specified is expected to have the same format asNetwork.getInfo().setupNetwork(urlOrProvider, options): Deploy the gateway and UST Token on a remote blockchain and return the correspondingNetwork. The only value that is required inoptionsisownerKeywhich is a secret key of a funded account. Available options are:ownerKey: This is required and needs to be a funded secret key.name: The name of the network. Defaults to`Chain ${n}`chainId: The chainId of the created network. Defaults ton.userKeys: An array of funded secretKeys to createNetwork.userWalletswith. Defaults to[].operatorKey,relayerKey: They both default toownerKey.adminKeys: Defaults to[ownerKey].threshold: The number of required admins to perform administrative tasks on the gateway. Defaults to1.
listen(port, callback = null): This will serve all the created networks on portport. Each network is served at/iwhereiis the index of the network innetworks(the first network created is at/0and so on).getAllNetworks(url): This will retreive all the networks served bylistencalled from a different instance.relay(): A function that passes all the messages to all the gateways and calls the appropriateIAxelarExecutablecontracts.getDepostiAddress(sourceNetwork, destinationNetwork, destinationAddress, symbol): This function generates a deposit address onnetwork1that will route any funds of typesymboldeposited there (minus some fee) to thedestinationAddressinnetwork2.getFee(sourceNetwork, destinationNetwork, symbol): returns the fee for transferring funds. Is set to a constant1,000,000.getGasPrice(sourceNetwork, destinationNetwork, tokenOnSource): returns the gas price to execute ondestinationChain, to be payed insourceChainin token specified bytokenOnSource(which is given as an address).tokenOnSource=AddressZerocorresponds to the native token of the source chain. It always returns1but may change in the future.stop(network): Destroys the network and removes it from the list of tracked networks.stopAll(): Stops all tracked networks.networks: A list of all theNetworks in this instance.
Smart Contracts
To use the Networks created you need to interact with the deployed AxelarGateway contract. You can send remote contract calls to the contracts implementing the IAxelarExecutable interface.
AxelarGateway
This contract exposes three functions to use:
sendToken(string destinationChain, string destinationAddress, string symbol, uint256 amount): ThedestinationChainhas to match the network name for the token to reach its destination after relaying. ThedestinationAddressis the human-readable version of the address, prefixed with0x. This is astringinstead of anaddressbecause in the real world you can send token to non-evm chains that have other address formats as well.tokenSymbolhas to match one of the tokens that are deployed in the network, by default just UST but additional tokens can be added (seedeployTokenunderNetwork).callContract(string destinationChain, string contractDestinationAddress, bytes payload): See above fordestinationChainandcontractDestinationAddress.payloadis the information passed to the contract on the destination chain. Useabi.encodeto producepayloads.callContractWithToken(string destinationChain, string contractDestinationAddress, bytes payload, string symbol, uint256 amount): This is a combination of the above two functions, but the token has to arrive at the contract that is executing.
IAxelarExecutable
This interface is to be implemented for a contract to be able to receive remote contract calls. There are two functions that can be overriden, but depending on the use you may only choose to override one of them only.
_execute(string memory sourceChain, string memory sourceAddress, bytes calldata payload): This will automatically be called when Axelar relays all messages.sourceChainandsourceAddresscan be used to validate who is making the contract call, andpayloadcan be decoded withabi.decodeto produce any data needed._executeWithToken(string memory sourceChain, string memory sourceAddress, bytes calldata payload, string memory symbol, uinst256 amount): This is the same as above but it is guaranteed to have also receivedamounttoken specified bysymbol. You can use _getTokenAddress(symbol) to obtain the address of the ERC20 token received.
AxelarGasReceiver
This contract is automatically deployed and can be used to pay gas for the destination contract execution on the source chain. Smart contracts calling callContract and callContractWithToken should also handle paying for gas. It exposes many functions, but the main ones are
receiveGas(string destinationChain, string destinationAddress, bytes payload, address gasToken, uint256 gasAmount): ReceivesgasAmountofgasTokento execute the contract call specified. The execution will use a gasLimit ofgasAmount / getGasPrice(...)(see above forgetGasPrice).receiveGasNative(string destinationChain, string destinationAddress, bytes payload): As above with the native token as thegasTokenandmsg.valueas thegasAmount.receiveGasWithToken(string destinationChain, string destinationAddress, bytes payload, string symbol, uint256 amountThrough, address gasToken, uint256 gasAmount),receiveGasNtiveWithToken(string destinationChain, string destinationAddress, bytes payload, string symbol, uint256 amountThrough): Similar to the above functions but they are forcallContractWithTokeninstead ofcallContract.ReceiveGas(Native)AndCallRemote(WithToken)(...): There are four such functions that will also pass the call to the gateway after receiving gas, for convenience.
3 years ago