A fully typed SDK and proxy server built with Elysia for Polymarket APIs. This package provides standalone SDK clients, WebSocket real-time streaming, and a proxy server with type-safe endpoints for CLOB and Gamma APIs, featuring comprehensive validation and automatic OpenAPI schema generation. Available in both TypeScript and Go.
- Fully Typed SDK: Complete TypeScript support with no
anytypes - WebSocket Client: Real-time market data streaming with auto-reconnection
- Proxy Server: REST API with OpenAPI documentation
- MCP Server: Model Context Protocol server for AI interactions
- Type Safety: End-to-end type validation and transformation
- Multiple Runtimes: Supports Bun, Node.js, Deno, and Cloudflare Workers
- Multi-Language Support: TypeScript and Go clients with identical APIs
- Reason: The official Polymarket SDKs in TypeScript and Python aren't fully typed; some return values are
unknown/any. - Solution: A fully typed SDK plus a translation proxy server with end-to-end type safety and OpenAPI.
- Codegen: Generate SDKs in other languages from the proxy server's OpenAPI schema.
- Transformations: The proxy doesn't always return exactly the same payload as the original API. It normalizes data by parsing and validating fields. For example, some endpoints return an array of strings as a JSON-stringified string; the proxy parses this into a proper typed array for easier consumption and validation.
- Status: Work in progress — not all APIs are included yet.
- Dual-Purpose Package: Standalone SDK clients + Elysia proxy server
- Unified TypeBox Validation: Single source of truth for all schema validation using Elysia TypeBox
- Type Safety: Full TypeScript typing throughout with no
anytypes - Standalone SDKs: Use
PolymarketSDKandGammaSDKdirectly in your applications - Proxy Server: Optional Elysia server with REST API endpoints
- OpenAPI Schema Generation: Automatic Swagger documentation generation
- CORS Support: Ready for web application integration
- Comprehensive Error Handling: Structured error responses with proper status codes
- Health Checks: Built-in health monitoring endpoints
- Production Ready: Includes proper logging, validation, and error handling
This package provides two ways to use Polymarket APIs:
PolymarketSDK: For CLOB operations (requires credentials)GammaSDK: For Gamma API operations (no credentials required)PolymarketWebSocketClient: For real-time market data streaming (TypeScript)WebSocketClient: For real-time market data streaming (Go)
- Gamma API (
/gamma/*) - Market and event data fromgamma-api.polymarket.com - CLOB API (
/clob/*) - Trading and price history from Polymarket CLOB client
src/
├── mod.ts # Main SDK exports (JSR entry point)
├── index.ts # Elysia server entry point
├── client.ts # Proxy client (referenced in JSR)
├── run.ts # Server runner for development
├── sdk/ # Standalone SDK clients
│ ├── index.ts # SDK exports
│ ├── client.ts # PolymarketSDK (CLOB client)
│ ├── gamma-client.ts # GammaSDK (Gamma API client)
│ └── websocket-client.ts # WebSocket client for real-time data
├── routes/ # Elysia server routes
│ ├── gamma.ts # Gamma API endpoints
│ └── clob.ts # CLOB API endpoints
├── types/
│ ├── elysia-schemas.ts # Unified TypeBox schema definitions
│ └── websocket-schemas.ts # WebSocket message schemas (Zod)
└── utils/ # Utility functions
go-client/
├── client/
│ ├── clob_client.go # CLOB client implementation
│ └── websocket_client.go # WebSocket client implementation
├── types/
│ ├── types.go # Core type definitions
│ └── websocket.go # WebSocket message types
└── examples/
├── websocket_simple.go # Simple WebSocket example
└── websocket_subscription.go # Advanced WebSocket example
.→./src/mod.ts- Main SDK exports./proxy→./src/client.ts- Proxy client./sdk→./src/sdk/index.ts- Direct SDK access
import { GammaSDK } from "@hk/polymarket";
const gammaSDK = new GammaSDK();
// Get all active markets
const markets = await gammaSDK.getActiveMarkets();
// Get markets with filtering
const filteredMarkets = await gammaSDK.getMarkets({
limit: "10",
active: "true",
volume_num_min: "1000",
});
// Get specific market by slug
const market = await gammaSDK.getMarketBySlug("bitcoin-above-100k");
// Get events with filtering
const events = await gammaSDK.getEvents({
limit: "5",
active: "true",
end_date_min: "2024-01-01",
});import { PolymarketSDK } from "@hk/polymarket";
const polymarketSDK = new PolymarketSDK({
privateKey: "your_private_key",
funderAddress: "your_funder_address",
});
// Get price history for a market
const priceHistory = await polymarketSDK.getPriceHistory({
market: "0x123...", // CLOB token ID
interval: "1h",
startDate: "2024-01-01",
endDate: "2024-01-31",
});
// Check CLOB connection health
const health = await polymarketSDK.healthCheck();Stream real-time market data with automatic authentication, reconnection, and type-safe message handling.
import { ClobClient } from "@polymarket/clob-client";
import { Wallet } from "@ethersproject/wallet";
import { PolymarketWebSocketClient } from "@hk/polymarket";
const signer = new Wallet(process.env.POLYMARKET_KEY!);
const clobClient = new ClobClient("https://clob.polymarket.com", 137, signer);
// Create WebSocket client with asset IDs to subscribe to
const ws = new PolymarketWebSocketClient(clobClient, {
assetIds: ["60487116984468020978247225474488676749601001829886755968952521846780452448915"],
autoReconnect: true,
debug: true,
});
// Register event handlers
ws.on({
onBook: (msg) => {
console.log(`📚 Book Update - Bids: ${msg.bids.length}, Asks: ${msg.asks.length}`);
// Fully typed message with validation
},
onPriceChange: (msg) => {
console.log(`💹 Price Change - ${msg.price_changes.length} changes`);
},
onLastTradePrice: (msg) => {
console.log(`💰 Trade: ${msg.side} @ ${msg.price}`);
},
onError: (error) => console.error("Error:", error),
onConnect: () => console.log("Connected!"),
});
// Connect and start receiving data
await ws.connect();import (
"github.com/HuakunShen/polymarket-kit/go-client/client"
"github.com/HuakunShen/polymarket-kit/go-client/types"
)
config := &client.ClientConfig{
Host: "https://clob.polymarket.com",
ChainID: types.ChainPolygon,
PrivateKey: os.Getenv("POLYMARKET_KEY"),
}
clobClient, _ := client.NewClobClient(config)
// Create WebSocket client
wsClient := client.NewWebSocketClient(clobClient, &client.WebSocketClientOptions{
AssetIDs: []string{
"60487116984468020978247225474488676749601001829886755968952521846780452448915",
},
AutoReconnect: true,
Debug: true,
})
// Register event handlers
wsClient.On(&client.WebSocketCallbacks{
OnBook: func(msg *types.BookMessage) {
fmt.Printf("📚 Book Update - Bids: %d, Asks: %d\n",
len(msg.Bids), len(msg.Asks))
},
OnPriceChange: func(msg *types.PriceChangeMessage) {
fmt.Printf("💹 Price Change - %d changes\n", len(msg.PriceChanges))
},
OnLastTradePrice: func(msg *types.LastTradePriceMessage) {
fmt.Printf("💰 Trade: %s @ %s\n", msg.Side, msg.Price)
},
OnError: func(err error) {
fmt.Printf("Error: %v\n", err)
},
})
// Connect and start receiving data
wsClient.Connect()- ✅ Automatic Authentication - Handles API key derivation automatically
- ✅ Type-Safe Messages - Full validation and typing for all message types
- ✅ Auto-Reconnection - Configurable reconnection with retry logic
- ✅ Event Handlers - Clean callback API for each message type
- ✅ Connection Management - Easy subscribe/unsubscribe methods
- ✅ Debug Logging - Optional detailed logging for troubleshooting
The WebSocket client handles four message types:
- Book Messages - Full orderbook snapshots and updates
- Price Change Messages - Real-time price level changes
- Tick Size Change Messages - Minimum tick size updates
- Last Trade Price Messages - Trade execution events
See WebSocket Client Documentation for detailed API reference and examples.
All types are exported from the unified schema:
import type {
// Market & Event Types
MarketType,
EventType,
MarketQueryType,
EventQueryType,
PriceHistoryQueryType,
PriceHistoryResponseType,
// WebSocket Types
MarketChannelMessage,
BookMessage,
PriceChangeMessage,
TickSizeChangeMessage,
LastTradePriceMessage,
WebSocketClientOptions,
WebSocketClientCallbacks,
} from "@hk/polymarket";GET /- API information and available endpointsGET /health- Global health checkGET /docs- Swagger/OpenAPI documentation
GET /gamma/markets- Get markets with comprehensive filtering- Query params:
limit,offset,order,ascending,id,slug,archived,active,closed,clob_token_ids,condition_ids,liquidity_num_min,liquidity_num_max,volume_num_min,volume_num_max,start_date_min,start_date_max,end_date_min,end_date_max,tag_id,related_tags
- Query params:
GET /gamma/events- Get events with comprehensive filtering- Query params:
limit,offset,order,ascending,id,slug,archived,active,closed,liquidity_min,liquidity_max,volume_min,volume_max,start_date_min,start_date_max,end_date_min,end_date_max,tag,tag_id,related_tags,tag_slug
- Query params:
GET /clob/prices-history- Get price history for a market token- Required query param:
market(CLOB token ID) - Time range options:
startTs,endTs(Unix timestamps) ORstartDate,endDate(ISO strings) - Interval option:
interval(1m, 1h, 6h, 1d, 1w, max) - Data resolution:
fidelity(resolution in minutes) - Headers:
x-polymarket-key,x-polymarket-funder(required in production)
- Required query param:
GET /clob/health- CLOB client connection health checkGET /clob/cache/stats- Get cache statistics for SDK instances and CLOB clientsDELETE /clob/cache- Clear all caches
-
Install from JSR:
# Using Deno deno add @hk/polymarket # Using Bun bunx jsr add @hk/polymarket # Using npm npx jsr add @hk/polymarket
-
Use directly in your code:
import { GammaSDK, PolymarketSDK } from "@hk/polymarket"; // No server setup required!
-
Install dependencies:
bun install
-
Environment Variables:
# Required for CLOB API endpoints POLYMARKET_KEY=your_private_key_here POLYMARKET_FUNDER=your_funder_address # Optional PORT=3000 # defaults to 3000 SDK_CACHE_MAX_SIZE=50 # defaults to 50 SDK_CACHE_TTL_HOURS=1 # defaults to 1 CLOB_CLIENT_CACHE_MAX_SIZE=100 # defaults to 100 CLOB_CLIENT_CACHE_TTL_MINUTES=30 # defaults to 30
-
Development:
bun run dev
-
Production:
bun run src/index.ts
-
Deploy to Cloudflare Workers (optional):
bun run deploy
The server automatically generates OpenAPI 3.0 schemas that can be used to create type-safe SDKs for other languages:
- Swagger UI: Visit
/docswhen the server is running - Raw JSON: Visit
/docs/jsonto get the OpenAPI JSON schema
The generated OpenAPI schema can be used with various code generators:
# Using openapi-generator-cli
npm install -g @openapitools/openapi-generator-cli
# Generate Python client
openapi-generator-cli generate \
-i http://localhost:3000/docs/json \
-g python \
-o ./generated/python-client \
--additional-properties=packageName=polymarket_proxy_client# Generate Go client
openapi-generator-cli generate \
-i http://localhost:3000/docs/json \
-g go \
-o ./generated/go-client \
--additional-properties=packageName=polymarket# Generate TypeScript client
openapi-generator-cli generate \
-i http://localhost:3000/docs/json \
-g typescript-axios \
-o ./generated/ts-clientThis package uses a single source of truth for all type definitions and validation through Elysia TypeBox schemas located in src/types/elysia-schemas.ts. This provides:
- Compile-time type safety: Full TypeScript types for all API operations
- Runtime validation: Automatic request/response validation in proxy server routes
- OpenAPI generation: Automatic schema generation for documentation
- Cross-platform compatibility: TypeBox schemas work across Bun, Node.js, Deno, and Cloudflare Workers
// All schemas are defined once in elysia-schemas.ts
export const MarketSchema = t.Object({
id: t.String(),
question: t.String(),
// ... comprehensive type definitions
});
// Types are automatically derived
export type MarketType = typeof MarketSchema.static;Previously, this package had duplicate schema definitions:
- ❌
sdk/types.ts(Effect schemas) - ❌
types/elysia-schemas.ts(TypeBox schemas)
Now we have:
- ✅ Single source:
types/elysia-schemas.ts(TypeBox schemas only) - ✅ No duplicate maintenance
- ✅ Consistent validation across SDK and server
- ✅ Smaller bundle size (removed Effect dependency)
import { GammaSDK, PolymarketSDK, type MarketType } from "@hk/polymarket";
// Using GammaSDK
const gamma = new GammaSDK();
const markets: MarketType[] = await gamma.getMarkets({
limit: "10",
active: "true",
});
// Using PolymarketSDK
const polySdk = new PolymarketSDK({
privateKey: process.env.POLYMARKET_KEY!,
funderAddress: process.env.POLYMARKET_FUNDER!,
});
const priceHistory = await polySdk.getPriceHistory({
market: "0x123...",
interval: "1h",
startDate: "2024-01-01",
});// Direct HTTP API calls to proxy server
const markets = await fetch(
"http://localhost:3000/gamma/markets?limit=10&active=true"
).then((res) => res.json());
const priceHistory = await fetch(
"http://localhost:3000/clob/prices-history?market=0x123&interval=1h",
{
headers: {
"x-polymarket-key": "your_key",
"x-polymarket-funder": "your_funder",
},
}
).then((res) => res.json());import polymarket_proxy_client
client = polymarket_proxy_client.ApiClient()
api = polymarket_proxy_client.GammaAPIApi(client)
# Get markets
markets = api.gamma_markets_get(slug="bitcoin-above-100k")
# Get price history
price_data = api.clob_price_history_token_id_get(
token_id="0x123",
interval="1h"
)The Model Context Protocol (MCP) server provides a natural language interface to Polymarket data for AI models and assistants.
# Start the MCP server
bun run src/mcp/polymarket.ts- Market Analysis:
get_markets,get_market_by_id,get_market_by_slug - Event Management:
get_events,get_event_by_id,get_event_markdown - Search & Discovery:
search_polymarket,get_tags - Analytics:
get_market_trends,get_popular_markets
markets://active: Live feed of active marketsevents://featured: Featured events and tournaments
Configure the MCP server in your AI client:
{
"mcpServers": {
"polymarket": {
"command": "bun",
"args": ["run", "path/to/polymarket-kit/src/mcp/polymarket.ts"]
}
}
}# Market Discovery
"Show me the most active prediction markets right now"
"Find markets about the 2024 US election"
"What are the trending markets in the last 24 hours?"
# Event Analysis
"Give me details about event ID 456 in markdown format"
"What are the featured events happening this week?"
"Show me all markets for the World Cup event"
# Market Research
"Analyze market trends for the past week"
"What are the most popular markets by trading volume?"
"Show me markets that have seen significant price changes"
See GEMINI.md for detailed usage examples and integration guides.
- Basic Elysia server setup
- Gamma API routes with full typing
- CLOB API routes with full typing
- OpenAPI documentation generation
- CORS and error handling
- Unified TypeBox schema system
- Standalone SDK clients
- JSR package publishing support
- Eliminated duplicate schemas
- Comprehensive caching system
- Automated SDK generation pipeline for other languages
- Python SDK with proper typing
- Go SDK generation
- Enhanced TypeScript client generation
- Rate limiting and request throttling
- Authentication/API key management
- Monitoring and metrics collection
- WebSocket support for real-time data ✅
- Type-safe WebSocket message schemas ✅
- Auto-reconnection and error handling ✅
- Enhanced error recovery mechanisms
- WebSocket Integration: Full real-time market data streaming with type-safe clients in TypeScript and Go
- Message Validation: Comprehensive Zod/struct validation for all WebSocket message types
- Auto-Reconnection: Robust connection management with configurable retry logic
- Schema Consolidation: Migrated from dual Effect + TypeBox schemas to unified TypeBox-only approach
- Type Safety: Eliminated all
anytypes and improved TypeScript strictness - Bundle Optimization: Removed Effect dependency, reduced package size
- SDK Architecture: Clean separation between standalone SDKs and proxy server
- JSR Support: Ready for publishing to JavaScript Registry with proper exports
- Follow the existing TypeScript patterns
- Ensure all endpoints have proper Elysia type validation
- Update OpenAPI documentation for new endpoints
- Test with both development and production builds
MIT