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();