pmxt-core 2.20.0 → 2.20.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.
Files changed (113) hide show
  1. package/dist/exchanges/baozi/fetcher.d.ts +40 -0
  2. package/dist/exchanges/baozi/fetcher.js +155 -0
  3. package/dist/exchanges/baozi/index.d.ts +2 -0
  4. package/dist/exchanges/baozi/index.js +60 -131
  5. package/dist/exchanges/baozi/normalizer.d.ts +14 -0
  6. package/dist/exchanges/baozi/normalizer.js +208 -0
  7. package/dist/exchanges/interfaces.d.ts +28 -0
  8. package/dist/exchanges/interfaces.js +2 -0
  9. package/dist/exchanges/kalshi/api.d.ts +1 -1
  10. package/dist/exchanges/kalshi/api.js +1 -1
  11. package/dist/exchanges/kalshi/fetcher.d.ts +126 -0
  12. package/dist/exchanges/kalshi/fetcher.js +313 -0
  13. package/dist/exchanges/kalshi/index.d.ts +6 -6
  14. package/dist/exchanges/kalshi/index.js +119 -202
  15. package/dist/exchanges/kalshi/normalizer.d.ts +25 -0
  16. package/dist/exchanges/kalshi/normalizer.js +294 -0
  17. package/dist/exchanges/limitless/api.d.ts +1 -1
  18. package/dist/exchanges/limitless/api.js +1 -1
  19. package/dist/exchanges/limitless/fetcher.d.ts +81 -0
  20. package/dist/exchanges/limitless/fetcher.js +238 -0
  21. package/dist/exchanges/limitless/index.d.ts +6 -9
  22. package/dist/exchanges/limitless/index.js +81 -79
  23. package/dist/exchanges/limitless/normalizer.d.ts +14 -0
  24. package/dist/exchanges/limitless/normalizer.js +117 -0
  25. package/dist/exchanges/limitless/websocket.d.ts +3 -0
  26. package/dist/exchanges/limitless/websocket.js +5 -4
  27. package/dist/exchanges/myriad/api.d.ts +1 -1
  28. package/dist/exchanges/myriad/api.js +1 -1
  29. package/dist/exchanges/myriad/fetcher.d.ts +73 -0
  30. package/dist/exchanges/myriad/fetcher.js +217 -0
  31. package/dist/exchanges/myriad/index.d.ts +2 -0
  32. package/dist/exchanges/myriad/index.js +40 -97
  33. package/dist/exchanges/myriad/normalizer.d.ts +14 -0
  34. package/dist/exchanges/myriad/normalizer.js +167 -0
  35. package/dist/exchanges/myriad/websocket.d.ts +3 -1
  36. package/dist/exchanges/myriad/websocket.js +4 -3
  37. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  38. package/dist/exchanges/polymarket/api-clob.js +1 -1
  39. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  40. package/dist/exchanges/polymarket/api-data.js +1 -1
  41. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  42. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  43. package/dist/exchanges/polymarket/fetcher.d.ts +99 -0
  44. package/dist/exchanges/polymarket/fetcher.js +335 -0
  45. package/dist/exchanges/polymarket/index.d.ts +2 -0
  46. package/dist/exchanges/polymarket/index.js +80 -66
  47. package/dist/exchanges/polymarket/normalizer.d.ts +18 -0
  48. package/dist/exchanges/polymarket/normalizer.js +126 -0
  49. package/dist/exchanges/probable/api.d.ts +1 -1
  50. package/dist/exchanges/probable/api.js +1 -1
  51. package/dist/exchanges/probable/fetcher.d.ts +106 -0
  52. package/dist/exchanges/probable/fetcher.js +357 -0
  53. package/dist/exchanges/probable/index.d.ts +3 -1
  54. package/dist/exchanges/probable/index.js +73 -105
  55. package/dist/exchanges/probable/normalizer.d.ts +14 -0
  56. package/dist/exchanges/probable/normalizer.js +109 -0
  57. package/dist/utils/error-mapper.d.ts +8 -0
  58. package/dist/utils/error-mapper.js +58 -26
  59. package/package.json +3 -3
  60. package/dist/exchanges/baozi/fetchEvents.d.ts +0 -8
  61. package/dist/exchanges/baozi/fetchEvents.js +0 -39
  62. package/dist/exchanges/baozi/fetchMarkets.d.ts +0 -5
  63. package/dist/exchanges/baozi/fetchMarkets.js +0 -160
  64. package/dist/exchanges/baozi/fetchOHLCV.d.ts +0 -6
  65. package/dist/exchanges/baozi/fetchOHLCV.js +0 -10
  66. package/dist/exchanges/baozi/fetchOrderBook.d.ts +0 -12
  67. package/dist/exchanges/baozi/fetchOrderBook.js +0 -36
  68. package/dist/exchanges/baozi/fetchTrades.d.ts +0 -6
  69. package/dist/exchanges/baozi/fetchTrades.js +0 -10
  70. package/dist/exchanges/kalshi/fetchEvents.d.ts +0 -5
  71. package/dist/exchanges/kalshi/fetchEvents.js +0 -196
  72. package/dist/exchanges/kalshi/fetchMarkets.d.ts +0 -6
  73. package/dist/exchanges/kalshi/fetchMarkets.js +0 -247
  74. package/dist/exchanges/kalshi/fetchOHLCV.d.ts +0 -3
  75. package/dist/exchanges/kalshi/fetchOHLCV.js +0 -97
  76. package/dist/exchanges/kalshi/fetchOrderBook.d.ts +0 -2
  77. package/dist/exchanges/kalshi/fetchOrderBook.js +0 -60
  78. package/dist/exchanges/kalshi/fetchTrades.d.ts +0 -3
  79. package/dist/exchanges/kalshi/fetchTrades.js +0 -33
  80. package/dist/exchanges/limitless/fetchEvents.d.ts +0 -4
  81. package/dist/exchanges/limitless/fetchEvents.js +0 -173
  82. package/dist/exchanges/limitless/fetchMarkets.d.ts +0 -3
  83. package/dist/exchanges/limitless/fetchMarkets.js +0 -152
  84. package/dist/exchanges/limitless/fetchOHLCV.d.ts +0 -7
  85. package/dist/exchanges/limitless/fetchOHLCV.js +0 -49
  86. package/dist/exchanges/limitless/fetchOrderBook.d.ts +0 -6
  87. package/dist/exchanges/limitless/fetchOrderBook.js +0 -41
  88. package/dist/exchanges/limitless/fetchTrades.d.ts +0 -8
  89. package/dist/exchanges/limitless/fetchTrades.js +0 -27
  90. package/dist/exchanges/myriad/fetchEvents.d.ts +0 -4
  91. package/dist/exchanges/myriad/fetchEvents.js +0 -48
  92. package/dist/exchanges/myriad/fetchMarkets.d.ts +0 -4
  93. package/dist/exchanges/myriad/fetchMarkets.js +0 -102
  94. package/dist/exchanges/myriad/fetchOHLCV.d.ts +0 -3
  95. package/dist/exchanges/myriad/fetchOHLCV.js +0 -83
  96. package/dist/exchanges/myriad/fetchOrderBook.d.ts +0 -2
  97. package/dist/exchanges/myriad/fetchOrderBook.js +0 -39
  98. package/dist/exchanges/polymarket/fetchEvents.d.ts +0 -4
  99. package/dist/exchanges/polymarket/fetchEvents.js +0 -135
  100. package/dist/exchanges/polymarket/fetchMarkets.d.ts +0 -4
  101. package/dist/exchanges/polymarket/fetchMarkets.js +0 -214
  102. package/dist/exchanges/polymarket/fetchOHLCV.d.ts +0 -7
  103. package/dist/exchanges/polymarket/fetchOHLCV.js +0 -98
  104. package/dist/exchanges/polymarket/fetchOrderBook.d.ts +0 -6
  105. package/dist/exchanges/polymarket/fetchOrderBook.js +0 -33
  106. package/dist/exchanges/polymarket/fetchTrades.d.ts +0 -9
  107. package/dist/exchanges/polymarket/fetchTrades.js +0 -43
  108. package/dist/exchanges/probable/fetchEvents.d.ts +0 -6
  109. package/dist/exchanges/probable/fetchEvents.js +0 -151
  110. package/dist/exchanges/probable/fetchMarkets.d.ts +0 -4
  111. package/dist/exchanges/probable/fetchMarkets.js +0 -239
  112. package/dist/exchanges/probable/fetchTrades.d.ts +0 -10
  113. package/dist/exchanges/probable/fetchTrades.js +0 -40
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KalshiNormalizer = void 0;
4
+ exports.sortRawEvents = sortRawEvents;
5
+ const market_utils_1 = require("../../utils/market-utils");
6
+ const price_1 = require("./price");
7
+ class KalshiNormalizer {
8
+ normalizeMarket(raw) {
9
+ // This normalizes a single-market event. For multi-market events, use normalizeMarketsFromEvent.
10
+ if (!raw || !raw.markets || raw.markets.length === 0)
11
+ return null;
12
+ return this.normalizeRawMarket(raw, raw.markets[0]);
13
+ }
14
+ normalizeMarketsFromEvent(rawEvent) {
15
+ const markets = rawEvent.markets || [];
16
+ const results = [];
17
+ for (const market of markets) {
18
+ const um = this.normalizeRawMarket(rawEvent, market);
19
+ if (um)
20
+ results.push(um);
21
+ }
22
+ return results;
23
+ }
24
+ normalizeRawMarket(event, market) {
25
+ if (!market)
26
+ return null;
27
+ let price = 0.5;
28
+ if (market.last_price) {
29
+ price = (0, price_1.fromKalshiCents)(market.last_price);
30
+ }
31
+ else if (market.yes_ask && market.yes_bid) {
32
+ price = ((0, price_1.fromKalshiCents)(market.yes_ask) + (0, price_1.fromKalshiCents)(market.yes_bid)) / 2;
33
+ }
34
+ else if (market.yes_ask) {
35
+ price = (0, price_1.fromKalshiCents)(market.yes_ask);
36
+ }
37
+ let candidateName = null;
38
+ if (market.subtitle || market.yes_sub_title) {
39
+ candidateName = (market.subtitle || market.yes_sub_title);
40
+ }
41
+ let priceChange = 0;
42
+ if (market.previous_price_dollars !== undefined && market.last_price_dollars !== undefined) {
43
+ priceChange = market.last_price_dollars - market.previous_price_dollars;
44
+ }
45
+ const outcomes = [
46
+ {
47
+ outcomeId: market.ticker,
48
+ marketId: market.ticker,
49
+ label: candidateName || 'Yes',
50
+ price,
51
+ priceChange24h: priceChange,
52
+ },
53
+ {
54
+ outcomeId: `${market.ticker}-NO`,
55
+ marketId: market.ticker,
56
+ label: candidateName ? `Not ${candidateName}` : 'No',
57
+ price: (0, price_1.invertKalshiUnified)(price),
58
+ priceChange24h: -priceChange,
59
+ },
60
+ ];
61
+ const unifiedTags = [];
62
+ if (event.category)
63
+ unifiedTags.push(event.category);
64
+ if (event.tags && Array.isArray(event.tags)) {
65
+ for (const tag of event.tags) {
66
+ if (!unifiedTags.includes(tag))
67
+ unifiedTags.push(tag);
68
+ }
69
+ }
70
+ const um = {
71
+ id: market.ticker,
72
+ marketId: market.ticker,
73
+ eventId: event.event_ticker,
74
+ title: event.title,
75
+ description: market.rules_primary || market.rules_secondary || '',
76
+ outcomes,
77
+ resolutionDate: new Date(market.expiration_time),
78
+ volume24h: Number(market.volume_24h || market.volume || 0),
79
+ volume: Number(market.volume || 0),
80
+ liquidity: Number(market.liquidity || 0),
81
+ openInterest: Number(market.open_interest || 0),
82
+ url: `https://kalshi.com/events/${event.event_ticker}`,
83
+ category: event.category,
84
+ tags: unifiedTags,
85
+ };
86
+ (0, market_utils_1.addBinaryOutcomes)(um);
87
+ return um;
88
+ }
89
+ normalizeEvent(raw) {
90
+ if (!raw)
91
+ return null;
92
+ const markets = this.normalizeMarketsFromEvent(raw);
93
+ return {
94
+ id: raw.event_ticker,
95
+ title: raw.title,
96
+ description: raw.mututals_description || this.deriveEventDescription(raw.markets || []),
97
+ slug: raw.event_ticker,
98
+ markets,
99
+ volume24h: markets.reduce((sum, m) => sum + m.volume24h, 0),
100
+ volume: markets.some(m => m.volume !== undefined)
101
+ ? markets.reduce((sum, m) => sum + (m.volume ?? 0), 0)
102
+ : undefined,
103
+ url: `https://kalshi.com/events/${raw.event_ticker}`,
104
+ image: raw.image_url,
105
+ category: raw.category,
106
+ tags: raw.tags || [],
107
+ };
108
+ }
109
+ normalizeOHLCV(rawCandles, params) {
110
+ const candles = rawCandles.map((c) => {
111
+ const p = c.price || {};
112
+ const ask = c.yes_ask || {};
113
+ const bid = c.yes_bid || {};
114
+ const getVal = (field) => {
115
+ const pf = p[field];
116
+ const af = ask[field];
117
+ const bf = bid[field];
118
+ if (pf !== null && pf !== undefined)
119
+ return pf;
120
+ if (af !== null && af !== undefined && bf !== null && bf !== undefined) {
121
+ return (af + bf) / 2;
122
+ }
123
+ return p.previous || 0;
124
+ };
125
+ return {
126
+ timestamp: c.end_period_ts * 1000,
127
+ open: (0, price_1.fromKalshiCents)(getVal('open')),
128
+ high: (0, price_1.fromKalshiCents)(getVal('high')),
129
+ low: (0, price_1.fromKalshiCents)(getVal('low')),
130
+ close: (0, price_1.fromKalshiCents)(getVal('close')),
131
+ volume: c.volume || 0,
132
+ };
133
+ });
134
+ if (params.limit && candles.length > params.limit) {
135
+ return candles.slice(-params.limit);
136
+ }
137
+ return candles;
138
+ }
139
+ normalizeOrderBook(raw, id) {
140
+ const data = raw.orderbook_fp;
141
+ const isNoOutcome = id.endsWith('-NO');
142
+ let bids;
143
+ let asks;
144
+ if (isNoOutcome) {
145
+ bids = (data.no_dollars || []).map((level) => ({
146
+ price: parseFloat(level[0]),
147
+ size: parseFloat(level[1]),
148
+ }));
149
+ asks = (data.yes_dollars || []).map((level) => ({
150
+ price: Math.round((1 - parseFloat(level[0])) * 10000) / 10000,
151
+ size: parseFloat(level[1]),
152
+ }));
153
+ }
154
+ else {
155
+ bids = (data.yes_dollars || []).map((level) => ({
156
+ price: parseFloat(level[0]),
157
+ size: parseFloat(level[1]),
158
+ }));
159
+ asks = (data.no_dollars || []).map((level) => ({
160
+ price: Math.round((1 - parseFloat(level[0])) * 10000) / 10000,
161
+ size: parseFloat(level[1]),
162
+ }));
163
+ }
164
+ bids.sort((a, b) => b.price - a.price);
165
+ asks.sort((a, b) => a.price - b.price);
166
+ return { bids, asks, timestamp: Date.now() };
167
+ }
168
+ normalizeTrade(raw, _index) {
169
+ return {
170
+ id: raw.trade_id,
171
+ timestamp: new Date(raw.created_time).getTime(),
172
+ price: (0, price_1.fromKalshiCents)(raw.yes_price),
173
+ amount: raw.count,
174
+ side: raw.taker_side === 'yes' ? 'buy' : 'sell',
175
+ };
176
+ }
177
+ normalizeUserTrade(raw, _index) {
178
+ return {
179
+ id: raw.fill_id,
180
+ timestamp: new Date(raw.created_time).getTime(),
181
+ price: (0, price_1.fromKalshiCents)(raw.yes_price),
182
+ amount: raw.count,
183
+ side: raw.side === 'yes' ? 'buy' : 'sell',
184
+ orderId: raw.order_id,
185
+ };
186
+ }
187
+ normalizeOrder(raw) {
188
+ return {
189
+ id: raw.order_id,
190
+ marketId: raw.ticker,
191
+ outcomeId: raw.ticker,
192
+ side: raw.side === 'yes' ? 'buy' : 'sell',
193
+ type: raw.type === 'limit' ? 'limit' : 'market',
194
+ price: raw.yes_price ? raw.yes_price / 100 : undefined,
195
+ amount: raw.count,
196
+ status: this.mapOrderStatus(raw.status),
197
+ filled: raw.count - (raw.remaining_count || 0),
198
+ remaining: raw.remaining_count || 0,
199
+ timestamp: new Date(raw.created_time).getTime(),
200
+ };
201
+ }
202
+ normalizePosition(raw) {
203
+ const absPosition = Math.abs(raw.position);
204
+ const entryPrice = absPosition > 0 ? raw.total_cost / absPosition / 100 : 0;
205
+ return {
206
+ marketId: raw.ticker,
207
+ outcomeId: raw.ticker,
208
+ outcomeLabel: raw.ticker,
209
+ size: raw.position,
210
+ entryPrice,
211
+ currentPrice: raw.market_price ? raw.market_price / 100 : entryPrice,
212
+ unrealizedPnL: raw.market_exposure ? raw.market_exposure / 100 : 0,
213
+ realizedPnL: raw.realized_pnl ? raw.realized_pnl / 100 : 0,
214
+ };
215
+ }
216
+ normalizeBalance(raw) {
217
+ const available = raw.balance / 100;
218
+ const total = raw.portfolio_value / 100;
219
+ return [{
220
+ currency: 'USD',
221
+ total,
222
+ available,
223
+ locked: total - available,
224
+ }];
225
+ }
226
+ // -- Helpers ---------------------------------------------------------------
227
+ mapOrderStatus(status) {
228
+ switch ((status ?? '').toLowerCase()) {
229
+ case 'resting': return 'open';
230
+ case 'canceled':
231
+ case 'cancelled': return 'cancelled';
232
+ case 'executed':
233
+ case 'filled': return 'filled';
234
+ default: return 'open';
235
+ }
236
+ }
237
+ deriveEventDescription(markets) {
238
+ const texts = markets
239
+ .map((m) => m.rules_primary)
240
+ .filter((t) => typeof t === 'string' && t.length > 0);
241
+ if (texts.length === 0)
242
+ return '';
243
+ if (texts.length === 1)
244
+ return texts[0];
245
+ let prefix = texts[0];
246
+ for (const t of texts) {
247
+ while (!t.startsWith(prefix))
248
+ prefix = prefix.slice(0, -1);
249
+ if (!prefix)
250
+ break;
251
+ }
252
+ const suffixCandidates = texts.map((t) => t.slice(prefix.length));
253
+ let suffix = suffixCandidates[0];
254
+ for (const t of suffixCandidates) {
255
+ while (!t.endsWith(suffix))
256
+ suffix = suffix.slice(1);
257
+ if (!suffix)
258
+ break;
259
+ }
260
+ if (prefix.length + suffix.length < 20)
261
+ return texts[0];
262
+ const variables = texts.map((t) => t.slice(prefix.length, suffix.length ? t.length - suffix.length : undefined));
263
+ if (new Set(variables).size === 1)
264
+ return texts[0];
265
+ return prefix + '{x}' + suffix;
266
+ }
267
+ }
268
+ exports.KalshiNormalizer = KalshiNormalizer;
269
+ // -- Event sorting utility (exported for fetchEvents) -------------------------
270
+ function eventVolume(event) {
271
+ return (event.markets || []).reduce((sum, m) => sum + Number(m.volume || 0), 0);
272
+ }
273
+ function eventLiquidity(event) {
274
+ return (event.markets || []).reduce((sum, m) => sum + Number(m.open_interest || m.liquidity || 0), 0);
275
+ }
276
+ function eventNewest(event) {
277
+ const times = (event.markets || [])
278
+ .map((m) => (m.close_time ? new Date(m.close_time).getTime() : 0))
279
+ .filter((t) => t > 0);
280
+ return times.length > 0 ? Math.min(...times) : 0;
281
+ }
282
+ function sortRawEvents(events, sort) {
283
+ const copy = [...events];
284
+ if (sort === 'newest') {
285
+ copy.sort((a, b) => eventNewest(b) - eventNewest(a));
286
+ }
287
+ else if (sort === 'liquidity') {
288
+ copy.sort((a, b) => eventLiquidity(b) - eventLiquidity(a));
289
+ }
290
+ else {
291
+ copy.sort((a, b) => eventVolume(b) - eventVolume(a));
292
+ }
293
+ return copy;
294
+ }
@@ -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-03-14T16:22:11.425Z
3
+ * Generated at: 2026-03-14T21:28:31.877Z
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-03-14T16:22:11.425Z
6
+ * Generated at: 2026-03-14T21:28:31.877Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.limitlessApiSpec = {
@@ -0,0 +1,81 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { MarketFetchParams, EventFetchParams, OHLCVParams, TradesParams, MyTradesParams } from '../../BaseExchange';
3
+ import { IExchangeFetcher, FetcherContext } from '../interfaces';
4
+ export interface LimitlessRawMarket {
5
+ slug: string;
6
+ title?: string;
7
+ question?: string;
8
+ description?: string;
9
+ tokens?: Record<string, string>;
10
+ prices?: number[];
11
+ expirationTimestamp?: string;
12
+ volumeFormatted?: number;
13
+ volume?: number;
14
+ logo?: string | null;
15
+ categories?: string[];
16
+ tags?: string[];
17
+ markets?: LimitlessRawMarket[];
18
+ expired?: boolean;
19
+ winningOutcomeIndex?: number | null;
20
+ tradeType?: string;
21
+ [key: string]: unknown;
22
+ }
23
+ export interface LimitlessRawEvent {
24
+ slug: string;
25
+ title?: string;
26
+ question?: string;
27
+ description?: string;
28
+ logo?: string | null;
29
+ categories?: string[];
30
+ tags?: string[];
31
+ markets?: LimitlessRawMarket[];
32
+ expired?: boolean;
33
+ winningOutcomeIndex?: number | null;
34
+ [key: string]: unknown;
35
+ }
36
+ export interface LimitlessRawPricePoint {
37
+ price: number | string;
38
+ timestamp: number | string;
39
+ [key: string]: unknown;
40
+ }
41
+ export interface LimitlessRawOrderBookLevel {
42
+ price: number | string;
43
+ size: number | string;
44
+ [key: string]: unknown;
45
+ }
46
+ export interface LimitlessRawOrderBook {
47
+ bids: LimitlessRawOrderBookLevel[];
48
+ asks: LimitlessRawOrderBookLevel[];
49
+ timestamp?: number;
50
+ [key: string]: unknown;
51
+ }
52
+ export interface LimitlessRawTrade {
53
+ id?: string;
54
+ timestamp?: number;
55
+ createdAt?: string;
56
+ price?: string;
57
+ quantity?: string;
58
+ amount?: string;
59
+ side?: string;
60
+ orderId?: string;
61
+ [key: string]: unknown;
62
+ }
63
+ export declare class LimitlessFetcher implements IExchangeFetcher<LimitlessRawMarket, LimitlessRawEvent> {
64
+ private readonly ctx;
65
+ private readonly http;
66
+ private readonly apiKey?;
67
+ constructor(ctx: FetcherContext, http: AxiosInstance, apiKey?: string);
68
+ fetchRawMarkets(params?: MarketFetchParams): Promise<LimitlessRawMarket[]>;
69
+ fetchRawEvents(params: EventFetchParams): Promise<LimitlessRawEvent[]>;
70
+ fetchRawOHLCV(id: string, params: OHLCVParams): Promise<LimitlessRawPricePoint[]>;
71
+ fetchRawOrderBook(id: string): Promise<LimitlessRawOrderBook>;
72
+ fetchRawTrades(_id: string, _params: TradesParams): Promise<LimitlessRawTrade[]>;
73
+ fetchRawMyTrades(_params: MyTradesParams, apiKey: string): Promise<LimitlessRawTrade[]>;
74
+ fetchRawPositions(account: string): Promise<unknown[]>;
75
+ private fetchRawMarketBySlug;
76
+ private searchRawMarkets;
77
+ private fetchRawMarketsDefault;
78
+ private fetchRawEventBySlug;
79
+ private searchRawEvents;
80
+ private fetchRawEventsDefault;
81
+ }
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.LimitlessFetcher = void 0;
37
+ const utils_1 = require("./utils");
38
+ const errors_1 = require("./errors");
39
+ const validation_1 = require("../../utils/validation");
40
+ // ---------------------------------------------------------------------------
41
+ // Fetcher
42
+ // ---------------------------------------------------------------------------
43
+ class LimitlessFetcher {
44
+ ctx;
45
+ http;
46
+ apiKey;
47
+ constructor(ctx, http, apiKey) {
48
+ this.ctx = ctx;
49
+ this.http = http;
50
+ this.apiKey = apiKey;
51
+ }
52
+ async fetchRawMarkets(params) {
53
+ if (params?.status === 'inactive' || params?.status === 'closed') {
54
+ return [];
55
+ }
56
+ const { HttpClient, MarketFetcher } = await Promise.resolve().then(() => __importStar(require('@limitless-exchange/sdk')));
57
+ try {
58
+ const httpClient = new HttpClient({
59
+ baseURL: utils_1.LIMITLESS_API_URL,
60
+ apiKey: this.apiKey,
61
+ });
62
+ const marketFetcher = new MarketFetcher(httpClient);
63
+ if (params?.marketId) {
64
+ return this.fetchRawMarketBySlug(marketFetcher, params.marketId);
65
+ }
66
+ if (params?.slug) {
67
+ return this.fetchRawMarketBySlug(marketFetcher, params.slug);
68
+ }
69
+ if (params?.eventId) {
70
+ return this.fetchRawMarketBySlug(marketFetcher, params.eventId);
71
+ }
72
+ if (params?.query) {
73
+ return this.searchRawMarkets(params.query, params);
74
+ }
75
+ return this.fetchRawMarketsDefault(marketFetcher, params);
76
+ }
77
+ catch (error) {
78
+ throw errors_1.limitlessErrorMapper.mapError(error);
79
+ }
80
+ }
81
+ async fetchRawEvents(params) {
82
+ try {
83
+ if (params.eventId || params.slug) {
84
+ const slug = params.eventId || params.slug;
85
+ return this.fetchRawEventBySlug(slug);
86
+ }
87
+ if (params.query) {
88
+ return this.searchRawEvents(params);
89
+ }
90
+ return this.fetchRawEventsDefault(params);
91
+ }
92
+ catch (error) {
93
+ throw errors_1.limitlessErrorMapper.mapError(error);
94
+ }
95
+ }
96
+ async fetchRawOHLCV(id, params) {
97
+ (0, validation_1.validateIdFormat)(id, 'OHLCV');
98
+ if (!params.resolution) {
99
+ throw new Error('fetchOHLCV requires a resolution parameter. Use OHLCVParams with resolution specified.');
100
+ }
101
+ try {
102
+ const { mapIntervalToFidelity } = await Promise.resolve().then(() => __importStar(require('./utils')));
103
+ const fidelity = mapIntervalToFidelity(params.resolution);
104
+ const data = await this.ctx.callApi('MarketOrderbookController_getHistoricalPrice', { slug: id, fidelity });
105
+ return data.prices || [];
106
+ }
107
+ catch (error) {
108
+ throw errors_1.limitlessErrorMapper.mapError(error);
109
+ }
110
+ }
111
+ async fetchRawOrderBook(id) {
112
+ (0, validation_1.validateIdFormat)(id, 'OrderBook');
113
+ try {
114
+ const data = await this.ctx.callApi('MarketOrderbookController_getOrderbook', { slug: id });
115
+ return {
116
+ bids: data.bids || [],
117
+ asks: data.asks || [],
118
+ timestamp: data.timestamp,
119
+ };
120
+ }
121
+ catch (error) {
122
+ return { bids: [], asks: [] };
123
+ }
124
+ }
125
+ async fetchRawTrades(_id, _params) {
126
+ throw errors_1.limitlessErrorMapper.mapError(new Error('Limitless fetchTrades not implemented: No public market trades API available.'));
127
+ }
128
+ async fetchRawMyTrades(_params, apiKey) {
129
+ try {
130
+ const response = await this.http.get('https://api.limitless.exchange/portfolio/trades', {
131
+ headers: { Authorization: `Bearer ${apiKey}` },
132
+ });
133
+ const trades = Array.isArray(response.data) ? response.data : (response.data?.data || []);
134
+ return trades;
135
+ }
136
+ catch (error) {
137
+ throw errors_1.limitlessErrorMapper.mapError(error);
138
+ }
139
+ }
140
+ async fetchRawPositions(account) {
141
+ const result = await this.ctx.callApi('PublicPortfolioController_getPositions', { account });
142
+ return result?.data || result || [];
143
+ }
144
+ // -- Private helpers -------------------------------------------------------
145
+ async fetchRawMarketBySlug(marketFetcher, slug) {
146
+ const market = await marketFetcher.getMarket(slug);
147
+ return market ? [market] : [];
148
+ }
149
+ async searchRawMarkets(query, params) {
150
+ const data = await this.ctx.callApi('MarketSearchController_search', {
151
+ query: query,
152
+ limit: params?.limit || 250000,
153
+ page: params?.page || 1,
154
+ similarityThreshold: params?.similarityThreshold || 0.5,
155
+ });
156
+ const rawResults = data?.markets || [];
157
+ const allRawMarkets = [];
158
+ for (const res of rawResults) {
159
+ if (res.markets && Array.isArray(res.markets)) {
160
+ for (const child of res.markets) {
161
+ allRawMarkets.push(child);
162
+ }
163
+ }
164
+ else {
165
+ allRawMarkets.push(res);
166
+ }
167
+ }
168
+ return allRawMarkets;
169
+ }
170
+ async fetchRawMarketsDefault(marketFetcher, params) {
171
+ const limit = params?.limit || 250000;
172
+ const offset = params?.offset || 0;
173
+ let sortBy = 'lp_rewards';
174
+ if (params?.sort === 'volume') {
175
+ sortBy = 'high_value';
176
+ }
177
+ try {
178
+ const totalToFetch = limit + offset;
179
+ return await (0, utils_1.paginateLimitlessMarkets)(marketFetcher, totalToFetch, sortBy);
180
+ }
181
+ catch (error) {
182
+ throw errors_1.limitlessErrorMapper.mapError(error);
183
+ }
184
+ }
185
+ async fetchRawEventBySlug(slug) {
186
+ const { HttpClient, MarketFetcher } = await Promise.resolve().then(() => __importStar(require('@limitless-exchange/sdk')));
187
+ const httpClient = new HttpClient({ baseURL: utils_1.LIMITLESS_API_URL });
188
+ const marketFetcher = new MarketFetcher(httpClient);
189
+ const market = await marketFetcher.getMarket(slug);
190
+ return market ? [market] : [];
191
+ }
192
+ async searchRawEvents(params) {
193
+ const data = await this.ctx.callApi('MarketSearchController_search', {
194
+ query: params.query,
195
+ limit: params?.limit || 10000,
196
+ similarityThreshold: 0.5,
197
+ });
198
+ let markets = data?.markets || [];
199
+ const status = params?.status || 'active';
200
+ if (status === 'active') {
201
+ markets = markets.filter((m) => !m.expired && m.winningOutcomeIndex === null);
202
+ }
203
+ else if (status === 'inactive' || status === 'closed') {
204
+ markets = markets.filter((m) => m.expired === true || m.winningOutcomeIndex !== null);
205
+ }
206
+ return markets;
207
+ }
208
+ async fetchRawEventsDefault(params) {
209
+ const limit = params?.limit || 10000;
210
+ let page = 1;
211
+ const pageSize = 25;
212
+ const MAX_PAGES = 40;
213
+ const allGroups = [];
214
+ while (allGroups.length < limit && page <= MAX_PAGES) {
215
+ const response = await this.http.get(`${utils_1.LIMITLESS_API_URL}/markets/active`, {
216
+ params: {
217
+ page,
218
+ limit: pageSize,
219
+ tradeType: 'group',
220
+ sortBy: params?.sort === 'newest' ? 'newest' : params?.sort === 'liquidity' ? 'lp_rewards' : 'high_value',
221
+ }
222
+ });
223
+ const items = response.data?.data || response.data || [];
224
+ if (items.length === 0)
225
+ break;
226
+ for (const item of items) {
227
+ if (allGroups.length >= limit)
228
+ break;
229
+ allGroups.push(item);
230
+ }
231
+ if (items.length < pageSize)
232
+ break;
233
+ page++;
234
+ }
235
+ return allGroups;
236
+ }
237
+ }
238
+ exports.LimitlessFetcher = LimitlessFetcher;
@@ -37,16 +37,21 @@ export declare class LimitlessExchange extends PredictionMarketExchange {
37
37
  private client?;
38
38
  private wsConfig?;
39
39
  private ws?;
40
+ private readonly fetcher;
41
+ private readonly normalizer;
40
42
  constructor(options?: ExchangeCredentials | LimitlessExchangeOptions);
41
43
  get name(): string;
44
+ private getHeaders;
45
+ protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
46
+ protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
42
47
  fetchOHLCV(id: string, params: OHLCVParams): Promise<PriceCandle[]>;
43
48
  fetchOrderBook(id: string): Promise<OrderBook>;
44
49
  fetchTrades(id: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
50
+ fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
45
51
  createOrder(params: CreateOrderParams): Promise<Order>;
46
52
  cancelOrder(orderId: string): Promise<Order>;
47
53
  fetchOrder(orderId: string): Promise<Order>;
48
54
  fetchOpenOrders(marketId?: string): Promise<Order[]>;
49
- fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
50
55
  fetchClosedOrders(params?: OrderHistoryParams): Promise<Order[]>;
51
56
  fetchAllOrders(params?: OrderHistoryParams): Promise<Order[]>;
52
57
  fetchPositions(address?: string): Promise<Position[]>;
@@ -128,17 +133,9 @@ export declare class LimitlessExchange extends PredictionMarketExchange {
128
133
  unwatchAddress(address: string): Promise<void>;
129
134
  close(): Promise<void>;
130
135
  protected mapImplicitApiError(error: any): any;
131
- protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
132
- protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
133
136
  private getAddressOnChainBalance;
134
137
  private ensureClient;
135
- /**
136
- * Ensure authentication is initialized before trading operations.
137
- */
138
138
  private ensureAuth;
139
- /**
140
- * Initialize WebSocket with API key if available.
141
- */
142
139
  private ensureWs;
143
140
  /**
144
141
  * Fetch a composite activity snapshot for a Base-chain address from the Limitless