pmxt-core 2.9.2 → 2.9.3

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 (67) hide show
  1. package/dist/BaseExchange.d.ts +118 -4
  2. package/dist/BaseExchange.js +160 -7
  3. package/dist/exchanges/baozi/fetchEvents.js +16 -11
  4. package/dist/exchanges/baozi/index.d.ts +5 -0
  5. package/dist/exchanges/baozi/index.js +6 -0
  6. package/dist/exchanges/kalshi/api.d.ts +7 -1
  7. package/dist/exchanges/kalshi/api.js +11 -2
  8. package/dist/exchanges/kalshi/config.d.ts +103 -0
  9. package/dist/exchanges/kalshi/config.js +144 -0
  10. package/dist/exchanges/kalshi/fetchEvents.d.ts +2 -2
  11. package/dist/exchanges/kalshi/fetchEvents.js +138 -67
  12. package/dist/exchanges/kalshi/fetchMarkets.d.ts +2 -2
  13. package/dist/exchanges/kalshi/fetchMarkets.js +36 -25
  14. package/dist/exchanges/kalshi/fetchOHLCV.d.ts +3 -3
  15. package/dist/exchanges/kalshi/fetchOHLCV.js +20 -17
  16. package/dist/exchanges/kalshi/fetchOrderBook.d.ts +2 -0
  17. package/dist/exchanges/kalshi/fetchOrderBook.js +60 -0
  18. package/dist/exchanges/kalshi/fetchTrades.d.ts +3 -0
  19. package/dist/exchanges/kalshi/fetchTrades.js +32 -0
  20. package/dist/exchanges/kalshi/index.d.ts +20 -4
  21. package/dist/exchanges/kalshi/index.js +171 -90
  22. package/dist/exchanges/kalshi/kalshi.test.js +440 -157
  23. package/dist/exchanges/kalshi/utils.d.ts +1 -3
  24. package/dist/exchanges/kalshi/utils.js +15 -16
  25. package/dist/exchanges/kalshi/websocket.d.ts +4 -3
  26. package/dist/exchanges/kalshi/websocket.js +87 -61
  27. package/dist/exchanges/kalshi-demo/index.d.ts +10 -0
  28. package/dist/exchanges/kalshi-demo/index.js +23 -0
  29. package/dist/exchanges/limitless/api.d.ts +1 -1
  30. package/dist/exchanges/limitless/api.js +1 -1
  31. package/dist/exchanges/limitless/fetchEvents.d.ts +2 -1
  32. package/dist/exchanges/limitless/fetchEvents.js +95 -49
  33. package/dist/exchanges/limitless/fetchOHLCV.d.ts +2 -2
  34. package/dist/exchanges/limitless/index.d.ts +11 -3
  35. package/dist/exchanges/limitless/index.js +69 -1
  36. package/dist/exchanges/limitless/utils.js +1 -0
  37. package/dist/exchanges/myriad/api.d.ts +1 -1
  38. package/dist/exchanges/myriad/api.js +1 -1
  39. package/dist/exchanges/myriad/fetchOHLCV.d.ts +2 -2
  40. package/dist/exchanges/myriad/index.d.ts +9 -3
  41. package/dist/exchanges/myriad/index.js +34 -0
  42. package/dist/exchanges/myriad/utils.js +5 -1
  43. package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
  44. package/dist/exchanges/polymarket/api-clob.js +1 -1
  45. package/dist/exchanges/polymarket/api-data.d.ts +1 -1
  46. package/dist/exchanges/polymarket/api-data.js +1 -1
  47. package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
  48. package/dist/exchanges/polymarket/api-gamma.js +1 -1
  49. package/dist/exchanges/polymarket/auth.js +3 -1
  50. package/dist/exchanges/polymarket/fetchEvents.js +116 -80
  51. package/dist/exchanges/polymarket/fetchOHLCV.d.ts +2 -2
  52. package/dist/exchanges/polymarket/index.d.ts +30 -6
  53. package/dist/exchanges/polymarket/index.js +101 -31
  54. package/dist/exchanges/polymarket/utils.js +1 -0
  55. package/dist/exchanges/probable/api.d.ts +1 -1
  56. package/dist/exchanges/probable/api.js +1 -1
  57. package/dist/exchanges/probable/index.d.ts +45 -3
  58. package/dist/exchanges/probable/index.js +61 -0
  59. package/dist/exchanges/probable/utils.js +5 -1
  60. package/dist/index.d.ts +4 -0
  61. package/dist/index.js +5 -1
  62. package/dist/server/app.js +56 -48
  63. package/dist/server/utils/port-manager.js +1 -1
  64. package/dist/types.d.ts +29 -0
  65. package/dist/utils/throttler.d.ts +17 -0
  66. package/dist/utils/throttler.js +50 -0
  67. package/package.json +7 -4
