This sample app demonstrates how to use Circle's Cross-Chain Transfer Protocol (CCTP) to transfer USDC across chains. It walks through the CCTP flow — approve on EVM source chains, burn, attest through Circle's IRIS sandbox API, and mint — on both EVM and Solana testnets using a Next.js interface.
Note: This demo now uses injected user wallets for signing. Use testnet wallets only and do not treat this sample as production-ready custody or wallet infrastructure.
- Node.js 22+
- An injected EVM wallet such as MetaMask
- An injected Solana wallet such as Phantom
- Testnet USDC on the relevant chains and native tokens for gas fees
-
Clone this repository:
git clone https://github.com/circlefin/circle-cctp-crosschain-transfer.git
-
Install dependencies:
npm install
-
Start the app in development:
npm run dev
The app will be running at http://localhost:3000.
- The app is built with Next.js (App Router) and uses viem for EVM interactions and @coral-xyz/anchor + @solana/web3.js for Solana interactions.
- The core transfer logic lives in a single React hook (
use-cross-chain-transfer.ts) that orchestrates the four CCTP steps: approve spending on EVM source chains, burn USDC on the source chain, retrieve an attestation from Circle's IRIS sandbox API, and mint USDC on the destination chain. Solana transfers do not require a separate approval transaction. - Chain configuration (contract addresses, destination domains, viem chain definitions) is centralized in a single
CHAIN_CONFIGSrecord inchains.ts. - The app uses the connected EVM and/or Solana wallet based on the selected source and destination chains.
- Arbitrum Sepolia
- Arc Testnet
- Avalanche Fuji
- Base Sepolia
- Codex Testnet
- Cronos Testnet
- Edge Testnet
- Ethereum Sepolia
- HyperEvm Testnet
- Injective Testnet
- Ink Sepolia
- Linea Sepolia
- Monad Testnet
- Morph Hoodi
- Optimism Sepolia
- Pharos Atlantic
- Plume Sepolia
- Polygon Amoy
- Sei Testnet
- Solana Devnet
- Sonic Testnet
- Unichain Sepolia
- Worldchain Sepolia
- XDC Testnet
- XLayer Testnet
src/hooks/use-cross-chain-transfer.ts: Core CCTP transfer hook (approve, burn, attest, mint)src/lib/chains.ts: Centralized chain configuration and contract addressessrc/lib/solana-utils.ts: Solana-specific utilities (Anchor setup, PDA derivation, nonce decoding)src/app/page.tsx: Main UI for selecting chains, entering amounts, and viewing transfer progresssrc/components/timer.tsx: Transfer duration timer
- This sample is scoped to testnets only.
- Connect an EVM wallet for EVM source or destination chains.
- Connect a Solana wallet for Solana source or destination chains.
- Attestation polling can take several minutes depending on source chain finality.
npm run dev: Start the Next.js development servernpm run build: Build the production applicationnpm run start: Start the production servernpm run lint: Run ESLint
This sample application:
- Assumes testnet or sandbox usage only
- Relies on injected browser wallets for signing
- Is not intended for production use without modification
See SECURITY.md for vulnerability reporting guidelines. Please report vulnerabilities privately through Circle's Vulnerability Disclosure Program.