{"id":50996247,"url":"https://github.com/casatrick/oracle-resolution-worker","last_synced_at":"2026-06-20T09:35:21.412Z","repository":{"id":309622975,"uuid":"1019405370","full_name":"casatrick/oracle-resolution-worker","owner":"casatrick","description":"Oracle resolution worker for prediction markets: polls Pyth/Switchboard/sports feeds, settles markets, handles retries/disputes, and exposes health/metrics.","archived":false,"fork":false,"pushed_at":"2026-04-22T07:21:52.000Z","size":319,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-06-19T07:36:49.155Z","etag":null,"topics":["backend","docker","oracle","postgresql","prediction-market","prometheus","pyth","solana","switchboard"],"latest_commit_sha":null,"homepage":"https://roswelly.github.io/oracle-resolution-worker/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/casatrick.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-14T09:22:44.000Z","updated_at":"2026-04-22T07:22:58.000Z","dependencies_parsed_at":"2025-08-12T23:40:33.483Z","dependency_job_id":"2def6944-762d-4f75-bc99-446a30927761","html_url":"https://github.com/casatrick/oracle-resolution-worker","commit_stats":null,"previous_names":["roswelly/solana-relayer","roswelly/oracle-resolution-worker","casatrick/oracle-resolution-worker"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/casatrick/oracle-resolution-worker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casatrick%2Foracle-resolution-worker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casatrick%2Foracle-resolution-worker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casatrick%2Foracle-resolution-worker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casatrick%2Foracle-resolution-worker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/casatrick","download_url":"https://codeload.github.com/casatrick/oracle-resolution-worker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/casatrick%2Foracle-resolution-worker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34565240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["backend","docker","oracle","postgresql","prediction-market","prometheus","pyth","solana","switchboard"],"created_at":"2026-06-20T09:35:19.719Z","updated_at":"2026-06-20T09:35:21.400Z","avatar_url":"https://github.com/casatrick.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# oracle-resolution-worker\n\nBackend worker for prediction-market settlement:\n\n- polls Pyth, Switchboard, and sports APIs\n- performs source-consensus checks\n- triggers settlement on your backend/API\n- pushes retry/dispute tasks through an internal queue\n- schedules exponential-backoff retries\n- raises disputes when divergence or retry ceilings are hit\n- exposes `/health` and `/metrics` for ops visibility\n- supports memory or PostgreSQL repository backends\n\n## Architecture\n\n- `src/services/resolutionWorker.ts` - polling loop + orchestration\n- `src/oracles/*` - per-source adapters\n- `src/settlement/settlementClient.ts` - settlement trigger client\n- `src/services/resolutionQueue.ts` - async retry/dispute queue pipeline\n- `src/services/disputeService.ts` - dispute writes/logging\n- `src/state/repository.ts` - in-memory repository\n- `src/state/postgresRepository.ts` - PostgreSQL repository\n- `src/observability/*` - health and Prometheus-style metrics\n\n## Quick start\n\n1. Install dependencies\n\n```bash\nnpm install\n```\n\n2. Configure environment\n\n```bash\ncopy .env.example .env\n```\n\n3. Run locally\n\n```bash\nnpm run dev\n```\n\n## Docker demo stack\n\nRun full stack (Postgres + worker + mock settlement API):\n\n```bash\ndocker compose up --build\n```\n\nThen verify:\n\n- worker metrics: `http://localhost:9090/metrics`\n- worker health: `http://localhost:9090/health`\n- mock settlement health: `http://localhost:8080/health`\n\nNotes:\n\n- seeded markets are in `docker/postgres-init/01-seed.sql`\n- worker service in `docker-compose.yml` uses `REPOSITORY_BACKEND=postgres`\n- one market uses live Pyth for demo; sports endpoint is placeholder unless you configure it\n\n## Configuration\n\n- `WORKER_INTERVAL_MS`: loop interval\n- `MAX_RETRY_ATTEMPTS`: max retries before dispute\n- `BASE_RETRY_DELAY_MS`: base backoff delay\n- `QUEUE_POLL_INTERVAL_MS`: async queue processing interval\n- `MIN_ORACLE_SOURCES`: minimum successful oracle reads\n- `ORACLE_PRICE_DIVERGENCE_BPS`: max tolerated spread before dispute\n- `REPOSITORY_BACKEND`: `memory` or `postgres`\n- `DATABASE_URL`: required when `REPOSITORY_BACKEND=postgres`\n- `METRICS_PORT`: HTTP port serving `/health` and `/metrics`\n- `SETTLEMENT_API_*`: backend settlement endpoint credentials/timeouts\n- `PYTH_ENDPOINT`: Pyth Hermes endpoint\n- `SWITCHBOARD_ENDPOINT`: Switchboard adapter/proxy endpoint\n- `SPORTS_API_*`: sports result provider endpoint and token\n- `MARKETS_SEED_FILE`: optional path to JSON market seed file\n\n## Markets seed JSON shape\n\nUse `MARKETS_SEED_FILE` to point at a JSON array:\n\n```json\n[\n  {\n    \"id\": \"market-btc-hourly\",\n    \"type\": \"price\",\n    \"status\": \"ready_for_resolution\",\n    \"symbol\": \"Crypto.BTC/USD\",\n    \"expectedSources\": [\"pyth\", \"switchboard\"],\n    \"retryCount\": 0\n  },\n  {\n    \"id\": \"market-nba-game-1\",\n    \"type\": \"sports\",\n    \"status\": \"ready_for_resolution\",\n    \"sportsEventId\": \"nba_2026_04_22_game_1\",\n    \"expectedSources\": [\"sports\"],\n    \"retryCount\": 0\n  }\n]\n```\n\n## Production notes\n\n- add idempotency keys on settlement calls\n- route disputes into your governance/manual resolution workflow\n- connect `PostgresMarketRepository` to migrations and managed backups\n- wire Prometheus/Grafana alerts off `/metrics`\n- externalize queue into Redis/SQS if multi-instance scaling is needed\n\n## PostgreSQL schema\n\nRun the schema in `src/state/postgres.schema.sql` before booting with `REPOSITORY_BACKEND=postgres`.\n\n## CI\n\nGitHub Actions workflow is included at `.github/workflows/ci.yml` and runs install, typecheck, and build on push/PR.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcasatrick%2Foracle-resolution-worker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcasatrick%2Foracle-resolution-worker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcasatrick%2Foracle-resolution-worker/lists"}