pmxt-core 2.43.19 → 2.43.24

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 (88) hide show
  1. package/dist/exchanges/baozi/errors.d.ts +1 -1
  2. package/dist/exchanges/baozi/errors.js +1 -1
  3. package/dist/exchanges/gemini-titan/errors.d.ts +3 -3
  4. package/dist/exchanges/gemini-titan/errors.js +1 -1
  5. package/dist/exchanges/gemini-titan/index.js +1 -1
  6. package/dist/exchanges/gemini-titan/normalizer.js +2 -2
  7. package/dist/exchanges/gemini-titan/websocket.js +16 -3
  8. package/dist/exchanges/hyperliquid/errors.d.ts +3 -3
  9. package/dist/exchanges/hyperliquid/errors.js +1 -1
  10. package/dist/exchanges/hyperliquid/index.js +1 -1
  11. package/dist/exchanges/kalshi/api.d.ts +1 -1
  12. package/dist/exchanges/kalshi/api.js +1 -1
  13. package/dist/exchanges/kalshi/auth.js +3 -0
  14. package/dist/exchanges/kalshi/errors.d.ts +2 -2
  15. package/dist/exchanges/kalshi/fetcher.d.ts +1 -0
  16. package/dist/exchanges/kalshi/fetcher.js +3 -3
  17. package/dist/exchanges/kalshi/index.js +1 -1
  18. package/dist/exchanges/kalshi/normalizer.d.ts +1 -1
  19. package/dist/exchanges/kalshi/normalizer.js +4 -4
  20. package/dist/exchanges/kalshi/websocket.d.ts +1 -0
  21. package/dist/exchanges/kalshi/websocket.js +29 -13
  22. package/dist/exchanges/limitless/api.d.ts +1 -1
  23. package/dist/exchanges/limitless/api.js +1 -1
  24. package/dist/exchanges/limitless/auth.js +3 -0
  25. package/dist/exchanges/limitless/client.js +9 -0
  26. package/dist/exchanges/limitless/errors.d.ts +2 -2
  27. package/dist/exchanges/limitless/index.js +1 -1
  28. package/dist/exchanges/limitless/normalizer.js +4 -2
  29. package/dist/exchanges/limitless/utils.js +3 -0
  30. package/dist/exchanges/limitless/websocket.js +37 -7
  31. package/dist/exchanges/metaculus/cancelOrder.d.ts +1 -1
  32. package/dist/exchanges/metaculus/cancelOrder.js +3 -3
  33. package/dist/exchanges/metaculus/errors.d.ts +3 -3
  34. package/dist/exchanges/mock/index.js +32 -15
  35. package/dist/exchanges/myriad/api.d.ts +1 -1
  36. package/dist/exchanges/myriad/api.js +1 -1
  37. package/dist/exchanges/myriad/errors.d.ts +2 -2
  38. package/dist/exchanges/myriad/websocket.js +16 -4
  39. package/dist/exchanges/opinion/api.d.ts +1 -1
  40. package/dist/exchanges/opinion/api.js +1 -1
  41. package/dist/exchanges/opinion/errors.d.ts +2 -2
  42. package/dist/exchanges/opinion/errors.js +4 -3
  43. package/dist/exchanges/opinion/fetcher.js +1 -1
  44. package/dist/exchanges/opinion/index.js +1 -1
  45. package/dist/exchanges/opinion/utils.d.ts +1 -1
  46. package/dist/exchanges/opinion/utils.js +2 -2
  47. package/dist/exchanges/opinion/websocket.js +35 -6
  48. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  49. package/dist/exchanges/polymarket/api-clob.js +1 -1
  50. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  51. package/dist/exchanges/polymarket/api-data.js +1 -1
  52. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  53. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  54. package/dist/exchanges/polymarket/auth.js +22 -3
  55. package/dist/exchanges/polymarket/errors.d.ts +3 -3
  56. package/dist/exchanges/polymarket/fetcher.js +3 -0
  57. package/dist/exchanges/polymarket/index.js +1 -1
  58. package/dist/exchanges/polymarket/normalizer.js +6 -4
  59. package/dist/exchanges/polymarket/websocket.d.ts +2 -0
  60. package/dist/exchanges/polymarket/websocket.js +53 -27
  61. package/dist/exchanges/polymarket_us/normalizer.js +3 -3
  62. package/dist/exchanges/polymarket_us/websocket.js +6 -0
  63. package/dist/exchanges/probable/api.d.ts +1 -1
  64. package/dist/exchanges/probable/api.js +1 -1
  65. package/dist/exchanges/probable/errors.d.ts +2 -2
  66. package/dist/exchanges/probable/errors.js +1 -1
  67. package/dist/exchanges/probable/index.js +2 -2
  68. package/dist/exchanges/smarkets/auth.js +6 -0
  69. package/dist/exchanges/smarkets/errors.d.ts +3 -3
  70. package/dist/exchanges/smarkets/errors.js +7 -2
  71. package/dist/exchanges/smarkets/fetcher.js +16 -6
  72. package/dist/feeds/binance/binance-feed.js +20 -2
  73. package/dist/feeds/chainlink/chainlink-feed.js +18 -3
  74. package/dist/router/Router.js +1 -3
  75. package/dist/router/client.d.ts +16 -8
  76. package/dist/router/client.js +7 -3
  77. package/dist/server/index.js +6 -5
  78. package/dist/server/openapi.yaml +1 -1
  79. package/dist/subscriber/external/goldsky.d.ts +2 -1
  80. package/dist/subscriber/external/goldsky.js +33 -14
  81. package/dist/subscriber/watcher.js +6 -8
  82. package/dist/types.d.ts +1 -1
  83. package/dist/utils/error-mapper.d.ts +7 -7
  84. package/dist/utils/error-mapper.js +54 -47
  85. package/dist/utils/market-utils.js +4 -4
  86. package/dist/utils/throttler.d.ts +2 -0
  87. package/dist/utils/throttler.js +8 -0
  88. package/package.json +3 -3
