import { ethers } from 'ethers' const transactionHash = '0xc37329f7bfada70be0a695031b270741542d1dd477fc0a2e0f476d242b8ff508' // sepolia 11155111 const srcChainRPC = 'https://sepolia.gateway.tenderly.co' // base sepolia 84532 const destChainRPC = 'https://base-sepolia.gateway.tenderly.co' const messengerAddress = '0x7865fAfC2db2093669d92c0F33AeEF291086BEFD' async function main() { // decode message on origin chain const srcProvider = new ethers.JsonRpcProvider(srcChainRPC) const transactionReceipt = await srcProvider.getTransactionReceipt(transactionHash) const eventTopic = ethers.solidityPackedKeccak256( ['string'], ['MessageSent(bytes)'] ) const log = transactionReceipt?.logs.find((l) => l.topics[0] === eventTopic) const abiCoder = ethers.AbiCoder.defaultAbiCoder() const messageBytes = abiCoder.decode(['bytes'], log.data)[0] const messageHash = ethers.keccak256(messageBytes) // get attestation from Circle's servers // NB: url for testnets only const url = `https://iris-api-sandbox.circle.com/attestations/${messageHash}` const resp = await fetch(url) const { attestation, status } = await resp.json() console.log({ messageBytes, attestation, status }) // receive attestation on dest server if (status === 'completed') { // get destination provider const destProvider = new ethers.JsonRpcProvider(destChainRPC) // TODO: parse signer // get contract const messenger = new ethers.Contract( messengerAddress, ['function receiveMessage(bytes,bytes)'], destProvider ) await messenger.receiveMessage(messageBytes, attestation) } } main().then(() => console.log('ok'))