Skip to main content

The executable transaction

The payload to send onchain lives in the quote’s tx object:
FieldDescription
tx.toRialtoRouter contract address; the to of your transaction.
tx.dataABI-encoded calldata for the swap.
tx.valueNative value to send. 0 for ERC20 sells; the sell amount for native ETH sells.
tx.estimated_gasBackend gas estimate. Still run wallet or RPC gas estimation before sending.
tx.signature_offsetByte offset in tx.data where the taker’s 65-byte Permit2 signature is inserted. Present only for Permit2 settlement.
permit2EIP-712 typed-data message the taker signs. Present only for Permit2 settlement.
The settlement field tells you which mode applies. Choose your handling from settlement, not from assumptions. Do not modify quote_id, route, platform_fee, permit2.message.witness, or tx.data except for replacing the Permit2 signature placeholder. A changed route or witness will not match the signed quote and may revert. Use the returned permit2 payload as the source of truth; do not recompute the bytes32 witness quoteId from the UUID yourself.

Permit2 settlement

Permit2 is the default for ERC20 sells. The taker authorizes a single exact transfer by signing an EIP-712 message bound to the precise swap, including recipient, buy token, minimum output, deadline, quote id, and the hash of the route actions. Steps:
  1. If issues.allowance is non-null, ask the taker to approve issues.allowance.spender for at least sell_amount. For Permit2 quotes this spender is the Permit2 contract.
  2. Have the taker wallet sign the permit2 object as EIP-712 typed data.
  3. Splice the returned 65-byte signature into tx.data at tx.signature_offset.
  4. Send the transaction from the taker wallet using to, the patched data, and value.
Most wallet libraries accept the returned domain, types, primaryType, and message directly. If your library rejects EIP712Domain inside types, remove only that key before calling signTypedData; do not change the message or witness fields.
function splicePermit2Signature(
  txData: string,
  signatureOffset: number,
  signature: string
): string {
  const data = txData.startsWith("0x") ? txData.slice(2) : txData;
  const sig = signature.startsWith("0x") ? signature.slice(2) : signature;
  if (sig.length !== 130) {
    throw new Error("Permit2 signature must be 65 bytes");
  }
  const start = signatureOffset * 2;
  return `0x${data.slice(0, start)}${sig}${data.slice(start + sig.length)}`;
}

Allowance settlement

A quote returns settlement: “allowance” with no permit2 object and no signature_offset when Permit2 is not the right path, for example native ETH sells, or a flow where the taker already wants to use ERC20 allowance.
  • ERC20 sells. If issues.allowance is non-null, the taker approves issues.allowance.spender for at least the raw sell_amount, then sends the transaction. Do not modify tx.data.
  • Native ETH sells. Send the transaction with tx.value; no ERC20 approval and no signature are needed.

Simulation

Every route Rialto returns is validated against live chain state before it is quoted, so the transaction in a quote is pre-validated. You can also simulate the returned transaction yourself before submitting. A successful simulation confirms the route still fills and the output meets min_buy_amount; a failure means the quote has gone stale, so request a fresh quote.

Submission

For the taker-submitted flow, submit the transaction from the taker wallet. The Rialto API does not sign or broadcast this direct-flow transaction. Quotes reflect live liquidity and can go stale quickly, so request a fresh quote if the user waits.

Direct-flow checklist

API_KEY='rialto_live_example.redacted_secret'

curl -sS 'https://rialto-trade-api.rialto.xyz/quote?sell_token=WETH&buy_token=USDC&sell_amount=0.01&taker=0x1111111111111111111111111111111111111111&slippage_bps=50' \
  -H "Authorization: Bearer $API_KEY" -o quote.json

# In your app:
# - If quote.issues.balance is non-null, show an insufficient-balance error.
# - If quote.issues.allowance is non-null, approve quote.issues.allowance.spender.
# - Permit2: sign quote.permit2 as EIP-712, then splice the signature into
#   quote.tx.data at quote.tx.signature_offset.
# - Allowance/native: use quote.tx.data as-is.
# - Optional: eth_estimateGas / eth_call quote.tx from the taker.
# - Direct flow: submit quote.tx from the taker wallet.
# - Gasless flow: use POST /gasless/submit instead of sending quote.tx yourself.