pmxt-core 2.8.0 → 2.9.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 (83) hide show
  1. package/dist/BaseExchange.d.ts +48 -0
  2. package/dist/BaseExchange.js +116 -0
  3. package/dist/exchanges/kalshi/api.d.ts +1763 -0
  4. package/dist/exchanges/kalshi/api.js +2554 -0
  5. package/dist/exchanges/kalshi/fetchEvents.d.ts +3 -2
  6. package/dist/exchanges/kalshi/fetchEvents.js +9 -16
  7. package/dist/exchanges/kalshi/fetchMarkets.d.ts +3 -2
  8. package/dist/exchanges/kalshi/fetchMarkets.js +24 -32
  9. package/dist/exchanges/kalshi/fetchOHLCV.d.ts +1 -2
  10. package/dist/exchanges/kalshi/fetchOHLCV.js +9 -11
  11. package/dist/exchanges/kalshi/index.d.ts +2 -1
  12. package/dist/exchanges/kalshi/index.js +161 -183
  13. package/dist/exchanges/kalshi/kalshi.test.js +51 -31
  14. package/dist/exchanges/limitless/api.d.ts +555 -0
  15. package/dist/exchanges/limitless/api.js +863 -0
  16. package/dist/exchanges/limitless/fetchEvents.d.ts +1 -2
  17. package/dist/exchanges/limitless/fetchEvents.js +9 -15
  18. package/dist/exchanges/limitless/fetchMarkets.d.ts +1 -2
  19. package/dist/exchanges/limitless/fetchMarkets.js +9 -16
  20. package/dist/exchanges/limitless/fetchOHLCV.d.ts +1 -2
  21. package/dist/exchanges/limitless/fetchOHLCV.js +2 -11
  22. package/dist/exchanges/limitless/fetchOrderBook.d.ts +1 -2
  23. package/dist/exchanges/limitless/fetchOrderBook.js +2 -11
  24. package/dist/exchanges/limitless/index.d.ts +1 -0
  25. package/dist/exchanges/limitless/index.js +28 -7
  26. package/dist/exchanges/limitless/websocket.d.ts +2 -1
  27. package/dist/exchanges/limitless/websocket.js +6 -4
  28. package/dist/exchanges/myriad/api.d.ts +294 -0
  29. package/dist/exchanges/myriad/api.js +690 -0
  30. package/dist/exchanges/myriad/fetchOHLCV.d.ts +1 -2
  31. package/dist/exchanges/myriad/fetchOHLCV.js +3 -11
  32. package/dist/exchanges/myriad/fetchOrderBook.d.ts +1 -2
  33. package/dist/exchanges/myriad/fetchOrderBook.js +3 -11
  34. package/dist/exchanges/myriad/index.d.ts +2 -0
  35. package/dist/exchanges/myriad/index.js +116 -103
  36. package/dist/exchanges/myriad/websocket.d.ts +2 -2
  37. package/dist/exchanges/myriad/websocket.js +28 -6
  38. package/dist/exchanges/polymarket/api-clob.d.ts +346 -0
  39. package/dist/exchanges/polymarket/api-clob.js +517 -0
  40. package/dist/exchanges/polymarket/api-data.d.ts +789 -0
  41. package/dist/exchanges/polymarket/api-data.js +860 -0
  42. package/dist/exchanges/polymarket/api-gamma.d.ts +556 -0
  43. package/dist/exchanges/polymarket/api-gamma.js +1161 -0
  44. package/dist/exchanges/polymarket/fetchEvents.js +0 -68
  45. package/dist/exchanges/polymarket/fetchOHLCV.d.ts +1 -2
  46. package/dist/exchanges/polymarket/fetchOHLCV.js +4 -10
  47. package/dist/exchanges/polymarket/fetchOrderBook.d.ts +1 -2
  48. package/dist/exchanges/polymarket/fetchOrderBook.js +2 -10
  49. package/dist/exchanges/polymarket/fetchTrades.d.ts +1 -2
  50. package/dist/exchanges/polymarket/fetchTrades.js +2 -11
  51. package/dist/exchanges/polymarket/index.d.ts +10 -0
  52. package/dist/exchanges/polymarket/index.js +110 -5
  53. package/dist/exchanges/probable/api.d.ts +605 -0
  54. package/dist/exchanges/probable/api.js +887 -0
  55. package/dist/exchanges/probable/fetchEvents.d.ts +3 -3
  56. package/dist/exchanges/probable/fetchEvents.js +28 -25
  57. package/dist/exchanges/probable/fetchMarkets.d.ts +1 -1
  58. package/dist/exchanges/probable/fetchMarkets.js +25 -21
  59. package/dist/exchanges/probable/index.d.ts +1 -0
  60. package/dist/exchanges/probable/index.js +92 -10
  61. package/dist/exchanges/probable/utils.d.ts +1 -2
  62. package/dist/exchanges/probable/utils.js +4 -11
  63. package/dist/index.d.ts +1 -0
  64. package/dist/index.js +3 -1
  65. package/dist/utils/openapi.d.ts +9 -0
  66. package/dist/utils/openapi.js +59 -0
  67. package/package.json +4 -3
  68. package/dist/exchanges/kalshi/fetchOrderBook.d.ts +0 -3
  69. package/dist/exchanges/kalshi/fetchOrderBook.js +0 -59
  70. package/dist/exchanges/kalshi/fetchTrades.d.ts +0 -4
  71. package/dist/exchanges/kalshi/fetchTrades.js +0 -31
  72. package/dist/exchanges/limitless/fetchPositions.d.ts +0 -2
  73. package/dist/exchanges/limitless/fetchPositions.js +0 -34
  74. package/dist/exchanges/myriad/fetchTrades.d.ts +0 -4
  75. package/dist/exchanges/myriad/fetchTrades.js +0 -62
  76. package/dist/exchanges/polymarket/fetchPositions.d.ts +0 -2
  77. package/dist/exchanges/polymarket/fetchPositions.js +0 -34
  78. package/dist/exchanges/probable/fetchOHLCV.d.ts +0 -4
  79. package/dist/exchanges/probable/fetchOHLCV.js +0 -83
  80. package/dist/exchanges/probable/fetchOrderBook.d.ts +0 -3
  81. package/dist/exchanges/probable/fetchOrderBook.js +0 -37
  82. package/dist/exchanges/probable/fetchPositions.d.ts +0 -2
  83. package/dist/exchanges/probable/fetchPositions.js +0 -33
