docs/interface-contract.md,
which pins the account layouts, instruction arguments, transaction layouts, and REST/WS
surface both sides build against. This page maps how they fit together.
System overview
The on-chain settlement program (programs/pitchmarket/)
A greenfield Anchor program (no fork) that owns all money movement:
- Market PDAs with two SPL outcome mints (YES/NO) and a collateral pool per market.
- Per-user Vault PDAs — deposit once, then trade silently.
settle_match— verifies both users’ ed25519 order signatures on-chain via instruction introspection, enforces per-order fill accounting, and executes the NORMAL/MINT/MERGE money movement.resolve_market(tier-a operator key today) andredeem(winning shares → USDC, 1:1).
3fdgRPcZnwWcaGi197dkZDyq24VHoWJcGzKTVfMxNPWs — see
On-chain program for the accounts and instruction surface.
The backend service (backend/)
matching— a unified price-time-priority ladder that pairs NORMAL, MINT, and MERGE fills (see Matching engine).exchange— the trading core every order flows through: signature verify → soft-lock → match → Postgres mirror → crank → WebSocket events. Both the public API and the MM bot submit through it; nothing writes to the book or store directly.store— Postgres (Neon). Explicitly an index and soft-lock ledger: on-chain state is authoritative for money;orders.remainingmirrors the on-chainOrderStatus, never the other way around.crank— builds the pinned 3-instructionsettle_matchtransaction (as a v0 transaction with a per-market address lookup table — the legacy format is 1421+ bytes, over the 1232-byte limit) and submits it. Falls back to an off-chain mirror mode when no chain is configured.rfq,precision,mmbot,lifecycle,feed,oneliner,index— combos, precision pools, two-sided MINT liquidity, market auto-creation and resolution from the TxLINE feed, AI one-liners, and the chain-state reconciler.
Clients
frontend/— Next.js app: markets index, market page with live ladder, combos builder, precision pools, portfolio with realized/unrealized PnL. Wallets via Privy embedded wallets (with a localStorage ed25519 fallback wallet). Orders are borsh-encoded and signed client-side; the TypeScript encoder is pinned to the same golden vector as the Rust and Go encoders and checked at build time.mobile/— Expo (React Native) app covering the core loop: markets, trade, deposit, portfolio. Shares the signed-order and live-market client layer with the web frontend.
The seams that keep it honest
- Five borsh encoders, one golden vector. The signed
Ordermessage is encoded in Rust, Go, and TypeScript (web + mobile + test harness). A shared golden vector pins all of them byte-identical; touching any encoder means updating the same vector in every suite. See Signed messages. - On-chain is truth for money. Postgres soft-locks are UX; a
settle_matchrevert unwinds the soft-lock and re-emitsorder_update(interface contract §6). - All order flow goes through
internal/exchange. Skipping it would skip signature verification, soft-locks, the crank, or WS events.