Documentation Index
Fetch the complete documentation index at: https://docs.arc.io/llms.txt
Use this file to discover all available pages before exploring further.
Register Arc as a supported chain in your bridge or interoperability protocol.
Arc’s deterministic finality, USDC-native gas model, and CCTP integration
require specific configuration choices that differ from probabilistic-finality
chains.
Prerequisites
Before you begin:
- Familiarity with deploying contracts on EVM chains using Foundry or Hardhat
- Access to an Arc RPC endpoint (
https://rpc.testnet.arc.network)
- A funded deployer wallet with USDC on Arc (USDC is the gas token)
- Understanding of your protocol’s chain registration and relay architecture
Register Arc with the following parameters:
| Property | Value |
|---|
| Chain ID | 5042002 (testnet) |
| RPC (HTTPS) | https://rpc.testnet.arc.network |
| RPC (WebSocket) | wss://rpc.testnet.arc.network |
| Block explorer | https://testnet.arcscan.app |
| Native gas token | USDC |
| Native token decimals | 18 (native), 6 (ERC-20 interface) |
| EVM target | Prague hard fork |
| Block time | Sub-second |
| Finality | Deterministic (BFT consensus) |
| CCTP domain | 26 |
Steps
Arc uses deterministic BFT finality. Once a block is committed, it is
irreversible. There are no reorgs.
Set your required confirmations to 1. A single confirmation on Arc provides
the same settlement guarantee as 64+ confirmations on Ethereum or 20+ on other
L2s.
| Chain type | Typical confirmations | Arc confirmations |
|---|
| Ethereum (PoS) | 64 blocks (~13 min) | 1 block (<1 s) |
| Optimistic rollups | 7 days (challenge period) | 1 block (<1 s) |
| Other L2s | 10–20 blocks | 1 block (<1 s) |
If your protocol uses safe or finalized block tags in RPC calls, both
resolve to the latest block on Arc. You do not need separate handling for
pending vs. finalized states.
For your bridge configuration:
import { defineChain } from "viem";
export const arcTestnet = defineChain({
id: 5042002,
name: "Arc Testnet",
nativeCurrency: {
name: "USDC",
symbol: "USDC",
decimals: 18,
},
rpcUrls: {
default: {
http: ["https://rpc.testnet.arc.network"],
webSocket: ["wss://rpc.testnet.arc.network"],
},
},
blockExplorers: {
default: {
name: "Arcscan",
url: "https://testnet.arcscan.app",
},
},
});
// Bridge confirmation config
const arcBridgeConfig = {
chainId: 5042002,
requiredConfirmations: 1, // Deterministic finality—1 is sufficient
finalityType: "deterministic" as const,
avgBlockTimeMs: 500,
};
Step 2. Route USDC via CCTP
Arc uses Circle’s Cross-Chain Transfer Protocol (CCTP) as the canonical USDC
bridge. CCTP uses a burn-and-mint model, meaning USDC on Arc is always
native—never wrapped or locked.
Do not deploy wrapped USDC (e.g., wUSDC, USDC.e) on Arc. Route all USDC
transfers through CCTP to maintain fungibility with the native token. Wrapped
variants create fragmented liquidity and user confusion.
| Contract | Address | Notes |
|---|
| TokenMessengerV2 | 0x8FE6B999Dc680CcFDD5Bf7EB0974218be2542DAA | Initiates crosschain burns |
| MessageTransmitterV2 | 0xE737e5cEBEEBa77EFE34D4aa090756590b1CE275 | Receives and attests messages |
| USDC | 0x3600000000000000000000000000000000000000 | Native USDC (ERC-20 interface) |
| CCTP domain | 26 | Use in depositForBurn calls |
If your bridge aggregates routes, prefer the CCTP path for USDC transfers to and
from Arc over any lock-and-mint or liquidity-pool approach.
Step 3. Deploy relay and adapter contracts
Arc is EVM-compatible (Prague hard fork target). Standard deployment tooling
works without modification:
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
// Deploy using standard viem workflow
const account = privateKeyToAccount(
process.env.DEPLOYER_PRIVATE_KEY as `0x${string}`,
);
const walletClient = createWalletClient({
account,
chain: arcTestnet,
transport: http("https://rpc.testnet.arc.network"),
});
// CREATE2 deterministic deployment works as expected
// Permit2 is available at the canonical address
const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
const MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
Key deployment considerations:
- CREATE2 factory works at the standard address for deterministic deploys
- Permit2 is deployed at
0x000000000022D473030F116dDEE9F6B43aC78BA3
- Multicall3 is available at the standard address
- No EIP-4844 blob transactions—use
type: 2 (EIP-1559) transactions
PREVRANDAO always returns 0—do not use it for randomness in relay
selection
If your contracts reference block.prevrandao for relay shuffling or random
selection, replace it with an external oracle or deterministic round-robin
approach on Arc.
Step 4. Fund relayers with USDC for gas
Arc uses USDC as its gas token, not ETH. Your relay executors and watchers need
USDC balances to submit transactions.
import { parseUnits, formatUnits } from "viem";
// Check relayer gas balance (USDC with 18 decimals at native level)
const balance = await publicClient.getBalance({
address: relayerAddress,
});
console.log(`Relayer balance: ${formatUnits(balance, 18)} USDC`);
// Fund relayer via ERC-20 transfer (6 decimals)
const USDC_ADDRESS = "0x3600000000000000000000000000000000000000";
const fundTx = await walletClient.writeContract({
address: USDC_ADDRESS,
abi: [
{
name: "transfer",
type: "function",
inputs: [
{ name: "to", type: "address" },
{ name: "amount", type: "uint256" },
],
outputs: [{ type: "bool" }],
stateMutability: "nonpayable",
},
],
functionName: "transfer",
args: [relayerAddress, parseUnits("1000", 6)], // 1,000 USDC
});
Do not send ETH to relayers on Arc. ETH has no function on the network.
Relayers need only USDC to pay for gas.
Gas cost estimation:
Arc’s fee model uses a smoothed moving average inspired by EIP-1559. Gas prices
are stable and predictable. A typical relay transaction costs well under $0.01
in USDC gas fees.
Step 5. Connect your relay infrastructure
For high-throughput relay operations, connect to Arc using WebSocket for
real-time block and event streaming:
import { createPublicClient, webSocket, http } from "viem";
// WebSocket for real-time event monitoring (relay watchers)
const wsClient = createPublicClient({
chain: arcTestnet,
transport: webSocket("wss://rpc.testnet.arc.network"),
});
// HTTP for transaction submission (relay executors)
const httpClient = createPublicClient({
chain: arcTestnet,
transport: http("https://rpc.testnet.arc.network"),
});
// Watch for bridge events with immediate finality
const unwatch = wsClient.watchContractEvent({
address: YOUR_BRIDGE_CONTRACT,
abi: bridgeAbi,
eventName: "MessageSent",
onLogs: (logs) => {
// Each log is final on receipt—no need to wait for confirmations
for (const log of logs) {
processRelayMessage(log);
}
},
});
Node provider options for relay infrastructure:
| Provider | Notes |
|---|
| Alchemy | Managed RPC, WebSocket support |
| Blockdaemon | Enterprise-grade node infrastructure |
| dRPC | Decentralized RPC network |
| QuickNode | Managed endpoints with analytics |
| Self-hosted | Run your own Arc node for lowest latency |
For latency-sensitive relay operations, run a dedicated Arc node. Arc’s node
software is lightweight and designed for high-throughput block production.
Step 6. Integrate price feeds (optional)
If your bridge logic requires price oracles for fee estimation or value
validation, the following oracle providers are available on Arc:
| Provider | Use case |
|---|
| Chainlink | Price feeds, CCIP |
| Pyth | High-frequency price data |
| Redstone | Pull-based oracle model |
| Stork | Low-latency price feeds |
Integration checklist
Use this checklist to verify your Arc integration is complete:
Key differences from other EVM chains
| Consideration | Typical EVM chain | Arc |
|---|
| Confirmation safety | Wait 12–64 blocks | 1 block is final |
| Gas token | ETH or chain-native token | USDC |
| Reorg handling | Required | Not needed |
| USDC bridging | Lock-and-mint or liquidity pools | CCTP burn-and-mint (native) |
| Block time | 2–12 seconds | Sub-second |
| Fee volatility | High (auction-based) | Low (smoothed moving average) |