This example uses web3.js to transfer USDC from an address on ETH testnet to another address on AVAX testnet.
The script requires Node.js installed.
- Install dependencies by running
npm install
- Create a
.env
file and add below variables to it:ETH_TESTNET_RPC=<ETH_TESTNET_RPC_URL> AVAX_TESTNET_RPC=<AVAX_TESTNET_RPC_URL> ETH_PRIVATE_KEY=<ADD_ORIGINATING_ADDRESS_PRIVATE_KEY> AVAX_PRIVATE_KEY=<ADD_RECEIPIENT_ADDRESS_PRIVATE_KEY> RECIPIENT_ADDRESS=<ADD_RECEIPIENT_ADDRESS_FOR_AVAX> AMOUNT=<ADD_AMOUNT_TO_BE_TRANSFERED>
- Run the script by running
npm run start
The script has 5 steps:
-
First step approves
ETH_TOKEN_MESSENGER_CONTRACT_ADDRESS
to withdraw USDC from our eth address.const approveTx = await usdcEthContract.methods.approve(ETH_TOKEN_MESSENGER_CONTRACT_ADDRESS, amount).send({gas: approveTxGas})
-
Second step executes
depositForBurn
function onTokenMessengerContract
deployed in Sepolia testnetconst burnTx = await ethTokenMessengerContract.methods.depositForBurn(amount, AVAX_DESTINATION_DOMAIN, destinationAddressInBytes32, USDC_ETH_CONTRACT_ADDRESS).send();
-
Third step extracts
messageBytes
emitted byMessageSent
event fromdepositForBurn
transaction logs and hashes the retrievedmessageBytes
usingkeccak256
hashing algorithmconst transactionReceipt = await web3.eth.getTransactionReceipt(burnTx.transactionHash); const eventTopic = web3.utils.keccak256('MessageSent(bytes)') const log = transactionReceipt.logs.find((l) => l.topics[0] === eventTopic) const messageBytes = web3.eth.abi.decodeParameters(['bytes'], log.data)[0] const messageHash = web3.utils.keccak256(messageBytes);
-
Fourth step polls the attestation service to acquire signature using the
messageHash
from previous step.let attestationResponse = {status: 'pending'}; while(attestationResponse.status != 'complete') { const response = await fetch(`https://iris-api-sandbox.circle.com/attestations/${messageHash}`); attestationResponse = await response.json() await new Promise(r => setTimeout(r, 2000)); }
-
Last step calls
receiveMessage
function onMessageTransmitterContract
deployed in Avalanche Fuji Network to receive USDC at AVAX address.Note: The attestation service is rate-limited, please limit your requests to less than 1 per second.
const receiveTx = await avaxMessageTransmitterContract.receiveMessage(receivingMessageBytes, signature);