@@ -32,15 +32,17 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
39
  exports.fetchEvents = fetchEvents;
37
40
  const utils_1 = require("./utils");
38
41
  const errors_1 = require("./errors");
39
- async function fetchEventBySlug(slug) {
42
+ const axios_1 = __importDefault(require("axios"));
43
+ async function fetchEventBySlug(slug, http = axios_1.default) {
40
44
  const { HttpClient, MarketFetcher } = await Promise.resolve().then(() => __importStar(require('@limitless-exchange/sdk')));
41
45
  const httpClient = new HttpClient({ baseURL: utils_1.LIMITLESS_API_URL });
42
- // TODO: Ideally inject http into HttpClient if supported, but SDK abstracts it.
43
- // For now, single market fetch uses SDK's internal client.
44
46
  const marketFetcher = new MarketFetcher(httpClient);
45
47
  const market = await marketFetcher.getMarket(slug);
46
48
  if (!market)
@@ -56,72 +58,116 @@ async function fetchEventBySlug(slug) {
56
58
  if (unifiedMarket)
57
59
  marketsList = [unifiedMarket];
58
60
  }
59
- return {
61
+ const unifiedEvent = {
60
62
  id: market.slug,
61
63
  title: market.title || market.question,
62
64
  description: market.description || '',
63
65
  slug: market.slug,
64
66
  markets: marketsList,
67
+ volume24h: marketsList.reduce((sum, m) => sum + m.volume24h, 0),
68
+ volume: marketsList.some(m => m.volume !== undefined) ? marketsList.reduce((sum, m) => sum + (m.volume ?? 0), 0) : undefined,
65
69
  url: `https://limitless.exchange/markets/${market.slug}`,
66
70
  image: market.logo || `https://limitless.exchange/api/og?slug=${market.slug}`,
67
71
  category: market.categories?.[0],
68
72
  tags: market.tags || []
69
73
  };
74
+ return unifiedEvent;
70
75
  }
71
- async function fetchEvents(params, callApi) {
76
+ function rawMarketToEvent(market) {
77
+ let marketsList = [];
78
+ if (market.markets && Array.isArray(market.markets)) {
79
+ marketsList = market.markets
80
+ .map((child) => (0, utils_1.mapMarketToUnified)(child))
81
+ .filter((m) => m !== null);
82
+ }
83
+ else {
84
+ const unifiedMarket = (0, utils_1.mapMarketToUnified)(market);
85
+ if (unifiedMarket)
86
+ marketsList = [unifiedMarket];
87
+ }
88
+ const unifiedEvent = {
89
+ id: market.slug,
90
+ title: market.title || market.question,
91
+ description: market.description || '',
92
+ slug: market.slug,
93
+ markets: marketsList,
94
+ volume24h: marketsList.reduce((sum, m) => sum + m.volume24h, 0),
95
+ volume: marketsList.some(m => m.volume !== undefined) ? marketsList.reduce((sum, m) => sum + (m.volume ?? 0), 0) : undefined,
96
+ url: `https://limitless.exchange/markets/${market.slug}`,
97
+ image: market.logo || `https://limitless.exchange/api/og?slug=${market.slug}`,
98
+ category: market.categories?.[0],
99
+ tags: market.tags || []
100
+ };
101
+ return unifiedEvent;
102
+ }
103
+ async function fetchEvents(params, callApi, http = axios_1.default) {
72
104
  try {
73
105
  // Handle eventId/slug lookup (same thing for Limitless)
74
106
  if (params.eventId || params.slug) {
75
107
  const slug = params.eventId || params.slug;
76
- const event = await fetchEventBySlug(slug);
108
+ const event = await fetchEventBySlug(slug, http);
77
109
  return event ? [event] : [];
78
110
  }
79
- // NOTE: The Limitless /markets/search endpoint currently only returns active/funded markets.
80
- // It does not include expired or resolved markets in search results.
81
- // Consequently, status 'inactive' will likely return 0 results and 'all' will only show active markets.
82
- const data = await callApi('MarketSearchController_search', {
83
- query: params.query,
84
- limit: params?.limit || 10000,
85
- similarityThreshold: 0.5,
86
- });
87
- let markets = data?.markets || [];
88
- // Filter by status based on expired/resolved state
89
- // Active: not expired and not resolved
90
- // Inactive: expired OR resolved (has winningOutcomeIndex)
91
- const status = params?.status || 'active';
92
- if (status === 'active') {
93
- markets = markets.filter((m) => !m.expired && m.winningOutcomeIndex === null);
111
+ // Query-based search: use the /markets/search endpoint
112
+ if (params.query) {
113
+ return await searchEvents(params, callApi);
94
114
  }
95
- else if (status === 'inactive' || status === 'closed') {
96
- markets = markets.filter((m) => m.expired === true || m.winningOutcomeIndex !== null);
97
- }
98
- // If status === 'all', don't filter
99
- return markets.map((market) => {
100
- let marketsList = [];
101
- if (market.markets && Array.isArray(market.markets)) {
102
- marketsList = market.markets
103
- .map((child) => (0, utils_1.mapMarketToUnified)(child))
104
- .filter((m) => m !== null);
105
- }
106
- else {
107
- const unifiedMarket = (0, utils_1.mapMarketToUnified)(market);
108
- if (unifiedMarket)
109
- marketsList = [unifiedMarket];
110
- }
111
- return {
112
- id: market.slug,
113
- title: market.title || market.question,
114
- description: market.description || '',
115
- slug: market.slug,
116
- markets: marketsList,
117
- url: `https://limitless.exchange/markets/${market.slug}`,
118
- image: market.logo || `https://limitless.exchange/api/og?slug=${market.slug}`,
119
- category: market.categories?.[0],
120
- tags: market.tags || []
121
- };
122
- });
115
+ // Default: fetch active group markets from /markets/active
116
+ // On Limitless, "events" = group markets (tradeType === 'group')
117
+ return await fetchEventsDefault(params, http);
123
118
  }
124
119
  catch (error) {
125
120
  throw errors_1.limitlessErrorMapper.mapError(error);
126
121
  }
127
122
  }
123
+ async function searchEvents(params, callApi) {
124
+ // NOTE: The Limitless /markets/search endpoint currently only returns active/funded markets.
125
+ const data = await callApi('MarketSearchController_search', {
126
+ query: params.query,
127
+ limit: params?.limit || 10000,
128
+ similarityThreshold: 0.5,
129
+ });
130
+ let markets = data?.markets || [];
131
+ const status = params?.status || 'active';
132
+ if (status === 'active') {
133
+ markets = markets.filter((m) => !m.expired && m.winningOutcomeIndex === null);
134
+ }
135
+ else if (status === 'inactive' || status === 'closed') {
136
+ markets = markets.filter((m) => m.expired === true || m.winningOutcomeIndex !== null);
137
+ }
138
+ return markets.map(rawMarketToEvent);
139
+ }
140
+ async function fetchEventsDefault(params, http = axios_1.default) {
141
+ // Limitless has no dedicated /events endpoint.
142
+ // Group markets (tradeType === 'group') are the semantic equivalent of events.
143
+ // We use GET /markets/active and filter for groups only.
144
+ const limit = params?.limit || 10000;
145
+ let page = 1;
146
+ const pageSize = 25; // Limitless API hard limit
147
+ const MAX_PAGES = 40; // Safety cap
148
+ const allGroups = [];
149
+ while (allGroups.length < limit && page <= MAX_PAGES) {
150
+ const response = await http.get(`${utils_1.LIMITLESS_API_URL}/markets/active`, {
151
+ params: {
152
+ page,
153
+ limit: pageSize,
154
+ tradeType: 'group',
155
+ sortBy: params?.sort === 'newest' ? 'newest' : params?.sort === 'liquidity' ? 'lp_rewards' : 'high_value',
156
+ }
157
+ });
158
+ const items = response.data?.data || response.data || [];
159
+ if (items.length === 0)
160
+ break;
161
+ for (const item of items) {
162
+ if (allGroups.length >= limit)
163
+ break;
164
+ const event = rawMarketToEvent(item);
165
+ allGroups.push(event);
166
+ }
167
+ // If the page returned fewer items than the page size, we've reached the end
168
+ if (items.length < pageSize)
169
+ break;
170
+ page++;
171
+ }
172
+ return allGroups;
173
+ }
@@ -1,7 +1,7 @@
1
- import { HistoryFilterParams, OHLCVParams } from '../../BaseExchange';
1
+ import { OHLCVParams } from '../../BaseExchange';
2
2
  import { PriceCandle } from '../../types';
3
3
  /**
4
4
  * Fetch historical price data (candles) for a specific market.
5
5
  * @param id - The market slug
6
6
  */
7
- export declare function fetchOHLCV(id: string, params: OHLCVParams | HistoryFilterParams, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>): Promise<PriceCandle[]>;
7
+ export declare function fetchOHLCV(id: string, params: OHLCVParams, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>): Promise<PriceCandle[]>;
@@ -1,5 +1,5 @@
1
- import { PredictionMarketExchange, MarketFetchParams, HistoryFilterParams, OHLCVParams, TradesParams, ExchangeCredentials, EventFetchParams } from '../../BaseExchange';
2
- import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, Order, Position, Balance, CreateOrderParams } from '../../types';
1
+ import { PredictionMarketExchange, MarketFetchParams, HistoryFilterParams, OHLCVParams, TradesParams, ExchangeCredentials, EventFetchParams, MyTradesParams, OrderHistoryParams } from '../../BaseExchange';
2
+ import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, UserTrade, Order, Position, Balance, CreateOrderParams } from '../../types';
3
3
  import { LimitlessWebSocketConfig } from './websocket';
4
4
  export type { LimitlessWebSocketConfig };
5
5
  export interface LimitlessExchangeOptions {
@@ -21,6 +21,11 @@ export declare class LimitlessExchange extends PredictionMarketExchange {
21
21
  fetchBalance: true;
22
22
  watchOrderBook: true;
23
23
  watchTrades: true;
24
+ fetchMyTrades: true;
25
+ fetchClosedOrders: true;
26
+ fetchAllOrders: true;
27
+ buildOrder: false;
28
+ submitOrder: false;
24
29
  };
25
30
  private auth?;
26
31
  private client?;
@@ -30,7 +35,7 @@ export declare class LimitlessExchange extends PredictionMarketExchange {
30
35
  protected mapImplicitApiError(error: any): any;
31
36
  protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
32
37
  protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
33
- fetchOHLCV(id: string, params: OHLCVParams | HistoryFilterParams): Promise<PriceCandle[]>;
38
+ fetchOHLCV(id: string, params: OHLCVParams): Promise<PriceCandle[]>;
34
39
  fetchOrderBook(id: string): Promise<OrderBook>;
35
40
  fetchTrades(id: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
36
41
  private ensureClient;
@@ -42,6 +47,9 @@ export declare class LimitlessExchange extends PredictionMarketExchange {
42
47
  cancelOrder(orderId: string): Promise<Order>;
43
48
  fetchOrder(orderId: string): Promise<Order>;
44
49
  fetchOpenOrders(marketId?: string): Promise<Order[]>;
50
+ fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
51
+ fetchClosedOrders(params?: OrderHistoryParams): Promise<Order[]>;
52
+ fetchAllOrders(params?: OrderHistoryParams): Promise<Order[]>;
45
53
  fetchPositions(): Promise<Position[]>;
46
54
  fetchBalance(): Promise<Balance[]>;
47
55
  private ws?;
@@ -31,6 +31,11 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
31
31
  fetchBalance: true,
32
32
  watchOrderBook: true,
33
33
  watchTrades: true,
34
+ fetchMyTrades: true,
35
+ fetchClosedOrders: true,
36
+ fetchAllOrders: true,
37
+ buildOrder: false,
38
+ submitOrder: false,
34
39
  };
35
40
  auth;
36
41
  client;
@@ -53,6 +58,7 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
53
58
  credentials = options;
54
59
  }
55
60
  super(credentials);
61
+ this.rateLimit = 200;
56
62
  this.wsConfig = wsConfig;
57
63
  // Initialize auth if API key or private key are provided
58
64
  // API key is now the primary authentication method
@@ -93,7 +99,7 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
93
99
  return (0, fetchMarkets_1.fetchMarkets)(params, apiKey, this.callApi.bind(this));
94
100
  }
95
101
  async fetchEventsImpl(params) {
96
- return (0, fetchEvents_1.fetchEvents)(params, this.callApi.bind(this));
102
+ return (0, fetchEvents_1.fetchEvents)(params, this.callApi.bind(this), this.http);
97
103
  }
98
104
  async fetchOHLCV(id, params) {
99
105
  return (0, fetchOHLCV_1.fetchOHLCV)(id, params, this.callApi.bind(this));
@@ -225,6 +231,68 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
225
231
  throw errors_1.limitlessErrorMapper.mapError(error);
226
232
  }
227
233
  }
234
+ async fetchMyTrades(params) {
235
+ const auth = this.ensureAuth();
236
+ try {
237
+ const response = await this.http.get('https://api.limitless.exchange/portfolio/trades', {
238
+ headers: { Authorization: `Bearer ${auth.getApiKey()}` },
239
+ });
240
+ const trades = Array.isArray(response.data) ? response.data : (response.data?.data || []);
241
+ return trades.map((t) => ({
242
+ id: t.id || String(t.timestamp),
243
+ timestamp: t.createdAt ? new Date(t.createdAt).getTime() : (t.timestamp || 0),
244
+ price: parseFloat(t.price || '0'),
245
+ amount: parseFloat(t.quantity || t.amount || '0'),
246
+ side: (t.side || '').toLowerCase() === 'buy' ? 'buy' : 'sell',
247
+ orderId: t.orderId,
248
+ }));
249
+ }
250
+ catch (error) {
251
+ throw errors_1.limitlessErrorMapper.mapError(error);
252
+ }
253
+ }
254
+ async fetchClosedOrders(params) {
255
+ const client = this.ensureClient();
256
+ if (!params?.marketId) {
257
+ console.warn('Limitless: fetchClosedOrders requires marketId (slug). Returning [].');
258
+ return [];
259
+ }
260
+ const orders = await client.getOrders(params.marketId, ['MATCHED']);
261
+ return orders.map((o) => ({
262
+ id: o.id,
263
+ marketId: params.marketId,
264
+ outcomeId: o.tokenId || 'unknown',
265
+ side: o.side.toLowerCase(),
266
+ type: 'limit',
267
+ price: parseFloat(o.price),
268
+ amount: parseFloat(o.quantity),
269
+ status: 'filled',
270
+ filled: parseFloat(o.quantity),
271
+ remaining: 0,
272
+ timestamp: o.createdAt ? new Date(o.createdAt).getTime() : Date.now(),
273
+ }));
274
+ }
275
+ async fetchAllOrders(params) {
276
+ const client = this.ensureClient();
277
+ if (!params?.marketId) {
278
+ console.warn('Limitless: fetchAllOrders requires marketId (slug). Returning [].');
279
+ return [];
280
+ }
281
+ const orders = await client.getOrders(params.marketId, ['LIVE', 'MATCHED']);
282
+ return orders.map((o) => ({
283
+ id: o.id,
284
+ marketId: params.marketId,
285
+ outcomeId: o.tokenId || 'unknown',
286
+ side: o.side.toLowerCase(),
287
+ type: 'limit',
288
+ price: parseFloat(o.price),
289
+ amount: parseFloat(o.quantity),
290
+ status: o.status === 'LIVE' ? 'open' : 'filled',
291
+ filled: o.status === 'MATCHED' ? parseFloat(o.quantity) : 0,
292
+ remaining: o.status === 'LIVE' ? parseFloat(o.quantity) : 0,
293
+ timestamp: o.createdAt ? new Date(o.createdAt).getTime() : Date.now(),
294
+ }));
295
+ }
228
296
  async fetchPositions() {
229
297
  const auth = this.ensureAuth();
230
298
  const address = auth.getAddress();
@@ -35,6 +35,7 @@ function mapMarketToUnified(market) {
35
35
  const um = {
36
36
  id: market.slug,
37
37
  marketId: market.slug,
38
+ eventId: market.slug,
38
39
  title: market.title || market.question,
39
40
  description: market.description,
40
41
  outcomes: outcomes,
@@ -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-02-19T07:57:20.660Z
3
+ * Generated at: 2026-03-04T17:45:20.632Z
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-02-19T07:57:20.660Z
6
+ * Generated at: 2026-03-04T17:45:20.632Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.myriadApiSpec = {
@@ -1,3 +1,3 @@
1
- import { OHLCVParams, HistoryFilterParams } from '../../BaseExchange';
1
+ import { OHLCVParams } from '../../BaseExchange';
2
2
  import { PriceCandle } from '../../types';
3
- export declare function fetchOHLCV(id: string, params: OHLCVParams | HistoryFilterParams, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>): Promise<PriceCandle[]>;
3
+ export declare function fetchOHLCV(id: string, params: OHLCVParams, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>): Promise<PriceCandle[]>;
@@ -1,5 +1,5 @@
1
- import { PredictionMarketExchange, MarketFilterParams, HistoryFilterParams, OHLCVParams, TradesParams, ExchangeCredentials, EventFetchParams } from '../../BaseExchange';
2
- import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, Balance, Order, Position, CreateOrderParams } from '../../types';
1
+ import { PredictionMarketExchange, MarketFilterParams, HistoryFilterParams, OHLCVParams, TradesParams, ExchangeCredentials, EventFetchParams, MyTradesParams } from '../../BaseExchange';
2
+ import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, UserTrade, Balance, Order, Position, CreateOrderParams } from '../../types';
3
3
  export declare class MyriadExchange extends PredictionMarketExchange {
4
4
  readonly has: {
5
5
  fetchMarkets: true;
@@ -15,6 +15,11 @@ export declare class MyriadExchange extends PredictionMarketExchange {
15
15
  fetchBalance: "emulated";
16
16
  watchOrderBook: "emulated";
17
17
  watchTrades: "emulated";
18
+ fetchMyTrades: true;
19
+ fetchClosedOrders: false;
20
+ fetchAllOrders: false;
21
+ buildOrder: false;
22
+ submitOrder: false;
18
23
  };
19
24
  private auth?;
20
25
  private ws?;
@@ -26,9 +31,10 @@ export declare class MyriadExchange extends PredictionMarketExchange {
26
31
  private ensureAuth;
27
32
  protected fetchMarketsImpl(params?: MarketFilterParams): Promise<UnifiedMarket[]>;
28
33
  protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
29
- fetchOHLCV(id: string, params: OHLCVParams | HistoryFilterParams): Promise<PriceCandle[]>;
34
+ fetchOHLCV(id: string, params: OHLCVParams): Promise<PriceCandle[]>;
30
35
  fetchOrderBook(id: string): Promise<OrderBook>;
31
36
  fetchTrades(id: string, params: TradesParams | HistoryFilterParams): Promise<Trade[]>;
37
+ fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
32
38
  createOrder(params: CreateOrderParams): Promise<Order>;
33
39
  cancelOrder(_orderId: string): Promise<Order>;
34
40
  fetchOrder(_orderId: string): Promise<Order>;
@@ -28,11 +28,17 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
28
28
  fetchBalance: 'emulated',
29
29
  watchOrderBook: 'emulated',
30
30
  watchTrades: 'emulated',
31
+ fetchMyTrades: true,
32
+ fetchClosedOrders: false,
33
+ fetchAllOrders: false,
34
+ buildOrder: false,
35
+ submitOrder: false,
31
36
  };
32
37
  auth;
33
38
  ws;
34
39
  constructor(credentials) {
35
40
  super(credentials);
41
+ this.rateLimit = 500;
36
42
  if (credentials?.apiKey) {
37
43
  this.auth = new auth_1.MyriadAuth(credentials);
38
44
  }
@@ -118,6 +124,34 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
118
124
  side: t.action === 'buy' ? 'buy' : 'sell',
119
125
  }));
120
126
  }
127
+ async fetchMyTrades(params) {
128
+ const walletAddress = this.ensureAuth().walletAddress;
129
+ if (!walletAddress) {
130
+ throw new errors_2.AuthenticationError('fetchMyTrades requires a wallet address. Pass privateKey as the wallet address in credentials.', 'Myriad');
131
+ }
132
+ const queryParams = { address: walletAddress };
133
+ if (params?.marketId) {
134
+ const parts = params.marketId.split(':');
135
+ if (parts.length >= 2)
136
+ queryParams.market_id = parts[1];
137
+ }
138
+ if (params?.since)
139
+ queryParams.since = Math.floor(params.since.getTime() / 1000);
140
+ if (params?.until)
141
+ queryParams.until = Math.floor(params.until.getTime() / 1000);
142
+ if (params?.limit)
143
+ queryParams.limit = params.limit;
144
+ const data = await this.callApi('getUsersEvents', queryParams);
145
+ const events = data.data || data.events || [];
146
+ const tradeEvents = events.filter((e) => e.action === 'buy' || e.action === 'sell');
147
+ return tradeEvents.map((t, i) => ({
148
+ id: `${t.blockNumber || t.timestamp}-${i}`,
149
+ timestamp: (t.timestamp || 0) * 1000,
150
+ price: t.shares > 0 ? Number(t.value) / Number(t.shares) : 0,
151
+ amount: Number(t.shares || 0),
152
+ side: t.action === 'buy' ? 'buy' : 'sell',
153
+ }));
154
+ }
121
155
  // ------------------------------------------------------------------------
122
156
  // Trading
123
157
  // ------------------------------------------------------------------------
@@ -65,6 +65,7 @@ function mapMarketToUnified(market) {
65
65
  }));
66
66
  const um = {
67
67
  marketId: `${market.networkId}:${market.id}`,
68
+ eventId: market.questionId ? String(market.questionId) : undefined,
68
69
  title: market.title || '',
69
70
  description: market.description || '',
70
71
  outcomes,
@@ -88,12 +89,15 @@ function mapQuestionToEvent(question) {
88
89
  if (um)
89
90
  markets.push(um);
90
91
  }
91
- return {
92
+ const unifiedEvent = {
92
93
  id: String(question.id),
93
94
  title: question.title || '',
94
95
  description: '',
95
96
  slug: String(question.id),
96
97
  markets,
98
+ volume24h: markets.reduce((sum, m) => sum + m.volume24h, 0),
99
+ volume: markets.some(m => m.volume !== undefined) ? markets.reduce((sum, m) => sum + (m.volume ?? 0), 0) : undefined,
97
100
  url: `https://myriad.markets`,
98
101
  };
102
+ return unifiedEvent;
99
103
  }
@@ -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-02-19T07:57:20.409Z
3
+ * Generated at: 2026-03-04T17:45:20.586Z
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-02-19T07:57:20.409Z
6
+ * Generated at: 2026-03-04T17:45:20.586Z
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-02-19T07:57:20.513Z
3
+ * Generated at: 2026-03-04T17:45:20.602Z
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-02-19T07:57:20.513Z
6
+ * Generated at: 2026-03-04T17:45:20.602Z
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-02-19T07:57:20.469Z
3
+ * Generated at: 2026-03-04T17:45:20.600Z
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-02-19T07:57:20.469Z
6
+ * Generated at: 2026-03-04T17:45:20.600Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketGammaSpec = {
@@ -99,7 +99,9 @@ class PolymarketAuth {
99
99
  try {
100
100
  // Polymarket Data API / Profiles endpoint
101
101
  // Path-based: https://data-api.polymarket.com/profiles/0x...
102
- const response = await axios_1.default.get(`https://data-api.polymarket.com/profiles/${address}`);
102
+ const response = await axios_1.default.get(`https://data-api.polymarket.com/profiles/${address}`, {
103
+ headers: { 'User-Agent': 'pmxt (https://github.com/pmxt-dev/pmxt)' }
104
+ });
103
105
  const profile = response.data;
104
106
  // console.log(`[PolymarketAuth] Profile for ${address}:`, JSON.stringify(profile));
105
107
  if (profile && profile.proxyAddress) {