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
@@ -47,12 +47,18 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
47
47
  fetchBalance: true,
48
48
  watchOrderBook: true,
49
49
  watchTrades: false,
50
+ fetchMyTrades: true,
51
+ fetchClosedOrders: false,
52
+ fetchAllOrders: false,
53
+ buildOrder: false,
54
+ submitOrder: false,
50
55
  };
51
56
  auth;
52
57
  ws;
53
58
  wsConfig;
54
59
  constructor(credentials, wsConfig) {
55
60
  super(credentials);
61
+ this.rateLimit = 500;
56
62
  this.wsConfig = wsConfig;
57
63
  if (credentials?.privateKey && credentials?.apiKey && credentials?.apiSecret && credentials?.passphrase) {
58
64
  this.auth = new auth_1.ProbableAuth(credentials);
@@ -82,9 +88,45 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
82
88
  async fetchEventsImpl(params) {
83
89
  return (0, fetchEvents_1.fetchEvents)(params, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }), (queryParams) => this.callApi('getPublicApiV1PublicSearch', queryParams));
84
90
  }
91
+ /**
92
+ * Fetch a single event by its numeric ID (Probable only).
93
+ *
94
+ * @param id - The numeric event ID
95
+ * @returns The UnifiedEvent, or null if not found
96
+ *
97
+ * @example-ts Get event by ID
98
+ * const event = await exchange.getEventById('42');
99
+ * if (event) {
100
+ * console.log(event.title);
101
+ * console.log(event.markets.length, 'markets');
102
+ * }
103
+ *
104
+ * @example-python Get event by ID
105
+ * event = exchange.get_event_by_id('42')
106
+ * if event:
107
+ * print(event.title)
108
+ * print(len(event.markets), 'markets')
109
+ */
85
110
  async getEventById(id) {
86
111
  return (0, fetchEvents_1.fetchEventById)(id, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
87
112
  }
113
+ /**
114
+ * Fetch a single event by its URL slug (Probable only).
115
+ *
116
+ * @param slug - The event's URL slug (e.g. `"trump-2024-election"`)
117
+ * @returns The UnifiedEvent, or null if not found
118
+ *
119
+ * @example-ts Get event by slug
120
+ * const event = await exchange.getEventBySlug('trump-2024-election');
121
+ * if (event) {
122
+ * console.log(event.title);
123
+ * }
124
+ *
125
+ * @example-python Get event by slug
126
+ * event = exchange.get_event_by_slug('trump-2024-election')
127
+ * if event:
128
+ * print(event.title)
129
+ */
88
130
  async getEventBySlug(slug) {
89
131
  return (0, fetchEvents_1.fetchEventBySlug)(slug, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
90
132
  }
@@ -142,6 +184,25 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
142
184
  }
143
185
  return candles;
144
186
  }
187
+ async fetchMyTrades(params) {
188
+ const auth = this.ensureAuth();
189
+ const address = auth.getAddress();
190
+ const queryParams = { user: address };
191
+ if (params?.limit)
192
+ queryParams.limit = params.limit;
193
+ const data = await this.callApi('getPublicApiV1Trades', queryParams);
194
+ const trades = Array.isArray(data) ? data : (data.data || []);
195
+ return trades.map((t) => ({
196
+ id: String(t.tradeId || t.id || t.timestamp),
197
+ timestamp: typeof t.time === 'number'
198
+ ? (t.time > 1e12 ? t.time : t.time * 1000)
199
+ : Date.now(),
200
+ price: parseFloat(t.price || '0'),
201
+ amount: parseFloat(t.qty || t.size || t.amount || '0'),
202
+ side: (t.side || '').toLowerCase() === 'buy' ? 'buy' : 'sell',
203
+ orderId: t.orderId,
204
+ }));
205
+ }
145
206
  // --------------------------------------------------------------------------
146
207
  // Trading Methods
147
208
  // --------------------------------------------------------------------------
@@ -29,6 +29,7 @@ function mapMarketToUnified(market, event) {
29
29
  }
