From fe061aad4f43f93c488a7b0545c449c7932fe998 Mon Sep 17 00:00:00 2001 From: Samuel Tinnerholm Date: Fri, 5 Jun 2026 15:04:40 +0000 Subject: [PATCH 1/2] fix: name hardcoded chain IDs --- core/src/exchanges/limitless/client.ts | 6 +++--- core/src/exchanges/limitless/config.ts | 2 ++ core/src/exchanges/limitless/index.ts | 4 ++-- core/src/exchanges/polymarket/auth.ts | 6 +++--- core/src/exchanges/polymarket/config.ts | 1 + core/src/exchanges/polymarket/index.ts | 3 ++- core/src/exchanges/probable/auth.ts | 9 +++++---- core/src/exchanges/probable/config.ts | 2 ++ core/src/exchanges/probable/websocket.ts | 3 ++- 9 files changed, 22 insertions(+), 14 deletions(-) create mode 100644 core/src/exchanges/polymarket/config.ts create mode 100644 core/src/exchanges/probable/config.ts diff --git a/core/src/exchanges/limitless/client.ts b/core/src/exchanges/limitless/client.ts index 0ba431af..970ebd79 100644 --- a/core/src/exchanges/limitless/client.ts +++ b/core/src/exchanges/limitless/client.ts @@ -1,6 +1,6 @@ import { HttpClient, OrderClient, OrderBuilder, OrderSigner, MarketFetcher, Side, OrderType } from '@limitless-exchange/sdk'; import { Wallet, providers, Contract } from 'ethers'; -import { LIMITLESS_RPC_URL } from './config'; +import { LIMITLESS_CHAIN_ID, LIMITLESS_RPC_URL } from './config'; import { scaledIntegerToNumber } from './utils'; const DEFAULT_LIMITLESS_API_URL = process.env.LIMITLESS_BASE_URL || 'https://api.limitless.exchange'; @@ -204,7 +204,7 @@ export class LimitlessClient { // Sign with the EOA private key. const orderSigner = new OrderSigner(wallet); const signature = await orderSigner.signOrder(unsignedOrder, { - chainId: 8453, + chainId: LIMITLESS_CHAIN_ID, contractAddress: market.venue.exchange, }); @@ -387,7 +387,7 @@ export class LimitlessClient { const ABI = ["function balanceOf(address) view returns (uint256)", "function decimals() view returns (uint8)"]; const provider = new providers.StaticJsonRpcProvider(LIMITLESS_RPC_URL, { - chainId: 8453, + chainId: LIMITLESS_CHAIN_ID, name: 'base', }); const contract = new Contract(USDC_ADDRESS, ABI, provider); diff --git a/core/src/exchanges/limitless/config.ts b/core/src/exchanges/limitless/config.ts index bed2d5fd..85695435 100644 --- a/core/src/exchanges/limitless/config.ts +++ b/core/src/exchanges/limitless/config.ts @@ -1 +1,3 @@ +export const LIMITLESS_BASE_URL = process.env.LIMITLESS_BASE_URL || 'https://api.limitless.exchange'; export const LIMITLESS_RPC_URL = process.env.LIMITLESS_RPC_URL || 'https://mainnet.base.org'; +export const LIMITLESS_CHAIN_ID = 8453; // Base mainnet diff --git a/core/src/exchanges/limitless/index.ts b/core/src/exchanges/limitless/index.ts index 79008d78..840e6df2 100644 --- a/core/src/exchanges/limitless/index.ts +++ b/core/src/exchanges/limitless/index.ts @@ -32,7 +32,7 @@ import { FetcherContext } from '../interfaces'; import { limitlessApiSpec } from './api'; import { LimitlessAuth } from './auth'; import { LimitlessClient } from './client'; -import { LIMITLESS_RPC_URL } from './config'; +import { LIMITLESS_CHAIN_ID, LIMITLESS_RPC_URL } from './config'; import { limitlessErrorMapper } from './errors'; import { LimitlessFetcher } from './fetcher'; import { LimitlessNormalizer } from './normalizer'; @@ -572,7 +572,7 @@ export class LimitlessExchange extends PredictionMarketExchange { // Static network avoids ethers v5 auto-detect (eth_chainId), which can throw // noNetwork / NETWORK_ERROR on flaky public RPCs (#92). const provider = new providers.StaticJsonRpcProvider(LIMITLESS_RPC_URL, { - chainId: 8453, + chainId: LIMITLESS_CHAIN_ID, name: 'base', }); diff --git a/core/src/exchanges/polymarket/auth.ts b/core/src/exchanges/polymarket/auth.ts index 5aa2e3fb..51c9041f 100644 --- a/core/src/exchanges/polymarket/auth.ts +++ b/core/src/exchanges/polymarket/auth.ts @@ -7,10 +7,10 @@ import { polygon } from 'viem/chains'; import axios from 'axios'; import { ExchangeCredentials } from '../../BaseExchange'; import { logger } from '../../utils/logger'; +import { POLYMARKET_CHAIN_ID } from './config'; import { polymarketErrorMapper } from './errors'; const DEFAULT_POLYMARKET_HOST = process.env.POLYMARKET_CLOB_URL || 'https://clob.polymarket.com'; -const POLYGON_CHAIN_ID = 137; // Polymarket CLOB signature types — determines how the CLOB API // resolves the on-chain address holding the user's funds. @@ -93,7 +93,7 @@ export class PolymarketAuth { // Otherwise, derive/create them using L1 auth const l1Client = new ClobClient({ host: this.host, - chain: POLYGON_CHAIN_ID, + chain: POLYMARKET_CHAIN_ID, signer: this.signer, }); @@ -278,7 +278,7 @@ export class PolymarketAuth { this.clobClient = new ClobClient({ host: this.host, - chain: POLYGON_CHAIN_ID, + chain: POLYMARKET_CHAIN_ID, signer: this.signer, creds: apiCreds, signatureType: finalSignatureType, diff --git a/core/src/exchanges/polymarket/config.ts b/core/src/exchanges/polymarket/config.ts new file mode 100644 index 00000000..11eb8877 --- /dev/null +++ b/core/src/exchanges/polymarket/config.ts @@ -0,0 +1 @@ +export const POLYMARKET_CHAIN_ID = 137; // Polygon mainnet diff --git a/core/src/exchanges/polymarket/index.ts b/core/src/exchanges/polymarket/index.ts index fa62caf6..fd695784 100644 --- a/core/src/exchanges/polymarket/index.ts +++ b/core/src/exchanges/polymarket/index.ts @@ -37,6 +37,7 @@ import { polymarketClobSpec } from './api-clob'; import { polymarketDataSpec } from './api-data'; import { polymarketGammaSpec } from './api-gamma'; import { PolymarketAuth } from './auth'; +import { POLYMARKET_CHAIN_ID } from './config'; import { logger } from '../../utils/logger'; import { polymarketErrorMapper } from './errors'; import { PolymarketFetcher } from './fetcher'; @@ -752,7 +753,7 @@ export class PolymarketExchange extends PredictionMarketExchange { // Static network avoids ethers v5 auto-detect (eth_chainId), which can throw // noNetwork / NETWORK_ERROR on flaky public RPCs (#92). const provider = new ethers.providers.StaticJsonRpcProvider('https://polygon-rpc.com', { - chainId: 137, + chainId: POLYMARKET_CHAIN_ID, name: 'matic', }); const pusdAddress = '0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB'; // pUSD (Polymarket USD) diff --git a/core/src/exchanges/probable/auth.ts b/core/src/exchanges/probable/auth.ts index 0d126f57..92d1f652 100644 --- a/core/src/exchanges/probable/auth.ts +++ b/core/src/exchanges/probable/auth.ts @@ -3,6 +3,7 @@ import { privateKeyToAccount } from 'viem/accounts'; import { createWalletClient, http } from 'viem'; import { bsc, bscTestnet } from 'viem/chains'; import { ExchangeCredentials } from '../../BaseExchange'; +import { PROBABLE_CHAIN_ID, PROBABLE_TESTNET_CHAIN_ID } from './config'; /** * Manages Probable authentication and CLOB client initialization. @@ -36,8 +37,8 @@ export class ProbableAuth { return this.clobClient; } - const chainId = parseInt(process.env.PROBABLE_CHAIN_ID || '56', 10); - const chain = chainId === 97 ? bscTestnet : bsc; + const chainId = parseInt(process.env.PROBABLE_CHAIN_ID || String(PROBABLE_CHAIN_ID), 10); + const chain = chainId === PROBABLE_TESTNET_CHAIN_ID ? bscTestnet : bsc; const account = privateKeyToAccount(this.credentials.privateKey as `0x${string}`); const wallet = createWalletClient({ @@ -56,9 +57,9 @@ export class ProbableAuth { // disagree on WalletClient. Runtime shape is identical. const walletForClob = wallet as any; - if (chainId === 56) { + if (chainId === PROBABLE_CHAIN_ID) { this.clobClient = createClobClient({ - chainId: 56, + chainId: PROBABLE_CHAIN_ID, wallet: walletForClob, credential, }); diff --git a/core/src/exchanges/probable/config.ts b/core/src/exchanges/probable/config.ts new file mode 100644 index 00000000..0234301c --- /dev/null +++ b/core/src/exchanges/probable/config.ts @@ -0,0 +1,2 @@ +export const PROBABLE_CHAIN_ID = 56; // BSC mainnet +export const PROBABLE_TESTNET_CHAIN_ID = 97; // BSC testnet diff --git a/core/src/exchanges/probable/websocket.ts b/core/src/exchanges/probable/websocket.ts index cfaf48c8..79e5dded 100644 --- a/core/src/exchanges/probable/websocket.ts +++ b/core/src/exchanges/probable/websocket.ts @@ -1,6 +1,7 @@ import type { createClobClient } from '@prob/clob'; import { OrderBook, OrderLevel } from '../../types'; import { DEFAULT_WATCH_TIMEOUT_MS, withWatchTimeout } from '../../utils/watch-timeout'; +import { PROBABLE_CHAIN_ID } from './config'; interface QueuedPromise { resolve: (value: T | PromiseLike) => void; @@ -37,7 +38,7 @@ export class ProbableWebSocket { private async ensureClient(): Promise> { if (this.client) return this.client; - const chainId = this.config.chainId || parseInt(process.env.PROBABLE_CHAIN_ID || '56', 10); + const chainId = this.config.chainId || parseInt(process.env.PROBABLE_CHAIN_ID || String(PROBABLE_CHAIN_ID), 10); const wsUrl = this.config.wsUrl || process.env.PROBABLE_WS_URL || 'wss://ws.probable.markets/public/api/v1'; const baseUrl = this.config.baseUrl || process.env.PROBABLE_BASE_URL || 'https://api.probable.markets/public/api/v1'; From d58268044e947685daa8ecf2985bcd820ac251be Mon Sep 17 00:00:00 2001 From: Samuel Tinnerholm Date: Mon, 8 Jun 2026 08:00:52 +0000 Subject: [PATCH 2/2] chore: regenerate API references --- core/api-doc-config.generated.json | 40 +++++++++++++++--------------- sdks/python/API_REFERENCE.md | 2 +- sdks/typescript/API_REFERENCE.md | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/core/api-doc-config.generated.json b/core/api-doc-config.generated.json index 3e176c67..485c7be1 100644 --- a/core/api-doc-config.generated.json +++ b/core/api-doc-config.generated.json @@ -1,5 +1,5 @@ { - "_generated": "Auto-generated by extract-jsdoc.js on 2026-06-02T00:34:44.916Z. Do not edit manually.", + "_generated": "Auto-generated by extract-jsdoc.js on 2026-06-08T07:59:12.497Z. Do not edit manually.", "methods": { "has": { "summary": "HTTP verb for the endpoint (e.g. GET, POST). */", @@ -566,7 +566,7 @@ "type": "UnifiedEvent[]", "description": "Filtered array of events" }, - "source": "BaseExchange.ts:1317" + "source": "BaseExchange.ts:1318" }, "watchOrderBook": { "summary": "Watch order book updates in real-time via WebSocket.", @@ -595,7 +595,7 @@ "type": "OrderBook", "description": "Promise that resolves with the current orderbook state" }, - "source": "BaseExchange.ts:1413" + "source": "BaseExchange.ts:1414" }, "watchOrderBooks": { "summary": "Watch multiple order books simultaneously via WebSocket.", @@ -624,7 +624,7 @@ "type": "Record", "description": "Promise that resolves with order books keyed by ID" }, - "source": "BaseExchange.ts:1426" + "source": "BaseExchange.ts:1427" }, "unwatchOrderBook": { "summary": "Unsubscribe from a previously watched order book stream.", @@ -641,7 +641,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1454" + "source": "BaseExchange.ts:1455" }, "watchTrades": { "summary": "Watch trade executions in real-time via WebSocket.", @@ -676,7 +676,7 @@ "type": "Trade[]", "description": "Promise that resolves with recent trades" }, - "source": "BaseExchange.ts:1467" + "source": "BaseExchange.ts:1468" }, "watchAddress": { "summary": "Stream activity for a public wallet address", @@ -699,7 +699,7 @@ "type": "SubscribedAddressSnapshot", "description": "Promise that resolves with the latest SubscribedAddressSnapshot snapshot" }, - "source": "BaseExchange.ts:1481" + "source": "BaseExchange.ts:1482" }, "unwatchAddress": { "summary": "Stop watching a previously registered wallet address and release its resource updates.", @@ -716,7 +716,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1494" + "source": "BaseExchange.ts:1495" }, "close": { "summary": "Close all WebSocket connections and clean up resources.", @@ -726,7 +726,7 @@ "type": "void", "description": "Result" }, - "source": "BaseExchange.ts:1503" + "source": "BaseExchange.ts:1504" }, "fetchMarketMatches": { "summary": "Find the same or related market on other venues. Two modes:", @@ -743,7 +743,7 @@ "type": "MatchResult[]", "description": "Array of matched markets with relation and confidence" }, - "source": "BaseExchange.ts:1517" + "source": "BaseExchange.ts:1518" }, "fetchMatches": { "summary": "fetchMatches", @@ -760,7 +760,7 @@ "type": "MatchResult[]", "description": "Result" }, - "source": "BaseExchange.ts:1533" + "source": "BaseExchange.ts:1534" }, "fetchEventMatches": { "summary": "Find the same or related event on other venues. Two modes:", @@ -777,7 +777,7 @@ "type": "EventMatchResult[]", "description": "Array of matched events with market-level match details" }, - "source": "BaseExchange.ts:1541" + "source": "BaseExchange.ts:1542" }, "compareMarketPrices": { "summary": "Compare live prices for the same market across venues. Finds identity matches and returns side-by-side best bid/ask prices so you can spot price differences at a glance.", @@ -794,7 +794,7 @@ "type": "PriceComparison[]", "description": "Array of price comparisons across venues" }, - "source": "BaseExchange.ts:1557" + "source": "BaseExchange.ts:1558" }, "fetchRelatedMarkets": { "summary": "Find related markets across venues. Discovers subset/superset market relationships", @@ -811,7 +811,7 @@ "type": "PriceComparison[]", "description": "Array of subset/superset matches with live prices" }, - "source": "BaseExchange.ts:1567" + "source": "BaseExchange.ts:1568" }, "fetchMatchedMarkets": { "summary": "fetchMatchedMarkets", @@ -828,7 +828,7 @@ "type": "MatchedMarketPair[]", "description": "Result" }, - "source": "BaseExchange.ts:1578" + "source": "BaseExchange.ts:1579" }, "fetchMatchedPrices": { "summary": "fetchMatchedPrices", @@ -845,7 +845,7 @@ "type": "MatchedPricePair[]", "description": "Array of matched market pairs with prices from each venue" }, - "source": "BaseExchange.ts:1586" + "source": "BaseExchange.ts:1587" }, "fetchHedges": { "summary": "fetchHedges", @@ -862,7 +862,7 @@ "type": "PriceComparison[]", "description": "Array of subset/superset matches with live prices" }, - "source": "BaseExchange.ts:1597" + "source": "BaseExchange.ts:1598" }, "fetchArbitrage": { "summary": "fetchArbitrage", @@ -879,7 +879,7 @@ "type": "ArbitrageOpportunity[]", "description": "Array of arbitrage opportunities sorted by spread" }, - "source": "BaseExchange.ts:1607" + "source": "BaseExchange.ts:1608" }, "watchPrices": { "summary": "Watch AMM price updates for a market address (Limitless only).", @@ -950,7 +950,7 @@ "description": "Result" }, "exchangeOnly": "polymarket", - "source": "index.ts:143" + "source": "index.ts:144" }, "preWarmMarket": { "summary": "Pre-warm the SDK's internal caches for a market outcome.", @@ -968,7 +968,7 @@ "description": "Result" }, "exchangeOnly": "polymarket", - "source": "index.ts:209" + "source": "index.ts:210" }, "getEventById": { "summary": "Fetch a single event by its numeric ID (Probable only).", diff --git a/sdks/python/API_REFERENCE.md b/sdks/python/API_REFERENCE.md index dac681ce..b20f3aa2 100644 --- a/sdks/python/API_REFERENCE.md +++ b/sdks/python/API_REFERENCE.md @@ -1456,7 +1456,7 @@ title: str # The market title (e.g., "Will BTC close above $100k on Dec 31?"). description: str # Long-form market description or resolution criteria. slug: str # URL-friendly slug for the market. outcomes: List[MarketOutcome] # The possible outcomes for this market. -resolution_date: str # When the market is scheduled to resolve. +resolution_date: str # When the market is scheduled to resolve. Optional because some venues do not publish a cutoff for every market (e.g. Opinion categorical children) — emit `undefined` rather than coercing to epoch. volume24h: float # Trading volume over the past 24 hours (USD). volume: float # Total / Lifetime volume liquidity: float # Current market liquidity (USD). diff --git a/sdks/typescript/API_REFERENCE.md b/sdks/typescript/API_REFERENCE.md index f8504e0a..ec2f3280 100644 --- a/sdks/typescript/API_REFERENCE.md +++ b/sdks/typescript/API_REFERENCE.md @@ -1456,7 +1456,7 @@ title: string; // The market title (e.g., "Will BTC close above $100k on Dec 31? description: string; // Long-form market description or resolution criteria. slug: string; // URL-friendly slug for the market. outcomes: MarketOutcome[]; // The possible outcomes for this market. -resolutionDate: string; // When the market is scheduled to resolve. +resolutionDate: string; // When the market is scheduled to resolve. Optional because some venues do not publish a cutoff for every market (e.g. Opinion categorical children) — emit `undefined` rather than coercing to epoch. volume24h: number; // Trading volume over the past 24 hours (USD). volume: number; // Total / Lifetime volume liquidity: number; // Current market liquidity (USD).