Skip to main content
Stablecoin liquidity does not live on one chain. With Circle’s CCTP V2, USDC moves natively across 13+ chains by burning on the source and minting on the destination: no wrapped tokens, no bridge pools. That is great for liquidity and a problem for whoever has to account for it: a single dollar can be burned on Ethereum but not yet minted on Base, and your cash position is now split across two ledgers and a few minutes of uncertainty. This guide builds one cross-chain settlement ledger. A multi-chain Turbo pipeline indexes every burn and every mint, matches them by nonce, and gives your treasury a single table showing exactly where every dollar is: settled, or in-flight.

How CCTP transfers work

Every CCTP transfer produces two onchain events on two different chains, correlated by a nonce (and a message hash):
  • Source: DepositForBurn on the TokenMessenger contract, carrying the nonce, burn amount, destinationDomain, and mintRecipient.
  • Destination: MintAndWithdraw on the MessageTransmitter/TokenMinter, carrying the matching nonce and mint amount.
  • In-flight means the burn exists but the mint has not landed yet. Fast Transfers resolve in seconds; Standard Transfers wait for source-chain hard finality (~13-19 minutes on Ethereum).
CCTP identifies each chain by a numeric domain ID, not a chain ID: Ethereum 0, Avalanche 1, Optimism 2, Arbitrum 3, Noble 4, Solana 5, Base 6, Polygon PoS 7. Confirm the current list and contract addresses in Circle’s CCTP docs.

Prerequisites

  • The Turbo CLI extension installed and logged in.
  • A Postgres database and a Goldsky secret.
  • The TokenMessenger and MessageTransmitter contract addresses for each chain you settle on (from Circle’s docs). CCTP V2 is live on Ethereum, Base, Arbitrum, Optimism, Polygon, and Avalanche, all supported by Goldsky across every product.

Step 1: Index burns across every source chain

Stream DepositForBurn from the TokenMessenger on each chain and combine them with UNION ALL. This is the multi-chain monitoring pattern with a decode step.
cctp-burns.yaml
The event_params[n] positions above follow the CCTP ABI field order. Confirm them against the ABI you fetch, since V1 and V2 differ. Fetching the ABI with _gs_fetch_abi (rather than hardcoding) keeps the pipeline correct across upgrades.

Step 2: Index mints on every destination chain

Mirror Step 1 for the destination side. Exactly as each source chain tagged its burns with a constant source_domain, each destination chain tags its mints with its own destination_domain, persisted so the ledger records where each mint landed. The join key itself is (source_domain, nonce), and both come from the MessageReceived event on each chain’s MessageTransmitter (the MintAndWithdraw event does not carry the nonce).
cctp-mints.yaml
Confirm the MessageReceived event name and event_params positions against the ABI you fetch; they differ between CCTP V1 and V2. CCTP nonces are scoped per source domain, so the join key is (source_domain, nonce). Both come from MessageReceived, while destination_domain records the chain the mint landed on. Amount and recipient already live on the burn row, so the mint row only needs those keys plus timing. A chain is both a source and a destination, so you can fold burns and mints into one pipeline with more sinks, or keep them split for clarity.

Step 3: Reconcile into one ledger

With both tables filling in real time, the cross-chain ledger is a single join on the message identity, (source_domain, nonce):
You now have, in one query:
  • Where every dollar is: settled on the destination, or in-flight between chains.
  • Your true cross-chain cash position: sum settled balances per domain, plus in-flight amounts by destination.
  • Corridor analytics: volume and settlement latency by (source_domain → destination_domain).
  • Stuck-transfer detection: anything delayed past your SLA.

Step 4: Alert on stuck transfers with Compose

Turn delayed from a dashboard row into an action. A scheduled Compose task checks pending transfers against Circle’s Iris attestation service and escalates anything unresolved.
src/tasks/cctp-watchdog.ts
Every check is traced and the task retries durably, so the watchdog itself never silently dies.

Business outcomes

  • One cross-chain cash position instead of a spreadsheet per chain.
  • In-flight visibility: you know the moment a transfer is late, with the exact nonce to investigate.
  • Corridor intelligence: real settlement times and volumes per route, to tune where you hold liquidity.
  • Works with Circle Gateway too: the same burn/mint ledger underpins reporting on unified USDC balances.

Resources

Can’t find what you’re looking for? Reach out to us at support@goldsky.com for help.