A 402 names a token. Your wallet holds what it holds. When those disagree, PipRail can
convert the difference through 10 open, keyless
routes across 18 chains.
Nothing swaps by itself, and PipRail takes nothing on top.
10
routes
18
chains
21
mainnet proofs
0%
taken by PipRail
Never automatic
Paying never swaps. Planning never swaps. There is no autoSwap flag, because converting one asset into another is a priced, irreversible act a payment library should not do on your behalf. A test asserts the default is byte-identical.
Open and keyless
Every route had to answer a plain server request with no API key to qualify. Several need no API at all: the quote is an on-chain read and the swap is a contract call your own key signs.
PipRail takes 0%
We never set an integrator, platform or referrer fee on any route. You pay the pool fee, which each quote reads from the venue and reports back, and the chain gas. Nothing else.
An invoice names an exact amount. Some routes honour that exactly.
Most routers are exact-input: you say what you will spend and find out what
arrives. An x402 invoice is the other way round.
3 routes take the invoice amount directly
They ask for the amount the invoice names and cap the input on-chain,
so the trade fails rather than overspends. On TON the router enforces a floor at or
above the invoice instead, so a little more can arrive and less never does. Proven to
the unit: one Aptos swap was asked for 0.05 USDT and the chain's own deposit event
recorded exactly 50000 base units.
Hyperion
STON.fi
SunSwap V2
The rest are sized from a probe, then checked
Where a venue only offers exact-input, PipRail prices a nominal trade, scales the
input to the amount you need, then re-quotes and
verifies the real route clears the invoice. A route that would land short
returns null rather than a swap that leaves you
still unable to pay.
Every route, and what it costs you
2 where the ledger itself swaps and there is no third party at all,
8 through a named venue. Each earned its place by settling a real
mainnet transaction we then read back from a public node.
A PathPaymentStrictReceive addressed to your own account: one atomic operation, routed across the order books and liquidity pools.
On
Stellar
No trading fee on the order books (spread only); the protocol liquidity pools charge a fixed 0.30%. Nobody can add an integrator fee, because there is no field for one.
Proven on mainnet · 3
f7b784d4…a0aa 0.2652 XLM → 0.05 USDC (native in, and the ledger records source and destination as the same account)
3aa2ca9e…5f03 USDC → 0.2 XLM (the reverse direction, token in)
27f50b2c…e385 0.1064 XLM → 0.02 USDC (run straight from the committed example, so the documented flow is proven too)
A cross-currency Payment addressed to your own account, which the ledger permits precisely for currency conversion. Auto-bridged through XRP where that is cheaper.
On
XRP Ledger
No protocol fee on the order books (spread only); AMM pools charge a per-pool fee set by liquidity providers, 0% to 1%, paid to the pool. No integrator fee is expressible.
Jupiter routes and builds a serialized transaction; your own keypair signs it locally and this process broadcasts it. Jupiter never signs and never holds the funds.
On
Solana
No platform fee. Verified per quote rather than assumed: PipRail never sets platformFeeBps, and every quote is inspected so the note says so if one ever appears.
Proven on mainnet · 2
2rXpQYVe…J4rq 0.1031 USDC → 0.001 SOL (token in, exact output)
UEeXBp3s…VTk5 0.000485 SOL → 0.05 USDC (the reverse direction, native in)
KyberSwap routes; your own wallet calls the router contract directly. An ERC-20 swap costs two transactions (an approve, then the swap); a native-in swap costs one.
On 9 chains
Ethereum
Optimism
BNB Chain
Polygon
Base
Arbitrum
Avalanche
Linea
Robinhood
No integrator fee. Verified per quote rather than assumed: PipRail sends no fee parameters, and the returned extraFee block is inspected so the note says so if one ever appears.
Proven on mainnet · 5
0x1748b6…8d4d 0.0101 USDT → USDC on BNB Chain (the ERC-20 path, which needs an approval first)
0x424299…8f10 native ETH → 0.360518 USDG on Robinhood Chain (a 100ms-block chain, where a route goes stale fast: the default 50 bps slippage reverted first, 300 bps cleared)
0xe27f95…fb00 native BNB → 0.02 USDC (the native-in path, which needs no approval)
0xb28b80…4032 0.00117 USDC → EURC on Base (a second EVM chain on the same implementation)
Aftermath routes and returns a COMPLETE serialized programmable transaction block; your own keypair signs it locally and this process broadcasts it. It never signs and never holds the funds.
On
Sui
No fee added by the router: the route reports its own coinIn/coinOut tradeFee as zero, and the only cost is the underlying pool fee (about 0.014% on the probed route). PipRail passes no fee parameter.
Proven on mainnet · 1
GtykrnLx…3Cha 0.0657 SUI to 0.0505 USDC (native in; the balance changes on chain match the quote exactly)
One ft_transfer_call receipt chain: token contract to AMM and back to you, inside a single transaction you sign. No solver takes possession, which is exactly why this is used instead of an intent network.
On
NEAR
The pool's own total_fee, read live per pool (0.01% on the route used). There is no integrator fee for PipRail to set or waive.
Proven on mainnet · 1
FAb28z1t…jszT 0.0505 USDT to 0.05 USDC (token to token across a stable pool, 14 receipts, all successful)
Vestige returns an UNSIGNED atomic transaction group in which every signer is you. The SDK asserts that at runtime before signing anything, then signs locally and submits.
On
Algorand
The pool's own fee (0.30% on the probed route) plus the group's network fee. PipRail sends no fee parameter.
Proven on mainnet · 1
5UV7SWSJ…32UA 0.5094 ALGO to 0.05 USDC (a four-transaction atomic group, every signer the sender)
Called contract-to-contract with NO API in the middle: the quote is an on-chain view and the swap is a Move entry function your own account signs. Uniquely, exact_output_swap_entry takes the amount you want OUT plus an on-chain input cap, so an x402 invoice is priced exactly rather than approximated.
On
Aptos
The pool's own fee, read off-chain-state per route (0.01% on the stable pool used here). No API key, no integrator fee: the entry function has no fee parameter to set.
Proven on mainnet · 4
0x927293…1adc 0.049997 USDC to exactly 0.05 USDT (the stable pair, and the first swap in this SDK to deliver an EXACT output rather than at-least)
0xae849e…059e 0.040012 USDT to exactly 0.04 USDC (the reverse direction, which takes the opposite on-chain price bound)
0x792111…7981 0.0459 APT to exactly 0.03 USDC (native APT in, on a different fee tier)
0x640bce…a707 0.012842 USDC to exactly 0.02 APT (native APT out, where the balance delta nets off gas and only the deposit event proves the exact amount)
Exact-output route, priced by STON.fi's keyless reverse_swap simulation, which fixes the ASK side and returns the offer required. PipRail pads the request so the router's on-chain floor (min_ask_units) is at or above the invoice: you may receive slightly more, never less. The swap is one message your own wallet signs to the router the simulation named. TON settles asynchronously, so arrival is a balance check rather than one atomic receipt.
On
TON
The pool's own fee, reported per route by the simulation (about 0.10% on the routes used here). No API key and no referral field.
Proven on mainnet · 2
1f6d58d0…eb3f 0.035528 TON for 0.05 USDT (native TON in, through the pTON proxy jetton, on the v2.2 router. The wallet transaction that STARTED the swap (opcode 0x01f3835d), not the gas refund that lands moments later)
f76ae97e…7947 0.028171 USDT for 0.02 TON (the jetton-to-TON direction, which the simulation routed through a DIFFERENT router version (v2.1). A TEP-74 jetton transfer (opcode 0x0f8a7ea5) carrying the swap as its forward payload)
Called contract-to-contract with NO API: getAmountsIn prices an exact output and swapETHForExactTokens executes it with the input capped on-chain. Selling native TRX is one transaction; selling a TRC-20 is two, because the router moves the input with transferFrom and needs an approval first. SunSwap's own front end uses an undocumented, obfuscated hostname, which a payments SDK should not depend on, so this skips the service entirely.
On
Tron
The pool's own 0.30% constant-product fee. No API key and no integrator fee: the router has no such parameter. Tron's ENERGY charge is the dominant cost, see below.
Not yet proven on mainnet
Shipped without a mainnet proof, deliberately and openly. The route is real, and every part of it that can be checked without spending has been: both directions quote live through the SDK, and the approve and the router call both execute cleanly in constant-call simulations against the real contracts. It has NOT been broadcast because Tron charges about 230,629 ENERGY per swap, which without staked energy is roughly 23 TRX (about $7.79) regardless of trade size, plus about 10 TRX more the first time a TRC-20 is approved. The project test wallets hold 8.1 TRX. A user with energy can swap today; we simply have not paid to prove it.
The other way round: by chain
Same data, indexed by the thing you probably already know. Sorted by how much of it we
have proven.
Chain
Routes
Proofs
Aptos
Hyperion
4
Stellar
Stellar SDEX
3
Base
KyberSwap
2
BNB Chain
KyberSwap
2
Solana
Jupiter
2
TON
STON.fi
2
XRP Ledger
XRPL DEX + AMM
2
Algorand
Vestige
1
NEAR
Ref Finance
1
Robinhood
KyberSwap
1
Sui
Aftermath
1
Arbitrum
KyberSwap
not yet
Avalanche
KyberSwap
not yet
Ethereum
KyberSwap
not yet
Linea
KyberSwap
not yet
Optimism
KyberSwap
not yet
Polygon
KyberSwap
not yet
Tron
SunSwap V2
not yet
Every one of the 10 families PipRail supports can swap.
Look first, then commit
The shape of the API is the point: one call reads and prices, a second one moves money.
You never get the second by accident.
swap.ts
import { PipRailClient, summarizeSwap } from'@piprail/sdk'const client = newPipRailClient({ chain: 'aptos', wallet: { key: KEY } })
// 1. Read. Nothing is signed, nothing is spent, nothing is committed to.const quote = await client.quoteSwap({ from: 'USDC', to: 'USDT', wantAmount: '0.05' })
// null is never "you are broke": it means no route, no liquidity, or a failed read.if (!quote) return
console.log(summarizeSwap(quote))
// Swap ~0.050002 USDC → 0.05 USDT (at most 0.050503 USDC, 1% slippage). Rate from Hyperion.// 2. The ONLY call that moves anything.const receipt = await client.swap(quote)
quoteSwap() never throws for a read problem, and
null never means "you are broke": it means no route,
no liquidity, a read that failed, or a chain with no swap support. Slippage rides
on-chain wherever the venue allows it, so a
market that moves past your tolerance fails the transaction instead of overspending.
Nothing is swapped when that happens, though chains that charge for a reverted
transaction still take the gas.
Two things we deliberately did not do
Both are absences, and both are the point.
There is no swap tool for agents
Your spend policy governs paying a merchant. A swap moves your own funds
between denominations, so it sits outside every cap you have. An agent able to swap
could drain a wallet through fees and slippage without tripping a single budget check.
So quoteSwap and
swap are for a developer writing code, and the
MCP server exposes neither. The missing tool is the safety property.
What we turned down
Every candidate was probed from a plain server request with no key. 0x and 1inch
answered 401, Squid and Rango wanted an integrator header, thirdweb Bridge required a
key and takes an unavoidable 0.30%, and Odos and OpenOcean bot-blocked the request
entirely. None of them ship here. An endpoint that blocks a server is not a headless
integration, however good its documentation is.
And one route ships without a proof, which we would rather say than hide
SunSwap V2:Shipped without a mainnet proof, deliberately and openly. The route is real, and every part of it that can be checked without spending has been: both directions quote live through the SDK, and the approve and the router call both execute cleanly in constant-call simulations against the real contracts. It has NOT been broadcast because Tron charges about 230,629 ENERGY per swap, which without staked energy is roughly 23 TRX (about $7.79) regardless of trade size, plus about 10 TRX more the first time a TRC-20 is approved. The project test wallets hold 8.1 TRX. A user with energy can swap today; we simply have not paid to prove it.
Common questions
Does PipRail swap my tokens automatically?
No, and there is no setting that makes it. Paying never swaps and planning never swaps. quoteSwap() reads and prices; swap() is the only call that moves anything, and you have to write it yourself. A test asserts the default behaviour is byte-identical whether or not the feature exists, so ignoring it costs you nothing.
What does PipRail charge for a swap?
Nothing. PipRail never sets an integrator, platform, referrer or partner fee field on any route, and several of the routes have no such parameter to set. You pay the pool fee, which each quote reads from the venue and reports back to you, plus the chain gas.
Who holds my funds during a swap?
You do. Every route is a transaction your own key signs, sending funds to your own address. No route takes custody, and none of them signs on your behalf. Two of them do not even call an API: on Aptos and Tron the quote is an on-chain read and the swap is a contract call.
Why is there no swap tool for AI agents?
Because your spend policy governs paying a merchant, not moving your own money between denominations. A swap sits outside every budget cap you have, so an agent able to swap could drain a wallet through fees and slippage without tripping a single check. The MCP server therefore exposes no swap tool at all. The missing tool is the safety property.
How do I know these routes actually work?
Every listed route settled a real mainnet transaction that we then read back from a public node, never from a documentation page. There are 21 of them on this page and you can open every one. Where a route ships without a proof, it says so in plain language and explains why, rather than showing an empty table.
Like & share PipRail
Star on GitHub Follow @piprailhq