pmxt-core 2.42.7 → 2.43.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.
Files changed (54) hide show
  1. package/dist/BaseExchange.d.ts +33 -12
  2. package/dist/BaseExchange.js +57 -17
  3. package/dist/exchanges/baozi/index.d.ts +2 -2
  4. package/dist/exchanges/baozi/index.js +2 -2
  5. package/dist/exchanges/gemini-titan/index.d.ts +2 -2
  6. package/dist/exchanges/gemini-titan/index.js +2 -2
  7. package/dist/exchanges/hyperliquid/index.d.ts +1 -1
  8. package/dist/exchanges/hyperliquid/index.js +1 -1
  9. package/dist/exchanges/kalshi/api.d.ts +32 -1
  10. package/dist/exchanges/kalshi/api.js +38 -1
  11. package/dist/exchanges/kalshi/fetcher.d.ts +11 -5
  12. package/dist/exchanges/kalshi/fetcher.js +12 -0
  13. package/dist/exchanges/kalshi/index.d.ts +7 -6
  14. package/dist/exchanges/kalshi/index.js +40 -31
  15. package/dist/exchanges/limitless/api.d.ts +1 -1
  16. package/dist/exchanges/limitless/api.js +1 -1
  17. package/dist/exchanges/limitless/index.d.ts +2 -2
  18. package/dist/exchanges/limitless/index.js +3 -2
  19. package/dist/exchanges/mock/index.d.ts +1 -1
  20. package/dist/exchanges/mock/index.js +1 -1
  21. package/dist/exchanges/myriad/api.d.ts +1 -1
  22. package/dist/exchanges/myriad/api.js +1 -1
  23. package/dist/exchanges/myriad/index.d.ts +2 -2
  24. package/dist/exchanges/myriad/index.js +2 -2
  25. package/dist/exchanges/opinion/api.d.ts +1 -1
  26. package/dist/exchanges/opinion/api.js +1 -1
  27. package/dist/exchanges/opinion/index.d.ts +2 -2
  28. package/dist/exchanges/opinion/index.js +2 -2
  29. package/dist/exchanges/polymarket/api-clob.d.ts +14 -1
  30. package/dist/exchanges/polymarket/api-clob.js +20 -1
  31. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  32. package/dist/exchanges/polymarket/api-data.js +1 -1
  33. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  34. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  35. package/dist/exchanges/polymarket/fetcher.d.ts +2 -0
  36. package/dist/exchanges/polymarket/fetcher.js +24 -0
  37. package/dist/exchanges/polymarket/index.d.ts +3 -2
  38. package/dist/exchanges/polymarket/index.js +17 -2
  39. package/dist/exchanges/polymarket_us/index.d.ts +2 -2
  40. package/dist/exchanges/polymarket_us/index.js +2 -2
  41. package/dist/exchanges/probable/api.d.ts +1 -1
  42. package/dist/exchanges/probable/api.js +1 -1
  43. package/dist/exchanges/probable/index.d.ts +2 -2
  44. package/dist/exchanges/probable/index.js +2 -2
  45. package/dist/exchanges/smarkets/index.d.ts +1 -1
  46. package/dist/exchanges/smarkets/index.js +1 -1
  47. package/dist/router/Router.d.ts +1 -1
  48. package/dist/router/Router.js +4 -4
  49. package/dist/router/e2e-orderbook.d.ts +1 -0
  50. package/dist/router/e2e-orderbook.js +58 -0
  51. package/dist/server/method-verbs.json +27 -2
  52. package/dist/server/openapi.yaml +50 -4
  53. package/dist/types.d.ts +2 -0
  54. package/package.json +3 -3
