Before you start
Start with a Next.js app that hasParaProvider, a login flow, and an EVM wallet for the signed-in user. These Para guides cover that setup:
The wallet needs native USDC to bridge and ETH for Ethereum gas. It also needs enough USDC on Arc to pay for a destination transaction, since Arc uses USDC as its gas token. Review the transfer amount and network fees with the user before submitting a mainnet transaction.
This route uses CCTP domain
0 for Ethereum and domain 26 for Arc. These are protocol domain IDs, not EVM chain IDs. Bridge Kit’s Ethereum and Arc chain definitions carry the domains and CCTP contract addresses; the example does not hardcode them.Install the bridge packages
From your Para Next.js application, install Bridge Kit, Circle’s viem adapter, and the Para viem integration. The versions below are the ones used for this guide.NEXT_PUBLIC_ETHEREUM_RPC_URL and NEXT_PUBLIC_ARC_RPC_URL to RPC endpoints for the two mainnets. The values are public browser configuration, so do not put private RPC credentials in them.
Connect Para to Bridge Kit
Use and inside your existingParaProvider to check the signed-in Para wallet. Confirm the session with . selects the EVM wallet, and gives Circle’s ViemAdapter a wallet client for each chain. Both clients use the same Para account.
src/hooks/useCctpAdapter.ts
Bridge Ethereum USDC to Arc
Callbridge() in response to a user action. Bridge Kit uses CCTP V2 to burn USDC on Ethereum, waits for Circle’s attestation, then mints USDC on Arc. Setting useForwarder: false keeps the Arc mint signed by Para. The result contains each step and the overall state. amount is a human-readable USDC amount.
src/hooks/useCctpBridge.ts
bridgeUsdc("1.00") from a transfer button. It returns the Bridge Kit result and a summary with status, failedStep, and the burn and mint transaction hashes and explorer links. Show a transfer as complete only when status is complete. For a failed transfer, read failedStep?.name and failedStep?.errorMessage. Handle errors thrown before Bridge Kit returns a result separately. Open the Ethereum burn and Arc mint explorer links to check their receipts and transferred amounts. The fetchAttestation event records progress between those transactions; it is not itself an onchain transaction.
Resume an interrupted transfer
Ifresult.state is error, inspect result.steps before asking the user to try again. An approved or burned transfer may already have spent gas or destroyed the source USDC. Keep that result and pass it to resumeTransfer(result) from a separate Resume action. The hook gives Bridge Kit’s retry() a fresh authenticated Para adapter and returns the updated result and status summary.
Do not start a second bridge() call to recover a transfer whose burn succeeded. If a retry still fails, keep the burn transaction hash and investigate the failed step before attempting another transaction. A pending result is not a confirmed destination mint.