XRPL to XRPL EVM Sidechain transfer
This guide shows how relay a transfer message manually from XRPL to an XRPL EVM Sidechain.
- Send a
verify_messages
transaction
axelard tx wasm execute axelar13w698a6pjytxj6jzprs6pznaxhan3flhf76fr0nc7jg3udcsa07q9c7da3 '{ verify_messages: [ { user_message: { tx_id: TX_HASH, source_address: SOURCE_ADDRESS, destination_chain: "xrpl-evm-sidechain", destination_address: DESTINATION_ADDRESS, amount: { drops: AMOUNT_IN_DROPS }, payload_hash: PAYLOAD_HASH, }, }, ], }' --gas 20000000 --gas-adjustment 1.5 --gas-prices 0.00005uamplifier --chain-id devnet-amplifier --node http://devnet-amplifier.axelar.dev:26657
- Route incoming messages for XRPL Axelar gateway.
axelard tx wasm execute axelar13w698a6pjytxj6jzprs6pznaxhan3flhf76fr0nc7jg3udcsa07q9c7da3 '{ route_incoming_messages: [ { payload: relayerRequest.userRequest.payload, message: { user_message: userMessage, }, }, ], }' --gas 20000000 --gas-adjustment 1.5 --gas-prices 0.00005uamplifier --chain-id devnet-amplifier --node http://devnet-amplifier.axelar.dev:26657
- Execute the ITS Hub message. To compute the payload field, you need to run the following script.
const { ethers } = require("ethers"); const interchainTransfer = { // TODO: Check if this is correct messageType: ethers.BigNumber.from("0"), // 0 - Send transfer tokenId: "TOKEN_ID" // XRP token ID sourceAddress: "SOURCE_ADDRESS", destinationAddress: "DESTINATION_ADDRESS", amount: ethers.utils.parseUnits(dropsToXrp("AMOUNT_IN_DROPS").toString()), data: "TRANSACTION_DATA", }; const abiCoder = new ethers.utils.AbiCoder(); const messageEncoded = abiCoder.encode( ["uint256", "bytes32", "bytes", "bytes", "uint256", "bytes"], [ interchainTransfer.messageType, interchainTransfer.tokenId, interchainTransfer.sourceAddress, interchainTransfer.destinationAddress, interchainTransfer.amount, interchainTransfer.data, ], ); const hubMessage = abiCoder.encode( ["uint256", "string", "bytes"], // TODO: Check if this is correct [ethers.BigNumber.from("3"), relayerRequest.userRequest.destinationChain, messageEncoded], );
axelard tx wasm execute axelar1yvfcrdke7fasxfaxx2r706h7h85rnk3w68cc5f4fkmafz5j755ssl8h9p0 '{ execute: { cc_id: { source_chain: "xrpl-evm-sidechain", message_id: MESSAGE_ID, }, payload: CALCULATED_PAYLOAD, }, }' --gas 20000000 --gas-adjustment 1.5 --gas-prices 0.00005uamplifier --chain-id devnet-amplifier --node http://devnet-amplifier.axelar.dev:26657
- Route the message.
axelard tx wasm execute axelar1yvfcrdke7fasxfaxx2r706h7h85rnk3w68cc5f4fkmafz5j755ssl8h9p0'{ route_messages: [ { cc_id: { source_chain: "xrpl", message_id: MESSAGE_ID_FROM_STEP_3, }, destination_chain: "axelarnet", destination_address: "axelar10jzzmv5m7da7dn2xsfac0yqe7zamy34uedx3e28laq0p6f3f8dzqp649fp", source_address: "rP9iHnCmJcVPtzCwYJjU1fryC2pEcVqDHv", payload_hash: PAYLOAD_HASH, }, ], }' --gas 20000000 --gas-adjustment 1.5 --gas-prices 0.00005uamplifier --chain-id devnet-amplifier --node http://devnet-amplifier.axelar.dev:26657
- Construct transfer proof.
axelard tx wasm execute axelar19pu8hfnwgc0vjhadmvmgz3w4d2g7d7qlg6jjky9y2mf8ea4vf4usj6ramg '{ construct_proof: [ { source_chain: "axelarnet", message_id: MESSAGE_ID_FROM_STEP_4, }, ], }' --gas 20000000 --gas-adjustment 1.5 --gas-prices 0.00005uamplifier --chain-id devnet-amplifier --node http://devnet-amplifier.axelar.dev:26657
- Query the contract state to check if the proof was completed. You can find the
multisig_session_id
in the response of theconstruct_proof
transaction.
axelard q wasm contract-state smart axelar19pu8hfnwgc0vjhadmvmgz3w4d2g7d7qlg6jjky9y2mf8ea4vf4usj6ramg '{ proof: { multisig_session_id: multisigSessionId, }, }' --chain-id devnet-amplifier --node http://devnet-amplifier.axelar.dev:26657 --output json
- Send the
execute_data
from the previous step to the destinations Axelar gateway.
const provider = new providers.JsonRpcProvider("XRPL_EVM_SIDECHAIN_RPC"); const wallet = new Wallet("YOUR_PRIVATE_KEY", provider); const tx = await wallet.sendTransaction({ from: wallet.address, to: "0x48CF6E93C4C1b014F719Db2aeF049AA86A255fE2", data: "EXECUTE_DATA", value: "0", }); await tx.wait();
- Execute the ITS transfer.
const provider = new providers.JsonRpcProvider("XRPL_EVM_SIDECHAIN_RPC"); const wallet = new Wallet("YOUR_PRIVATE_KEY", provider); const appContract = new Contract("0x48CF6E93C4C1b014F719Db2aeF049AA86A255fE2", IAxelarExecutable.abi, wallet); const tx = await appContract.execute( "COMMAND_ID", "axelarnet", "TRANSLATED_SOURCE_ADDRESS", `CALCULATED_PAYLOAD`, ); await tx.wait();