TAIFOONarc.taifoon.dev (same-origin at /api/arc/*on this site). Nothing here signs: the user's wallet signs, Circle mints, the chain proves. Numbers below are from a real 2 USDC transfer through CctpFeeRouterV3 on 2026-09-17: burn 0xf9a42459…0563 (Base 51432516) → Circle forwarded in 10 s → Arc mint 0xa1dbc1b9…35fe; 1.962351 USDC arrived.0 · Where the money goes
| Leg | Who takes it | 2 USDC example |
|---|---|---|
| Service fee | Taifoon's router, on-chain: max(10 bps, 0.02 USDC floor), split 50 % operator / 50 % reseller vault (t3rn when attributed) | 0.02 (floor) → 0.01 / 0.01 |
| Burned | amount − service fee, handed to Circle's TokenMessengerV2 | 1.98 |
| Circle fee | bps tier (standard 0, fast 0.325 bps) + forwarder fee (≈0.016), taken out of the burned amount; Circle charges the whole maxFee | 0.017649 |
| Arrives on Arc | native USDC minted to the recipient by Circle's forwarder | 1.962351 |
The floor exists because a transfer costs the operator real money regardless of size (a relay on Arc if Circle ever does not forward ≈ 0.005 USDC of gas, plus infrastructure); below 20 USDC the floor dominates, above it 10 bps does.
1 · Quote and compare
| Call | Gives you |
|---|---|
POST /v1/compare | Every rail for the pair, priced live where a vendor exists (cctp, lifi, across…), with eta_seconds and eta_source. For Base → Arc: CCTP $0.004 total, Jumper $0.033. |
GET /v1/cctp/fees/:src/:dst | Circle's tiers for the pair (standard 0 bps / fast 0.325 bps) — the forwarder fee comes from Circle's ?forward=true variant and is folded into the plan. |
POST /v1/lifi/quote | Jumper's tool and a ready-to-sign transaction, when you prefer an aggregator route. |
2 · Plan
POST /v1/bridge/plan with { src_chain_id, dst_chain_id, recipient, amount, speed? } (amount in USDC base units; add X-Arc-Partner if you resell). The answer is the quote and the transactions in one object — the same numbers the wallet signs:
| Field | Meaning |
|---|---|
route.via | cctp_fee_router (CctpFeeRouterV3 on Base, and on Arc for the way back) or token_messenger_v2_direct_forwarded on chains without a router |
steps[] | approve (skip if allowance suffices) then bridge: to, data, value, chain_id |
amounts_usdc_units | amount, service_fee (+ service_fee_reason: bps | floor), partner_share, operator_share, burned, circle_max_fee, circle_fee_estimate, expected_received |
fees | service bps + floor, Circle bps, circle_forward_fee_units, and the source of each number |
forwarding | states that the burn carries the cctp-forward hook and that maxFee funds Circle's forwarder — the two conditions under which Circle mints on Arc itself |
maxFee covers its fee. A hooked burn with a too-small maxFee is attested and then forwardState: FAILED · INSUFFICIENT_FEE — the money is safe but someone must relay it. The plan sizes maxFeefrom Circle's live numbers so this cannot happen.3 · Sign
Your wallet sends the steps in order on the source chain. Taifoon's router takes the fee, pays the reseller vault, approves TokenMessengerV2 and calls depositForBurnWithHook — one transaction, one Bridged event with the partner id, amounts and finality tier. Smart-account wallets (EIP-5792) can batch approve + bridge atomically.
4 · Follow the state machine
| Call | Gives you |
|---|---|
POST /v1/bridge/track | Registers any send ({ chain_id, tx_hash }); router burns are also discovered from chain within a minute. |
GET /v1/bridge/tx/:chain/:hash | One bridge: state (burned → attested → minted; needs_relay for un-hooked burns; stuck past SLA with a resolution), transition timeline, hooked, mint_tx, duration_s, ETA quoted vs. measured. |
GET /v1/bridge/status/:chain/:hash | Circle's attestation mirror incl. forward_state / forward_tx_hash. |
GET /v1/bridge/relay-plan/:chain/:hash | The fallback: once attested, the exact receiveMessage transaction any Arc-funded address may send. Reports minted: true when already done. |
GET /v1/bridge/queue | Everything unresolved across all users, oldest first, with what happens next. |
GET /v1/bridge/ledger?sender=&partner= | Records + summary: volume, fee split, measured p50/p90 burn→mint per tier. |
GET /v1/bridge/events/:chain | The router's Bridged logs decoded, straight from chain. |
GET /v1/bridge/metrics | Prometheus: states, unresolved, SLA breaches, volume, fees, durations, quoted ETA. |
Every bridge view carries producer: spinner-da-api when Taifoon's data plane answered (the source of truth), arc-api-local-fallback when the gateway had to answer alone.
5 · Prove it
GET /v1/bridge/proof/:chain/:tx?log_index= returns the ReceiptInclusion the Base verifier consumes (21-field header RLP, key, receipt RLP, root-first trie nodes, the log, its eventHash) and the verifier's verdict by eth_call (TaifoonV5ProofVerifier.verifyWithReceipt, 0x2D47…44f8 on Base). The same proof for the Arc mint proves delivery. Human view: /proof/tx/:chain/:tx. Built by the data plane (/api/v5/proof/receipt, /api/v5/verify/receipt), cached once built.
6 · Plumbing you can rely on
| Call | Gives you |
|---|---|
POST /v1/rpc/:chain | Read-only JSON-RPC passthrough (blockNumber, getBlockByNumber/Hash, getTransactionReceipt, getBlockReceipts, getLogs, eth_call) tried against every known endpoint for the chain — no single public RPC serves everything. |
GET /v1/chains, GET /v1/catalogue, GET /v1/health | Coverage, protocols, liveness. |
Contracts on Base: router 0x7D93c3B6Cca19581010bA2543e39F3DD231965eb (V3: hooked, 10 bps, 0.02 floor, owner-set, two-step ownership), verifier 0x2D475a53eAA8F9AC78B69bD2429275a622C644f8. On Arc (source side, Arc → Base): router 0xBf4283b791d5a5541F01BC93ef5DD9B9dC8f334c, same fee policy; Circle's forward fee from Arc is about 0.054 USDC, three times the Base → Arc one, and the plan shows it before you sign. Circle: TokenMessengerV2 0x28b5…cf5d, MessageTransmitterV2 0x81D4…B64, Arc domain 26, Arc USDC facade 0x3600…0000.