Skip to main content

Swap Flow

Firmament quotes first. Settlement starts only after the backend accepts an RFQ.

1. Request a quote

API consumers send the friendly shape:
  • input_asset and output_asset — case-insensitive asset symbols or ids, e.g. USDC, usdc, SOL, sol, cbBTC, cbbtc. Discoverable via GET /v1/assets and GET /v1/pairs.
  • amount — decimal string in the input asset’s display units (e.g. "0.01").
  • taker_wallet — the connected Solana wallet that will settle.
  • expiry_seconds (optional) — overrides the configured default.
The legacy shape (input_mint, output_mint, input_amount_raw) is still accepted for existing API consumers. Accepted responses include the legacy quote_id, quoted_output_amount_raw, spread_bps, expires_at, risk_checks, and htlc_terms fields plus display-friendly pair, input, output, and next_action fields. The next_action advertises the next route to call. Rejected responses include a stable reason and readable risk_check_details plus a user-facing message and suggested_action. If protocol workers are disabled, RFQ routes return an unavailable error.

2. Start wallet settlement

The browser creates a SHA-256 preimage commitment and calls wallet settlement for the accepted quote. Only the hash is sent to the backend at this step. The preimage itself stays in the browser until redeem time and is never persisted by the server. The backend creates a trade and returns an unsigned taker lock transaction. The response includes a next_action pointing at the taker-lock route.

3. Record taker lock

The connected wallet signs and submits the taker lock. The app records the signature with the backend. The runtime can then reserve maker liquidity and advance settlement state.

4. Redeem

The taker reveals the preimage. If no redeem signature is supplied, the backend returns an unsigned taker redeem transaction. If a signature is supplied, the backend records the final taker redeem step.

5. Recover, abandon, or refund

Trade and active wallet-settlement state are persisted in SQLite. A browser refresh or backend restart can call POST /v1/trades/{trade_id}/resume to get the latest persisted phase, known signatures, and the next unsigned wallet transaction when one is available. Before funds are locked, the app can call POST /v1/trades/{trade_id}/abandon with the browser-held secret_hash to mark the unused settlement failed and start over. If the quote expires before lock, resume/lock attempts fail the settlement instead of rebuilding a stale transaction. After the taker lock is on chain and the HTLC expiry has passed, the app can call POST /v1/trades/{trade_id}/taker-refund first without a signature to prepare the refund transaction, then again with the connected wallet’s submitted refund signature. When the browser submits a lock, redeem, or refund signature, the backend waits for confirmation and validates the matching HTLC account effect before moving the settlement forward.

6. Read trade status

The trade route returns:
  • settlement status
  • observed transaction signatures and typed signature kinds
  • legacy amounts envelope plus display-friendly input and output views (asset, amount, amount_raw, decimals, mint)
  • ledger summary
Use it as the user-facing status source for a settlement. The Runtime tab shows global recent trades; the swap page’s wallet history drawer shows trades attributed to the connected wallet/browser.