pmxt-core 2.37.1 → 2.37.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.
- package/dist/exchanges/baozi/websocket.d.ts +6 -0
- package/dist/exchanges/baozi/websocket.js +7 -1
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/kalshi/websocket.d.ts +2 -0
- package/dist/exchanges/kalshi/websocket.js +7 -3
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/opinion/websocket.d.ts +2 -0
- package/dist/exchanges/opinion/websocket.js +5 -2
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/polymarket/websocket.d.ts +2 -0
- package/dist/exchanges/polymarket/websocket.js +5 -2
- package/dist/exchanges/polymarket_us/websocket.d.ts +6 -1
- package/dist/exchanges/polymarket_us/websocket.js +8 -3
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/probable/websocket.d.ts +2 -0
- package/dist/exchanges/probable/websocket.js +3 -1
- package/dist/utils/watch-timeout.d.ts +18 -0
- package/dist/utils/watch-timeout.js +35 -0
- package/package.json +3 -3
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { Connection } from '@solana/web3.js';
|
|
2
2
|
import { OrderBook } from '../../types';
|
|
3
|
+
export interface BaoziWebSocketConfig {
|
|
4
|
+
/** Timeout in ms for watch methods to receive data (default: 30000). 0 = no timeout. */
|
|
5
|
+
watchTimeoutMs?: number;
|
|
6
|
+
}
|
|
3
7
|
/**
|
|
4
8
|
* Uses Solana's onAccountChange to watch market PDA updates.
|
|
5
9
|
* When the account data changes (new bet placed), we re-parse
|
|
6
10
|
* and emit a new synthetic order book.
|
|
7
11
|
*/
|
|
8
12
|
export declare class BaoziWebSocket {
|
|
13
|
+
private config;
|
|
9
14
|
private orderBookResolvers;
|
|
10
15
|
private subscriptions;
|
|
16
|
+
constructor(config?: BaoziWebSocketConfig);
|
|
11
17
|
watchOrderBook(connection: Connection, outcomeId: string): Promise<OrderBook>;
|
|
12
18
|
private resolveOrderBook;
|
|
13
19
|
close(connection: Connection): Promise<void>;
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BaoziWebSocket = void 0;
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
|
+
const watch_timeout_1 = require("../../utils/watch-timeout");
|
|
5
6
|
const utils_1 = require("./utils");
|
|
6
7
|
/**
|
|
7
8
|
* Uses Solana's onAccountChange to watch market PDA updates.
|
|
@@ -9,8 +10,12 @@ const utils_1 = require("./utils");
|
|
|
9
10
|
* and emit a new synthetic order book.
|
|
10
11
|
*/
|
|
11
12
|
class BaoziWebSocket {
|
|
13
|
+
config;
|
|
12
14
|
orderBookResolvers = new Map();
|
|
13
15
|
subscriptions = new Map();
|
|
16
|
+
constructor(config = {}) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
14
19
|
async watchOrderBook(connection, outcomeId) {
|
|
15
20
|
const marketPubkey = outcomeId.replace(/-YES$|-NO$|-\d+$/, '');
|
|
16
21
|
const marketKey = new web3_js_1.PublicKey(marketPubkey);
|
|
@@ -45,12 +50,13 @@ class BaoziWebSocket {
|
|
|
45
50
|
}, 'confirmed');
|
|
46
51
|
this.subscriptions.set(marketPubkey, subId);
|
|
47
52
|
}
|
|
48
|
-
|
|
53
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
49
54
|
if (!this.orderBookResolvers.has(marketPubkey)) {
|
|
50
55
|
this.orderBookResolvers.set(marketPubkey, []);
|
|
51
56
|
}
|
|
52
57
|
this.orderBookResolvers.get(marketPubkey).push({ resolve, reject });
|
|
53
58
|
});
|
|
59
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBook('${outcomeId}')`);
|
|
54
60
|
}
|
|
55
61
|
resolveOrderBook(marketPubkey, orderBook) {
|
|
56
62
|
const resolvers = this.orderBookResolvers.get(marketPubkey);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
3
|
-
* Generated at: 2026-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.700Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const kalshiApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.kalshiApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
6
|
-
* Generated at: 2026-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.700Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.kalshiApiSpec = {
|
|
@@ -5,6 +5,8 @@ export interface KalshiWebSocketConfig {
|
|
|
5
5
|
wsUrl?: string;
|
|
6
6
|
/** Reconnection interval in milliseconds (default: 5000) */
|
|
7
7
|
reconnectIntervalMs?: number;
|
|
8
|
+
/** Timeout in ms for watch methods to receive data (default: 30000). 0 = no timeout. */
|
|
9
|
+
watchTimeoutMs?: number;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* Kalshi WebSocket implementation for real-time order book and trade streaming.
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.KalshiWebSocket = void 0;
|
|
7
7
|
const ws_1 = __importDefault(require("ws"));
|
|
8
|
+
const watch_timeout_1 = require("../../utils/watch-timeout");
|
|
8
9
|
/**
|
|
9
10
|
* Kalshi WebSocket implementation for real-time order book and trade streaming.
|
|
10
11
|
* Follows CCXT Pro-style async iterator pattern.
|
|
@@ -340,12 +341,13 @@ class KalshiWebSocket {
|
|
|
340
341
|
this.subscribeToOrderbook([ticker]);
|
|
341
342
|
}
|
|
342
343
|
// Return a promise that resolves on the next orderbook update
|
|
343
|
-
|
|
344
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
344
345
|
if (!this.orderBookResolvers.has(ticker)) {
|
|
345
346
|
this.orderBookResolvers.set(ticker, []);
|
|
346
347
|
}
|
|
347
348
|
this.orderBookResolvers.get(ticker).push({ resolve, reject });
|
|
348
349
|
});
|
|
350
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBook('${ticker}')`);
|
|
349
351
|
}
|
|
350
352
|
async watchOrderBooks(tickers) {
|
|
351
353
|
if (this.isTerminated) {
|
|
@@ -366,7 +368,7 @@ class KalshiWebSocket {
|
|
|
366
368
|
this.subscribeToOrderbook(newTickers);
|
|
367
369
|
}
|
|
368
370
|
// Wait for all tickers to receive at least one snapshot/update
|
|
369
|
-
const
|
|
371
|
+
const dataPromise = Promise.all(tickers.map((ticker) => new Promise((resolve, reject) => {
|
|
370
372
|
if (!this.orderBookResolvers.has(ticker)) {
|
|
371
373
|
this.orderBookResolvers.set(ticker, []);
|
|
372
374
|
}
|
|
@@ -377,6 +379,7 @@ class KalshiWebSocket {
|
|
|
377
379
|
reject,
|
|
378
380
|
});
|
|
379
381
|
})));
|
|
382
|
+
const entries = await (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBooks(${JSON.stringify(tickers)})`);
|
|
380
383
|
const result = {};
|
|
381
384
|
for (const [ticker, book] of entries) {
|
|
382
385
|
result[ticker] = book;
|
|
@@ -398,12 +401,13 @@ class KalshiWebSocket {
|
|
|
398
401
|
else {
|
|
399
402
|
this.subscribeToTrades([ticker]);
|
|
400
403
|
}
|
|
401
|
-
|
|
404
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
402
405
|
if (!this.tradeResolvers.has(ticker)) {
|
|
403
406
|
this.tradeResolvers.set(ticker, []);
|
|
404
407
|
}
|
|
405
408
|
this.tradeResolvers.get(ticker).push({ resolve, reject });
|
|
406
409
|
});
|
|
410
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchTrades('${ticker}')`);
|
|
407
411
|
}
|
|
408
412
|
async close() {
|
|
409
413
|
this.isTerminated = true;
|
|
@@ -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-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.746Z
|
|
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-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.746Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.limitlessApiSpec = {
|
|
@@ -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-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.759Z
|
|
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-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.759Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.myriadApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
3
|
-
* Generated at: 2026-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.764Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const opinionApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.opinionApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
6
|
-
* Generated at: 2026-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.764Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.opinionApiSpec = {
|
|
@@ -2,6 +2,8 @@ import { OrderBook, Trade } from "../../types";
|
|
|
2
2
|
export interface OpinionWebSocketConfig {
|
|
3
3
|
/** Reconnection interval in milliseconds (default: 5000) */
|
|
4
4
|
reconnectIntervalMs?: number;
|
|
5
|
+
/** Timeout in ms for watch methods to receive data (default: 30000). 0 = no timeout. */
|
|
6
|
+
watchTimeoutMs?: number;
|
|
5
7
|
}
|
|
6
8
|
/**
|
|
7
9
|
* Opinion Trade WebSocket implementation for real-time order book and trade streaming.
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.OpinionWebSocket = void 0;
|
|
7
7
|
const ws_1 = __importDefault(require("ws"));
|
|
8
|
+
const watch_timeout_1 = require("../../utils/watch-timeout");
|
|
8
9
|
/**
|
|
9
10
|
* Opinion Trade WebSocket implementation for real-time order book and trade streaming.
|
|
10
11
|
* Follows CCXT Pro-style async iterator pattern.
|
|
@@ -262,12 +263,13 @@ class OpinionWebSocket {
|
|
|
262
263
|
else {
|
|
263
264
|
this.sendSubscribe("market.depth.diff", marketId);
|
|
264
265
|
}
|
|
265
|
-
|
|
266
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
266
267
|
if (!this.orderBookResolvers.has(marketId)) {
|
|
267
268
|
this.orderBookResolvers.set(marketId, []);
|
|
268
269
|
}
|
|
269
270
|
this.orderBookResolvers.get(marketId).push({ resolve, reject });
|
|
270
271
|
});
|
|
272
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBook('${marketId}')`);
|
|
271
273
|
}
|
|
272
274
|
/**
|
|
273
275
|
* Watch trade updates for a given binary market.
|
|
@@ -288,12 +290,13 @@ class OpinionWebSocket {
|
|
|
288
290
|
else {
|
|
289
291
|
this.sendSubscribe("market.last.trade", marketId);
|
|
290
292
|
}
|
|
291
|
-
|
|
293
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
292
294
|
if (!this.tradeResolvers.has(marketId)) {
|
|
293
295
|
this.tradeResolvers.set(marketId, []);
|
|
294
296
|
}
|
|
295
297
|
this.tradeResolvers.get(marketId).push({ resolve, reject });
|
|
296
298
|
});
|
|
299
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchTrades('${marketId}')`);
|
|
297
300
|
}
|
|
298
301
|
/**
|
|
299
302
|
* Close the WebSocket connection and reject all pending promises.
|
|
@@ -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-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.707Z
|
|
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-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.707Z
|
|
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-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.724Z
|
|
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-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.724Z
|
|
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-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.720Z
|
|
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-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.720Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketGammaSpec = {
|
|
@@ -15,6 +15,8 @@ export interface PolymarketWebSocketConfig {
|
|
|
15
15
|
flushIntervalMs?: number;
|
|
16
16
|
/** Watcher subscription configurations */
|
|
17
17
|
watcherConfig?: WatcherConfig;
|
|
18
|
+
/** Timeout in ms for watch methods to receive data (default: 30000). 0 = no timeout. */
|
|
19
|
+
watchTimeoutMs?: number;
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Wrapper around @nevuamarkets/poly-websockets that provides CCXT Pro-style
|
|
@@ -43,6 +43,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
43
43
|
exports.PolymarketWebSocket = void 0;
|
|
44
44
|
const goldsky_1 = require("../../subscriber/external/goldsky");
|
|
45
45
|
const watcher_1 = require("../../subscriber/watcher");
|
|
46
|
+
const watch_timeout_1 = require("../../utils/watch-timeout");
|
|
46
47
|
/**
|
|
47
48
|
* Wrapper around @nevuamarkets/poly-websockets that provides CCXT Pro-style
|
|
48
49
|
* watchOrderBook() and watchTrades() methods.
|
|
@@ -75,12 +76,13 @@ class PolymarketWebSocket {
|
|
|
75
76
|
await this.manager.addSubscriptions([id]);
|
|
76
77
|
}
|
|
77
78
|
// Return a promise that resolves on the next orderbook update
|
|
78
|
-
|
|
79
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
79
80
|
if (!this.orderBookResolvers.has(id)) {
|
|
80
81
|
this.orderBookResolvers.set(id, []);
|
|
81
82
|
}
|
|
82
83
|
this.orderBookResolvers.get(id).push({ resolve, reject });
|
|
83
84
|
});
|
|
85
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBook('${id}')`);
|
|
84
86
|
}
|
|
85
87
|
async unwatchOrderBook(id) {
|
|
86
88
|
if (!this.manager) {
|
|
@@ -108,12 +110,13 @@ class PolymarketWebSocket {
|
|
|
108
110
|
await this.manager.addSubscriptions([id]);
|
|
109
111
|
}
|
|
110
112
|
// Return a promise that resolves on the next trade
|
|
111
|
-
|
|
113
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
112
114
|
if (!this.tradeResolvers.has(id)) {
|
|
113
115
|
this.tradeResolvers.set(id, []);
|
|
114
116
|
}
|
|
115
117
|
this.tradeResolvers.get(id).push({ resolve, reject });
|
|
116
118
|
});
|
|
119
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchTrades('${id}')`);
|
|
117
120
|
}
|
|
118
121
|
async watchAddress(address, types) {
|
|
119
122
|
return this.watcher.watch(address, types);
|
|
@@ -16,16 +16,21 @@
|
|
|
16
16
|
import type { PolymarketUS as PolymarketUSClient } from 'polymarket-us';
|
|
17
17
|
import { OrderBook, Trade } from '../../types';
|
|
18
18
|
import { PolymarketUSNormalizer } from './normalizer';
|
|
19
|
+
export interface PolymarketUSWebSocketConfig {
|
|
20
|
+
/** Timeout in ms for watch methods to receive data (default: 30000). 0 = no timeout. */
|
|
21
|
+
watchTimeoutMs?: number;
|
|
22
|
+
}
|
|
19
23
|
export declare class PolymarketUSWebSocket {
|
|
20
24
|
private readonly client;
|
|
21
25
|
private readonly normalizer;
|
|
26
|
+
private readonly config;
|
|
22
27
|
private socket;
|
|
23
28
|
private initializationPromise?;
|
|
24
29
|
private readonly bookSubscriptions;
|
|
25
30
|
private readonly tradeSubscriptions;
|
|
26
31
|
private readonly orderBookResolvers;
|
|
27
32
|
private readonly tradeResolvers;
|
|
28
|
-
constructor(client: PolymarketUSClient, normalizer: PolymarketUSNormalizer);
|
|
33
|
+
constructor(client: PolymarketUSClient, normalizer: PolymarketUSNormalizer, config?: PolymarketUSWebSocketConfig);
|
|
29
34
|
watchOrderBook(id: string): Promise<OrderBook>;
|
|
30
35
|
watchTrades(id: string): Promise<Trade[]>;
|
|
31
36
|
close(): Promise<void>;
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.PolymarketUSWebSocket = void 0;
|
|
19
|
+
const watch_timeout_1 = require("../../utils/watch-timeout");
|
|
19
20
|
const price_1 = require("./price");
|
|
20
21
|
function sideFromOrderSide(raw) {
|
|
21
22
|
if (raw === 'ORDER_SIDE_BUY')
|
|
@@ -44,15 +45,17 @@ function slugFromId(id) {
|
|
|
44
45
|
class PolymarketUSWebSocket {
|
|
45
46
|
client;
|
|
46
47
|
normalizer;
|
|
48
|
+
config;
|
|
47
49
|
socket = null;
|
|
48
50
|
initializationPromise;
|
|
49
51
|
bookSubscriptions = new Set();
|
|
50
52
|
tradeSubscriptions = new Set();
|
|
51
53
|
orderBookResolvers = new Map();
|
|
52
54
|
tradeResolvers = new Map();
|
|
53
|
-
constructor(client, normalizer) {
|
|
55
|
+
constructor(client, normalizer, config = {}) {
|
|
54
56
|
this.client = client;
|
|
55
57
|
this.normalizer = normalizer;
|
|
58
|
+
this.config = config;
|
|
56
59
|
}
|
|
57
60
|
async watchOrderBook(id) {
|
|
58
61
|
const slug = slugFromId(id);
|
|
@@ -61,11 +64,12 @@ class PolymarketUSWebSocket {
|
|
|
61
64
|
this.bookSubscriptions.add(slug);
|
|
62
65
|
this.socket.subscribeMarketData(`book:${slug}`, [slug]);
|
|
63
66
|
}
|
|
64
|
-
|
|
67
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
65
68
|
const queue = this.orderBookResolvers.get(slug) ?? [];
|
|
66
69
|
queue.push({ resolve, reject });
|
|
67
70
|
this.orderBookResolvers.set(slug, queue);
|
|
68
71
|
});
|
|
72
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBook('${id}')`);
|
|
69
73
|
}
|
|
70
74
|
async watchTrades(id) {
|
|
71
75
|
const slug = slugFromId(id);
|
|
@@ -74,11 +78,12 @@ class PolymarketUSWebSocket {
|
|
|
74
78
|
this.tradeSubscriptions.add(slug);
|
|
75
79
|
this.socket.subscribeTrades(`trade:${slug}`, [slug]);
|
|
76
80
|
}
|
|
77
|
-
|
|
81
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
78
82
|
const queue = this.tradeResolvers.get(slug) ?? [];
|
|
79
83
|
queue.push({ resolve, reject });
|
|
80
84
|
this.tradeResolvers.set(slug, queue);
|
|
81
85
|
});
|
|
86
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchTrades('${id}')`);
|
|
82
87
|
}
|
|
83
88
|
async close() {
|
|
84
89
|
if (this.socket) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
3
|
-
* Generated at: 2026-05-03T09:
|
|
3
|
+
* Generated at: 2026-05-03T09:26:01.752Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const probableApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.probableApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
6
|
-
* Generated at: 2026-05-03T09:
|
|
6
|
+
* Generated at: 2026-05-03T09:26:01.752Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.probableApiSpec = {
|
|
@@ -6,6 +6,8 @@ export interface ProbableWebSocketConfig {
|
|
|
6
6
|
baseUrl?: string;
|
|
7
7
|
/** Chain ID (default: 56 for BSC mainnet) */
|
|
8
8
|
chainId?: number;
|
|
9
|
+
/** Timeout in ms for watch methods to receive data (default: 30000). 0 = no timeout. */
|
|
10
|
+
watchTimeoutMs?: number;
|
|
9
11
|
}
|
|
10
12
|
/**
|
|
11
13
|
* Probable WebSocket implementation for real-time order book streaming.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ProbableWebSocket = void 0;
|
|
4
|
+
const watch_timeout_1 = require("../../utils/watch-timeout");
|
|
4
5
|
/**
|
|
5
6
|
* Probable WebSocket implementation for real-time order book streaming.
|
|
6
7
|
* Uses the @prob/clob SDK's subscribePublicStream (no auth required).
|
|
@@ -42,12 +43,13 @@ class ProbableWebSocket {
|
|
|
42
43
|
this.subscriptions.set(tokenId, sub);
|
|
43
44
|
}
|
|
44
45
|
// Return a promise that resolves on the next orderbook update
|
|
45
|
-
|
|
46
|
+
const dataPromise = new Promise((resolve, reject) => {
|
|
46
47
|
if (!this.orderBookResolvers.has(tokenId)) {
|
|
47
48
|
this.orderBookResolvers.set(tokenId, []);
|
|
48
49
|
}
|
|
49
50
|
this.orderBookResolvers.get(tokenId).push({ resolve, reject });
|
|
50
51
|
});
|
|
52
|
+
return (0, watch_timeout_1.withWatchTimeout)(dataPromise, this.config.watchTimeoutMs ?? watch_timeout_1.DEFAULT_WATCH_TIMEOUT_MS, `watchOrderBook('${tokenId}')`);
|
|
51
53
|
}
|
|
52
54
|
handleOrderBookUpdate(tokenId, data) {
|
|
53
55
|
const bids = (data.bids || []).map((b) => ({
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default timeout for watch methods (30 seconds).
|
|
3
|
+
*
|
|
4
|
+
* Generous enough for valid but illiquid markets, but prevents
|
|
5
|
+
* hanging forever on non-existing IDs.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_WATCH_TIMEOUT_MS = 30000;
|
|
8
|
+
/**
|
|
9
|
+
* Wrap a watch promise with a timeout that rejects if no data arrives.
|
|
10
|
+
*
|
|
11
|
+
* Used by all exchange WebSocket implementations to prevent indefinite
|
|
12
|
+
* hangs when subscribing to non-existing market IDs.
|
|
13
|
+
*
|
|
14
|
+
* @param promise - The data promise (resolves when WS data arrives)
|
|
15
|
+
* @param timeoutMs - Maximum time to wait in milliseconds (0 = no timeout)
|
|
16
|
+
* @param label - Human-readable label for the error message
|
|
17
|
+
*/
|
|
18
|
+
export declare function withWatchTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_WATCH_TIMEOUT_MS = void 0;
|
|
4
|
+
exports.withWatchTimeout = withWatchTimeout;
|
|
5
|
+
/**
|
|
6
|
+
* Default timeout for watch methods (30 seconds).
|
|
7
|
+
*
|
|
8
|
+
* Generous enough for valid but illiquid markets, but prevents
|
|
9
|
+
* hanging forever on non-existing IDs.
|
|
10
|
+
*/
|
|
11
|
+
exports.DEFAULT_WATCH_TIMEOUT_MS = 30_000;
|
|
12
|
+
/**
|
|
13
|
+
* Wrap a watch promise with a timeout that rejects if no data arrives.
|
|
14
|
+
*
|
|
15
|
+
* Used by all exchange WebSocket implementations to prevent indefinite
|
|
16
|
+
* hangs when subscribing to non-existing market IDs.
|
|
17
|
+
*
|
|
18
|
+
* @param promise - The data promise (resolves when WS data arrives)
|
|
19
|
+
* @param timeoutMs - Maximum time to wait in milliseconds (0 = no timeout)
|
|
20
|
+
* @param label - Human-readable label for the error message
|
|
21
|
+
*/
|
|
22
|
+
function withWatchTimeout(promise, timeoutMs, label) {
|
|
23
|
+
if (timeoutMs <= 0)
|
|
24
|
+
return promise;
|
|
25
|
+
let timer;
|
|
26
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
27
|
+
timer = setTimeout(() => {
|
|
28
|
+
reject(new Error(`${label}: timed out after ${timeoutMs}ms waiting for data. ` +
|
|
29
|
+
`The ID may not exist on this exchange.`));
|
|
30
|
+
}, timeoutMs);
|
|
31
|
+
});
|
|
32
|
+
return Promise.race([promise, timeoutPromise]).finally(() => {
|
|
33
|
+
clearTimeout(timer);
|
|
34
|
+
});
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.37.
|
|
3
|
+
"version": "2.37.2",
|
|
4
4
|
"description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"test": "jest -c jest.config.js",
|
|
30
30
|
"server": "tsx watch src/server/index.ts",
|
|
31
31
|
"server:prod": "node dist/server/index.js",
|
|
32
|
-
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.37.
|
|
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.37.
|
|
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.37.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.37.2,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
|
|
34
34
|
"fetch:openapi": "node scripts/fetch-openapi-specs.js",
|
|
35
35
|
"extract:jsdoc": "node ../scripts/extract-jsdoc.js",
|
|
36
36
|
"generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",
|