TaifoonTAIFOON
TaifoonTAIFOON
Arc · Bridge Gateway
REAL · THE COORDINATION LAYER · everything here is served under one namespace at taifoon.io/v1 — 3 of its operations cover this page's subject. Machine-readable at /v1/openapi.json, and every endpoint with a working example is listed in the API overview.

One API, every route

Arc compares cross-chain routes across 32 bridge protocols and tells you what each one actually costs. You ask once; it quotes them all and ranks them.
TL;DR

POST /v1/compare with a source chain, destination chain, token addresses and an amount. You get every protocol that can serve the pair, ranked best-first, with fees, gas and a provenance label saying how each number was obtained. No key is required to quote.

The gateway is read-only. It quotes routes and builds deposit calldata for your user to sign — it never holds funds and never signs anything on their behalf.

Quoting a route

Token fields take contract addresses, not symbols, because the same symbol means different contracts on different chains. Amounts are strings in the token's own base units — 1000 USDC (6 decimals) is "1000000000".

curl -X POST https://arc.taifoon.dev/v1/compare \
  -H 'Content-Type: application/json' \
  -d '{
    "src_chain_id": 8453,
    "dst_chain_id": 42161,
    "src_token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "dst_token": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
    "input_amount": "1000000000",
    "output_amount": "0"
  }'

The response carries the winning slug in best and one entry per protocol in rows, already sorted:

{
  "best": "across",
  "protocol_count": 25,
  "value_usd": 1000.0,
  "rows": [
    {
      "protocol_slug":   "across",
      "protocol_name":   "Across Protocol V3",
      "total_cost_usd":  0.955239,
      "protocol_fee_usd": 0.106841,
      "gas_cost_usd":    0.008398,
      "amount_out_usd":  999.053159,
      "fee_bps":         28,
      "source":          "vendor",
      "priced":          true,
      "executable":      true,
      "best":            true
    }
  ]
}

Reading a quote honestly

Two fields decide how much weight a number deserves. Read them before you read the price.

FieldMeaning
source: "vendor"The fee came from the protocol's own live API. This is a real price.
source: "synthetic"The fee came from a constant in our catalogue. It is an estimate, and it can be wrong.
priced: falseNobody has priced this protocol yet. A 0 fee here means unknown, not free.
executable: trueA fill path exists for this protocol. Non-executable rows are omitted from compare.
Why the cheapest row is not always first

Ranking is by provenance first, then cost. A route with a real vendor quote outranks a cheaper unpriced one. This is deliberate: ranking on cost alone put unpriced placeholders claiming 0 fees above the one protocol publishing real numbers, which made the cheapest-looking route the least trustworthy. Unpriced routes stay in the list — nothing is hidden — but they cannot win.

The rest of the surface

EndpointWhat it gives you
POST /v1/compareEvery protocol for a pair, ranked, with full cost breakdown.
POST /v1/routeThe same set ranked by coverage tier rather than cost.
POST /v1/quoteA single protocol's quote when you already know which you want.
GET /v1/chainsSupported chains with per-chain protocol coverage counts.
GET /v1/catalogueAll 32 protocols, their families, fee models and chains.
GET /v1/modeWhether the instance is live or simulating, and its network.
GET /v1/healthLiveness.
GET /v1/cctp/fees/:src/:dstCircle CCTP v2 fee tiers for a pair, live from Circle. Base → Arc: standard 0 bps, fast 0.325 bps.
GET /v1/cctp/attestation/:src/:txAttestation status for a burn — pending_confirmations, then complete with the message and attestation for the destination mint.
POST /v1/bridge/planThe bridge as a service: your exact approve + burn transactions, Circle's live fee tier, and the service-fee split for the partner in X-Arc-Partner.
GET /v1/bridge/status/:src/:txAttestation progress for a burn made through the plan.
GET /v1/bridge/relay-plan/:src/:txOnce complete: the exact receiveMessage transaction for any funded relayer on the destination.
GET /v1/bridge/events/:chain?sender=&partner=&blocks=The router's Bridged ledger, decoded — a reseller's volume and share, or one wallet's bridges, read from chain by us.
GET /v1/bridge/queueEvery bridge we service that is not resolved yet — state, age, what happens next, and the resolution when past SLA.
GET /v1/bridge/tx/:chain/:hashOne bridge in the standardized shape: burned → attested → minted (Circle) or sent → done (LI.FI), stuck after 45 min unattested / 15 min unforwarded, with its transition timeline.
POST /v1/bridge/trackRegister a send for the state machine to follow ({ chain_id, tx_hash }; classified from the receipt). Router burns are found on their own.
GET /v1/bridge/ledgerAll records + summary: volume, fee split, measured p50/p90 burn→mint by tier; ?sender= / ?partner=t3rn.
GET /v1/bridge/proof/:chain/:tx?log_index=The receipt-inclusion proof (ReceiptInclusion) plus the Base verifier's verdict by eth_call. Human view at www.taifoon.io/proof/tx/:chain/:tx.
POST /v1/lifi/quoteJumper (LI.FI) for a pair: the tool it resolved to, the amount out, and a ready-to-sign transaction. Base → Arc is listed.