@@ -161,14 +161,19 @@ class MockExchange extends BaseExchange_1.PredictionMarketExchange {
161
161
  const candidates = f.pick(CANDIDATES);
162
162
  const rawPrices = candidates.map(() => f.float(0.05, 0.9));
163
163
  const total = rawPrices.reduce((s, p) => s + p, 0);
164
- outcomes = candidates.map((label, i) => ({
165
- outcomeId: `${marketId}-${i}`,
166
- marketId,
167
- label,
168
- price: round(rawPrices[i] / total, 3),
169
- priceChange24h: round(f.float(-0.05, 0.05), 3),
170
- metadata: { clobTokenId: `mock-clob-${seed}-${i}` },
171
- }));
164
+ outcomes = candidates.map((label, i) => {
165
+ const rawPrice = rawPrices[i];
166
+ if (rawPrice === undefined)
167
+ throw new Error(`Missing raw price at index ${i}`);
168
+ return {
169
+ outcomeId: `${marketId}-${i}`,
170
+ marketId,
171
+ label,
172
+ price: round(rawPrice / total, 3),
173
+ priceChange24h: round(f.float(-0.05, 0.05), 3),
174
+ metadata: { clobTokenId: `mock-clob-${seed}-${i}` },
175
+ };
176
+ });
172
177
  }
