Copy import { ethers } from "ethers" ;
import { approveEth , CHAIN_ID_AVAX , getAllowanceEth , getEmitterAddressEth , parseSequenceFromLogEth , redeemOnEthWithType , transferFromEth , tryNativeToUint8Array } from "@algo-foundry/messina-sdk" ;
import { getSignedVAA } from "@algo-foundry/messina-sdk/lib/cjs/rpc/getSignedVAAUpdate" ;
const provider = new ethers . providers .WebSocketProvider (< ETH_NODE_URL >) as any;
const signer = new ethers.Wallet(< ETH_PRIVATE_KEY >, provider);
const allowance: ethers.BigNumber = await getAllowanceEth("0xC74303104E4aa5833A59767d59e958f4a0F308D4","0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", signer);
if(allowance.lt(AMOUNT_TO_TRANSFER)){
await approveEth (
"0xC74303104E4aa5833A59767d59e958f4a0F308D4" ,
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ,
signer ,
AMOUNT_TO_TRANSFER
);
}
const receipt: ethers.ContractReceipt = await transferFromEth(
"0xC74303104E4aa5833A59767d59e958f4a0F308D4",
signer,
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
BigInt(AMOUNT_TO_TRANSFER * Math.pow(10, 6)), // AMOUNT_TO_TRANSFER * (10 ^ ASSET_DECIMALS)
CHAIN_ID_AVAX,
tryNativeToUint8Array(signer.address, CHAIN_ID_AVAX),
"WORMHOLE"
);
const emitterAddr = getEmitterAddressEth("0xC74303104E4aa5833A59767d59e958f4a0F308D4");
const sequence: string = parseSequenceFromLogEth(receipt, "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B");
let signedVAA = await getSignedVAA(< GUARDIAN_GRPC >, emitterAddr, 'CHAIN_ID_ETHEREUM', sequence, 1000, 5);
// @ts-ignore
const vaaBytes = new Uint8Array(signedVAA!.match(/.{ 1 , 2 }/g)!.map((byte: any) => parseInt(byte, 16)));
const cctpMessage = await getCCTPAttestation(provider, receipt.transactionHash);
const redeem = await redeemOnEthWithType(
"0x201a2F5e03b83B542E617b3004379C8691254c0A",
signer, // Wallet from ethers js
vaaBytes,
"CCTP",
cctpMessage,
"WORMHOLE"
);
async function getCCTPAttestation(
provider: ethers.providers.WebSocketProvider,
transactionHash: string,
): Promise< string > {
const eventTopic = '0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036'
const transferReceipt = await provider .getTransactionReceipt (transactionHash)
const cctpLog = transferReceipt . logs .find ((log) => log .topics[ 0 ] === eventTopic)
const circleBridgeMessage = ethers . utils . defaultAbiCoder .decode (
[ 'bytes' ] ,
(cctpLog as ethers . providers . Log ).data ,
)[ 0 ]
const cctpMessageHash = ethers . utils .keccak256 (circleBridgeMessage)
const response = await fetch (
`https://iris-api.circle.com/attestations/ ${ cctpMessageHash } ` ,
)
if ( response .status != 200 ) {
return ''
}
const jsonResponse = await response.json()
return jsonResponse.status === 'complete'
? circleBridgeMessage + jsonResponse.attestation.substring(2)
: ''
}