redeemOnEthWithType()

Initiates transaction to receive tokens from the contract on EVM for USDC Tokens that are supported via Circle's CCTP (https://developers.circle.com/stablecoins/supported-domains).

Method Parameters

tokenBridgeAddress: string

Ethereum bridge contract address

signer: ethers.Signer

ethers js Signer

signedVAA: Uint8Array

Parsed signed VAA

messageType: string

receiving message type ("CCTP")

messagePayload: string

receiving message payload

network: string

network to use ("WORMHOLE"/"MESSINA")

Returns

Returns ethers js ethers.ContractReceipt

Usage

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)
    : ''
}

Last updated