173
178
  const market = {
174
179
  marketId,
@@ -221,13 +226,19 @@ class MockExchange extends BaseExchange_1.PredictionMarketExchange {
221
226
  for (const m of markets) {
222
227
  if (!m.eventId)
223
228
  continue;
224
- if (!eventMap.has(m.eventId))
225
- eventMap.set(m.eventId, []);
226
- eventMap.get(m.eventId).push(m);
229
+ const existing = eventMap.get(m.eventId);
230
+ if (existing) {
231
+ existing.push(m);
232
+ }
233
+ else {
234
+ eventMap.set(m.eventId, [m]);
235
+ }
227
236
  }
228
237
  const events = [];
229
238
  for (const [eventId, eventMarkets] of eventMap) {
230
239
  const f = rng(eventId);
240
+ if (eventMarkets.length === 0)
241
+ continue;
231
242
  const first = eventMarkets[0];
232
243
  const volume24h = round(eventMarkets.reduce((s, m) => s + m.volume24h, 0), 2);
233
244
  const volume = round(eventMarkets.reduce((s, m) => s + (m.volume ?? 0), 0), 2);
@@ -444,7 +455,10 @@ class MockExchange extends BaseExchange_1.PredictionMarketExchange {
444
455
  const sizeChange = params.side === 'buy' ? amount : -amount;
445
456
  this._setPosition(params, price, sizeChange);
446
457
  this._pushTrade(f, params, orderId, price, amount, ts);
447
- return { ...this._orders.get(orderId) };
458
+ const filled = this._orders.get(orderId);
459
+ if (!filled)
460
+ throw new Error(`Order disappeared after fill: ${orderId}`);
461
+ return { ...filled };
448
462
  }
449
463
  _placeRestingLimit(params, ts, price) {
450
464
  const ro = new seededRng_1.SeededRng('oid:' + this._ordSeq);
@@ -543,7 +557,10 @@ class MockExchange extends BaseExchange_1.PredictionMarketExchange {
543
557
  this._setPosition(cp, p, current.side === 'buy' ? fillAmt : -fillAmt);
544
558
  this._pushTrade(f, cp, orderId, p, fillAmt, ts);
545
559
  this._orders.set(orderId, next);
546
- return { ...this._orders.get(orderId) };
560
+ const updated = this._orders.get(orderId);
561
+ if (!updated)
562
+ throw new Error(`Order disappeared after fill: ${orderId}`);
563
+ return { ...updated };
547
564
  }
548
565
  async cancelOrder(orderId) {
549
566
  const current = this._orders.get(orderId);
@@ -558,7 +575,7 @@ class MockExchange extends BaseExchange_1.PredictionMarketExchange {
558
575
  this._freeCash += rest;
559
576
  this._lockedByBuy.delete(orderId);
560
577
  }
561
- const u = { ...current, status: 'cancelled', remaining: 0, timestamp: Date.now() };
578
+ const u = { ...current, status: 'canceled', remaining: 0, timestamp: Date.now() };
562
579
  this._orders.set(orderId, u);
563
580
  return { ...u };
564
581
  }
@@ -581,7 +598,7 @@ class MockExchange extends BaseExchange_1.PredictionMarketExchange {
581
598
  }
582
599
  async fetchClosedOrders() {
583
600
  return Array.from(this._orders.values())
584
- .filter(o => o.status === 'filled' || o.status === 'cancelled' || o.status === 'rejected')
601
+ .filter(o => o.status === 'filled' || o.status === 'canceled' || o.status === 'rejected')
585
602
  .map(o => ({ ...o }));
586
603
  }
587
604
  async fetchAllOrders() {
@@ -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-05-24T16:33:23.421Z
3
+ * Generated at: 2026-05-24T18:05:59.982Z
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-05-24T16:33:23.421Z
6
+ * Generated at: 2026-05-24T18:05:59.982Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.myriadApiSpec = {
@@ -2,7 +2,7 @@ import { ErrorMapper } from '../../utils/error-mapper';
2
2
  import { BadRequest } from '../../errors';
3
3
  export declare class MyriadErrorMapper extends ErrorMapper {
4
4
  constructor();
5
- protected extractErrorMessage(error: any): string;
6
- protected mapBadRequestError(message: string, data: any): BadRequest;
5
+ protected extractErrorMessage(error: unknown): string;
6
+ protected mapBadRequestError(message: string, data: unknown): BadRequest;
7
7
  }
8
8
  export declare const myriadErrorMapper: MyriadErrorMapper;
@@ -34,8 +34,14 @@ class MyriadWebSocket {
34
34
  this.orderBookResolvers.set(outcomeId, []);
35
35
  this.orderBookRejecters.set(outcomeId, []);
36
36
  }
37
- this.orderBookResolvers.get(outcomeId).push(resolve);
38
- this.orderBookRejecters.get(outcomeId).push(reject);
37
+ const resolvers = this.orderBookResolvers.get(outcomeId);
38
+ const rejecters = this.orderBookRejecters.get(outcomeId);
39
+ if (!resolvers || !rejecters) {
40
+ reject(new Error(`Failed to initialize orderBook resolvers for outcomeId=${outcomeId}`));
41
+ return;
42
+ }
43
+ resolvers.push(resolve);
44
+ rejecters.push(reject);
39
45
  if (!this.orderBookTimers.has(outcomeId)) {
40
46
  this.startOrderBookPolling(outcomeId);
41
47
  }
@@ -49,8 +55,14 @@ class MyriadWebSocket {
49
55
  this.tradeResolvers.set(outcomeId, []);
50
56
  this.tradeRejecters.set(outcomeId, []);
51
57
  }
52
- this.tradeResolvers.get(outcomeId).push(resolve);
53
- this.tradeRejecters.get(outcomeId).push(reject);
58
+ const resolvers = this.tradeResolvers.get(outcomeId);
59
+ const rejecters = this.tradeRejecters.get(outcomeId);
60
+ if (!resolvers || !rejecters) {
61
+ reject(new Error(`Failed to initialize trade resolvers for outcomeId=${outcomeId}`));
62
+ return;
63
+ }
64
+ resolvers.push(resolve);
65
+ rejecters.push(reject);
54
66
  if (!this.tradeTimers.has(outcomeId)) {
55
67
  this.startTradePolling(outcomeId);
56
68
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
3
- * Generated at: 2026-05-24T16:33:23.424Z
3
+ * Generated at: 2026-05-24T18:05:59.987Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const opinionApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.opinionApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
6
- * Generated at: 2026-05-24T16:33:23.424Z
6
+ * Generated at: 2026-05-24T18:05:59.987Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.opinionApiSpec = {
@@ -2,7 +2,7 @@ import { ErrorMapper } from '../../utils/error-mapper';
2
2
  import { BadRequest } from '../../errors';
3
3
  export declare class OpinionErrorMapper extends ErrorMapper {
4
4
  constructor();
5
- protected extractErrorMessage(error: any): string;
6
- protected mapBadRequestError(message: string, data: any): BadRequest;
5
+ protected extractErrorMessage(error: unknown): string;
6
+ protected mapBadRequestError(message: string, data: unknown): BadRequest;
7
7
  }
8
8
  export declare const opinionErrorMapper: OpinionErrorMapper;
@@ -23,11 +23,12 @@ class OpinionErrorMapper extends error_mapper_1.ErrorMapper {
23
23
  return super.extractErrorMessage(error);
24
24
  }
25
25
  mapBadRequestError(message, data) {
26
- if (data && typeof data === 'object') {
26
+ if (typeof data === 'object' && data !== null) {
27
+ const obj = data;
27
28
  // OpenAPI format: { code: number, msg: string }
28
29
  // SDK format: { errno: number, errmsg: string }
29
- const errorCode = data.code ?? data.errno;
30
- const errorMsg = data.msg || data.errmsg || message;
30
+ const errorCode = obj.code ?? obj.errno;
31
+ const errorMsg = obj.msg || obj.errmsg || message;
31
32
  if (errorCode !== undefined && errorCode !== 0) {
32
33
  return new errors_1.BadRequest(`Opinion API error (code ${errorCode}): ${errorMsg}`, this.exchangeName);
33
34
  }
@@ -264,7 +264,7 @@ class OpinionFetcher {
264
264
  const list = extractList(result);
265
265
  if (!list || list.length === 0)
266
266
  break;
267
- allItems = [...allItems, ...list];
267
+ allItems.push(...list);
268
268
  if (allItems.length >= total)
269
269
  break;
270
270
  if (targetCount !== undefined && allItems.length >= targetCount)
@@ -313,7 +313,7 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
313
313
  side: 'buy',
314
314
  type: 'limit',
315
315
  amount: 0,
316
- status: 'cancelled',
316
+ status: 'canceled',
317
317
  filled: 0,
318
318
  remaining: 0,
319
319
  timestamp: Date.now(),
@@ -17,7 +17,7 @@ export declare const OPINION_ORDER_STATUS: {
17
17
  export declare function mapStatusToOpinion(status: string): string | undefined;
18
18
  export declare function mapSortToOpinion(sort?: string): number | undefined;
19
19
  export declare function mapIntervalToOpinion(interval: CandleInterval): string;
20
- export declare function mapOrderStatus(status: number): 'pending' | 'open' | 'filled' | 'cancelled' | 'rejected';
20
+ export declare function mapOrderStatus(status: number): 'pending' | 'open' | 'filled' | 'canceled' | 'rejected';
21
21
  export declare function parseNumStr(value: string | undefined | null): number;
22
22
  export declare function toMillis(ts: number | undefined | null): number;
23
23
  export declare function intervalToMs(interval: CandleInterval): number;
@@ -61,8 +61,8 @@ function mapOrderStatus(status) {
61
61
  switch (status) {
62
62
  case exports.OPINION_ORDER_STATUS.PENDING: return 'pending';
63
63
  case exports.OPINION_ORDER_STATUS.FILLED: return 'filled';
64
- case exports.OPINION_ORDER_STATUS.CANCELED: return 'cancelled';
65
- case exports.OPINION_ORDER_STATUS.EXPIRED: return 'cancelled'; // expired -> cancelled
64
+ case exports.OPINION_ORDER_STATUS.CANCELED: return 'canceled';
65
+ case exports.OPINION_ORDER_STATUS.EXPIRED: return 'canceled'; // expired -> canceled
66
66
  case exports.OPINION_ORDER_STATUS.FAILED: return 'rejected'; // failed -> rejected
67
67
  default: return 'pending';
68
68
  }
@@ -48,8 +48,27 @@ class OpinionWebSocket {
48
48
  this.isConnecting = true;
49
49
  this.connectionPromise = new Promise((resolve, reject) => {
50
50
  try {
51
+ const CONNECTION_TIMEOUT_MS = 30_000;
52
+ let settled = false;
53
+ const connectionTimer = setTimeout(() => {
54
+ if (!settled) {
55
+ settled = true;
56
+ this.isConnecting = false;
57
+ this.connectionPromise = undefined;
58
+ logger_1.logger.error("Opinion WebSocket connection timed out", { timeoutMs: CONNECTION_TIMEOUT_MS });
59
+ if (this.ws) {
60
+ this.ws.terminate();
61
+ this.ws = undefined;
62
+ }
63
+ reject(new Error(`Opinion WebSocket connection timed out after ${CONNECTION_TIMEOUT_MS}ms`));
64
+ }
65
+ }, CONNECTION_TIMEOUT_MS);
51
66
  this.ws = new ws_1.default(this.wsUrl);
52
67
  this.ws.on("open", () => {
68
+ if (settled)
69
+ return;
70
+ settled = true;
71
+ clearTimeout(connectionTimer);
53
72
  this.isConnected = true;
54
73
  this.isConnecting = false;
55
74
  this.connectionPromise = undefined;
@@ -67,6 +86,10 @@ class OpinionWebSocket {
67
86
  }
68
87
  });
69
88
  this.ws.on("error", (error) => {
89
+ if (settled)
90
+ return;
91
+ settled = true;
92
+ clearTimeout(connectionTimer);
70
93
  logger_1.logger.error("Opinion WebSocket error", { error: String(error) });
71
94
  this.isConnecting = false;
72
95
  this.connectionPromise = undefined;
@@ -265,10 +288,13 @@ class OpinionWebSocket {
265
288
  this.sendSubscribe("market.depth.diff", marketId);
266
289
  }
267
290
  const dataPromise = new Promise((resolve, reject) => {
268
- if (!this.orderBookResolvers.has(marketId)) {
269
- this.orderBookResolvers.set(marketId, []);
291
+ const existing = this.orderBookResolvers.get(marketId);
292
+ if (existing) {
293
+ existing.push({ resolve, reject });
294
+ }
295
+ else {
296
+ this.orderBookResolvers.set(marketId, [{ resolve, reject }]);
270
297
  }
271
- this.orderBookResolvers.get(marketId).push({ resolve, reject });
272
298
  });
273
299
  return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBook('${marketId}')`);
274
300
  }
@@ -292,10 +318,13 @@ class OpinionWebSocket {
292
318
  this.sendSubscribe("market.last.trade", marketId);
293
319
  }
294
320
  const dataPromise = new Promise((resolve, reject) => {
295
- if (!this.tradeResolvers.has(marketId)) {
296
- this.tradeResolvers.set(marketId, []);
321
+ const existing = this.tradeResolvers.get(marketId);
322
+ if (existing) {
323
+ existing.push({ resolve, reject });
324
+ }
325
+ else {
326
+ this.tradeResolvers.set(marketId, [{ resolve, reject }]);
297
327
  }
298
- this.tradeResolvers.get(marketId).push({ resolve, reject });
299
328
  });
300
329
  return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchTrades('${marketId}')`);
301
330
  }
@@ -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-05-24T16:33:23.375Z
3
+ * Generated at: 2026-05-24T18:05:59.930Z
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-05-24T16:33:23.375Z
6
+ * Generated at: 2026-05-24T18:05:59.930Z
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-05-24T16:33:23.391Z
3
+ * Generated at: 2026-05-24T18:05:59.946Z
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-05-24T16:33:23.391Z
6
+ * Generated at: 2026-05-24T18:05:59.946Z
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-05-24T16:33:23.388Z
3
+ * Generated at: 2026-05-24T18:05:59.943Z
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-05-24T16:33:23.388Z
6
+ * Generated at: 2026-05-24T18:05:59.943Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketGammaSpec = {
@@ -125,13 +125,17 @@ class PolymarketAuth {
125
125
  signatureType: this.discoveredSignatureType ?? SIG_TYPE_EOA
126
126
  };
127
127
  }
128
+ if (!this.signerAddress) {
129
+ throw new Error('[polymarket] Wallet not initialized — privateKey required before discoverProxy()');
130
+ }
128
131
  const address = this.signerAddress;
129
132
  try {
130
133
  // Polymarket Data API / Profiles endpoint
131
134
  // Path-based: https://data-api.polymarket.com/profiles/0x...
132
135
  const dataApiUrl = process.env.POLYMARKET_DATA_URL || 'https://data-api.polymarket.com';
133
136
  const response = await axios_1.default.get(`${dataApiUrl}/profiles/${address}`, {
134
- headers: { 'User-Agent': 'pmxt (https://github.com/pmxt-dev/pmxt)' }
137
+ headers: { 'User-Agent': 'pmxt (https://github.com/pmxt-dev/pmxt)' },
138
+ timeout: 10_000,
135
139
  });
136
140
  const profile = response.data;
137
141
  // console.log(`[PolymarketAuth] Profile for ${address}:`, JSON.stringify(profile));
@@ -142,6 +146,9 @@ class PolymarketAuth {
142
146
  // If it's a proxy address but we don't know the type, 1 is a safe default for Polymarket.
143
147
  this.discoveredSignatureType = profile.isGnosisSafe ? SIG_TYPE_GNOSIS_SAFE : SIG_TYPE_POLY_PROXY;
144
148
  // console.log(`[PolymarketAuth] Auto-discovered proxy for ${address}: ${this.discoveredProxyAddress} (Type: ${this.discoveredSignatureType})`);
149
+ if (!this.discoveredProxyAddress || this.discoveredSignatureType === undefined) {
150
+ throw new Error('[polymarket] Proxy discovery incomplete — missing proxyAddress or signatureType');
151
+ }
145
152
  return {
146
153
  proxyAddress: this.discoveredProxyAddress,
147
154
  signatureType: this.discoveredSignatureType
@@ -236,8 +243,11 @@ class PolymarketAuth {
236
243
  // Get API credentials (L1 auth)
237
244
  const apiCreds = await this.getApiCredentials();
238
245
  // Final addresses
246
+ if (!this.signerAddress) {
247
+ throw new Error('[polymarket] Wallet not initialized — privateKey required before getClobClient()');
248
+ }
239
249
  const signerAddress = this.signerAddress;
240
- const finalProxyAddress = (proxyAddress || signerAddress);
250
+ const finalProxyAddress = proxyAddress || signerAddress;
241
251
  const finalSignatureType = signatureType;
242
252
  // Create L2-authenticated client
243
253
  // console.log(`[PolymarketAuth] Initializing ClobClient | Signer: ${signerAddress} | Funder: ${finalProxyAddress} | SigType: ${finalSignatureType}`);
@@ -266,12 +276,21 @@ class PolymarketAuth {
266
276
  * Synchronous getter for credentials funder address.
267
277
  */
268
278
  getFunderAddress() {
269
- return this.credentials.funderAddress || this.signerAddress;
279
+ if (this.credentials.funderAddress) {
280
+ return this.credentials.funderAddress;
281
+ }
282
+ if (!this.signerAddress) {
283
+ throw new Error('[polymarket] Wallet not initialized — no funderAddress or signerAddress available');
284
+ }
285
+ return this.signerAddress;
270
286
  }
271
287
  /**
272
288
  * Get the signer's address.
273
289
  */
274
290
  getAddress() {
291
+ if (!this.signerAddress) {
292
+ throw new Error('[polymarket] Wallet not initialized — privateKey required');
293
+ }
275
294
  return this.signerAddress;
276
295
  }
277
296
  /**
@@ -21,14 +21,14 @@ export declare class PolymarketErrorMapper extends ErrorMapper {
21
21
  * `errorMsg` path for any residual V1 responses (order submission still
22
22
  * returns `errorMsg` in some batch flows).
23
23
  */
24
- protected extractErrorMessage(error: any): string;
24
+ protected extractErrorMessage(error: unknown): string;
25
25
  /**
26
26
  * Override to handle V2 status code 425 (Too Early -- matching engine restarting)
27
27
  */
28
- protected mapByStatusCode(status: number, message: string, data: any, response?: any): BaseError;
28
+ protected mapByStatusCode(status: number, message: string, data: unknown, response?: unknown): BaseError;
29
29
  /**
30
30
  * Override to detect Polymarket-specific error patterns in 400 responses
31
31
  */
32
- protected mapBadRequestError(message: string, data: any): BadRequest;
32
+ protected mapBadRequestError(message: string, data: unknown): BadRequest;
33
33
  }
34
34
  export declare const polymarketErrorMapper: PolymarketErrorMapper;
@@ -376,6 +376,9 @@ class PolymarketFetcher {
376
376
  const rawEvents = await fetchWithStatus('closed');
377
377
  events = rawEvents.filter(filterClosed);
378
378
  }
379
+ if (!params.query) {
380
+ throw new Error('params.query is required for event search');
381
+ }
379
382
  const lowerQuery = params.query.toLowerCase();
380
383
  const searchIn = params.searchIn || 'title';
381
384
  return events.filter((event) => {
@@ -263,7 +263,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
263
263
  side: 'buy',
264
264
  type: 'limit',
265
265
  amount: 0,
266
- status: 'cancelled',
266
+ status: 'canceled',
267
267
  filled: 0,
268
268
  remaining: 0,
269
269
  timestamp: Date.now(),
@@ -64,10 +64,12 @@ class PolymarketNormalizer {
64
64
  }
65
65
  else {
66
66
  const candle = buckets.get(snappedMs);
67
- candle.high = Math.max(candle.high, price);
68
- candle.low = Math.min(candle.low, price);
69
- candle.close = price;
70
- candle.volume = (candle.volume || 0) + volume;
67
+ if (candle) {
68
+ candle.high = Math.max(candle.high, price);
69
+ candle.low = Math.min(candle.low, price);
70
+ candle.close = price;
71
+ candle.volume = (candle.volume || 0) + volume;
72
+ }
71
73
  }
72
74
  }
73
75
  const candles = Array.from(buckets.values()).sort((a, b) => a.timestamp - b.timestamp);
@@ -47,6 +47,8 @@ export interface PolymarketWebSocketConfig {
47
47
  watchTimeoutMs?: number;
48
48
  /** API credentials for the authenticated user channel (fills/orders). */
49
49
  userChannelCreds?: PolymarketUserChannelCreds;
50
+ /** Timeout in ms for WebSocket connections to open (default: 30000). */
51
+ connectionTimeoutMs?: number;
50
52
  }
51
53
  /**
52
54
  * Native WebSocket implementation for Polymarket market data.