pmxt-core 2.50.16 → 2.51.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 (50) hide show
  1. package/dist/exchanges/hunch/api.d.ts +736 -0
  2. package/dist/exchanges/hunch/api.js +820 -0
  3. package/dist/exchanges/hunch/auth.d.ts +36 -0
  4. package/dist/exchanges/hunch/auth.js +63 -0
  5. package/dist/exchanges/hunch/errors.d.ts +26 -0
  6. package/dist/exchanges/hunch/errors.js +94 -0
  7. package/dist/exchanges/hunch/fetcher.d.ts +204 -0
  8. package/dist/exchanges/hunch/fetcher.js +130 -0
  9. package/dist/exchanges/hunch/index.d.ts +51 -0
  10. package/dist/exchanges/hunch/index.js +330 -0
  11. package/dist/exchanges/hunch/normalizer.d.ts +56 -0
  12. package/dist/exchanges/hunch/normalizer.js +180 -0
  13. package/dist/exchanges/hunch/price.d.ts +5 -0
  14. package/dist/exchanges/hunch/price.js +12 -0
  15. package/dist/exchanges/hunch/utils.d.ts +79 -0
  16. package/dist/exchanges/hunch/utils.js +182 -0
  17. package/dist/exchanges/hunch/websocket.d.ts +25 -0
  18. package/dist/exchanges/hunch/websocket.js +137 -0
  19. package/dist/exchanges/hyperliquid/auth.js +15 -2
  20. package/dist/exchanges/hyperliquid/fetcher.d.ts +26 -1
  21. package/dist/exchanges/hyperliquid/fetcher.js +66 -4
  22. package/dist/exchanges/hyperliquid/index.d.ts +4 -1
  23. package/dist/exchanges/hyperliquid/index.js +84 -20
  24. package/dist/exchanges/hyperliquid/normalizer.d.ts +4 -3
  25. package/dist/exchanges/hyperliquid/normalizer.js +69 -11
  26. package/dist/exchanges/hyperliquid/utils.d.ts +7 -1
  27. package/dist/exchanges/hyperliquid/utils.js +16 -4
  28. package/dist/exchanges/kalshi/api.d.ts +1 -1
  29. package/dist/exchanges/kalshi/api.js +1 -1
  30. package/dist/exchanges/limitless/api.d.ts +1 -1
  31. package/dist/exchanges/limitless/api.js +1 -1
  32. package/dist/exchanges/myriad/api.d.ts +1 -1
  33. package/dist/exchanges/myriad/api.js +1 -1
  34. package/dist/exchanges/opinion/api.d.ts +1 -1
  35. package/dist/exchanges/opinion/api.js +1 -1
  36. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  37. package/dist/exchanges/polymarket/api-clob.js +1 -1
  38. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  39. package/dist/exchanges/polymarket/api-data.js +1 -1
  40. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  41. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  42. package/dist/exchanges/probable/api.d.ts +1 -1
  43. package/dist/exchanges/probable/api.js +1 -1
  44. package/dist/index.d.ts +4 -0
  45. package/dist/index.js +5 -1
  46. package/dist/server/app.js +1 -0
  47. package/dist/server/exchange-factory.js +8 -0
  48. package/dist/server/openapi.yaml +17 -0
  49. package/dist/types.d.ts +4 -0
  50. package/package.json +3 -3
@@ -8,6 +8,7 @@ const fetcher_1 = require("./fetcher");
8
8
  const normalizer_1 = require("./normalizer");
9
9
  const auth_1 = require("./auth");
10
10
  const errors_2 = require("./errors");
11
+ const utils_1 = require("./utils");
11
12
  class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
