Skip to main content
DarkPool’s backend is split into three workspaces:
PackageProcessesJob
@darkpool/serverapi, indexer, quote-workerREST + WebSocket, Sui event indexing, hot-strike quote polling
@darkpool/resolverresolverOO settlement endpoint + auto-settle keeper
@darkpool/shared(library)zod env schema, constants, byte helpers shared everywhere
All three run as tsx processes off one Docker image. See Docker Compose.

Service map

Ports

ProcessPort
api (REST + WS):8081
resolver:8082
agent runtime (optional):8083+
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.
Both shared services come up via docker compose up -d redis postgres.

Bootstrap order

# 1. Infrastructure
docker compose up -d redis postgres
pnpm --filter @darkpool/server db:migrate

# 2. One-command backend
docker compose up -d --build
# api : 8081
# indexer
# quote-worker
# resolver : 8082
Verify with 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 /ws WebSocket hub. Writes nothing to chain. Reads Postgres and devInspect for live quotes. Signs the sponsor leg of POST /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 one binary::<slug> stream per registry entry.
  • quote-worker. Hot-strike predict::get_trade_amounts poller (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::PositionMinted events and submits per-position redeems for expired oracles.

Tighter dev loop

Skip Docker and run the four processes in separate terminals with tsx watch:
# Terminal A: REST + WS api
pnpm --filter @darkpool/server dev:api

# Terminal B: Sui event indexer
pnpm --filter @darkpool/server dev:indexer

# Terminal C: Redis quote poller
pnpm --filter @darkpool/server dev:quote-worker

# Terminal D: Auto-settle keeper + OO settlement endpoint
pnpm --filter @darkpool/resolver dev
Don’t mix with the Docker services. They bind the same ports.