Backend worker for prediction-market settlement:
- polls Pyth, Switchboard, and sports APIs
- performs source-consensus checks
- triggers settlement on your backend/API
- pushes retry/dispute tasks through an internal queue
- schedules exponential-backoff retries
- raises disputes when divergence or retry ceilings are hit
- exposes
/healthand/metricsfor ops visibility - supports memory or PostgreSQL repository backends
src/services/resolutionWorker.ts- polling loop + orchestrationsrc/oracles/*- per-source adapterssrc/settlement/settlementClient.ts- settlement trigger clientsrc/services/resolutionQueue.ts- async retry/dispute queue pipelinesrc/services/disputeService.ts- dispute writes/loggingsrc/state/repository.ts- in-memory repositorysrc/state/postgresRepository.ts- PostgreSQL repositorysrc/observability/*- health and Prometheus-style metrics
- Install dependencies
npm install- Configure environment
copy .env.example .env- Run locally
npm run devRun full stack (Postgres + worker + mock settlement API):
docker compose up --buildThen verify:
- worker metrics:
http://localhost:9090/metrics - worker health:
http://localhost:9090/health - mock settlement health:
http://localhost:8080/health
Notes:
- seeded markets are in
docker/postgres-init/01-seed.sql - worker service in
docker-compose.ymlusesREPOSITORY_BACKEND=postgres - one market uses live Pyth for demo; sports endpoint is placeholder unless you configure it
WORKER_INTERVAL_MS: loop intervalMAX_RETRY_ATTEMPTS: max retries before disputeBASE_RETRY_DELAY_MS: base backoff delayQUEUE_POLL_INTERVAL_MS: async queue processing intervalMIN_ORACLE_SOURCES: minimum successful oracle readsORACLE_PRICE_DIVERGENCE_BPS: max tolerated spread before disputeREPOSITORY_BACKEND:memoryorpostgresDATABASE_URL: required whenREPOSITORY_BACKEND=postgresMETRICS_PORT: HTTP port serving/healthand/metricsSETTLEMENT_API_*: backend settlement endpoint credentials/timeoutsPYTH_ENDPOINT: Pyth Hermes endpointSWITCHBOARD_ENDPOINT: Switchboard adapter/proxy endpointSPORTS_API_*: sports result provider endpoint and tokenMARKETS_SEED_FILE: optional path to JSON market seed file
Use MARKETS_SEED_FILE to point at a JSON array:
[
{
"id": "market-btc-hourly",
"type": "price",
"status": "ready_for_resolution",
"symbol": "Crypto.BTC/USD",
"expectedSources": ["pyth", "switchboard"],
"retryCount": 0
},
{
"id": "market-nba-game-1",
"type": "sports",
"status": "ready_for_resolution",
"sportsEventId": "nba_2026_04_22_game_1",
"expectedSources": ["sports"],
"retryCount": 0
}
]- add idempotency keys on settlement calls
- route disputes into your governance/manual resolution workflow
- connect
PostgresMarketRepositoryto migrations and managed backups - wire Prometheus/Grafana alerts off
/metrics - externalize queue into Redis/SQS if multi-instance scaling is needed
Run the schema in src/state/postgres.schema.sql before booting with REPOSITORY_BACKEND=postgres.
GitHub Actions workflow is included at .github/workflows/ci.yml and runs install, typecheck, and build on push/PR.