12
13
  capabilityOverrides = {
13
14
  fetchSeries: false,
@@ -76,13 +77,14 @@ class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
76
77
  if (params.series !== undefined) {
77
78
  return [];
78
79
  }
79
- const [rawQuestions, meta, mids] = await Promise.all([
80
+ const [rawQuestions, meta, mids, volumeMap] = await Promise.all([
80
81
  this.fetcher.fetchRawEvents(params),
81
82
  this.fetcher.fetchOutcomeMeta(),
82
83
  this.fetcher.fetchAllMids(),
84
+ this.fetcher.fetchOutcomeVolumeMap(),
83
85
  ]);
84
86
  return rawQuestions
85
- .map(q => this.normalizer.normalizeEventWithMarkets(q, meta, mids))
87
+ .map(q => this.normalizer.normalizeEventWithMarkets(q, meta, mids, volumeMap))
86
88
  .filter((e) => e !== null);
87
89
  }
88
90
  async fetchOrderBook(outcomeId, _limit, _params) {
@@ -92,7 +94,13 @@ class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
92
94
  const raw = await this.fetcher.fetchRawOrderBook(outcomeId);
93
95
  return this.normalizer.normalizeOrderBook(raw, outcomeId);
94
96
  }
95
- async fetchOHLCV(outcomeId, params) {
97
+ // ponytail: Hyperliquid has no native batch order-book endpoint; loop client-side.
98
+ // Add a concurrency cap if rate limits start biting in practice.
99
+ async fetchOrderBooks(outcomeIds) {
100
+ const entries = await Promise.all(outcomeIds.map(async (id) => [id, await this.fetchOrderBook(id)]));
101
+ return Object.fromEntries(entries);
102
+ }
103
+ async fetchOHLCV(outcomeId, params = { resolution: '1h' }) {
96
104
  const raw = await this.fetcher.fetchRawOHLCV(outcomeId, params);
97
105
  return this.normalizer.normalizeOHLCV(raw, params);
98
106
  }
@@ -105,8 +113,11 @@ class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
105
113
  // -------------------------------------------------------------------------
106
114
  async fetchBalance() {
107
115
  const wallet = this.requireWallet();
108
- const raw = await this.fetcher.fetchRawUserState(wallet);
109
- return this.normalizer.normalizeBalance(raw);
116
+ const [perp, spot] = await Promise.all([
117
+ this.fetcher.fetchRawUserState(wallet),
118
+ this.fetcher.fetchRawSpotState(wallet),
119
+ ]);
120
+ return this.normalizer.normalizeBalance(perp, spot);
110
121
  }
111
122
  async fetchPositions() {
112
123
  const wallet = this.requireWallet();
@@ -129,6 +140,35 @@ class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
129
140
  .filter(f => f.coin.startsWith('#'))
130
141
  .map((f, i) => this.normalizer.normalizeUserTrade(f, i));
131
142
  }
143
+ // ponytail: HL exposes no "closed orders" endpoint, only userFills + openOrders.
144
+ // Synthesize closed orders as: oids seen in fills that are not currently open.
145
+ // Caveat — this surfaces *filled* orders, not *cancelled-with-no-fills* (HL drops those from public history).
146
+ async fetchClosedOrders() {
147
+ const wallet = this.requireWallet();
148
+ const [rawFills, rawOpen] = await Promise.all([
149
+ this.fetcher.fetchRawUserFills(wallet),
150
+ this.fetcher.fetchRawOpenOrders(wallet),
151
+ ]);
152
+ const openOids = new Set(rawOpen.map(o => o.oid));
153
+ const byOid = new Map();
154
+ for (const f of rawFills) {
155
+ if (!f.coin.startsWith('#'))
156
+ continue;
157
+ if (openOids.has(f.oid))
158
+ continue;
159
+ const list = byOid.get(f.oid) ?? [];
160
+ list.push(f);
161
+ byOid.set(f.oid, list);
162
+ }
163
+ return [...byOid.values()].map(fills => this.normalizer.synthesizeClosedOrder(fills));
164
+ }
165
+ async fetchAllOrders() {
166
+ const [open, closed] = await Promise.all([
167
+ this.fetchOpenOrders(),
168
+ this.fetchClosedOrders(),
169
+ ]);
170
+ return [...open, ...closed];
171
+ }
132
172
  // -------------------------------------------------------------------------
133
173
  // Trading (EIP-712 signing required)
134
174
  // -------------------------------------------------------------------------
@@ -167,18 +207,24 @@ class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
167
207
  if (data.status === 'err') {
168
208
  throw errors_2.hyperliquidErrorMapper.mapError(new Error(data.response || 'Order submission failed'));
169
209
  }
170
- const resting = data.response?.data?.statuses?.[0];
210
+ const status0 = data.response?.data?.statuses?.[0];
211
+ // HL returns one of: { resting: { oid } } | { filled: { oid, totalSz, avgPx } } | { error: string }
212
+ if (status0?.error) {
213
+ throw errors_2.hyperliquidErrorMapper.mapError(new Error(status0.error));
214
+ }
215
+ const oid = status0?.resting?.oid ?? status0?.filled?.oid;
216
+ const filledSz = status0?.filled?.totalSz ? parseFloat(status0.filled.totalSz) : 0;
171
217
  return {
172
- id: resting?.resting?.oid ? String(resting.resting.oid) : 'unknown',
218
+ id: oid !== undefined ? String(oid) : 'unknown',
173
219
  marketId: built.params.marketId,
174
220
  outcomeId: built.params.outcomeId,
175
221
  side: built.params.side,
176
222
  type: built.params.type,
177
- price: built.params.price,
223
+ price: status0?.filled?.avgPx ? parseFloat(status0.filled.avgPx) : built.params.price,
178
224
  amount: built.params.amount,
179
- status: resting?.resting ? 'open' : 'filled',
180
- filled: resting?.filled?.totalSz ? parseFloat(resting.filled.totalSz) : 0,
181
- remaining: built.params.amount - (resting?.filled?.totalSz ? parseFloat(resting.filled.totalSz) : 0),
225
+ status: status0?.resting ? 'open' : (status0?.filled ? 'filled' : 'pending'),
226
+ filled: filledSz,
227
+ remaining: built.params.amount - filledSz,
182
228
  timestamp: Date.now(),
183
229
  };
184
230
  }
@@ -192,11 +238,24 @@ class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
192
238
  }
193
239
  async cancelOrder(orderId) {
194
240
  const auth = this.requireAuth();
195
- // Key order matters for msgpack hash: type, cancels
196
- // Each cancel entry: a (asset), o (order id)
241
+ const wallet = this.requireWallet();
242
+ // HL needs the asset id of the order being cancelled, not just the oid.
243
+ // ponytail: look it up from openOrders. One extra HTTP call per cancel,
244
+ // and gives us a typed OrderNotFound when the caller's id is stale.
245
+ const oidNum = parseInt(orderId, 10);
246
+ if (!Number.isFinite(oidNum)) {
247
+ throw new Error(`Invalid Hyperliquid order id: ${orderId}`);
248
+ }
249
+ const open = await this.fetcher.fetchRawOpenOrders(wallet);
250
+ const target = open.find(o => o.oid === oidNum);
251
+ if (!target) {
252
+ throw errors_2.hyperliquidErrorMapper.mapError(new Error(`Order not found: ${orderId}`));
253
+ }
254
+ const decoded = (0, utils_1.fromCoinEncoding)(parseInt(target.coin.slice(1), 10));
255
+ const assetId = (0, utils_1.encodeAssetId)(decoded.outcomeId, decoded.side);
197
256
  const action = {
198
257
  type: 'cancel',
199
- cancels: [{ a: 0, o: parseInt(orderId, 10) }],
258
+ cancels: [{ a: assetId, o: oidNum }],
200
259
  };
201
260
  try {
202
261
  const requestBody = await auth.signExchangeRequest(action);
@@ -205,17 +264,22 @@ class HyperliquidExchange extends BaseExchange_1.PredictionMarketExchange {
205
264
  if (data.status === 'err') {
206
265
  throw new Error(data.response || 'Cancel failed');
207
266
  }
267
+ const status0 = data.response?.data?.statuses?.[0];
268
+ if (status0?.error) {
269
+ throw errors_2.hyperliquidErrorMapper.mapError(new Error(status0.error));
270
+ }
208
271
  return {
209
272
  id: orderId,
210
- marketId: '',
211
- outcomeId: '',
212
- side: 'buy',
273
+ marketId: this.normalizer['coinToMarketId'](target.coin),
274
+ outcomeId: this.normalizer['coinToOutcomeId'](target.coin),
275
+ side: target.side === 'B' ? 'buy' : 'sell',
213
276
  type: 'limit',
214
- amount: 0,
277
+ price: parseFloat(target.limitPx),
278
+ amount: parseFloat(target.sz),
215
279
  status: 'canceled',
216
280
  filled: 0,
217
- remaining: 0,
218
- timestamp: Date.now(),
281
+ remaining: parseFloat(target.sz),
282
+ timestamp: target.timestamp,
219
283
  };
220
284
  }
221
285
  catch (error) {
@@ -1,18 +1,19 @@
1
1
  import { UnifiedMarket, UnifiedEvent, OrderBook, PriceCandle, Trade, UserTrade, Position, Balance, Order } from '../../types';
2
2
  import { IExchangeNormalizer } from '../interfaces';
3
3
  import { OHLCVParams } from '../../BaseExchange';
4
- import { HyperliquidRawOutcomeWithQuestion, HyperliquidRawQuestion, HyperliquidRawL2Book, HyperliquidRawCandle, HyperliquidRawTrade, HyperliquidRawFill, HyperliquidRawOpenOrder, HyperliquidRawPosition, HyperliquidRawUserState, HyperliquidRawOutcomeMeta, HyperliquidRawMid } from './fetcher';
4
+ import { HyperliquidRawOutcomeWithQuestion, HyperliquidRawQuestion, HyperliquidRawL2Book, HyperliquidRawCandle, HyperliquidRawTrade, HyperliquidRawFill, HyperliquidRawOpenOrder, HyperliquidRawPosition, HyperliquidRawUserState, HyperliquidRawSpotState, HyperliquidRawOutcomeMeta, HyperliquidRawMid } from './fetcher';
5
5
  export declare class HyperliquidNormalizer implements IExchangeNormalizer<HyperliquidRawOutcomeWithQuestion, HyperliquidRawQuestion> {
6
6
  normalizeMarket(raw: HyperliquidRawOutcomeWithQuestion): UnifiedMarket | null;
7
7
  normalizeEvent(raw: HyperliquidRawQuestion): UnifiedEvent | null;
8
- normalizeEventWithMarkets(raw: HyperliquidRawQuestion, outcomeMeta: HyperliquidRawOutcomeMeta, mids: HyperliquidRawMid): UnifiedEvent | null;
8
+ normalizeEventWithMarkets(raw: HyperliquidRawQuestion, outcomeMeta: HyperliquidRawOutcomeMeta, mids: HyperliquidRawMid, volumeMap?: Map<number, number>): UnifiedEvent | null;
9
9
  normalizeOrderBook(raw: HyperliquidRawL2Book, _id: string): OrderBook;
10
10
  normalizeOHLCV(raw: HyperliquidRawCandle[], _params: OHLCVParams): PriceCandle[];
11
11
  normalizeTrade(raw: HyperliquidRawTrade, _index: number): Trade;
12
12
  normalizeUserTrade(raw: HyperliquidRawFill, _index: number): UserTrade;
13
+ synthesizeClosedOrder(fills: HyperliquidRawFill[]): Order;
13
14
  normalizeOpenOrder(raw: HyperliquidRawOpenOrder): Order;
14
15
  normalizePosition(raw: HyperliquidRawPosition): Position;
15
- normalizeBalance(raw: HyperliquidRawUserState): Balance[];
16
+ normalizeBalance(raw: HyperliquidRawUserState, spot?: HyperliquidRawSpotState): Balance[];
16
17
  private coinToMarketId;
17
18
  private coinToOutcomeId;
18
19
  }
@@ -176,7 +176,7 @@ class HyperliquidNormalizer {
176
176
  slug: `hl-${outcomeId}`,
177
177
  outcomes,
178
178
  resolutionDate: expiryDate ?? new Date(0),
179
- volume24h: 0,
179
+ volume24h: raw.volume24h ?? 0,
180
180
  liquidity: 0,
181
181
  url: buildMarketUrl(outcomeId),
182
182
  category,
@@ -218,7 +218,7 @@ class HyperliquidNormalizer {
218
218
  sourceMetadata: (0, metadata_1.buildSourceMetadata)(raw, HL_PROMOTED_EVENT_KEYS),
219
219
  };
220
220
  }
221
- normalizeEventWithMarkets(raw, outcomeMeta, mids) {
221
+ normalizeEventWithMarkets(raw, outcomeMeta, mids, volumeMap) {
222
222
  const event = this.normalizeEvent(raw);
223
223
  if (!event)
224
224
  return null;
@@ -235,6 +235,7 @@ class HyperliquidNormalizer {
235
235
  outcome,
236
236
  question: raw,
237
237
  midPrice,
238
+ volume24h: volumeMap?.get(outcomeId),
238
239
  });
239
240
  if (market) {
240
241
  markets.push(market);
@@ -284,6 +285,7 @@ class HyperliquidNormalizer {
284
285
  };
285
286
  }
286
287
  normalizeUserTrade(raw, _index) {
288
+ const fee = parseFloat(raw.fee);
287
289
  return {
288
290
  id: String(raw.tid),
289
291
  timestamp: raw.time,
@@ -291,6 +293,44 @@ class HyperliquidNormalizer {
291
293
  amount: parseFloat(raw.sz),
292
294
  side: raw.side === 'B' ? 'buy' : raw.side === 'A' ? 'sell' : 'unknown',
293
295
  orderId: String(raw.oid),
296
+ marketId: this.coinToMarketId(raw.coin),
297
+ outcomeId: this.coinToOutcomeId(raw.coin),
298
+ fee: Number.isFinite(fee) ? fee : undefined,
299
+ };
300
+ }
301
+ // ponytail: HL has no closed-orders endpoint; we reconstruct from the fills of one oid.
302
+ // amount = filled (we cannot recover the unfilled-then-cancelled portion); price = VWAP across fills.
303
+ synthesizeClosedOrder(fills) {
304
+ const first = fills[0];
305
+ let totalSz = 0;
306
+ let totalNotional = 0;
307
+ let totalFee = 0;
308
+ let earliest = first.time;
309
+ for (const f of fills) {
310
+ const sz = parseFloat(f.sz);
311
+ const px = parseFloat(f.px);
312
+ const fee = parseFloat(f.fee);
313
+ totalSz += sz;
314
+ totalNotional += sz * px;
315
+ if (Number.isFinite(fee))
316
+ totalFee += fee;
317
+ if (f.time < earliest)
318
+ earliest = f.time;
319
+ }
320
+ const vwap = totalSz > 0 ? totalNotional / totalSz : parseFloat(first.px);
321
+ return {
322
+ id: String(first.oid),
323
+ marketId: this.coinToMarketId(first.coin),
324
+ outcomeId: this.coinToOutcomeId(first.coin),
325
+ side: first.side === 'B' ? 'buy' : 'sell',
326
+ type: 'limit',
327
+ price: vwap,
328
+ amount: totalSz,
329
+ status: 'filled',
330
+ filled: totalSz,
331
+ remaining: 0,
332
+ timestamp: earliest,
333
+ fee: totalFee,
294
334
  };
295
335
  }
296
336
  normalizeOpenOrder(raw) {
@@ -333,16 +373,34 @@ class HyperliquidNormalizer {
333
373
  unrealizedPnL: parseFloat(raw.unrealizedPnl),
334
374
  };
335
375
  }
336
- normalizeBalance(raw) {
337
- const summary = raw.crossMarginSummary;
338
- const total = parseFloat(summary.accountValue);
339
- const locked = parseFloat(summary.totalMarginUsed);
340
- return [{
341
- currency: 'USDH',
376
+ normalizeBalance(raw, spot) {
377
+ const result = [];
378
+ // Spot balances: outcome markets quote against these (USDC, USDH, etc.).
379
+ for (const b of spot?.balances ?? []) {
380
+ const total = parseFloat(b.total);
381
+ const hold = parseFloat(b.hold);
382
+ if (!Number.isFinite(total) || total === 0)
383
+ continue;
384
+ result.push({
385
+ currency: b.coin,
342
386
  total,
343
- available: total - locked,
344
- locked,
345
- }];
387
+ available: total - (Number.isFinite(hold) ? hold : 0),
388
+ locked: Number.isFinite(hold) ? hold : 0,
389
+ });
390
+ }
391
+ // Perp cross-margin account, labelled as such so consumers don't conflate it with spot.
392
+ const summary = raw.crossMarginSummary;
393
+ const perpTotal = parseFloat(summary.accountValue);
394
+ const perpLocked = parseFloat(summary.totalMarginUsed);
395
+ if (Number.isFinite(perpTotal) && perpTotal > 0) {
396
+ result.push({
397
+ currency: 'USDC_PERP',
398
+ total: perpTotal,
399
+ available: perpTotal - perpLocked,
400
+ locked: perpLocked,
401
+ });
402
+ }
403
+ return result;
346
404
  }
347
405
  // -- Private helpers -------------------------------------------------------
348
406
  coinToMarketId(coin) {
@@ -39,7 +39,13 @@ export declare function toMidKey(outcomeId: number): string;
39
39
  */
40
40
  export declare function toMarketId(outcomeId: number): string;
41
41
  /**
42
- * Extract the numeric outcome ID from our market ID format.
42
+ * Extract the numeric outcome ID from a Hyperliquid identifier.
43
+ *
44
+ * Accepts either:
45
+ * - our canonical market ID, "hl-outcome-{N}"
46
+ * - a raw encoded asset token (numeric string >= OUTCOME_ASSET_BASE),
47
+ * as returned in UnifiedMarket.outcomes[].outcomeId. Decoded via
48
+ * decodeAssetId so callers can pass an outcome token directly.
43
49
  */
44
50
  export declare function fromMarketId(marketId: string): number;
45
51
  /**
@@ -69,14 +69,26 @@ function toMarketId(outcomeId) {
69
69
  return `hl-outcome-${outcomeId}`;
70
70
  }
71
71
  /**
72
- * Extract the numeric outcome ID from our market ID format.
72
+ * Extract the numeric outcome ID from a Hyperliquid identifier.
73
+ *
74
+ * Accepts either:
75
+ * - our canonical market ID, "hl-outcome-{N}"
76
+ * - a raw encoded asset token (numeric string >= OUTCOME_ASSET_BASE),
77
+ * as returned in UnifiedMarket.outcomes[].outcomeId. Decoded via
78
+ * decodeAssetId so callers can pass an outcome token directly.
73
79
  */
74
80
  function fromMarketId(marketId) {
75
81
  const match = marketId.match(/^hl-outcome-(\d+)$/);
76
- if (!match) {
77
- throw new Error(`Invalid Hyperliquid market ID: ${marketId}`);
82
+ if (match) {
83
+ return parseInt(match[1], 10);
84
+ }
85
+ if (/^\d+$/.test(marketId)) {
86
+ const assetId = parseInt(marketId, 10);
87
+ if (assetId >= config_1.OUTCOME_ASSET_BASE) {
88
+ return decodeAssetId(assetId).outcomeId;
89
+ }
78
90
  }
79
- return parseInt(match[1], 10);
91
+ throw new Error(`Invalid Hyperliquid market ID: ${marketId}`);
80
92
  }
81
93
  /**
82
94
  * Build an outcome ID string for the unified type.
@@ -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-06-18T14:38:45.783Z
3
+ * Generated at: 2026-06-22T13:10:46.874Z
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-06-18T14:38:45.783Z
6
+ * Generated at: 2026-06-22T13:10:46.874Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.kalshiApiSpec = {
@@ -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-06-18T14:38:45.822Z
3
+ * Generated at: 2026-06-22T13:10:46.913Z
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-06-18T14:38:45.822Z
6
+ * Generated at: 2026-06-22T13:10:46.913Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.limitlessApiSpec = {
@@ -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-06-18T14:38:45.834Z
3
+ * Generated at: 2026-06-22T13:10:46.925Z
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-06-18T14:38:45.834Z
6
+ * Generated at: 2026-06-22T13:10:46.925Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.myriadApiSpec = {
@@ -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-06-18T14:38:45.840Z
3
+ * Generated at: 2026-06-22T13:10:46.930Z
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-06-18T14:38:45.840Z
6
+ * Generated at: 2026-06-22T13:10:46.930Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.opinionApiSpec = {
@@ -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-06-18T14:38:45.790Z
3
+ * Generated at: 2026-06-22T13:10:46.882Z
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-06-18T14:38:45.790Z
6
+ * Generated at: 2026-06-22T13:10:46.882Z
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-06-18T14:38:45.803Z
3
+ * Generated at: 2026-06-22T13:10:46.896Z
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-06-18T14:38:45.803Z
6
+ * Generated at: 2026-06-22T13:10:46.896Z
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-06-18T14:38:45.801Z
3
+ * Generated at: 2026-06-22T13:10:46.893Z
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-06-18T14:38:45.801Z
6
+ * Generated at: 2026-06-22T13:10:46.893Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketGammaSpec = {
@@ -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-06-18T14:38:45.827Z
3
+ * Generated at: 2026-06-22T13:10:46.919Z
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-06-18T14:38:45.827Z
6
+ * Generated at: 2026-06-22T13:10:46.919Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.probableApiSpec = {
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ export * from './exchanges/hyperliquid';
19
19
  export * from './exchanges/gemini-titan';
20
20
  export * from './exchanges/suibets';
21
21
  export * from './exchanges/rain';
22
+ export * from './exchanges/hunch';
22
23
  export * from './router';
23
24
  export * from './feeds';
24
25
  export * from './server/app';
@@ -40,6 +41,7 @@ import { HyperliquidExchange } from './exchanges/hyperliquid';
40
41
  import { GeminiTitanExchange } from './exchanges/gemini-titan';
41
42
  import { SuiBetsExchange } from './exchanges/suibets';
42
43
  import { RainExchange } from './exchanges/rain';
44
+ import { HunchExchange } from './exchanges/hunch';
43
45
  import { Router } from './router';
44
46
  declare const pmxt: {
45
47
  Mock: typeof MockExchange;
@@ -58,6 +60,7 @@ declare const pmxt: {
58
60
  GeminiTitan: typeof GeminiTitanExchange;
59
61
  SuiBets: typeof SuiBetsExchange;
60
62
  Rain: typeof RainExchange;
63
+ Hunch: typeof HunchExchange;
61
64
  Router: typeof Router;
62
65
  };
63
66
  export declare const Mock: typeof MockExchange;
@@ -76,4 +79,5 @@ export declare const Hyperliquid: typeof HyperliquidExchange;
76
79
  export declare const GeminiTitan: typeof GeminiTitanExchange;
77
80
  export declare const SuiBets: typeof SuiBetsExchange;
78
81
  export declare const Rain: typeof RainExchange;
82
+ export declare const Hunch: typeof HunchExchange;
79
83
  export default pmxt;
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.Rain = exports.SuiBets = exports.GeminiTitan = exports.Hyperliquid = exports.PolymarketUS = exports.Smarkets = exports.Metaculus = exports.Opinion = exports.Myriad = exports.Baozi = exports.Probable = exports.KalshiDemo = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.Mock = exports.parseOpenApiSpec = void 0;
17
+ exports.Hunch = exports.Rain = exports.SuiBets = exports.GeminiTitan = exports.Hyperliquid = exports.PolymarketUS = exports.Smarkets = exports.Metaculus = exports.Opinion = exports.Myriad = exports.Baozi = exports.Probable = exports.KalshiDemo = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.Mock = exports.parseOpenApiSpec = void 0;
18
18
  __exportStar(require("./BaseExchange"), exports);
19
19
  __exportStar(require("./types"), exports);
20
20
  __exportStar(require("./utils/math"), exports);
@@ -37,6 +37,7 @@ __exportStar(require("./exchanges/hyperliquid"), exports);
37
37
  __exportStar(require("./exchanges/gemini-titan"), exports);
38
38
  __exportStar(require("./exchanges/suibets"), exports);
39
39
  __exportStar(require("./exchanges/rain"), exports);
40
+ __exportStar(require("./exchanges/hunch"), exports);
40
41
  __exportStar(require("./router"), exports);
41
42
  __exportStar(require("./feeds"), exports);
42
43
  __exportStar(require("./server/app"), exports);
@@ -58,6 +59,7 @@ const hyperliquid_1 = require("./exchanges/hyperliquid");
58
59
  const gemini_titan_1 = require("./exchanges/gemini-titan");
59
60
  const suibets_1 = require("./exchanges/suibets");
60
61
  const rain_1 = require("./exchanges/rain");
62
+ const hunch_1 = require("./exchanges/hunch");
61
63
  const router_1 = require("./router");
62
64
  const pmxt = {
63
65
  Mock: mock_1.MockExchange,
@@ -76,6 +78,7 @@ const pmxt = {
76
78
  GeminiTitan: gemini_titan_1.GeminiTitanExchange,
77
79
  SuiBets: suibets_1.SuiBetsExchange,
78
80
  Rain: rain_1.RainExchange,
81
+ Hunch: hunch_1.HunchExchange,
79
82
  Router: router_1.Router,
80
83
  };
81
84
  exports.Mock = mock_1.MockExchange;
@@ -94,4 +97,5 @@ exports.Hyperliquid = hyperliquid_1.HyperliquidExchange;
94
97
  exports.GeminiTitan = gemini_titan_1.GeminiTitanExchange;
95
98
  exports.SuiBets = suibets_1.SuiBetsExchange;
96
99
  exports.Rain = rain_1.RainExchange;
100
+ exports.Hunch = hunch_1.HunchExchange;
97
101
  exports.default = pmxt;
@@ -220,6 +220,7 @@ const defaultExchanges = {
220
220
  opinion: null,
221
221
  metaculus: null,
222
222
  smarkets: null,
223
+ hunch: null,
223
224
  mock: null,
224
225
  };
225
226
  function getDefaultExchange(exchangeName) {
@@ -16,6 +16,7 @@ const hyperliquid_1 = require("../exchanges/hyperliquid");
16
16
  const gemini_titan_1 = require("../exchanges/gemini-titan");
17
17
  const suibets_1 = require("../exchanges/suibets");
18
18
  const rain_1 = require("../exchanges/rain");
19
+ const hunch_1 = require("../exchanges/hunch");
19
20
  const mock_1 = require("../exchanges/mock");
20
21
  const router_1 = require("../router");
21
22
  function createExchange(name, credentials, bearerToken) {
@@ -124,6 +125,13 @@ function createExchange(name, credentials, bearerToken) {
124
125
  environment: (credentials?.environment ||
125
126
  process.env.RAIN_ENVIRONMENT),
126
127
  });
128
+ case "hunch":
129
+ return new hunch_1.HunchExchange({
130
+ privateKey: credentials?.privateKey || process.env.HUNCH_PRIVATE_KEY,
131
+ walletAddress: credentials?.walletAddress ||
132
+ process.env.HUNCH_WALLET_ADDRESS,
133
+ baseUrl: credentials?.baseUrl || process.env.HUNCH_BASE_URL,
134
+ });
127
135
  case "mock":
128
136
  return new mock_1.MockExchange();
129
137
  case "router":