Skip to main content
An RFQ (Request for Quote) goes through several stages from creation to on-chain settlement. This guide walks through the complete flow.

Status Flow

open → quoted → accepted → confirmed → executed
  ↓       ↓        ↓
expired  cancelled  (MM fails to confirm → cancelled)

Step-by-Step Flow

1

User Creates RFQ

The user submits a parlay bet request with 2-5 legs, each referencing a Kalshi market ticker and a side (yes/no).
POST /rfqs
{
  "legs": [
    { "kalshi_market_ticker": "KXBTC-25FEB07-T100000", "side": "yes" },
    { "kalshi_market_ticker": "KXETH-25FEB07-T3500", "side": "no" }
  ],
  "bet_amount": 100,
  "expires_in_seconds": 300
}
The system validates each leg against Kalshi market data, checks the user’s USDC balance, and broadcasts the RFQ to all connected market makers via WebSocket.Status: open
2

Market Makers Submit Quotes

Market makers see the RFQ on the rfqs:open WebSocket channel and submit quotes with their payout odds.
POST /mm/quotes
{
  "rfq_id": "<rfq-uuid>",
  "payout_odds": 4.0,
  "valid_for_seconds": 60
}
The payout is calculated as:
  • total_cost = bet_amount (e.g., $100)
  • total_payout = bet_amount x payout_odds (e.g., $400)
  • mm_payout (MM’s risk) = total_payout - total_cost (e.g., $300)
Status: quoted
3

User Accepts Best Quote

The user reviews quotes (sorted by best payout odds) and accepts one.
PUT /rfqs/<rfq-id>/quotes/<quote-id>/accept
This rejects all other pending quotes and gives the market maker a 60-second confirmation deadline.Status: accepted
4

Market Maker Confirms

The market maker must confirm within 60 seconds, triggering the on-chain escrow.
PUT /mm/quotes/<quote-id>/confirm
Status: confirmed
5

On-Chain Escrow Execution

The system executes a 3-step Solana transaction flow:
  1. create_parlay — Oracle creates the escrow PDA and token account
  2. deposit_user — User’s USDC stake is transferred to the escrow
  3. deposit_mm — Market maker’s risk USDC is transferred to the escrow
Status: executed
6

Settlement

A background service polls Kalshi every 30 seconds to check if all leg markets have settled.
  • All legs win — Total payout transferred to user (settled_win)
  • Any leg loses — Stakes returned proportionally (settled_loss)

Timeout Protection

Two background services protect against stuck escrows:
  • Settlement Service (every 30s) — Checks if all legs have resolved and settles the escrow
  • Timeout Service (every 60s) — Cancels escrows past their deadline (default 1 hour) and refunds deposits

Validation Rules

ParameterConstraint
Legs per parlay2-5
Bet amount11 - 10,000 USDC
Payout odds1.01x - 1000x
RFQ expiration60 - 3600 seconds
Quote validityConfigurable (default 60s)
MM confirmation window60 seconds
Escrow deadlineConfigurable (default 1 hour)