From a browser, call these through /api/arc/* on this origin rather than arc.taifoon.dev directly — the same-origin proxy avoids a CORS preflight and shares one rate-limit budget instead of one per tab.

Bridging to Arc

Arc (chain 5042) is served by Circle CCTP v2, the same rail Arc’s own App Kit uses. USDC is burned on the source chain and minted on Arc as native USDC (ERC-20 facade 0x3600000000000000000000000000000000000000). Standard transfers cost 0 bps; the route appears in /v1/compare with source: "vendor" because the fee is read from Circle live.

The flow is approvedepositForBurn (your wallet, on the source chain) → attestation (Circle) →receiveMessage (any relayer, on Arc). One thing to know before your first transfer: gas on Arc is USDC, so whoever calls receiveMessage there needs a little native USDC. In practice Arc mints are picked up by third-party relayers — we measured a Base burn minted on Arc 9 seconds later, with roughly 90 mints landing every five minutes — and /v1/bridge/relay-planis the fallback if nobody does. A recipient with no USDC on Arc has two other doors: Arc's own fiat onramp (App Kit), or via: "lifi"in the plan, where Jumper's tool delivers on Arc with no destination step.

Bridge as a service: Taifoon operates, partners resell

Use it directly at taifoon.io/bridge; the full call-by-call walkthrough with real numbers is in Bridge API, step by step.

POST /v1/bridge/plan turns the flow above into one call for an integrator. Send { src_chain_id, dst_chain_id, recipient, amount, speed? } (amount in USDC base units) and, if you are reselling, an X-Arc-Partner: <your-name> header. The answer is a list of steps your user signs in order — approve, then one burn — plus Circle's live fee tier and a full breakdown of what is burned and what is kept.

On Base the burn goes through CctpFeeRouter at 0xedF0C3B2BA863179780F7c595B9038b4075F08ed: one transaction pulls the amount, keeps the service fee (10 bps, hard-capped at 1% in the contract), pays the reseller's share (50%) to its registered vault, and hands the rest to Circle's TokenMessengerV2. The partner name is hashed (keccak256) into the Bridged event, so a reseller's volume and earnings are readable from the chain — and provable cross-chain with the same receipt proof the V5 verifier checks. An unregistered partner still bridges; its share simply goes to the operator until a vault is on file. On chains without a router the plan falls back to depositForBurn directly, with no service fee.

The service signs nothing. After the burn, poll /v1/bridge/status; when it reports complete, /v1/bridge/relay-plan returns the receiveMessage transaction any funded address may send on the destination. quote(amount, partner) on the router answers the same split without a transaction.

Rate limits

Quoting is unauthenticated and limited per IP: 30 requests per second with a burst of 60. Exceeding it returns 429 with an x-ratelimit-after header giving the seconds to wait. Reference data (/v1/chains, /v1/catalogue) is edge-cached, so polling it costs you nothing against that budget.

Executing a bridge

The gateway builds the deposit calldata; your user's wallet signs and sends it. Call /v1/donut/calldata/depositwith the route you chose and submit the returned transaction from the user's own address.

Fills are a separate, credentialed surface

Fills are not part of the public gateway. /v1/fill spends solver funds and is reachable only over the authenticated solver path — never the browser proxy. If you are integrating a solver rather than a front end, that is a separate credentialed surface; ask us for it directly.

Bringing your own token

Attaching a token means registering it with the solver's market-making layer: declare the chains it lives on and a risk tier, and it inherits the same quoting, cross-chain inventory rebalancing and edge capture as every other asset. A token nobody has tuned starts on the most conservative tier — wide spreads, a small position cap, and a minimum edge floor set against measured bridge costs rather than assumed ones.