POST /execute returns exactly one of them, tagged by
executionType. Your integration reads that single field and branches. Nothing else about the
flow changes.
One more value appears only if you ask for it: a Hinkal private swap, on a quote sent with
authorizeSteps: true, first answers AUTHORIZE, a signature to collect from the paying wallet,
before its TRANSACTION. See AUTHORIZE steps.
TRANSACTION
Sign and broadcast the returned transaction.
Across, Relay, Mayan, Eco Routes, THORChain, Jupiter, 0x Swap, 0x Solana, Nordstern, Fly Trade, KyberSwap, OKX DEX, Bebop (self-executed), Layerswap (EVM into BTC and Robinhood Chain stocks; Solana memo with
Across, Relay, Mayan, Eco Routes, THORChain, Jupiter, 0x Swap, 0x Solana, Nordstern, Fly Trade, KyberSwap, OKX DEX, Bebop (self-executed), Layerswap (EVM into BTC and Robinhood Chain stocks; Solana memo with
broadcastViaRavn), Hinkal (after its AUTHORIZE steps)SIGNATURE
Sign typed data, with no gas and no send. RAVN submits it.
0x Gasless, Bebop (gasless), CoW, Relay (gasless permit)
0x Gasless, Bebop (gasless), CoW, Relay (gasless permit)
DEPOSIT
Send the origin asset to an address.
NEAR Intents, Chainflip, Rift, Houdini Swap, Layerswap, Relay (BTC source)
NEAR Intents, Chainflip, Rift, Houdini Swap, Layerswap, Relay (BTC source)
A few venues return different types depending on the source chain or execution mode. See the
Execution column on Supported Chains & Venues for exactly which.The payloads
quoteToken. Pass that one, not the token from /quote, to
/submit-signature, /submit-transaction, and /status: a two-hop RAVN route is rebound to its
second hop at execute, and /submit-signature refuses its original token.
TRANSACTION with submit
Only on quotes made with broadcastViaRavn: true (see /quote). A
TRANSACTION that carries submit: { "url": "/api/v1/submit-transaction" } is a Solana payment to
Layerswap that RAVN checks before it is sent, or a Jupiter order that Jupiter lands (its market
maker or gas sponsor signs some of them too). Don’t broadcast it: sign transaction.serialized
without sending, post it to /submit-transaction with this
payload’s quoteToken, and poll /status with its statusRef, or with the txHash
/submit-transaction returns when there is none (Jupiter). A Jupiter order carrying your fee under
50 bps comes without submit: broadcast it like any other. Without broadcastViaRavn on the
quote, submit never appears on a TRANSACTION.
AUTHORIZE steps (Hinkal)
Only on a private quote you sent with authorizeSteps: true (or onlyVenues
naming hinkal) that Hinkal won. Before Hinkal’s swap can be built, the paying wallet (the quote’s
userAddress) signs twice, and /execute asks for each signature with an AUTHORIZE answer.
Signing moves no funds: the TRANSACTION that follows does.
AUTHORIZE
sign, then call /execute again with the same quoteToken, this
authorization, and the wallet’s signature, before expiresAt, with a new Idempotency-Key
(each answer is a request of its own). Repeat until a TRANSACTION comes back. Check each step
before your user signs it:
- Step 1,
personal_sign: opens a read-only Hinkal session for the wallet.messagemust read exactlyAuthorize Hinkal session,Session ID: …,Public Key: …on three lines. Refuse to sign one that addsThis signature can also be used to submit transactions.: that is Hinkal’s other session mode, whose key could move the wallet’s funds. - Step 2,
eth_signTypedData_v4: Hinkal’sPrivateSendBridgeorder, signed with the wallet on the input chain. It places the order. Its domain is only{ name: "Hinkal Enclave", chainId }on the input chain, it is for the input token (the zero address for the chain’s coin) and at most the input amount, andrecipientsholds exactly one entry: yourdestinationAddress. - The
TRANSACTION: theapprovalon a token sell, then the deposit into Hinkal’s contract (prooflessDepositon0x7cb60446d7635C68EDf1c568cac74A1f98c1Cfa4, the same address on every chain), RAVN’sfeebeside it when your key sets one, and astatusRef(Hinkal’s order id) to poll/statuswith and to recover with. Handle it like any otherTRANSACTION.
authorization is single-use and lasts until its expiresAt. Up to 12 Hinkal swaps can be
started (step 1) an hour per IP, or 120 per API key; past that /execute answers
502 BUILD_FAILED (“too many private swap attempts”). Calls without an API key share their
server’s IP, so send your key. Hinkal’s deposit is a heavy call, 450k to 670k gas measured. When
its TRANSACTION comes with batch: true (a token sell, with its approval or RAVN’s fee beside the
deposit), batch its calls only if your wallet lets you give the batch about 800k gas (above the
~400k the general rule under Paying a fee in one confirmation
allows), and otherwise send them one by one. A sale of the chain’s coin comes with batch: false:
send its calls one by one.
The order’s typed data embeds Hinkal’s route, several to tens of kilobytes; how
hardware wallets show or accept it is untested. A sandbox Hinkal quote skips the
steps and returns a stand-in DEPOSIT. On JavaScript or TypeScript, executeAndTrack
(SDK 0.4.1) checks and signs the steps, then sends the
deposit.
Branch logic
The approval step
Both TRANSACTION and SIGNATURE payloads can carry an optional approval, a ready-to-send
ERC-20 approve() call.
On
TRANSACTION: send approval, wait for it to be mined, then send transaction. The
swap moves your tokens with transferFrom, so an allowance that is merely broadcast, and not yet
in a block, still reverts, and the user pays gas for a failed transaction.
On SIGNATURE: land the allowance before you submit the signed order. Gasless does not mean
allowance-free: CoW settles through its vault relayer and Bebop through Permit2. Skip it and the
order is accepted and then silently never fills, with no error to debug.
RAVN reads your user’s allowance for spender on-chain when you call /execute (the wallet you
quoted as userAddress) and leaves approval out when it already covers amount. If that read
fails, approval is included anyway, so a token you have already approved can still carry one:
skip it when your own allowance read covers amount. The read sees the latest block only, so a
swap still pending that spends the same allowance isn’t counted: run one swap per token and
spender at a time.
approval.reset: some tokens (Ethereum USDT) refuse to change one non-zero allowance into
another. When your user holds a partial allowance on one, approval carries a reset, a ready-to-send
approve(spender, 0): send it, wait for it to be mined, then send the approval.
Paying a fee in one confirmation
On a route where RAVN collects your fee beside the swap (an execution carryingfee with a
transaction: Rift, private swaps, Eco Routes, Layerswap, Mayan routes paying no referrer, Fly
Trade’s coin sells outside Ethereum, Base and Polygon), a wallet that batches can take the swap and
the fee in one confirmation when /execute says batch: true: an ERC-20 fee, or a Fly
Trade coin sell’s fee on Robinhood Chain and Arbitrum, which RAVN takes as
WETH minted to it. Send calls (fee.transaction last, exactly as
given) in one batch:
- Report the on-chain hash of the transaction that carried the fee as
txHashon/status: never the EIP-5792 batchidor a 4337userOpHash. On aTRANSACTIONwith nostatusRef, the swap’s own hash asrefis enough. A relayed or smart-account wallet (EIP-7702, ERC-4337) works the same way. - One fee-bearing swap per batch. A batch carrying two fees proves only one of them.
- Any other native-coin fee (ETH, for example) is a plain transaction of its own, from a
regular wallet (
batch: false): RAVN proves it from the transaction’s own value. The one exception is a fee beside a NEAR Intents deposit (a private swap) on Ethereum, Base or Polygon: it may ride in the same batch as the deposit, as RAVN reads those chains’ internal transfers. A WETH fee’sfee.transactioncarries avaluetoo (the coin it mints from);batchis what says it may ride in the batch. - Batch a token deposit, or a native-coin deposit to NEAR Intents (it credits coin a smart account moves). Send any other native-coin deposit to a deposit address as a plain transfer: an exchange may not credit coin a contract moved.
- Wallets without batching send the fee as a second transaction, as in the example above. From Bitcoin, or a Solana deposit, the fee goes in the deposit’s own transaction, and a Solana transaction RAVN builds already carries it, so there’s nothing to batch.

