pmxt-core 2.9.2 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -140,6 +140,11 @@ export declare abstract class PredictionMarketExchange {
140
140
  protected credentials?: ExchangeCredentials;
141
141
  verbose: boolean;
142
142
  http: AxiosInstance;
143
+ enableRateLimit: boolean;
144
+ private _rateLimit;
145
+ private _throttler;
146
+ get rateLimit(): number;
147
+ set rateLimit(value: number);
143
148
  markets: Record<string, UnifiedMarket>;
144
149
  marketsBySlug: Record<string, UnifiedMarket>;
145
150
  loadedMarkets: boolean;
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.PredictionMarketExchange = void 0;
7
7
  const math_1 = require("./utils/math");
8
8
  const errors_1 = require("./errors");
9
+ const throttler_1 = require("./utils/throttler");
9
10
  const axios_1 = __importDefault(require("axios"));
10
11
  // ----------------------------------------------------------------------------
11
12
  // Base Exchange Class
@@ -14,6 +15,20 @@ class PredictionMarketExchange {
14
15
  credentials;
15
16
  verbose = false;
16
17
  http;
18
+ enableRateLimit = true;
19
+ _rateLimit = 1000;
20
+ _throttler;
21
+ get rateLimit() {
22
+ return this._rateLimit;
23
+ }
24
+ set rateLimit(value) {
25
+ this._rateLimit = value;
26
+ this._throttler = new throttler_1.Throttler({
27
+ refillRate: 1 / value,
28
+ capacity: 1,
29
+ delay: 1,
30
+ });
31
+ }
17
32
  // Market Cache
18
33
  markets = {};
19
34
  marketsBySlug = {};
@@ -39,6 +54,18 @@ class PredictionMarketExchange {
39
54
  constructor(credentials) {
40
55
  this.credentials = credentials;
41
56
  this.http = axios_1.default.create();
57
+ this._throttler = new throttler_1.Throttler({
58
+ refillRate: 1 / this._rateLimit,
59
+ capacity: 1,
60
+ delay: 1,
61
+ });
62
+ // Rate Limit Interceptor
63
+ this.http.interceptors.request.use(async (config) => {
64
+ if (this.enableRateLimit) {
65
+ await this._throttler.throttle();
66
+ }
67
+ return config;
68
+ });
42
69
  // Request Interceptor
43
70
  this.http.interceptors.request.use((config) => {
44
71
  if (this.verbose) {
@@ -43,6 +43,7 @@ class BaoziExchange extends BaseExchange_1.PredictionMarketExchange {
43
43
  credentials = options;
44
44
  }
45
45
  super(credentials);
46
+ this.rateLimit = 500;
46
47
  rpcUrl = rpcUrl
47
48
  || process.env.BAOZI_RPC_URL
48
49
  || process.env.HELIUS_RPC_URL
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
3
- * Generated at: 2026-02-19T07:57:20.394Z
3
+ * Generated at: 2026-02-22T07:47:40.083Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const kalshiApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.kalshiApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
6
- * Generated at: 2026-02-19T07:57:20.394Z
6
+ * Generated at: 2026-02-22T07:47:40.083Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.kalshiApiSpec = {
@@ -44,6 +44,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
44
44
  credentials = options;
45
45
  }
46
46
  super(credentials);
47
+ this.rateLimit = 100;
47
48
  this.wsConfig = wsConfig;
48
49
  if (credentials?.apiKey && credentials?.privateKey) {
49
50
  this.auth = new auth_1.KalshiAuth(credentials);
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
3
- * Generated at: 2026-02-19T07:57:20.577Z
3
+ * Generated at: 2026-02-22T07:47:40.130Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const limitlessApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.limitlessApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
6
- * Generated at: 2026-02-19T07:57:20.577Z
6
+ * Generated at: 2026-02-22T07:47:40.130Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.limitlessApiSpec = {
@@ -53,6 +53,7 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
53
53
  credentials = options;
54
54
  }
55
55
  super(credentials);
56
+ this.rateLimit = 200;
56
57
  this.wsConfig = wsConfig;
57
58
  // Initialize auth if API key or private key are provided
58
59
  // API key is now the primary authentication method
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
3
- * Generated at: 2026-02-19T07:57:20.660Z
3
+ * Generated at: 2026-02-22T07:47:40.144Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const myriadApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.myriadApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
6
- * Generated at: 2026-02-19T07:57:20.660Z
6
+ * Generated at: 2026-02-22T07:47:40.144Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.myriadApiSpec = {
@@ -33,6 +33,7 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
33
33
  ws;
34
34
  constructor(credentials) {
35
35
  super(credentials);
36
+ this.rateLimit = 500;
36
37
  if (credentials?.apiKey) {
37
38
  this.auth = new auth_1.MyriadAuth(credentials);
38
39
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
3
- * Generated at: 2026-02-19T07:57:20.409Z
3
+ * Generated at: 2026-02-22T07:47:40.090Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const polymarketClobSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.polymarketClobSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
6
- * Generated at: 2026-02-19T07:57:20.409Z
6
+ * Generated at: 2026-02-22T07:47:40.090Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketClobSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
3
- * Generated at: 2026-02-19T07:57:20.513Z
3
+ * Generated at: 2026-02-22T07:47:40.108Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const polymarketDataSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.polymarketDataSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
6
- * Generated at: 2026-02-19T07:57:20.513Z
6
+ * Generated at: 2026-02-22T07:47:40.108Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketDataSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
3
- * Generated at: 2026-02-19T07:57:20.469Z
3
+ * Generated at: 2026-02-22T07:47:40.103Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const polymarketGammaSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.polymarketGammaSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
6
- * Generated at: 2026-02-19T07:57:20.469Z
6
+ * Generated at: 2026-02-22T07:47:40.103Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketGammaSpec = {
@@ -46,9 +46,25 @@ export declare class PolymarketExchange extends PredictionMarketExchange {
46
46
  */
47
47
  private ensureAuth;
48
48
  /**
49
- * Pre-warm the SDK's internal caches for a token by fetching tick size,
50
- * fee rate, and neg-risk in parallel. Call this when you start watching
51
- * a market so that subsequent createOrder calls hit only POST /order.
49
+ * Pre-warm the SDK's internal caches for a market outcome.
50
+ *
51
+ * Fetches tick size, fee rate, and neg-risk in parallel so that subsequent
52
+ * `createOrder` calls skip those lookups and hit only `POST /order`.
53
+ * Call this when you start watching a market.
54
+ *
55
+ * @param outcomeId - The CLOB Token ID for the outcome (use `outcome.outcomeId`)
56
+ *
57
+ * @example-ts Pre-warm before placing orders
58
+ * const markets = await exchange.fetchMarkets({ query: 'Trump' });
59
+ * const outcomeId = markets[0].outcomes[0].outcomeId;
60
+ * await exchange.preWarmMarket(outcomeId);
61
+ * // Subsequent createOrder calls are faster
62
+ *
63
+ * @example-python Pre-warm before placing orders
64
+ * markets = exchange.fetch_markets(query='Trump')
65
+ * outcome_id = markets[0].outcomes[0].outcome_id
66
+ * exchange.pre_warm_market(outcome_id)
67
+ * # Subsequent create_order calls are faster
52
68
  */
53
69
  preWarmMarket(outcomeId: string): Promise<void>;
54
70
  createOrder(params: CreateOrderParams): Promise<Order>;
@@ -52,6 +52,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
52
52
  credentials = options;
53
53
  }
54
54
  super(credentials);
55
+ this.rateLimit = 200;
55
56
  this.wsConfig = wsConfig;
56
57
  // Initialize auth if credentials are provided
57
58
  if (credentials?.privateKey) {
@@ -185,9 +186,25 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
185
186
  return this.auth;
186
187
  }
187
188
  /**
188
- * Pre-warm the SDK's internal caches for a token by fetching tick size,
189
- * fee rate, and neg-risk in parallel. Call this when you start watching
190
- * a market so that subsequent createOrder calls hit only POST /order.
189
+ * Pre-warm the SDK's internal caches for a market outcome.
190
+ *
191
+ * Fetches tick size, fee rate, and neg-risk in parallel so that subsequent
192
+ * `createOrder` calls skip those lookups and hit only `POST /order`.
193
+ * Call this when you start watching a market.
194
+ *
195
+ * @param outcomeId - The CLOB Token ID for the outcome (use `outcome.outcomeId`)
196
+ *
197
+ * @example-ts Pre-warm before placing orders
198
+ * const markets = await exchange.fetchMarkets({ query: 'Trump' });
199
+ * const outcomeId = markets[0].outcomes[0].outcomeId;
200
+ * await exchange.preWarmMarket(outcomeId);
201
+ * // Subsequent createOrder calls are faster
202
+ *
203
+ * @example-python Pre-warm before placing orders
204
+ * markets = exchange.fetch_markets(query='Trump')
205
+ * outcome_id = markets[0].outcomes[0].outcome_id
206
+ * exchange.pre_warm_market(outcome_id)
207
+ * # Subsequent create_order calls are faster
191
208
  */
192
209
  async preWarmMarket(outcomeId) {
193
210
  const auth = this.ensureAuth();
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
3
- * Generated at: 2026-02-19T07:57:20.610Z
3
+ * Generated at: 2026-02-22T07:47:40.137Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const probableApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.probableApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
6
- * Generated at: 2026-02-19T07:57:20.610Z
6
+ * Generated at: 2026-02-22T07:47:40.137Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.probableApiSpec = {
@@ -26,7 +26,43 @@ export declare class ProbableExchange extends PredictionMarketExchange {
26
26
  private ensureAuth;
27
27
  protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
28
28
  protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
29
+ /**
30
+ * Fetch a single event by its numeric ID (Probable only).
31
+ *
32
+ * @param id - The numeric event ID
33
+ * @returns The UnifiedEvent, or null if not found
34
+ *
35
+ * @example-ts Get event by ID
36
+ * const event = await exchange.getEventById('42');
37
+ * if (event) {
38
+ * console.log(event.title);
39
+ * console.log(event.markets.length, 'markets');
40
+ * }
41
+ *
42
+ * @example-python Get event by ID
43
+ * event = exchange.get_event_by_id('42')
44
+ * if event:
45
+ * print(event.title)
46
+ * print(len(event.markets), 'markets')
47
+ */
29
48
  getEventById(id: string): Promise<UnifiedEvent | null>;
49
+ /**
50
+ * Fetch a single event by its URL slug (Probable only).
51
+ *
52
+ * @param slug - The event's URL slug (e.g. `"trump-2024-election"`)
53
+ * @returns The UnifiedEvent, or null if not found
54
+ *
55
+ * @example-ts Get event by slug
56
+ * const event = await exchange.getEventBySlug('trump-2024-election');
57
+ * if (event) {
58
+ * console.log(event.title);
59
+ * }
60
+ *
61
+ * @example-python Get event by slug
62
+ * event = exchange.get_event_by_slug('trump-2024-election')
63
+ * if event:
64
+ * print(event.title)
65
+ */
30
66
  getEventBySlug(slug: string): Promise<UnifiedEvent | null>;
31
67
  fetchOrderBook(id: string): Promise<OrderBook>;
32
68
  fetchOHLCV(id: string, params: OHLCVParams | HistoryFilterParams): Promise<PriceCandle[]>;
@@ -53,6 +53,7 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
53
53
  wsConfig;
54
54
  constructor(credentials, wsConfig) {
55
55
  super(credentials);
56
+ this.rateLimit = 500;
56
57
  this.wsConfig = wsConfig;
57
58
  if (credentials?.privateKey && credentials?.apiKey && credentials?.apiSecret && credentials?.passphrase) {
58
59
  this.auth = new auth_1.ProbableAuth(credentials);
@@ -82,9 +83,45 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
82
83
  async fetchEventsImpl(params) {
83
84
  return (0, fetchEvents_1.fetchEvents)(params, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }), (queryParams) => this.callApi('getPublicApiV1PublicSearch', queryParams));
84
85
  }
86
+ /**
87
+ * Fetch a single event by its numeric ID (Probable only).
88
+ *
89
+ * @param id - The numeric event ID
90
+ * @returns The UnifiedEvent, or null if not found
91
+ *
92
+ * @example-ts Get event by ID
93
+ * const event = await exchange.getEventById('42');
94
+ * if (event) {
95
+ * console.log(event.title);
96
+ * console.log(event.markets.length, 'markets');
97
+ * }
98
+ *
99
+ * @example-python Get event by ID
100
+ * event = exchange.get_event_by_id('42')
101
+ * if event:
102
+ * print(event.title)
103
+ * print(len(event.markets), 'markets')
104
+ */
85
105
  async getEventById(id) {
86
106
  return (0, fetchEvents_1.fetchEventById)(id, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
87
107
  }
108
+ /**
109
+ * Fetch a single event by its URL slug (Probable only).
110
+ *
111
+ * @param slug - The event's URL slug (e.g. `"trump-2024-election"`)
112
+ * @returns The UnifiedEvent, or null if not found
113
+ *
114
+ * @example-ts Get event by slug
115
+ * const event = await exchange.getEventBySlug('trump-2024-election');
116
+ * if (event) {
117
+ * console.log(event.title);
118
+ * }
119
+ *
120
+ * @example-python Get event by slug
121
+ * event = exchange.get_event_by_slug('trump-2024-election')
122
+ * if event:
123
+ * print(event.title)
124
+ */
88
125
  async getEventBySlug(slug) {
89
126
  return (0, fetchEvents_1.fetchEventBySlug)(slug, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
90
127
  }
@@ -0,0 +1,17 @@
1
+ export declare class Throttler {
2
+ private tokens;
3
+ private queue;
4
+ private running;
5
+ private lastTimestamp;
6
+ private refillRate;
7
+ private capacity;
8
+ private delay;
9
+ constructor(config: {
10
+ refillRate: number;
11
+ capacity: number;
12
+ delay: number;
13
+ });
14
+ throttle(cost?: number): Promise<void>;
15
+ private loop;
16
+ private sleep;
17
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Throttler = void 0;
4
+ class Throttler {
5
+ tokens = 0;
6
+ queue = [];
7
+ running = false;
8
+ lastTimestamp = 0;
9
+ refillRate;
10
+ capacity;
11
+ delay;
12
+ constructor(config) {
13
+ this.refillRate = config.refillRate;
14
+ this.capacity = config.capacity;
15
+ this.delay = config.delay;
16
+ }
17
+ async throttle(cost = 1) {
18
+ return new Promise((resolve) => {
19
+ this.queue.push({ resolve, cost });
20
+ if (!this.running) {
21
+ this.running = true;
22
+ this.loop();
23
+ }
24
+ });
25
+ }
26
+ async loop() {
27
+ while (this.queue.length > 0) {
28
+ const now = Date.now();
29
+ if (this.lastTimestamp > 0) {
30
+ const elapsed = now - this.lastTimestamp;
31
+ this.tokens = Math.min(this.tokens + elapsed * this.refillRate, this.capacity);
32
+ }
33
+ this.lastTimestamp = now;
34
+ const head = this.queue[0];
35
+ if (this.tokens >= 0) {
36
+ this.tokens -= head.cost;
37
+ head.resolve();
38
+ this.queue.shift();
39
+ }
40
+ else {
41
+ await this.sleep(this.delay);
42
+ }
43
+ }
44
+ this.running = false;
45
+ }
46
+ sleep(ms) {
47
+ return new Promise((resolve) => setTimeout(resolve, ms));
48
+ }
49
+ }
50
+ exports.Throttler = Throttler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxt-core",
3
- "version": "2.9.2",
3
+ "version": "2.11.0",
4
4
  "description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,8 +29,8 @@
29
29
  "test": "jest -c jest.config.js",
30
30
  "server": "tsx watch src/server/index.ts",
31
31
  "server:prod": "node dist/server/index.js",
32
- "generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.9.2,library=urllib3",
33
- "generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.9.2,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
32
+ "generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.11.0,library=urllib3",
33
+ "generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.11.0,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
34
34
  "fetch:openapi": "node scripts/fetch-openapi-specs.js",
35
35
  "extract:jsdoc": "node ../scripts/extract-jsdoc.js",
36
36
  "generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",