Sending USDC
The full life of a transfer — quote, funding, route lock, settlement, payout — and where every fee goes.
Every transfer follows the same visible path. You see plain language; behind each stage sits a real state machine and, from the moment you confirm, real escrow on Arc.
The lifecycle
Quote → Funded → Route secured → Processing → CompleteThe same lifecycle as a UML state diagram — [*] is the initial/final
pseudo-state, every transition is labeled with what triggers it:
UML state diagram — transfer lifecycle (IntentStatus)
[*] --> quoted : user requests a quote (POST /api/quote)
quoted --> deposited : user funds it — escrow deposit() (POST /api/send)
deposited --> fx_locked : settlement tick — FX leg locked at quoted rate
fx_locked --> settling : settle() begins — FX · payout · fee in one tx
settling --> claimable : payout leg settled (SETTLE_PAYOUT)
claimable --> claimed : recipient releases — EIP-712 claim() signature
claimed --> [*]
claimable --> refunded : timeoutAt lapses — agentFallback(TIMEOUT)
refunded --> [*]The engine is lazy: the state machine advances on reads and polls, so the feed you watch is the settlement itself. Agents can fire the same transitions — see Automation Agents for the refund branch.
- Quote — pick a corridor and amount on transvia.xyz/send. You see the rate, the destination amount, and every fee upfront. The rate is held for 60 seconds.
- Funded — you confirm. Your USDC moves into the
TransviaEscrowcontract on Arc and locks against your transfer id. - Route secured — the FX leg locks at your quoted rate. Your money is now insulated from rate movement.
- Processing — settlement runs in one atomic transaction: the FX leg, the payout leg, and the fee split.
- Complete — the recipient releases the payout with a signature. Gas is paid by the rail, not the recipient.
Watch every stage on transvia.xyz/transfers — each step lands in the timeline with its onchain transaction hash.
What you see vs what is onchain
The API exposes the underlying status vocabulary. It maps 1:1 to what the product shows:
| You see | API status | Onchain state |
|---|---|---|
| Quote | quoted | Nothing yet — rate locked for 60 seconds |
| Funded | deposited | deposit() — USDC locked in TransviaEscrow |
| Route secured | fx_locked | FX leg pinned to your quoted rate, funds still in escrow |
| Processing | settling | settle() — FX, payout, and fee legs in one atomic tx |
| Processing (payout ready) | claimable | Net payout settled — awaiting the recipient release signature |
| Complete | claimed | claim() — recipient EIP-712 signature verified |
| Refunded | refunded | refund() / agentFallback() — full amount back to sender |
Fees, and where they go
Fees are charged on the source amount, shown before you send, and split atomically onchain at settlement time — not offchain, not later.
| Component | Rate | Treasury | What it covers |
|---|---|---|---|
| FX / liquidity | 0.35% | lpTreasury | Route liquidity and FX access |
| Protocol | 0.10% | protocolTreasury | Settlement and network upkeep |
| Automation | 0.05% | agentTreasury | Policy-gated transfer monitoring |
| Total | 0.50% |
A 100 USDC transfer costs 0.50 USDC in total: 0.35 to liquidity, 0.10 to
protocol, 0.05 to automation. The split is emitted onchain as a FeeSplit
event — you can verify it on the explorer.
The refunded path
Most transfers complete. When one doesn't, your money is never stranded:
- Every transfer carries a 90-second claim window, set when you fund it.
- If nothing has progressed when the window lapses, the automation agent triggers a full refund to the sender address.
- A transfer that is simply waiting to be claimed is left alone — funds stay safely claimable and the agent only watches.
- You can also refund yourself once the window opens.
Refunds are onchain (agentFallback → Refunded), logged in the transfer
timeline, and recorded in the agent decision log. See
Automation Agents for how the agent decides.
Try it
- Send: transvia.xyz/send
- Track: transvia.xyz/transfers
- Automate: transvia.xyz/automation
- Same rail over HTTP: API