@@ -1,11 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.fetchOHLCV = fetchOHLCV;
7
- const axios_1 = __importDefault(require("axios"));
8
- const utils_1 = require("./utils");
9
4
  const errors_1 = require("./errors");
10
5
  // Myriad provides price charts via GET /markets/:id with these timeframes:
11
6
  // - 24h: 5-minute buckets (max 288)
@@ -27,7 +22,7 @@ function selectTimeframe(interval) {
27
22
  return '7d';
28
23
  }
29
24
  }
30
- async function fetchOHLCV(id, params, headers, http = axios_1.default) {
25
+ async function fetchOHLCV(id, params, callApi) {
31
26
  if (!params.resolution) {
32
27
  throw new Error('fetchOHLCV requires a resolution parameter.');
33
28
  }
@@ -41,11 +36,8 @@ async function fetchOHLCV(id, params, headers, http = axios_1.default) {
41
36
  const networkId = parts[0];
42
37
  const marketId = parts[1];
43
38
  const outcomeId = parts.length >= 3 ? parts[2] : undefined;
44
- const response = await http.get(`${utils_1.BASE_URL}/markets/${marketId}`, {
45
- params: { network_id: Number(networkId) },
46
- headers,
47
- });
48
- const market = response.data.data || response.data;
39
+ const response = await callApi('getMarkets', { id: marketId, network_id: Number(networkId) });
40
+ const market = response.data || response;
49
41
  const outcomes = market.outcomes || [];
50
42
  // Find the target outcome
51
43
  let targetOutcome = outcomes[0];
@@ -1,3 +1,2 @@
1
- import { AxiosInstance } from 'axios';
2
1
  import { OrderBook } from '../../types';
3
- export declare function fetchOrderBook(id: string, headers?: Record<string, string>, http?: AxiosInstance): Promise<OrderBook>;
2
+ export declare function fetchOrderBook(id: string, callApi: (operationId: string, params?: Record<string, any>) => Promise<any>): Promise<OrderBook>;
@@ -1,16 +1,11 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.fetchOrderBook = fetchOrderBook;
7
- const axios_1 = __importDefault(require("axios"));
8
- const utils_1 = require("./utils");
9
4
  const errors_1 = require("./errors");
10
5
  // Myriad is AMM-based -- there is no native order book.
11
6
  // We synthesize a minimal order book from the current outcome price
12
7
  // and quote data to give callers a consistent interface.
13
- async function fetchOrderBook(id, headers, http = axios_1.default) {
8
+ async function fetchOrderBook(id, callApi) {
14
9
  try {
15
10
  // id format: {networkId}:{marketId}:{outcomeId}
16
11
  const parts = id.split(':');
@@ -19,11 +14,8 @@ async function fetchOrderBook(id, headers, http = axios_1.default) {
19
14
  }
20
15
  const [networkId, marketId, outcomeId] = parts;
21
16
  // Fetch the market to get current prices
22
- const response = await http.get(`${utils_1.BASE_URL}/markets/${marketId}`, {
23
- params: { network_id: Number(networkId) },
24
- headers,
25
- });
26
- const market = response.data.data || response.data;
17
+ const response = await callApi('getMarkets', { id: marketId, network_id: Number(networkId) });
18
+ const market = response.data || response;
27
19
  const outcomes = market.outcomes || [];
28
20
  const outcome = outcomes.find((o) => String(o.id) === outcomeId) || outcomes[0];
29
21
  if (!outcome) {
@@ -21,6 +21,8 @@ export declare class MyriadExchange extends PredictionMarketExchange {
21
21
  constructor(credentials?: ExchangeCredentials);
22
22
  get name(): string;
23
23
  private getHeaders;
24
+ protected sign(_method: string, _path: string, _params: Record<string, any>): Record<string, string>;
25
+ protected mapImplicitApiError(error: any): any;
24
26
  private ensureAuth;
25
27
  protected fetchMarketsImpl(params?: MarketFilterParams): Promise<UnifiedMarket[]>;
26
28
  protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
@@ -6,12 +6,13 @@ const fetchMarkets_1 = require("./fetchMarkets");
6
6
  const fetchEvents_1 = require("./fetchEvents");
7
7
  const fetchOHLCV_1 = require("./fetchOHLCV");
8
8
  const fetchOrderBook_1 = require("./fetchOrderBook");
9
- const fetchTrades_1 = require("./fetchTrades");
10
9
  const auth_1 = require("./auth");
11
10
  const websocket_1 = require("./websocket");
12
11
  const errors_1 = require("./errors");
13
12
  const errors_2 = require("../../errors");
14
13
  const utils_1 = require("./utils");
14
+ const openapi_1 = require("../../utils/openapi");
15
+ const api_1 = require("./api");
15
16
  class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
16
17
  has = {
17
18
  fetchMarkets: true,
@@ -35,6 +36,8 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
35
36
  if (credentials?.apiKey) {
36
37
  this.auth = new auth_1.MyriadAuth(credentials);
37
38
  }
39
+ const descriptor = (0, openapi_1.parseOpenApiSpec)(api_1.myriadApiSpec, utils_1.BASE_URL);
40
+ this.defineImplicitApi(descriptor);
38
41
  }
39
42
  get name() {
40
43
  return 'Myriad';
@@ -45,6 +48,12 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
45
48
  }
46
49
  return { 'Content-Type': 'application/json' };
47
50
  }
51
+ sign(_method, _path, _params) {
52
+ return this.getHeaders();
53
+ }
54
+ mapImplicitApiError(error) {
55
+ throw errors_1.myriadErrorMapper.mapError(error);
56
+ }
48
57
  ensureAuth() {
49
58
  if (!this.auth) {
50
59
  throw new errors_2.AuthenticationError('This operation requires authentication. Initialize MyriadExchange with credentials (apiKey).', 'Myriad');
@@ -61,70 +70,97 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
61
70
  return (0, fetchEvents_1.fetchEvents)(params, this.getHeaders(), this.http);
62
71
  }
63
72
  async fetchOHLCV(id, params) {
64
- return (0, fetchOHLCV_1.fetchOHLCV)(id, params, this.getHeaders(), this.http);
73
+ return (0, fetchOHLCV_1.fetchOHLCV)(id, params, this.callApi.bind(this));
65
74
  }
66
75
  async fetchOrderBook(id) {
67
- return (0, fetchOrderBook_1.fetchOrderBook)(id, this.getHeaders(), this.http);
76
+ return (0, fetchOrderBook_1.fetchOrderBook)(id, this.callApi.bind(this));
68
77
  }
69
78
  async fetchTrades(id, params) {
70
79
  if ('resolution' in params && params.resolution !== undefined) {
71
80
  console.warn('[pmxt] Warning: The "resolution" parameter is deprecated for fetchTrades() and will be ignored. ' +
72
81
  'It will be removed in v3.0.0. Please remove it from your code.');
73
82
  }
74
- return (0, fetchTrades_1.fetchTrades)(id, params, this.getHeaders(), this.http);
83
+ const parts = id.split(':');
84
+ if (parts.length < 2) {
85
+ throw new Error(`Invalid Myriad ID format: "${id}". Expected "{networkId}:{marketId}" or "{networkId}:{marketId}:{outcomeId}".`);
86
+ }
87
+ const [networkId, marketId] = parts;
88
+ const outcomeId = parts.length >= 3 ? parts[2] : undefined;
89
+ const ensureDate = (d) => {
90
+ if (typeof d === 'string') {
91
+ if (!d.endsWith('Z') && !d.match(/[+-]\d{2}:\d{2}$/))
92
+ return new Date(d + 'Z');
93
+ return new Date(d);
94
+ }
95
+ return d;
96
+ };
97
+ const queryParams = {
98
+ id: marketId,
99
+ network_id: Number(networkId),
100
+ page: 1,
101
+ limit: params.limit || 100,
102
+ };
103
+ if (params.start)
104
+ queryParams.since = Math.floor(ensureDate(params.start).getTime() / 1000);
105
+ if (params.end)
106
+ queryParams.until = Math.floor(ensureDate(params.end).getTime() / 1000);
107
+ const data = await this.callApi('getMarketsEvents', queryParams);
108
+ const events = data.data || data.events || [];
109
+ const tradeEvents = events.filter((e) => e.action === 'buy' || e.action === 'sell');
110
+ const filtered = outcomeId
111
+ ? tradeEvents.filter((e) => String(e.outcomeId) === outcomeId)
112
+ : tradeEvents;
113
+ return filtered.map((t, index) => ({
114
+ id: `${t.blockNumber || t.timestamp}-${index}`,
115
+ timestamp: (t.timestamp || 0) * 1000,
116
+ price: t.shares > 0 ? Number(t.value) / Number(t.shares) : 0,
117
+ amount: Number(t.shares || 0),
118
+ side: t.action === 'buy' ? 'buy' : 'sell',
119
+ }));
75
120
  }
76
121
  // ------------------------------------------------------------------------
77
122
  // Trading
78
123
  // ------------------------------------------------------------------------
79
124
  async createOrder(params) {
80
- try {
81
- const auth = this.ensureAuth();
82
- const headers = auth.getHeaders();
83
- // Parse composite marketId: {networkId}:{marketId}
84
- const parts = params.marketId.split(':');
85
- if (parts.length < 2) {
86
- throw new Error(`Invalid marketId format: "${params.marketId}". Expected "{networkId}:{marketId}".`);
87
- }
88
- const [networkId, marketId] = parts;
89
- // Parse outcomeId: {networkId}:{marketId}:{outcomeId}
90
- const outcomeParts = params.outcomeId.split(':');
91
- const outcomeId = outcomeParts.length >= 3 ? Number(outcomeParts[2]) : Number(outcomeParts[0]);
92
- const quoteBody = {
93
- market_id: Number(marketId),
94
- outcome_id: outcomeId,
95
- network_id: Number(networkId),
96
- action: params.side,
97
- };
98
- if (params.side === 'buy') {
99
- quoteBody.value = params.amount;
100
- }
101
- else {
102
- quoteBody.shares = params.amount;
103
- }
104
- if (params.price) {
105
- // Use price as slippage tolerance for AMM
106
- quoteBody.slippage = 0.01;
107
- }
108
- const response = await this.http.post(`${utils_1.BASE_URL}/markets/quote`, quoteBody, { headers });
109
- const quote = response.data;
110
- return {
111
- id: `myriad-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
112
- marketId: params.marketId,
113
- outcomeId: params.outcomeId,
114
- side: params.side,
115
- type: 'market', // AMM only supports market orders
116
- price: quote.price_average,
117
- amount: params.side === 'buy' ? quote.value : quote.shares,
118
- status: 'pending',
119
- filled: 0,
120
- remaining: params.side === 'buy' ? quote.value : quote.shares,
121
- timestamp: Date.now(),
122
- fee: quote.fees ? (quote.fees.fee + quote.fees.treasury + quote.fees.distributor) : undefined,
123
- };
125
+ // Parse composite marketId: {networkId}:{marketId}
126
+ const parts = params.marketId.split(':');
127
+ if (parts.length < 2) {
128
+ throw new Error(`Invalid marketId format: "${params.marketId}". Expected "{networkId}:{marketId}".`);
129
+ }
130
+ const [networkId, marketId] = parts;
131
+ // Parse outcomeId: {networkId}:{marketId}:{outcomeId}
132
+ const outcomeParts = params.outcomeId.split(':');
133
+ const outcomeId = outcomeParts.length >= 3 ? Number(outcomeParts[2]) : Number(outcomeParts[0]);
134
+ const quoteBody = {
135
+ market_id: Number(marketId),
136
+ outcome_id: outcomeId,
137
+ network_id: Number(networkId),
138
+ action: params.side,
139
+ };
140
+ if (params.side === 'buy') {
141
+ quoteBody.value = params.amount;
124
142
  }
125
- catch (error) {
126
- throw errors_1.myriadErrorMapper.mapError(error);
143
+ else {
144
+ quoteBody.shares = params.amount;
127
145
  }
146
+ if (params.price) {
147
+ quoteBody.slippage = 0.01;
148
+ }
149
+ const quote = await this.callApi('postMarketsQuote', quoteBody);
150
+ return {
151
+ id: `myriad-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
152
+ marketId: params.marketId,
153
+ outcomeId: params.outcomeId,
154
+ side: params.side,
155
+ type: 'market',
156
+ price: quote.price_average,
157
+ amount: params.side === 'buy' ? quote.value : quote.shares,
158
+ status: 'pending',
159
+ filled: 0,
160
+ remaining: params.side === 'buy' ? quote.value : quote.shares,
161
+ timestamp: Date.now(),
162
+ fee: quote.fees ? (quote.fees.fee + quote.fees.treasury + quote.fees.distributor) : undefined,
163
+ };
128
164
  }
129
165
  async cancelOrder(_orderId) {
130
166
  throw new Error('cancelOrder() is not supported by Myriad (AMM-based exchange, no open orders)');
@@ -136,62 +172,39 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
136
172
  return []; // AMM: no open orders
137
173
  }
138
174
  async fetchPositions() {
139
- try {
140
- const auth = this.ensureAuth();
141
- const headers = auth.getHeaders();
142
- const walletAddress = auth.walletAddress;
143
- if (!walletAddress) {
144
- throw new errors_2.AuthenticationError('fetchPositions requires a wallet address. Pass privateKey as the wallet address in credentials.', 'Myriad');
145
- }
146
- const response = await this.http.get(`${utils_1.BASE_URL}/users/${walletAddress}/portfolio`, {
147
- params: { limit: 100 },
148
- headers,
149
- });
150
- const items = response.data.data || response.data.items || [];
151
- return items.map((pos) => ({
152
- marketId: `${pos.networkId}:${pos.marketId}`,
153
- outcomeId: `${pos.networkId}:${pos.marketId}:${pos.outcomeId}`,
154
- outcomeLabel: pos.outcomeTitle || `Outcome ${pos.outcomeId}`,
155
- size: Number(pos.shares || 0),
156
- entryPrice: Number(pos.price || 0),
157
- currentPrice: Number(pos.value || 0) / Math.max(Number(pos.shares || 1), 1),
158
- unrealizedPnL: Number(pos.profit || 0),
159
- }));
160
- }
161
- catch (error) {
162
- throw errors_1.myriadErrorMapper.mapError(error);
175
+ const walletAddress = this.ensureAuth().walletAddress;
176
+ if (!walletAddress) {
177
+ throw new errors_2.AuthenticationError('fetchPositions requires a wallet address. Pass privateKey as the wallet address in credentials.', 'Myriad');
163
178
  }
179
+ const data = await this.callApi('getUsersPortfolio', { address: walletAddress, limit: 100 });
180
+ const items = data.data || data.items || [];
181
+ return items.map((pos) => ({
182
+ marketId: `${pos.networkId}:${pos.marketId}`,
183
+ outcomeId: `${pos.networkId}:${pos.marketId}:${pos.outcomeId}`,
184
+ outcomeLabel: pos.outcomeTitle || `Outcome ${pos.outcomeId}`,
185
+ size: Number(pos.shares || 0),
186
+ entryPrice: Number(pos.price || 0),
187
+ currentPrice: Number(pos.value || 0) / Math.max(Number(pos.shares || 1), 1),
188
+ unrealizedPnL: Number(pos.profit || 0),
189
+ }));
164
190
  }
165
191
  async fetchBalance() {
166
- // Myriad is on-chain; balances are per-chain token balances.
167
- // The API doesn't expose a balance endpoint directly.
168
- // We approximate from portfolio positions.
169
- try {
170
- const auth = this.ensureAuth();
171
- const headers = auth.getHeaders();
172
- const walletAddress = auth.walletAddress;
173
- if (!walletAddress) {
174
- throw new errors_2.AuthenticationError('fetchBalance requires a wallet address. Pass privateKey as the wallet address in credentials.', 'Myriad');
175
- }
176
- const response = await this.http.get(`${utils_1.BASE_URL}/users/${walletAddress}/portfolio`, {
177
- params: { limit: 100 },
178
- headers,
179
- });
180
- const items = response.data.data || response.data.items || [];
181
- let totalValue = 0;
182
- for (const pos of items) {
183
- totalValue += Number(pos.value || 0);
184
- }
185
- return [{
186
- currency: 'USDC',
187
- total: totalValue,
188
- available: 0, // Cannot determine on-chain balance via API
189
- locked: totalValue,
190
- }];
192
+ const walletAddress = this.ensureAuth().walletAddress;
193
+ if (!walletAddress) {
194
+ throw new errors_2.AuthenticationError('fetchBalance requires a wallet address. Pass privateKey as the wallet address in credentials.', 'Myriad');
191
195
  }
192
- catch (error) {
193
- throw errors_1.myriadErrorMapper.mapError(error);
196
+ const data = await this.callApi('getUsersPortfolio', { address: walletAddress, limit: 100 });
197
+ const items = data.data || data.items || [];
198
+ let totalValue = 0;
199
+ for (const pos of items) {
200
+ totalValue += Number(pos.value || 0);
194
201
  }
202
+ return [{
203
+ currency: 'USDC',
204
+ total: totalValue,
205
+ available: 0,
206
+ locked: totalValue,
207
+ }];
195
208
  }
196
209
  // ------------------------------------------------------------------------
197
210
  // WebSocket (poll-based)
@@ -199,14 +212,14 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
199
212
  async watchOrderBook(id, _limit) {
200
213
  this.ensureAuth();
201
214
  if (!this.ws) {
202
- this.ws = new websocket_1.MyriadWebSocket(this.getHeaders());
215
+ this.ws = new websocket_1.MyriadWebSocket(this.callApi.bind(this));
203
216
  }
204
217
  return this.ws.watchOrderBook(id);
205
218
  }
206
219
  async watchTrades(id, _since, _limit) {
207
220
  this.ensureAuth();
208
221
  if (!this.ws) {
209
- this.ws = new websocket_1.MyriadWebSocket(this.getHeaders());
222
+ this.ws = new websocket_1.MyriadWebSocket(this.callApi.bind(this));
210
223
  }
211
224
  return this.ws.watchTrades(id);
212
225
  }
@@ -1,6 +1,6 @@
1
1
  import { OrderBook, Trade } from '../../types';
2
2
  export declare class MyriadWebSocket {
3
- private headers;
3
+ private callApi;
4
4
  private pollInterval;
5
5
  private orderBookTimers;
6
6
  private tradeTimers;
@@ -8,7 +8,7 @@ export declare class MyriadWebSocket {
8
8
  private tradeResolvers;
9
9
  private lastTradeTimestamp;
10
10
  private closed;
11
- constructor(headers: Record<string, string>, pollInterval?: number);
11
+ constructor(callApi: (operationId: string, params?: Record<string, any>) => Promise<any>, pollInterval?: number);
12
12
  watchOrderBook(id: string): Promise<OrderBook>;
13
13
  watchTrades(id: string): Promise<Trade[]>;
14
14
  close(): Promise<void>;
@@ -2,13 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MyriadWebSocket = void 0;
4
4
  const fetchOrderBook_1 = require("./fetchOrderBook");
5
- const fetchTrades_1 = require("./fetchTrades");
6
5
  // Myriad API v2 does not expose a WebSocket endpoint.
7
6
  // We implement a poll-based fallback that resolves promises
8
7
  // on each polling interval, matching the CCXT Pro async pattern.
9
8
  const DEFAULT_POLL_INTERVAL = 5000; // 5 seconds
10
9
  class MyriadWebSocket {
11
- headers;
10
+ callApi;
12
11
  pollInterval;
13
12
  orderBookTimers = new Map();
14
13
  tradeTimers = new Map();
@@ -16,8 +15,8 @@ class MyriadWebSocket {
16
15
  tradeResolvers = new Map();
17
16
  lastTradeTimestamp = new Map();
18
17
  closed = false;
19
- constructor(headers, pollInterval) {
20
- this.headers = headers;
18
+ constructor(callApi, pollInterval) {
19
+ this.callApi = callApi;
21
20
  this.pollInterval = pollInterval || DEFAULT_POLL_INTERVAL;
22
21
  }
23
22
  async watchOrderBook(id) {
@@ -62,7 +61,7 @@ class MyriadWebSocket {
62
61
  startOrderBookPolling(id) {
63
62
  const poll = async () => {
64
63
  try {
65
- const book = await (0, fetchOrderBook_1.fetchOrderBook)(id, this.headers);
64
+ const book = await (0, fetchOrderBook_1.fetchOrderBook)(id, this.callApi);
66
65
  const resolvers = this.orderBookResolvers.get(id) || [];
67
66
  this.orderBookResolvers.set(id, []);
68
67
  for (const resolve of resolvers) {
@@ -81,8 +80,31 @@ class MyriadWebSocket {
81
80
  startTradePolling(id) {
82
81
  const poll = async () => {
83
82
  try {
83
+ const parts = id.split(':');
84
+ const [networkId, marketId] = parts;
85
+ const outcomeId = parts.length >= 3 ? parts[2] : undefined;
84
86
  const since = this.lastTradeTimestamp.get(id);
85
- const trades = await (0, fetchTrades_1.fetchTrades)(id, { limit: 50, start: since ? new Date(since) : undefined }, this.headers);
87
+ const queryParams = {
88
+ id: marketId,
89
+ network_id: Number(networkId),
90
+ page: 1,
91
+ limit: 50,
92
+ };
93
+ if (since)
94
+ queryParams.since = Math.floor(since / 1000);
95
+ const data = await this.callApi('getMarketsEvents', queryParams);
96
+ const events = data.data || data.events || [];
97
+ const tradeEvents = events.filter((e) => e.action === 'buy' || e.action === 'sell');
98
+ const filtered = outcomeId
99
+ ? tradeEvents.filter((e) => String(e.outcomeId) === outcomeId)
100
+ : tradeEvents;
101
+ const trades = filtered.map((t, index) => ({
102
+ id: `${t.blockNumber || t.timestamp}-${index}`,
103
+ timestamp: (t.timestamp || 0) * 1000,
104
+ price: t.shares > 0 ? Number(t.value) / Number(t.shares) : 0,
105
+ amount: Number(t.shares || 0),
106
+ side: t.action === 'buy' ? 'buy' : 'sell',
107
+ }));
86
108
  if (trades.length > 0) {
87
109
  const maxTs = Math.max(...trades.map(t => t.timestamp));
88
110
  this.lastTradeTimestamp.set(id, maxTs + 1);