feat(polymarket): add prediction market endpoints#463
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new Polymarket module to the API, exposing prediction-market market/price/activity/positions/platform analytics from on-chain Polygon-derived datasets, enriched via a scraper metadata DB, following the existing Hono + Zod + ClickHouse query patterns.
Changes:
- Introduces Polymarket identifier/sort Zod schemas (condition_id, token_id, slug, event_type, sort_by variants) with unit tests.
- Adds 7 new
/v1/polymarket/*endpoints (handlers + ClickHouse SQL) for markets, OHLCV, open interest, activity feed, market positions leaderboard, platform aggregates, and user positions. - Registers the new Polymarket routes under the main router with cache-control middleware.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types/zod.ts | Adds Polymarket-specific query parameter schemas (IDs, slugs, enums). |
| src/types/zod.spec.ts | Adds unit tests covering the new Polymarket Zod schemas. |
| src/routes/polymarket/positions.ts | Implements /v1/polymarket/positions (user portfolio positions). |
| src/routes/polymarket/positions.sql | Query backing user positions with latest price enrichment + scraper join. |
| src/routes/polymarket/platform.ts | Implements /v1/polymarket/platform (platform-wide aggregates). |
| src/routes/polymarket/platform.sql | Query for platform time-series combining volume/OI/fees globals. |
| src/routes/polymarket/oi.ts | Implements /v1/polymarket/markets/oi (market open interest series). |
| src/routes/polymarket/oi.sql | Resolves market identity from scraper and returns OI time-series. |
| src/routes/polymarket/ohlcv.ts | Implements /v1/polymarket/markets/ohlc (per-token OHLCV + fees). |
| src/routes/polymarket/ohlcv.sql | Query for per-outcome OHLCV enriched with scraper metadata. |
| src/routes/polymarket/markets.ts | Implements /v1/polymarket/markets (market discovery/lookup). |
| src/routes/polymarket/markets.sql | Query for market metadata and outcome token IDs. |
| src/routes/polymarket/market_positions.ts | Implements /v1/polymarket/markets/positions (token leaderboard). |
| src/routes/polymarket/market_positions.sql | Query backing market positions leaderboard with current price lookup. |
| src/routes/polymarket/activity.ts | Implements /v1/polymarket/markets/activity (event feed). |
| src/routes/polymarket/activity.sql | Query unifying trades/splits/merges/redemptions into one feed. |
| src/routes/index.ts | Wires all new Polymarket routes into the main router. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
91cba6e to
e754712
Compare
Add validation schemas for condition_id, token_id, slug, event_type, and sort_by enums for markets, market positions, and user positions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Polymarket endpoints backed by on-chain Polygon data and scraper metadata: - GET /v1/polymarket/markets — market lookup and discovery - GET /v1/polymarket/markets/ohlc — OHLCV per outcome token - GET /v1/polymarket/markets/oi — open interest per market - GET /v1/polymarket/markets/activity — on-chain event feed - GET /v1/polymarket/markets/positions — per-token leaderboard - GET /v1/polymarket/platform — platform-wide aggregates - GET /v1/polymarket/positions — user portfolio with PNL Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 15 Polymarket DB tests covering all 7 endpoints plus validation error cases (missing required params) - Fix `v.timestamp` / `o.timestamp` table-prefix leak in platform and OHLCV SQL output — add explicit `AS timestamp` alias Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- OHLCV: use Nullable(String) + nullIf for MarketContext Tuple fields from LEFT JOIN (scraper lookup can return NULL) - Activity: include condition_id in trade branch guards and filters so condition_id-only queries return trades for that market - OI: reject when both condition_id and market_slug are provided Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Market positions and user positions handlers appended HAVING/ORDER BY but not LIMIT/OFFSET, causing all rows to be returned regardless of the limit parameter. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the 3-way JOIN of orderbook_global, open_interest_global, and fee_global views with a single read from the pre-aggregated state_platform table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…vity Move the LEFT JOINs for MarketContext resolution (scraper tables) from inside the 5 UNION ALL branches to a final SELECT on the paged result set. The CTE now returns raw asset_id/condition_id, and the JOINs run only on the LIMIT'd rows instead of all matching rows. Also replace the per-row LEFT JOIN for condition_id filtering with an IN subquery on the scraper lookup table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the latest_prices CTE (scans all daily orderbook, 5.3M rows) with a direct read from the pre-materialized state_latest_price ReplacingMergeTree table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ilter Add market closed status to the MarketContext tuple across all endpoints (positions, market_positions, ohlcv, oi, activity). The closed field comes from the polymarket_markets_by_asset_id lookup table with zero query cost. Replace the active filter parameter (net_position != 0) with closed (market resolved) on both position endpoints, aligning with Polymarket's own data model where market status is distinct from position balance. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add GET /v1/polymarket/users for user discovery (leaderboard) and lookup by address, reading from pre-aggregated state_user table - Move /v1/polymarket/positions to /v1/polymarket/users/positions - Rename OpenAPI tag from "Polymarket Positions" to "Polymarket Users" - Add polymarketUserSortBySchema (total_volume, realized_pnl, transactions) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add unrealized_pnl, total_pnl to response (from refreshable MV) - Add time_period query param (ALL, MONTH, WEEK, DAY) - Add sort_by options: total_pnl, unrealized_pnl - Add polymarketTimePeriodSchema - Read from pre-computed state_user table (hourly refresh) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…point Use standard interval naming (1h, 1d, 1w, 30d) instead of custom time_period values (ALL, MONTH, WEEK, DAY). Omitting interval defaults to all-time. ClickHouse state_user table now keyed by interval_min. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add computed PNL fields to /users/positions and /markets/positions responses. unrealized_pnl is position_value for open positions (zero for closed). total_pnl = realized_pnl + unrealized_pnl. Also add both as sort_by options. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move event_slug/event_title after market_slug in /markets response. Group PNL fields together (realized, unrealized, total, pct) in both position endpoints. Extract current_price to CTE in market_positions to avoid forward alias reference. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add 8 Polymarket prediction market endpoints serving on-chain Polygon event data enriched with scraper metadata. All endpoints follow existing Token API patterns (Zod validation, ClickHouse parameterized queries, OpenAPI via hono-openapi).
Endpoints
GET /v1/polymarket/markets[{label,token_id}]via SQLarrayMap.GET /v1/polymarket/markets/ohlcGET /v1/polymarket/markets/oiGET /v1/polymarket/markets/activityGET /v1/polymarket/markets/positionsGET /v1/polymarket/platformstate_platform.GET /v1/polymarket/usersstate_user.GET /v1/polymarket/users/positionsstate_latest_price.New Zod schemas
polymarketConditionIdSchema,polymarketTokenIdSchema,polymarketSlugSchema,polymarketEventTypeSchema,polymarketMarketSortBySchema,polymarketMarketPositionSortBySchema,polymarketPositionSortBySchema,polymarketUserSortBySchema🤖 Generated with Claude Code