Build on Sour
Sour is open-source. The matching engine is on-chain, the SDK ships in Rust and TypeScript, and the public app exposes REST + Solana account-WebSocket endpoints suitable for bots, indexers, and integrations.
Quick reference
- Mainnet program ID
- souryQgnM1xiNuGcmVYLPGT3MKqnGN8QTqP8zk8eape
- TypeScript SDK
- @sour/sdk (workspace package, source on GitHub)
- Rust SDK
- sour-client (target/client/rust/, regenerated per build)
- IDL
- target/idl/sour.idl.json (Quasar-emitted)
- Source
- github.com/GageBachik/sour
- Verification
- github.com/GageBachik/sour-verification
- Whitepaper
- sour.finance/docs/sour-flow-perps-whitepaper.pdf
Public REST endpoints
Hosted on app.sour.finance. All endpoints are GET and return JSON. Cached on Vercel KV with TTLs in the 1–60 second range — they are intended for integrations and bots, not high-frequency polling against the underlying RPC.
- GET /api/markets/indexSnapshot of every launch market: symbol, asset ID, OI (long/short), cum_skew, last clear price, smoothed price, last clear slot, fee_micros, max leverage, max OI notional, allocated LP bps, lookup-table address, price source. Cached 5s.
- GET /api/markets/[id]Per-market detail by market PDA.
- GET /api/markets/[id]/volumePer-market rolling volume.
- GET /api/healthProtocol + markets health rollup. Useful as a single liveness probe.
- GET /api/pricesLive Pyth-anchored mark prices for every launch market.
- GET /api/ohlcv?market=…OHLCV candles for charting.
- GET /api/positions/[owner]All open positions for a given trader pubkey.
- GET /api/protocolGlobal protocol state — LP NAV, share price, paused flags.
WebSocket / live data
Sour does not run a custom WebSocket gateway. Live state lives on-chain: subscribe directly to the program account or the specific PDAs you care about via Solana's native programSubscribe / accountSubscribe RPC method on a Helius, Triton, or QuickNode endpoint.
For price tape, subscribe to the relevant Pyth Pull oracle account. The mapping from Sour market → Pyth feed is exposed in the SDK at packages/sour-sdk/src/symbols.ts.
For order/fill events, decode SourEvent records emitted by the program. Decoders are in packages/sour-sdk/src/decode.ts.
Building a bot
- Step 1 — FundingDeposit USDC into your trader account via the SDK's deposit instruction. Trader accounts are PDA-derived from your wallet pubkey + the program ID.
- Step 2 — Order constructionUse the canonical TypeScript client at packages/sour-sdk/src/sour_client.ts for instruction building. The Quasar-generated client at target/client/typescript has known codegen bugs; do not use it directly.
- Step 3 — SubmissionSubmit your transactions with skipPreflight: true on mainnet — Helius keyed RPC rejects preflight (-32602). The pusher / keeper / frontend all do this.
- Step 4 — ReconciliationDecode the next batch's clear event to confirm fill price, OI move, and fee paid. Don't optimistically update your local state on submit — wait for the on-chain effect.
On-chain matching engine. No mock APIs. If you can read a Solana account, you can build on Sour.