@@ -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-05-22T13:35:19.540Z
3
+ * Generated at: 2026-05-22T18:51:26.907Z
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-05-22T13:35:19.540Z
6
+ * Generated at: 2026-05-22T18:51:26.907Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.probableApiSpec = {
@@ -27,7 +27,7 @@ export declare class ProbableExchange extends PredictionMarketExchange {
27
27
  * @returns The UnifiedEvent, or null if not found
28
28
  */
29
29
  getEventBySlug(slug: string): Promise<UnifiedEvent | null>;
30
- fetchOrderBook(outcomeId: string): Promise<OrderBook>;
30
+ fetchOrderBook(outcomeId: string, _limit?: number, _params?: Record<string, any>): Promise<OrderBook>;
31
31
  fetchOHLCV(outcomeId: string, params: OHLCVParams): Promise<PriceCandle[]>;
32
32
  fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
33
33
  fetchTrades(outcomeId: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
@@ -46,6 +46,6 @@ export declare class ProbableExchange extends PredictionMarketExchange {
46
46
  fetchOpenOrders(marketId?: string): Promise<Order[]>;
47
47
  fetchPositions(): Promise<Position[]>;
48
48
  fetchBalance(): Promise<Balance[]>;
49
- watchOrderBook(outcomeId: string, limit?: number): Promise<OrderBook>;
49
+ watchOrderBook(outcomeId: string, limit?: number, _params?: Record<string, any>): Promise<OrderBook>;
50
50
  close(): Promise<void>;
51
51
  }
@@ -116,7 +116,7 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
116
116
  }
117
117
  return event;
118
118
  }
119
- async fetchOrderBook(outcomeId) {
119
+ async fetchOrderBook(outcomeId, _limit, _params) {
120
120
  const raw = await this.fetcher.fetchRawOrderBook(outcomeId);
121
121
  return this.normalizer.normalizeOrderBook(raw, outcomeId);
122
122
  }
@@ -362,7 +362,7 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
362
362
  // --------------------------------------------------------------------------
363
363
  // WebSocket Streaming (public, no auth needed)
364
364
  // --------------------------------------------------------------------------
365
- async watchOrderBook(outcomeId, limit) {
365
+ async watchOrderBook(outcomeId, limit, _params = {}) {
366
366
  if (!this.ws) {
367
367
  this.ws = new websocket_1.ProbableWebSocket(this.wsConfig);
368
368
  }
@@ -18,7 +18,7 @@ export declare class SmarketsExchange extends PredictionMarketExchange {
18
18
  private requireAuth;
19
19
  protected fetchMarketsImpl(params?: MarketFilterParams): Promise<UnifiedMarket[]>;
20
20
  protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
21
- fetchOrderBook(outcomeId: string): Promise<OrderBook>;
21
+ fetchOrderBook(outcomeId: string, _limit?: number, _params?: Record<string, any>): Promise<OrderBook>;
22
22
  fetchTrades(outcomeId: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
23
23
  fetchBalance(): Promise<Balance[]>;
24
24
  fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
@@ -158,7 +158,7 @@ class SmarketsExchange extends BaseExchange_1.PredictionMarketExchange {
158
158
  .filter((e) => e !== null)
159
159
  .slice(0, limit);
160
160
  }
161
- async fetchOrderBook(outcomeId) {
161
+ async fetchOrderBook(outcomeId, _limit, _params) {
162
162
  const raw = await this.fetcher.fetchRawOrderBook(outcomeId);
163
163
  return this.normalizer.normalizeOrderBook(raw, outcomeId);
164
164
  }
@@ -8,7 +8,7 @@ export declare class Router extends PredictionMarketExchange {
8
8
  get name(): string;
9
9
  protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
10
10
  protected fetchEventsImpl(params?: EventFetchParams): Promise<UnifiedEvent[]>;
11
- fetchOrderBook(outcomeId: string, side?: 'yes' | 'no'): Promise<OrderBook>;
11
+ fetchOrderBook(outcomeId: string, limit?: number, params?: Record<string, any>): Promise<OrderBook>;
12
12
  fetchMarketMatches(params?: FetchMarketMatchesParams): Promise<MatchResult[]>;
13
13
  /**
14
14
  * Browse mode: fetch all matched market pairs from the catalog.
@@ -70,12 +70,12 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
70
70
  // -----------------------------------------------------------------------
71
71
  // Unified orderbook (cross-exchange merge)
72
72
  // -----------------------------------------------------------------------
73
- async fetchOrderBook(outcomeId, side) {
73
+ async fetchOrderBook(outcomeId, limit, params) {
74
74
  const exchangeNames = Object.keys(this.exchanges);
75
75
  if (exchangeNames.length === 0) {
76
76
  throw new Error('Router requires exchange instances for fetchOrderBook. Pass exchanges in RouterOptions.');
77
77
  }
78
- const resolvedSide = side ?? 'yes';
78
+ const resolvedSide = params?.side ?? 'yes';
79
79
  // Find identity matches across venues
80
80
  const matches = await this.fetchMarketMatches({
81
81
  marketId: outcomeId,
@@ -93,7 +93,7 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
93
93
  if (!outcome)
94
94
  continue;
95
95
  fetchPromises.push(exchange
96
- .fetchOrderBook(outcome.outcomeId, resolvedSide)
96
+ .fetchOrderBook(outcome.outcomeId, undefined, { side: resolvedSide })
97
97
  .then((book) => ({ book, venue: venueName, error: null }))
98
98
  .catch((error) => ({ book: null, venue: venueName, error })));
99
99
  }
@@ -102,7 +102,7 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
102
102
  if (matchedVenues.has(name))
103
103
  continue;
104
104
  fetchPromises.push(exchange
105
- .fetchOrderBook(outcomeId, resolvedSide)
105
+ .fetchOrderBook(outcomeId, undefined, { side: resolvedSide })
106
106
  .then((book) => ({ book, venue: name, error: null }))
107
107
  .catch((error) => ({ book: null, venue: name, error })));
108
108
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * E2E test for Router.fetchOrderBook — run with:
5
+ * npx ts-node src/router/e2e-orderbook.ts
6
+ *
7
+ * Requires PMXT_API_KEY in env.
8
+ */
9
+ const Router_1 = require("./Router");
10
+ const polymarket_1 = require("../exchanges/polymarket");
11
+ const limitless_1 = require("../exchanges/limitless");
12
+ async function main() {
13
+ const apiKey = process.env.PMXT_API_KEY;
14
+ if (!apiKey) {
15
+ console.error('Set PMXT_API_KEY');
16
+ process.exit(1);
17
+ }
18
+ const polymarket = new polymarket_1.PolymarketExchange({});
19
+ const limitless = new limitless_1.LimitlessExchange({});
20
+ const router = new Router_1.Router({
21
+ apiKey,
22
+ exchanges: { polymarket, limitless },
23
+ });
24
+ // Morocco FIFA World Cup market on Polymarket
25
+ const marketId = 'f017596d-4d53-49d5-a7d6-36ed9c37fdc4';
26
+ console.log('Fetching unified orderbook for Morocco (Polymarket + Limitless)...');
27
+ console.log(`Input market ID: ${marketId}`);
28
+ console.log('---');
29
+ const book = await router.fetchOrderBook(marketId, undefined, { side: 'yes' });
30
+ console.log(`Bids: ${book.bids.length} levels`);
31
+ console.log(`Asks: ${book.asks.length} levels`);
32
+ console.log('Top 5 bids:', book.bids.slice(0, 5));
33
+ console.log('Top 5 asks:', book.asks.slice(0, 5));
34
+ // Verify we got data from BOTH exchanges
35
+ // Polymarket top bid was 0.016, Limitless had 0.002
36
+ // If merged correctly, we should see both
37
+ const hasPoly = book.bids.some((b) => b.price === 0.016);
38
+ const hasLimitless = book.bids.some((b) => b.price === 0.002);
39
+ console.log('---');
40
+ console.log(`Has Polymarket levels: ${hasPoly}`);
41
+ console.log(`Has Limitless levels: ${hasLimitless}`);
42
+ if (hasPoly && hasLimitless) {
43
+ console.log('SUCCESS: Merged orderbook contains levels from both exchanges');
44
+ }
45
+ else if (!hasPoly && hasLimitless) {
46
+ console.log('PARTIAL: Only Limitless book (source market fetch failed)');
47
+ }
48
+ else if (hasPoly && !hasLimitless) {
49
+ console.log('PARTIAL: Only Polymarket book (matched market fetch failed)');
50
+ }
51
+ else {
52
+ console.log('FAIL: No data from either exchange');
53
+ }
54
+ }
55
+ main().catch((err) => {
56
+ console.error(err);
57
+ process.exit(1);
58
+ });
@@ -93,12 +93,27 @@
93
93
  "optional": false
94
94
  },
95
95
  {
96
- "name": "side",
97
- "kind": "string",
96
+ "name": "limit",
97
+ "kind": "number",
98
+ "optional": true
99
+ },
100
+ {
101
+ "name": "params",
102
+ "kind": "object",
98
103
  "optional": true
99
104
  }
100
105
  ]
101
106
  },
107
+ "fetchOrderBooks": {
108
+ "verb": "post",
109
+ "args": [
110
+ {
111
+ "name": "outcomeIds",
112
+ "kind": "unknown",
113
+ "optional": false
114
+ }
115
+ ]
116
+ },
102
117
  "fetchTrades": {
103
118
  "verb": "get",
104
119
  "args": [
@@ -306,6 +321,11 @@
306
321
  "name": "limit",
307
322
  "kind": "number",
308
323
  "optional": true
324
+ },
325
+ {
326
+ "name": "params",
327
+ "kind": "object",
328
+ "optional": true
309
329
  }
310
330
  ]
311
331
  },
@@ -321,6 +341,11 @@
321
341
  "name": "limit",
322
342
  "kind": "number",
323
343
  "optional": true
344
+ },
345
+ {
346
+ "name": "params",
347
+ "kind": "object",
348
+ "optional": true
324
349
  }
325
350
  ]
326
351
  },
@@ -641,10 +641,10 @@ paths:
641
641
  schema:
642
642
  type: string
643
643
  - in: query
644
- name: side
644
+ name: limit
645
645
  required: false
646
646
  schema:
647
- type: string
647
+ type: number
648
648
  responses:
649
649
  '200':
650
650
  description: Fetch Order Book response
@@ -657,9 +657,49 @@ paths:
657
657
  properties:
658
658
  data:
659
659
  $ref: '#/components/schemas/OrderBook'
660
+ description: Fetch the order book (bids/asks) for a specific outcome.
661
+ '/api/{exchange}/fetchOrderBooks':
662
+ post:
663
+ summary: Fetch Order Books
664
+ operationId: fetchOrderBooks
665
+ parameters:
666
+ - $ref: '#/components/parameters/ExchangeParam'
667
+ requestBody:
668
+ content:
669
+ application/json:
670
+ schema:
671
+ title: FetchOrderBooksRequest
672
+ type: object
673
+ properties:
674
+ args:
675
+ type: array
676
+ maxItems: 1
677
+ items:
678
+ type: array
679
+ items:
680
+ type: string
681
+ minItems: 1
682
+ credentials:
683
+ $ref: '#/components/schemas/ExchangeCredentials'
684
+ required:
685
+ - args
686
+ responses:
687
+ '200':
688
+ description: Fetch Order Books response
689
+ content:
690
+ application/json:
691
+ schema:
692
+ allOf:
693
+ - $ref: '#/components/schemas/BaseResponse'
694
+ - type: object
695
+ properties:
696
+ data:
697
+ type: object
698
+ additionalProperties:
699
+ $ref: '#/components/schemas/OrderBook'
660
700
  description: >-
661
- Fetch the current order book (bids/asks) for a specific outcome. Essential for calculating spread, depth, and
662
- execution prices.
701
+ Batch variant of {@link fetchOrderBook}. Fetches order books for multiple outcomes in a single request where the
702
+ exchange supports it.
663
703
  '/api/{exchange}/fetchTrades':
664
704
  get:
665
705
  summary: Fetch Trades
@@ -2473,6 +2513,9 @@ components:
2473
2513
  - metaculus
2474
2514
  - smarkets
2475
2515
  - polymarket_us
2516
+ - gemini-titan
2517
+ - hyperliquid
2518
+ - mock
2476
2519
  - router
2477
2520
  required: true
2478
2521
  description: The prediction market exchange to target.
@@ -2737,6 +2780,9 @@ components:
2737
2780
  timestamp:
2738
2781
  type: number
2739
2782
  description: Unix timestamp in milliseconds when the snapshot was taken.
2783
+ datetime:
2784
+ type: string
2785
+ description: ISO 8601 datetime string of the snapshot (CCXT-compatible).
2740
2786
  required:
2741
2787
  - bids
2742
2788
  - asks
package/dist/types.d.ts CHANGED
@@ -119,6 +119,8 @@ export interface OrderBook {
119
119
  asks: OrderLevel[];
120
120
  /** Unix timestamp in milliseconds when the snapshot was taken. */
121
121
  timestamp?: number;
122
+ /** ISO 8601 datetime string of the snapshot (CCXT-compatible). */
123
+ datetime?: string;
122
124
  }
123
125
  export interface Trade {
124
126
  /** The unique identifier for this trade. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxt-core",
3
- "version": "2.42.7",
3
+ "version": "2.43.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.42.7,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.42.7,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.43.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.43.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",