Skip to content

feat(polymarket): add prediction market endpoints#463

Open
0237h wants to merge 14 commits intomainfrom
feat/polymarket
Open

feat(polymarket): add prediction market endpoints#463
0237h wants to merge 14 commits intomainfrom
feat/polymarket

Conversation

@0237h
Copy link
Copy Markdown
Collaborator

@0237h 0237h commented Apr 2, 2026

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

Endpoint Tag Description
GET /v1/polymarket/markets Polymarket Markets Market lookup by condition_id, slug, or token_id. Discovery mode with sort_by and closed filter. Outcomes zipped as [{label,token_id}] via SQL arrayMap.
GET /v1/polymarket/markets/ohlc Polymarket Markets OHLCV price data per outcome token with fee metrics. MarketContext resolved via scraper lookup JOIN.
GET /v1/polymarket/markets/oi Polymarket Markets Open interest time-series per market. Accepts condition_id or market_slug (resolved via CTE).
GET /v1/polymarket/markets/activity Polymarket Markets Chronological feed of trades, splits, merges, and redemptions. Defaults to last 24h when no time range specified.
GET /v1/polymarket/markets/positions Polymarket Markets Per-token position leaderboard with PNL, current price, and closed filter.
GET /v1/polymarket/platform Polymarket Platform Platform-wide volume, open interest, and fee aggregates from pre-aggregated state_platform.
GET /v1/polymarket/users Polymarket Users User discovery (leaderboard by volume/PNL/transactions) and lookup by address. Reads from pre-aggregated state_user.
GET /v1/polymarket/users/positions Polymarket Users User portfolio with PNL breakdown per outcome token, current price via state_latest_price.

New Zod schemas

polymarketConditionIdSchema, polymarketTokenIdSchema, polymarketSlugSchema, polymarketEventTypeSchema, polymarketMarketSortBySchema, polymarketMarketPositionSortBySchema,
polymarketPositionSortBySchema, polymarketUserSortBySchema


🤖 Generated with Claude Code

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@YaroShkvorets YaroShkvorets temporarily deployed to feat/polymarket - token-api PR #463 April 2, 2026 20:56 — with Render Destroyed
@0237h 0237h force-pushed the feat/polymarket branch from ed8f623 to 60b4772 Compare April 6, 2026 21:19
@0237h 0237h force-pushed the feat/polymarket branch from c1caf61 to 91cba6e Compare April 7, 2026 15:55
0237h and others added 3 commits April 9, 2026 09:24
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>
0237h and others added 11 commits April 9, 2026 09:24
- 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants