All three run as
tsx processes off one Docker image. See Docker Compose.
Service map
Five services share one Postgres and one Redis. The api fronts REST + WS for the browser. The indexer streams Sui events into Postgres. The quote-worker keeps hot-strike quotes fresh. The resolver settles. The agent (optional) trades.
Ports
The agent ports start at 8083 because the resolver owns 8082.
Data stores
- Postgres (5433 in dev, 5432 in compose). Indexer destination. Drizzle ORM. Migrations in
packages/server/src/db/migrations/. - Redis. Quote cache + pubsub for WS fanout, plus self-sponsorship daily caps.
docker compose up -d redis postgres.
Bootstrap order
curl http://localhost:8081/health and check for [resolver] RESOLVER_KEY loaded. Signing as 0x… in the resolver logs.
What each process owns
- api. Every
/v1/*REST route and the/wsWebSocket hub. Writes nothing to chain. Reads Postgres and devInspect for live quotes. Signs the sponsor leg ofPOST /v1/sponsor. - indexer. Sui event poller. Persists cursors. Writes to Postgres via Drizzle. Streams:
predict::PositionMinted,predict::PositionRedeemed,predict::oracle::*,darkpool::oo_resolution::*,darkpool::agent::*,darkpool::dark_pool::*, plus onebinary::<slug>stream per registry entry. - quote-worker. Hot-strike
predict::get_trade_amountspoller (QUOTE_POLL_MS, default 2000). Caches in Redis. Publishes updates over pubsub for WS fanout. - resolver. Two jobs in one process. HTTP settlement endpoint for OO and atomic Pyth-update PTBs. Auto-settle keeper that scans
predict::PositionMintedevents and submits per-position redeems for expired oracles.
Tighter dev loop
Skip Docker and run the four processes in separate terminals withtsx watch:

