pmxt-core 2.34.3 → 2.35.2

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.
@@ -273,6 +273,15 @@ export interface PaginatedMarketsResult {
273
273
  /** Cursor to pass to the next call, or undefined if this is the last page */
274
274
  nextCursor?: string;
275
275
  }
276
+ /** Shape returned by fetchEventsPaginated */
277
+ export interface PaginatedEventsResult {
278
+ /** The page of unified events */
279
+ data: UnifiedEvent[];
280
+ /** Total number of events in the snapshot */
281
+ total: number;
282
+ /** Cursor to pass to the next call, or undefined if this is the last page */
283
+ nextCursor?: string;
284
+ }
276
285
  export declare abstract class PredictionMarketExchange {
277
286
  [key: string]: any;
278
287
  verbose: boolean;
@@ -301,6 +310,7 @@ export declare abstract class PredictionMarketExchange {
301
310
  private _throttler;
302
311
  private _snapshotTTL;
303
312
  private _snapshot?;
313
+ private _eventSnapshot?;
304
314
  private apiDescriptors;
305
315
  constructor(credentials?: ExchangeCredentials, options?: ExchangeOptions);
306
316
  private _rateLimit;
@@ -365,6 +375,27 @@ export declare abstract class PredictionMarketExchange {
365
375
  cursor?: string;
366
376
  filter?: MarketFilterCriteria;
367
377
  }): Promise<PaginatedMarketsResult>;
378
+ /**
379
+ * Paginated variant of {@link fetchEvents}.
380
+ *
381
+ * On the first call (no `cursor`), all events are fetched from the exchange
382
+ * and cached in an in-memory snapshot. A cursor is returned along with the
383
+ * first page. Subsequent calls with that cursor serve additional pages
384
+ * directly from the cached snapshot -- no additional API calls are made.
385
+ *
386
+ * The snapshot is invalidated after `snapshotTTL` ms (configured via `ExchangeOptions`
387
+ * in the constructor). A request using a cursor from an expired snapshot throws
388
+ * `'Cursor has expired'`.
389
+ *
390
+ * @param params.limit - Page size (default: return all events)
391
+ * @param params.cursor - Opaque cursor returned by a previous call
392
+ * @returns PaginatedEventsResult with data, total, and optional nextCursor
393
+ */
394
+ fetchEventsPaginated(params?: {
395
+ limit?: number;
396
+ cursor?: string;
397
+ filter?: EventFilterCriteria;
398
+ }): Promise<PaginatedEventsResult>;
368
399
  /**
369
400
  * Fetch events with optional keyword search.
370
401
  * Events group related markets together (e.g., "Who will be Fed Chair?" contains multiple candidate markets).
@@ -46,6 +46,7 @@ class PredictionMarketExchange {
46
46
  // Snapshot state for cursor-based pagination
47
47
  _snapshotTTL;
48
48
  _snapshot;
49
+ _eventSnapshot;
49
50
  apiDescriptors = [];
50
51
  constructor(credentials, options) {
51
52
  this.credentials = credentials;
@@ -254,6 +255,61 @@ class PredictionMarketExchange {
254
255
  const nextCursor = limit < markets.length ? `${this._snapshot.id}:${limit}` : undefined;
255
256
  return { data: applyFilter(slice), total: markets.length, nextCursor };
256
257
  }
258
+ /**
259
+ * Paginated variant of {@link fetchEvents}.
260
+ *
261
+ * On the first call (no `cursor`), all events are fetched from the exchange
262
+ * and cached in an in-memory snapshot. A cursor is returned along with the
263
+ * first page. Subsequent calls with that cursor serve additional pages
264
+ * directly from the cached snapshot -- no additional API calls are made.
265
+ *
266
+ * The snapshot is invalidated after `snapshotTTL` ms (configured via `ExchangeOptions`
267
+ * in the constructor). A request using a cursor from an expired snapshot throws
268
+ * `'Cursor has expired'`.
269
+ *
270
+ * @param params.limit - Page size (default: return all events)
271
+ * @param params.cursor - Opaque cursor returned by a previous call
272
+ * @returns PaginatedEventsResult with data, total, and optional nextCursor
273
+ */
274
+ async fetchEventsPaginated(params) {
275
+ const limit = params?.limit;
276
+ const cursor = params?.cursor;
277
+ const filter = params?.filter;
278
+ const applyFilter = (events) => filter ? this.filterEvents(events, filter) : events;
279
+ if (cursor) {
280
+ const sep = cursor.indexOf(':');
281
+ const snapshotId = cursor.substring(0, sep);
282
+ const offset = parseInt(cursor.substring(sep + 1), 10);
283
+ if (!this._eventSnapshot ||
284
+ this._eventSnapshot.id !== snapshotId ||
285
+ (this._snapshotTTL > 0 && Date.now() - this._eventSnapshot.takenAt > this._snapshotTTL)) {
286
+ throw new Error('Cursor has expired');
287
+ }
288
+ const events = this._eventSnapshot.events;
289
+ const slice = limit !== undefined ? events.slice(offset, offset + limit) : events.slice(offset);
290
+ const nextOffset = offset + slice.length;
291
+ const nextCursor = nextOffset < events.length ? `${snapshotId}:${nextOffset}` : undefined;
292
+ return { data: applyFilter(slice), total: events.length, nextCursor };
293
+ }
294
+ // No cursor -- (re)fetch snapshot
295
+ if (!this._eventSnapshot ||
296
+ this._snapshotTTL === 0 ||
297
+ Date.now() - this._eventSnapshot.takenAt > this._snapshotTTL) {
298
+ const events = await this.fetchEventsImpl({});
299
+ this._eventSnapshot = {
300
+ events,
301
+ takenAt: Date.now(),
302
+ id: Math.random().toString(36).slice(2),
303
+ };
304
+ }
305
+ const events = this._eventSnapshot.events;
306
+ if (!limit) {
307
+ return { data: applyFilter(events), total: events.length, nextCursor: undefined };
308
+ }
309
+ const slice = events.slice(0, limit);
310
+ const nextCursor = limit < events.length ? `${this._eventSnapshot.id}:${limit}` : undefined;
311
+ return { data: applyFilter(slice), total: events.length, nextCursor };
312
+ }
257
313
  /**
258
314
  * Fetch events with optional keyword search.
259
315
  * Events group related markets together (e.g., "Who will be Fed Chair?" contains multiple candidate markets).
@@ -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-04-24T12:14:13.697Z
3
+ * Generated at: 2026-04-24T18:10:16.330Z
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-04-24T12:14:13.697Z
6
+ * Generated at: 2026-04-24T18:10:16.330Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.kalshiApiSpec = {
@@ -105,7 +105,7 @@ class KalshiExchange extends BaseExchange_1.PredictionMarketExchange {
105
105
  }
106
106
  async fetchEventsImpl(params) {
107
107
  const rawEvents = await this.fetcher.fetchRawEvents(params);
108
- const limit = params?.limit || 10000;
108
+ const limit = params?.limit || 250000;
109
109
  const query = (params?.query || '').toLowerCase();
110
110
  const filtered = query
111
111
  ? rawEvents.filter((event) => (event.title || '').toLowerCase().includes(query))
@@ -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-04-24T12:14:13.734Z
3
+ * Generated at: 2026-04-24T18:10:16.380Z
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-04-24T12:14:13.734Z
6
+ * Generated at: 2026-04-24T18:10:16.380Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.limitlessApiSpec = {
@@ -211,7 +211,7 @@ class LimitlessFetcher {
211
211
  return markets;
212
212
  }
213
213
  async fetchRawEventsDefault(params) {
214
- const limit = params?.limit || 10000;
214
+ const limit = params?.limit || 250000;
215
215
  let page = 1;
216
216
  const pageSize = 25;
217
217
  const MAX_PAGES = 40;
@@ -10,26 +10,30 @@ function mapMarketToUnified(market) {
10
10
  if (!market)
11
11
  return null;
12
12
  const outcomes = [];
13
- // The new API provides 'tokens' and 'prices'
14
- // tokens: { no: "...", yes: "..." }
15
- // prices: [noPrice, yesPrice]
13
+ // The Limitless SDK provides:
14
+ // tokens: { yes: "...", no: "..." }
15
+ // prices: [yesPrice, noPrice] (always [yes, no] per SDK docs)
16
+ // Use explicit key lookup — Object.entries order is not guaranteed to
17
+ // match the prices array.
16
18
  if (market.tokens) {
17
- const tokenEntries = Object.entries(market.tokens);
18
- // Ensure prices array exists, otherwise default to empty
19
19
  const prices = Array.isArray(market.prices) ? market.prices : [];
20
- tokenEntries.forEach(([label, tokenId], index) => {
21
- const outcomePrice = prices[index] || 0;
22
- const outcomeIdValue = tokenId;
23
- outcomes.push({
24
- outcomeId: outcomeIdValue,
25
- marketId: market.slug,
26
- label: label.charAt(0).toUpperCase() + label.slice(1), // Capitalize 'yes'/'no'
27
- price: outcomePrice,
28
- priceChange24h: 0, // Not directly available in this flat list, can be computed if needed
29
- metadata: {
30
- clobTokenId: tokenId
31
- }
32
- });
20
+ const yesPrice = prices[0] || 0;
21
+ const noPrice = prices[1] || 0;
22
+ outcomes.push({
23
+ outcomeId: market.tokens.yes,
24
+ marketId: market.slug,
25
+ label: 'Yes',
26
+ price: yesPrice,
27
+ priceChange24h: 0,
28
+ metadata: { clobTokenId: market.tokens.yes },
29
+ });
30
+ outcomes.push({
31
+ outcomeId: market.tokens.no,
32
+ marketId: market.slug,
33
+ label: 'No',
34
+ price: noPrice,
35
+ priceChange24h: 0,
36
+ metadata: { clobTokenId: market.tokens.no },
33
37
  });
34
38
  }
35
39
  const um = {
@@ -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-04-24T12:14:13.746Z
3
+ * Generated at: 2026-04-24T18:10:16.395Z
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-04-24T12:14:13.746Z
6
+ * Generated at: 2026-04-24T18:10:16.395Z
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-04-24T12:14:13.751Z
3
+ * Generated at: 2026-04-24T18:10:16.400Z
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-04-24T12:14:13.751Z
6
+ * Generated at: 2026-04-24T18:10:16.400Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.opinionApiSpec = {
@@ -44,4 +44,5 @@ export declare class OpinionExchange extends PredictionMarketExchange {
44
44
  private ensureTradeAuth;
45
45
  private requireWalletAddress;
46
46
  private ensureWebSocket;
47
+ private enrichPrices;
47
48
  }
@@ -134,6 +134,7 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
134
134
  return descMatch;
135
135
  return titleMatch || descMatch;
136
136
  });
137
+ await this.enrichPrices(filtered);
137
138
  return filtered.slice(0, params.limit || 250000);
138
139
  }
139
140
  if (params?.sort === 'volume') {
@@ -144,19 +145,24 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
144
145
  }
145
146
  const offset = params?.offset || 0;
146
147
  const limit = params?.limit || 250000;
147
- return allMarkets.slice(offset, offset + limit);
148
+ const sliced = allMarkets.slice(offset, offset + limit);
149
+ await this.enrichPrices(sliced);
150
+ return sliced;
148
151
  }
149
152
  async fetchEventsImpl(params) {
150
153
  const rawEvents = await this.fetcher.fetchRawEvents(params);
151
- const limit = params.limit || 10000;
154
+ const limit = params.limit || 250000;
152
155
  const query = (params.query || '').toLowerCase();
153
156
  const filtered = query
154
157
  ? rawEvents.filter((raw) => (raw.marketTitle || '').toLowerCase().includes(query))
155
158
  : rawEvents;
156
- return filtered
159
+ const events = filtered
157
160
  .map((raw) => this.normalizer.normalizeEvent(raw))
158
161
  .filter((e) => e !== null)
159
162
  .slice(0, limit);
163
+ const allMarkets = events.flatMap((e) => e.markets);
164
+ await this.enrichPrices(allMarkets);
165
+ return events;
160
166
  }
161
167
  async fetchOHLCV(id, params) {
162
168
  const rawPoints = await this.fetcher.fetchRawOHLCV(id, params);
@@ -380,5 +386,8 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
380
386
  }
381
387
  return this.ws;
382
388
  }
389
+ async enrichPrices(markets) {
390
+ await this.normalizer.enrichMarketsWithPrices(markets, (tokenId) => this.fetcher.fetchRawLatestPrice(tokenId));
391
+ }
383
392
  }
384
393
  exports.OpinionExchange = OpinionExchange;
@@ -1,7 +1,7 @@
1
1
  import { OHLCVParams } from '../../BaseExchange';
2
2
  import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, UserTrade, Position, Order } from '../../types';
3
3
  import { IExchangeNormalizer } from '../interfaces';
4
- import { OpinionRawMarket, OpinionRawOrderBook, OpinionRawPricePoint, OpinionRawUserTrade, OpinionRawPosition, OpinionRawOrder } from './fetcher';
4
+ import { OpinionRawMarket, OpinionRawOrderBook, OpinionRawPricePoint, OpinionRawLatestPrice, OpinionRawUserTrade, OpinionRawPosition, OpinionRawOrder } from './fetcher';
5
5
  export declare class OpinionNormalizer implements IExchangeNormalizer<OpinionRawMarket, OpinionRawMarket> {
6
6
  normalizeMarket(raw: OpinionRawMarket): UnifiedMarket | null;
7
7
  normalizeMarketsFromEvent(raw: OpinionRawMarket): UnifiedMarket[];
@@ -14,6 +14,19 @@ export declare class OpinionNormalizer implements IExchangeNormalizer<OpinionRaw
14
14
  normalizeUserTrade(raw: OpinionRawUserTrade, index: number): UserTrade;
15
15
  normalizePosition(raw: OpinionRawPosition): Position;
16
16
  normalizeOrder(raw: OpinionRawOrder): Order;
17
+ /**
18
+ * Fetch latest prices for all markets in parallel and update outcome prices.
19
+ *
20
+ * Opinion's /market endpoint does not include prices, so outcomes are
21
+ * initially created with a placeholder. This method calls the supplied
22
+ * `fetchLatestPrice` callback (backed by /token/latest-price) for the
23
+ * first outcome of every market, derives the complementary price for
24
+ * binary outcomes, and re-runs addBinaryOutcomes().
25
+ *
26
+ * Uses Promise.allSettled so a single failed price fetch never breaks the
27
+ * whole batch — markets whose price fetch fails simply keep the placeholder.
28
+ */
29
+ enrichMarketsWithPrices(markets: UnifiedMarket[], fetchLatestPrice: (tokenId: string) => Promise<OpinionRawLatestPrice>): Promise<void>;
17
30
  private normalizeBinaryMarket;
18
31
  private normalizeChildMarket;
19
32
  }
@@ -30,8 +30,14 @@ class OpinionNormalizer {
30
30
  // Categorical: each child market becomes a separate UnifiedMarket
31
31
  const children = raw.childMarkets || [];
32
32
  const results = [];
33
+ const parentVolume24h = (0, utils_1.parseNumStr)(raw.volume24h);
34
+ const totalChildVolume = children.reduce((sum, c) => sum + (0, utils_1.parseNumStr)(c.volume), 0);
33
35
  for (const child of children) {
34
- const market = this.normalizeChildMarket(child, raw);
36
+ const childVolume = (0, utils_1.parseNumStr)(child.volume);
37
+ const childVolume24h = totalChildVolume > 0
38
+ ? (childVolume / totalChildVolume) * parentVolume24h
39
+ : 0;
40
+ const market = this.normalizeChildMarket(child, raw, childVolume24h);
35
41
  if (market)
36
42
  results.push(market);
37
43
  }
@@ -165,6 +171,49 @@ class OpinionNormalizer {
165
171
  timestamp: (0, utils_1.toMillis)(raw.createdAt),
166
172
  };
167
173
  }
174
+ // -- Price enrichment -----------------------------------------------------
175
+ /**
176
+ * Fetch latest prices for all markets in parallel and update outcome prices.
177
+ *
178
+ * Opinion's /market endpoint does not include prices, so outcomes are
179
+ * initially created with a placeholder. This method calls the supplied
180
+ * `fetchLatestPrice` callback (backed by /token/latest-price) for the
181
+ * first outcome of every market, derives the complementary price for
182
+ * binary outcomes, and re-runs addBinaryOutcomes().
183
+ *
184
+ * Uses Promise.allSettled so a single failed price fetch never breaks the
185
+ * whole batch — markets whose price fetch fails simply keep the placeholder.
186
+ */
187
+ async enrichMarketsWithPrices(markets, fetchLatestPrice) {
188
+ if (markets.length === 0)
189
+ return;
190
+ const results = await Promise.allSettled(markets.map(async (market) => {
191
+ const yesOutcome = market.outcomes[0];
192
+ if (!yesOutcome?.outcomeId)
193
+ return null;
194
+ const raw = await fetchLatestPrice(yesOutcome.outcomeId);
195
+ const yesPrice = parseFloat(raw?.price ?? '');
196
+ if (isNaN(yesPrice))
197
+ return null;
198
+ return { marketId: market.marketId, yesPrice };
199
+ }));
200
+ const priceMap = {};
201
+ for (const result of results) {
202
+ if (result.status === 'fulfilled' && result.value) {
203
+ priceMap[result.value.marketId] = result.value.yesPrice;
204
+ }
205
+ }
206
+ for (const market of markets) {
207
+ const yesPrice = priceMap[market.marketId];
208
+ if (yesPrice === undefined)
209
+ continue;
210
+ if (market.outcomes[0])
211
+ market.outcomes[0].price = yesPrice;
212
+ if (market.outcomes[1])
213
+ market.outcomes[1].price = 1 - yesPrice;
214
+ (0, market_utils_1.addBinaryOutcomes)(market);
215
+ }
216
+ }
168
217
  // -- Private helpers ------------------------------------------------------
169
218
  normalizeBinaryMarket(raw) {
170
219
  if (!raw || raw.marketType !== 0)
@@ -202,7 +251,7 @@ class OpinionNormalizer {
202
251
  (0, market_utils_1.addBinaryOutcomes)(market);
203
252
  return market;
204
253
  }
205
- normalizeChildMarket(child, parent) {
254
+ normalizeChildMarket(child, parent, volume24h = 0) {
206
255
  if (!child)
207
256
  return null;
208
257
  const marketId = String(child.marketId);
@@ -230,8 +279,8 @@ class OpinionNormalizer {
230
279
  title: child.marketTitle || '',
231
280
  description: child.rules || '',
232
281
  outcomes: [yesOutcome, noOutcome],
233
- resolutionDate: new Date((0, utils_1.toMillis)(child.cutoffAt || parent.cutoffAt)),
234
- volume24h: 0, // child markets do not have volume24h
282
+ resolutionDate: new Date((0, utils_1.toMillis)(child.cutoffAt)),
283
+ volume24h,
235
284
  volume: (0, utils_1.parseNumStr)(child.volume),
236
285
  liquidity: 0,
237
286
  url: `https://opinion.trade/market/${child.marketId}`,
@@ -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-04-24T12:14:13.704Z
3
+ * Generated at: 2026-04-24T18:10:16.340Z
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-04-24T12:14:13.704Z
6
+ * Generated at: 2026-04-24T18:10:16.340Z
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-04-24T12:14:13.717Z
3
+ * Generated at: 2026-04-24T18:10:16.358Z
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-04-24T12:14:13.717Z
6
+ * Generated at: 2026-04-24T18:10:16.358Z
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-04-24T12:14:13.715Z
3
+ * Generated at: 2026-04-24T18:10:16.354Z
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-04-24T12:14:13.715Z
6
+ * Generated at: 2026-04-24T18:10:16.354Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketGammaSpec = {
@@ -284,7 +284,7 @@ class PolymarketFetcher {
284
284
  // Private helpers -- Events
285
285
  // ------------------------------------------------------------------------
286
286
  async fetchRawEventsSearch(params) {
287
- const limit = params.limit || 10000;
287
+ const limit = params.limit || 25000;
288
288
  let sortParam = 'volume';
289
289
  if (params.sort === 'newest')
290
290
  sortParam = 'startDate';
@@ -339,7 +339,7 @@ class PolymarketFetcher {
339
339
  }).slice(0, limit);
340
340
  }
341
341
  async fetchRawEventsDefault(params) {
342
- const limit = params.limit || 10000;
342
+ const limit = params.limit || 25000;
343
343
  const status = params.status || 'active';
344
344
  let sortParam = 'volume';
345
345
  if (params.sort === 'newest')
@@ -516,7 +516,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
516
516
  return rawEvents
517
517
  .map((raw) => this.normalizer.normalizeEvent(raw))
518
518
  .filter((e) => e !== null)
519
- .slice(0, params.limit || 10000);
519
+ .slice(0, params.limit || 250000);
520
520
  }
521
521
  /**
522
522
  * Ensure authentication is initialized before trading operations.
@@ -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-04-24T12:14:13.739Z
3
+ * Generated at: 2026-04-24T18:10:16.389Z
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-04-24T12:14:13.739Z
6
+ * Generated at: 2026-04-24T18:10:16.389Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.probableApiSpec = {
@@ -148,7 +148,7 @@ class SmarketsExchange extends BaseExchange_1.PredictionMarketExchange {
148
148
  }
149
149
  async fetchEventsImpl(params) {
150
150
  const rawEvents = await this.fetcher.fetchRawEvents(params);
151
- const limit = params?.limit || 10000;
151
+ const limit = params?.limit || 250000;
152
152
  const query = (params?.query || '').toLowerCase();
153
153
  const filtered = query
154
154
  ? rawEvents.filter((event) => (event.event.name || '').toLowerCase().includes(query))
@@ -29,6 +29,16 @@
29
29
  }
30
30
  ]
31
31
  },
32
+ "fetchEventsPaginated": {
33
+ "verb": "get",
34
+ "args": [
35
+ {
36
+ "name": "params",
37
+ "kind": "object",
38
+ "optional": true
39
+ }
40
+ ]
41
+ },
32
42
  "fetchEvents": {
33
43
  "verb": "get",
34
44
  "args": [
@@ -214,6 +214,45 @@ paths:
214
214
  previous call slice directly from the cached snapshot — no additional API calls are made. The snapshot is
215
215
  invalidated after `snapshotTTL` ms (configured via `ExchangeOptions` in the constructor). A request using a
216
216
  cursor from an expired snapshot throws `'Cursor has expired'`.
217
+ '/api/{exchange}/fetchEventsPaginated':
218
+ get:
219
+ summary: Fetch Events Paginated
220
+ operationId: fetchEventsPaginated
221
+ parameters:
222
+ - $ref: '#/components/parameters/ExchangeParam'
223
+ - in: query
224
+ name: limit
225
+ required: false
226
+ schema:
227
+ type: number
228
+ - in: query
229
+ name: cursor
230
+ required: false
231
+ schema:
232
+ type: string
233
+ - in: query
234
+ name: filter
235
+ required: false
236
+ schema:
237
+ $ref: '#/components/schemas/EventFilterCriteria'
238
+ responses:
239
+ '200':
240
+ description: Fetch Events Paginated response
241
+ content:
242
+ application/json:
243
+ schema:
244
+ allOf:
245
+ - $ref: '#/components/schemas/BaseResponse'
246
+ - type: object
247
+ properties:
248
+ data:
249
+ $ref: '#/components/schemas/PaginatedEventsResult'
250
+ description: >-
251
+ Paginated variant of {@link fetchEvents}. On the first call (no `cursor`), all events are fetched from the
252
+ exchange and cached in an in-memory snapshot. A cursor is returned along with the first page. Subsequent calls
253
+ with that cursor serve additional pages directly from the cached snapshot -- no additional API calls are made.
254
+ The snapshot is invalidated after `snapshotTTL` ms (configured via `ExchangeOptions` in the constructor). A
255
+ request using a cursor from an expired snapshot throws `'Cursor has expired'`.
217
256
  '/api/{exchange}/fetchEvents':
218
257
  get:
219
258
  summary: Fetch Events
@@ -2323,6 +2362,24 @@ components:
2323
2362
  required:
2324
2363
  - data
2325
2364
  - total
2365
+ PaginatedEventsResult:
2366
+ type: object
2367
+ description: Shape returned by fetchEventsPaginated
2368
+ properties:
2369
+ data:
2370
+ type: array
2371
+ items:
2372
+ $ref: '#/components/schemas/UnifiedEvent'
2373
+ description: The page of unified events
2374
+ total:
2375
+ type: number
2376
+ description: Total number of events in the snapshot
2377
+ nextCursor:
2378
+ type: string
2379
+ description: 'Cursor to pass to the next call, or undefined if this is the last page'
2380
+ required:
2381
+ - data
2382
+ - total
2326
2383
  MarketFilterParams:
2327
2384
  type: object
2328
2385
  properties:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxt-core",
3
- "version": "2.34.3",
3
+ "version": "2.35.2",
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.34.3,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.34.3,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.35.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.35.2,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",