30
30
  const um = {
31
31
  marketId: String(market.id),
32
+ eventId: event ? String(event.id) : (market.event_id ? String(market.event_id) : undefined),
32
33
  title: market.question || market.title || '',
33
34
  description: market.description || '',
34
35
  outcomes,
@@ -56,17 +57,20 @@ function mapEventToUnified(event) {
56
57
  markets.push(mapped);
57
58
  }
58
59
  }
59
- return {
60
+ const unifiedEvent = {
60
61
  id: String(event.id),
61
62
  title: event.title || '',
62
63
  description: event.description || '',
63
64
  slug: event.slug || '',
64
65
  markets,
66
+ volume24h: markets.reduce((sum, m) => sum + m.volume24h, 0),
67
+ volume: markets.some(m => m.volume !== undefined) ? markets.reduce((sum, m) => sum + (m.volume ?? 0), 0) : undefined,
65
68
  url: `https://probable.markets/events/${event.slug || event.id}`,
66
69
  image: event.icon || event.image || undefined,
67
70
  category: event.category || undefined,
68
71
  tags: event.tags || [],
69
72
  };
73
+ return unifiedEvent;
70
74
  }
71
75
  async function enrichMarketsWithPrices(markets, callMidpoint) {
72
76
  const outcomes = [];
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from './errors';
6
6
  export * from './exchanges/polymarket';
7
7
  export * from './exchanges/limitless';
8
8
  export * from './exchanges/kalshi';
9
+ export * from './exchanges/kalshi-demo';
9
10
  export * from './exchanges/probable';
10
11
  export * from './exchanges/baozi';
11
12
  export * from './exchanges/myriad';
@@ -15,6 +16,7 @@ export * from './server/utils/lock-file';
15
16
  import { PolymarketExchange } from './exchanges/polymarket';
16
17
  import { LimitlessExchange } from './exchanges/limitless';
17
18
  import { KalshiExchange } from './exchanges/kalshi';
19
+ import { KalshiDemoExchange } from './exchanges/kalshi-demo';
18
20
  import { ProbableExchange } from './exchanges/probable';
19
21
  import { BaoziExchange } from './exchanges/baozi';
20
22
  import { MyriadExchange } from './exchanges/myriad';
@@ -22,6 +24,7 @@ declare const pmxt: {
22
24
  Polymarket: typeof PolymarketExchange;
23
25
  Limitless: typeof LimitlessExchange;
24
26
  Kalshi: typeof KalshiExchange;
27
+ KalshiDemo: typeof KalshiDemoExchange;
25
28
  Probable: typeof ProbableExchange;
26
29
  Baozi: typeof BaoziExchange;
27
30
  Myriad: typeof MyriadExchange;
@@ -29,6 +32,7 @@ declare const pmxt: {
29
32
  export declare const Polymarket: typeof PolymarketExchange;
30
33
  export declare const Limitless: typeof LimitlessExchange;
31
34
  export declare const Kalshi: typeof KalshiExchange;
35
+ export declare const KalshiDemo: typeof KalshiDemoExchange;
32
36
  export declare const Probable: typeof ProbableExchange;
33
37
  export declare const Baozi: typeof BaoziExchange;
34
38
  export declare const Myriad: typeof MyriadExchange;
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.Myriad = exports.Baozi = exports.Probable = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.parseOpenApiSpec = void 0;
17
+ exports.Myriad = exports.Baozi = exports.Probable = exports.KalshiDemo = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.parseOpenApiSpec = void 0;
18
18
  __exportStar(require("./BaseExchange"), exports);
19
19
  __exportStar(require("./types"), exports);
20
20
  __exportStar(require("./utils/math"), exports);
@@ -24,6 +24,7 @@ __exportStar(require("./errors"), exports);
24
24
  __exportStar(require("./exchanges/polymarket"), exports);
25
25
  __exportStar(require("./exchanges/limitless"), exports);
26
26
  __exportStar(require("./exchanges/kalshi"), exports);
27
+ __exportStar(require("./exchanges/kalshi-demo"), exports);
27
28
  __exportStar(require("./exchanges/probable"), exports);
28
29
  __exportStar(require("./exchanges/baozi"), exports);
29
30
  __exportStar(require("./exchanges/myriad"), exports);
@@ -33,6 +34,7 @@ __exportStar(require("./server/utils/lock-file"), exports);
33
34
  const polymarket_1 = require("./exchanges/polymarket");
34
35
  const limitless_1 = require("./exchanges/limitless");
35
36
  const kalshi_1 = require("./exchanges/kalshi");
37
+ const kalshi_demo_1 = require("./exchanges/kalshi-demo");
36
38
  const probable_1 = require("./exchanges/probable");
37
39
  const baozi_1 = require("./exchanges/baozi");
38
40
  const myriad_1 = require("./exchanges/myriad");
@@ -40,6 +42,7 @@ const pmxt = {
40
42
  Polymarket: polymarket_1.PolymarketExchange,
41
43
  Limitless: limitless_1.LimitlessExchange,
42
44
  Kalshi: kalshi_1.KalshiExchange,
45
+ KalshiDemo: kalshi_demo_1.KalshiDemoExchange,
43
46
  Probable: probable_1.ProbableExchange,
44
47
  Baozi: baozi_1.BaoziExchange,
45
48
  Myriad: myriad_1.MyriadExchange
@@ -47,6 +50,7 @@ const pmxt = {
47
50
  exports.Polymarket = polymarket_1.PolymarketExchange;
48
51
  exports.Limitless = limitless_1.LimitlessExchange;
49
52
  exports.Kalshi = kalshi_1.KalshiExchange;
53
+ exports.KalshiDemo = kalshi_demo_1.KalshiDemoExchange;
50
54
  exports.Probable = probable_1.ProbableExchange;
51
55
  exports.Baozi = baozi_1.BaoziExchange;
52
56
  exports.Myriad = myriad_1.MyriadExchange;
@@ -9,6 +9,7 @@ const cors_1 = __importDefault(require("cors"));
9
9
  const polymarket_1 = require("../exchanges/polymarket");
10
10
  const limitless_1 = require("../exchanges/limitless");
11
11
  const kalshi_1 = require("../exchanges/kalshi");
12
+ const kalshi_demo_1 = require("../exchanges/kalshi-demo");
12
13
  const probable_1 = require("../exchanges/probable");
13
14
  const baozi_1 = require("../exchanges/baozi");
14
15
  const myriad_1 = require("../exchanges/myriad");
@@ -18,44 +19,34 @@ const defaultExchanges = {
18
19
  polymarket: null,
19
20
  limitless: null,
20
21
  kalshi: null,
22
+ "kalshi-demo": null,
21
23
  probable: null,
22
24
  baozi: null,
23
- myriad: null
25
+ myriad: null,
24
26
  };
25
27
  async function startServer(port, accessToken) {
26
28
  const app = (0, express_1.default)();
27
29
  app.use((0, cors_1.default)());
28
30
  app.use(express_1.default.json());
29
31
  // Health check (public)
30
- app.get('/health', (req, res) => {
31
- res.json({ status: 'ok', timestamp: Date.now() });
32
+ app.get("/health", (req, res) => {
33
+ res.json({ status: "ok", timestamp: Date.now() });
32
34
  });
33
35
  // Auth Middleware
34
36
  app.use((req, res, next) => {
35
- const token = req.headers['x-pmxt-access-token'];
37
+ const token = req.headers["x-pmxt-access-token"];
36
38
  if (!token || token !== accessToken) {
37
- res.status(401).json({ success: false, error: 'Unauthorized: Invalid or missing access token' });
39
+ res.status(401).json({
40
+ success: false,
41
+ error: "Unauthorized: Invalid or missing access token",
42
+ });
38
43
  return;
39
44
  }
40
45
  next();
41
46
  });
42
- // Capability map endpoint: GET /api/:exchange/has
43
- app.get('/api/:exchange/has', (req, res, next) => {
44
- try {
45
- const exchangeName = req.params.exchange.toLowerCase();
46
- if (!defaultExchanges[exchangeName]) {
47
- defaultExchanges[exchangeName] = createExchange(exchangeName);
48
- }
49
- const exchange = defaultExchanges[exchangeName];
50
- res.json({ success: true, data: exchange.has });
51
- }
52
- catch (error) {
53
- next(error);
54
- }
55
- });
56
47
  // API endpoint: POST /api/:exchange/:method
57
48
  // Body: { args: any[], credentials?: ExchangeCredentials }
58
- app.post('/api/:exchange/:method', async (req, res, next) => {
49
+ app.post("/api/:exchange/:method", async (req, res, next) => {
59
50
  try {
60
51
  const exchangeName = req.params.exchange.toLowerCase();
61
52
  const methodName = req.params.method;
@@ -74,18 +65,20 @@ async function startServer(port, accessToken) {
74
65
  }
75
66
  exchange = defaultExchanges[exchangeName];
76
67
  }
77
- // Set verbose flag if present in request
78
- if (req.body.verbose === true) {
68
+ // Apply verbose logging if requested via header
69
+ if (req.headers["x-pmxt-verbose"] === "true") {
79
70
  exchange.verbose = true;
80
71
  }
81
72
  else {
82
73
  // Reset to false for singleton instances to avoid leaking state between requests
83
- // For new instances it defaults to false anyway
84
74
  exchange.verbose = false;
85
75
  }
86
76
  // 2. Validate Method
87
- if (typeof exchange[methodName] !== 'function') {
88
- res.status(404).json({ success: false, error: `Method '${methodName}' not found on ${exchangeName}` });
77
+ if (typeof exchange[methodName] !== "function") {
78
+ res.status(404).json({
79
+ success: false,
80
+ error: `Method '${methodName}' not found on ${exchangeName}`,
81
+ });
89
82
  return;
90
83
  }
91
84
  // 3. Execute with direct argument spreading
@@ -98,7 +91,7 @@ async function startServer(port, accessToken) {
98
91
  });
99
92
  // Error handler
100
93
  app.use((error, req, res, next) => {
101
- console.error('API Error:', error);
94
+ console.error("API Error:", error);
102
95
  if (error.stack) {
103
96
  console.error(error.stack);
104
97
  }
@@ -109,72 +102,87 @@ async function startServer(port, accessToken) {
109
102
  error: {
110
103
  message: error.message,
111
104
  code: error.code,
112
- retryable: error.retryable
113
- }
105
+ retryable: error.retryable,
106
+ },
114
107
  };
115
108
  // Add exchange context if available
116
109
  if (error.exchange) {
117
110
  errorResponse.error.exchange = error.exchange;
118
111
  }
119
112
  // Add retryAfter for rate limit errors
120
- if ('retryAfter' in error && error.retryAfter !== undefined) {
113
+ if ("retryAfter" in error && error.retryAfter !== undefined) {
121
114
  errorResponse.error.retryAfter = error.retryAfter;
122
115
  }
123
116
  // Add stack trace in development
124
- if (process.env.NODE_ENV === 'development') {
117
+ if (process.env.NODE_ENV === "development") {
125
118
  errorResponse.error.stack = error.stack;
126
119
  }
127
- res.status(error.status).json(errorResponse);
120
+ res.status(error.status || 500).json(errorResponse);
128
121
  return;
129
122
  }
130
123
  // Handle generic errors
131
124
  res.status(error.status || 500).json({
132
125
  success: false,
133
126
  error: {
134
- message: error.message || 'Internal server error',
135
- stack: process.env.NODE_ENV === 'development' ? error.stack : undefined
136
- }
127
+ message: error.message || "Internal server error",
128
+ stack: process.env.NODE_ENV === "development" ? error.stack : undefined,
129
+ },
137
130
  });
138
131
  });
139
- return app.listen(port, '127.0.0.1');
132
+ return app.listen(port, "127.0.0.1");
140
133
  }
141
134
  function createExchange(name, credentials) {
142
135
  switch (name) {
143
- case 'polymarket':
136
+ case "polymarket":
144
137
  return new polymarket_1.PolymarketExchange({
145
- privateKey: credentials?.privateKey || process.env.POLYMARKET_PK || process.env.POLYMARKET_PRIVATE_KEY,
138
+ privateKey: credentials?.privateKey ||
139
+ process.env.POLYMARKET_PK ||
140
+ process.env.POLYMARKET_PRIVATE_KEY,
146
141
  apiKey: credentials?.apiKey || process.env.POLYMARKET_API_KEY,
147
142
  apiSecret: credentials?.apiSecret || process.env.POLYMARKET_API_SECRET,
148
143
  passphrase: credentials?.passphrase || process.env.POLYMARKET_PASSPHRASE,
149
144
  funderAddress: credentials?.funderAddress,
150
- signatureType: credentials?.signatureType
145
+ signatureType: credentials?.signatureType,
151
146
  });
152
- case 'limitless':
147
+ case "limitless":
153
148
  return new limitless_1.LimitlessExchange({
154
- privateKey: credentials?.privateKey || process.env.LIMITLESS_PK || process.env.LIMITLESS_PRIVATE_KEY,
149
+ privateKey: credentials?.privateKey ||
150
+ process.env.LIMITLESS_PK ||
151
+ process.env.LIMITLESS_PRIVATE_KEY,
155
152
  apiKey: credentials?.apiKey || process.env.LIMITLESS_API_KEY,
156
153
  apiSecret: credentials?.apiSecret || process.env.LIMITLESS_API_SECRET,
157
- passphrase: credentials?.passphrase || process.env.LIMITLESS_PASSPHRASE
154
+ passphrase: credentials?.passphrase || process.env.LIMITLESS_PASSPHRASE,
158
155
  });
159
- case 'kalshi':
156
+ case "kalshi":
160
157
  return new kalshi_1.KalshiExchange({
161
- apiKey: credentials?.apiKey || process.env.KALSHI_API_KEY,
162
- privateKey: credentials?.privateKey || process.env.KALSHI_PRIVATE_KEY
158
+ credentials: {
159
+ apiKey: credentials?.apiKey || process.env.KALSHI_API_KEY,
160
+ privateKey: credentials?.privateKey || process.env.KALSHI_PRIVATE_KEY,
161
+ },
162
+ });
163
+ case "kalshi-demo":
164
+ return new kalshi_demo_1.KalshiDemoExchange({
165
+ credentials: {
166
+ apiKey: credentials?.apiKey || process.env.KALSHI_API_KEY,
167
+ privateKey: credentials?.privateKey || process.env.KALSHI_PRIVATE_KEY,
168
+ },
163
169
  });
164
- case 'probable':
170
+ case "probable":
165
171
  return new probable_1.ProbableExchange({
166
172
  apiKey: credentials?.apiKey || process.env.PROBABLE_API_KEY,
167
173
  apiSecret: credentials?.apiSecret || process.env.PROBABLE_API_SECRET,
168
174
  passphrase: credentials?.passphrase || process.env.PROBABLE_PASSPHRASE,
169
175
  privateKey: credentials?.privateKey || process.env.PROBABLE_PRIVATE_KEY,
170
176
  });
171
- case 'baozi':
177
+ case "baozi":
172
178
  return new baozi_1.BaoziExchange({
173
179
  privateKey: credentials?.privateKey || process.env.BAOZI_PRIVATE_KEY,
174
180
  });
175
- case 'myriad':
181
+ case "myriad":
176
182
  return new myriad_1.MyriadExchange({
177
- apiKey: credentials?.apiKey || process.env.MYRIAD_API_KEY || process.env.MYRIAD_PROD,
183
+ apiKey: credentials?.apiKey ||
184
+ process.env.MYRIAD_API_KEY ||
185
+ process.env.MYRIAD_PROD,
178
186
  privateKey: credentials?.privateKey || process.env.MYRIAD_WALLET_ADDRESS,
179
187
  });
180
188
  default:
@@ -61,7 +61,7 @@ class PortManager {
61
61
  server.close();
62
62
  resolve(true);
63
63
  });
64
- server.listen(port);
64
+ server.listen(port, '127.0.0.1');
65
65
  });
66
66
  }
67
67
  }
package/dist/types.d.ts CHANGED
@@ -14,6 +14,8 @@ export interface UnifiedEvent {
14
14
  description: string;
15
15
  slug: string;
16
16
  markets: UnifiedMarket[];
17
+ volume24h: number;
18
+ volume?: number;
17
19
  url: string;
18
20
  image?: string;
19
21
  category?: string;
@@ -22,6 +24,7 @@ export interface UnifiedEvent {
22
24
  export interface UnifiedMarket {
23
25
  /** The unique identifier for this market */
24
26
  marketId: string;
27
+ eventId?: string;
25
28
  title: string;
26
29
  description: string;
27
30
  slug?: string;
@@ -66,6 +69,9 @@ export interface Trade {
66
69
  amount: number;
67
70
  side: 'buy' | 'sell' | 'unknown';
68
71
  }
72
+ export interface UserTrade extends Trade {
73
+ orderId?: string;
74
+ }
69
75
  export interface Order {
70
76
  id: string;
71
77
  marketId: string;
@@ -107,3 +113,26 @@ export interface CreateOrderParams {
107
113
  tickSize?: number;
108
114
  negRisk?: boolean;
109
115
  }
116
+ export interface BuiltOrder {
117
+ /** The exchange name this order was built for. */
118
+ exchange: string;
119
+ /** The original params used to build this order. */
120
+ params: CreateOrderParams;
121
+ /**
122
+ * For CLOB exchanges (Polymarket): the EIP-712 signed order
123
+ * ready to POST to the exchange's order endpoint.
124
+ */
125
+ signedOrder?: Record<string, unknown>;
126
+ /**
127
+ * For on-chain AMM exchanges: the EVM transaction payload.
128
+ * Reserved for future exchanges; no current exchange populates this.
129
+ */
130
+ tx?: {
131
+ to: string;
132
+ data: string;
133
+ value: string;
134
+ chainId: number;
135
+ };
136
+ /** The raw, exchange-native payload. Always present. */
137
+ raw: unknown;
138
+ }
@@ -0,0 +1,17 @@
1
+ export declare class Throttler {
2
+ private tokens;
3
+ private queue;
4
+ private running;
5
+ private lastTimestamp;
6
+ private refillRate;
7
+ private capacity;
8
+ private delay;
9
+ constructor(config: {
10
+ refillRate: number;
11
+ capacity: number;
12
+ delay: number;
13
+ });
14
+ throttle(cost?: number): Promise<void>;
15
+ private loop;
16
+ private sleep;
17
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Throttler = void 0;
4
+ class Throttler {
5
+ tokens = 0;
6
+ queue = [];
7
+ running = false;
8
+ lastTimestamp = 0;
9
+ refillRate;
10
+ capacity;
11
+ delay;
12
+ constructor(config) {
13
+ this.refillRate = config.refillRate;
14
+ this.capacity = config.capacity;
15
+ this.delay = config.delay;
16
+ }
17
+ async throttle(cost = 1) {
18
+ return new Promise((resolve) => {
19
+ this.queue.push({ resolve, cost });
20
+ if (!this.running) {
21
+ this.running = true;
22
+ this.loop();
23
+ }
24
+ });
25
+ }
26
+ async loop() {
27
+ while (this.queue.length > 0) {
28
+ const now = Date.now();
29
+ if (this.lastTimestamp > 0) {
30
+ const elapsed = now - this.lastTimestamp;
31
+ this.tokens = Math.min(this.tokens + elapsed * this.refillRate, this.capacity);
32
+ }
33
+ this.lastTimestamp = now;
34
+ const head = this.queue[0];
35
+ if (this.tokens >= 0) {
36
+ this.tokens -= head.cost;
37
+ head.resolve();
38
+ this.queue.shift();
39
+ }
40
+ else {
41
+ await this.sleep(this.delay);
42
+ }
43
+ }
44
+ this.running = false;
45
+ }
46
+ sleep(ms) {
47
+ return new Promise((resolve) => setTimeout(resolve, ms));
48
+ }
49
+ }
50
+ exports.Throttler = Throttler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxt-core",
3
- "version": "2.9.2",
3
+ "version": "2.9.3",
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,12 +29,15 @@
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.9.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.9.2,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.9.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.9.3,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",
37
- "generate:sdk:all": "npm run generate:sdk:python && npm run generate:sdk:typescript && npm run generate:docs"
37
+ "generate:openapi": "node scripts/generate-openapi.js",
38
+ "generate:python-exchanges": "node scripts/generate-python-exchanges.js",
39
+ "generate:compliance": "node scripts/generate-compliance.js",
40
+ "generate:sdk:all": "npm run generate:openapi && npm run generate:sdk:python && npm run generate:python-exchanges && npm run generate:sdk:typescript && npm run generate:docs && npm run generate:compliance"
38
41
  },
39
42
  "keywords": [],
40
43
  "author": "",