pmxtjs 2.49.6 → 2.49.8
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/esm/generated/src/models/OrderBook.d.ts +20 -0
- package/dist/esm/generated/src/models/OrderBook.js +6 -0
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +3 -2
- package/dist/esm/pmxt/client.d.ts +1 -0
- package/dist/esm/pmxt/client.js +12 -4
- package/dist/esm/pmxt/hosted-mappers.js +7 -2
- package/dist/esm/pmxt/hosted-typed-data.js +12 -0
- package/dist/esm/pmxt/router.d.ts +6 -0
- package/dist/esm/pmxt/router.js +8 -0
- package/dist/esm/pmxt/server-manager.js +9 -5
- package/dist/esm/pmxt/ws-client.js +2 -2
- package/dist/generated/src/models/OrderBook.d.ts +20 -0
- package/dist/generated/src/models/OrderBook.js +6 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/pmxt/client.d.ts +1 -0
- package/dist/pmxt/client.js +13 -5
- package/dist/pmxt/hosted-mappers.js +7 -2
- package/dist/pmxt/hosted-typed-data.js +12 -0
- package/dist/pmxt/router.d.ts +6 -0
- package/dist/pmxt/router.js +8 -0
- package/dist/pmxt/server-manager.js +9 -5
- package/dist/pmxt/ws-client.js +2 -2
- package/generated/docs/GetExecutionPriceRequestArgsInner.md +6 -0
- package/generated/docs/OrderBook.md +6 -0
- package/generated/package.json +1 -1
- package/generated/src/models/OrderBook.ts +24 -0
- package/index.ts +3 -2
- package/package.json +2 -2
- package/pmxt/client.ts +15 -4
- package/pmxt/hosted-mappers.ts +7 -2
- package/pmxt/hosted-typed-data.ts +22 -0
- package/pmxt/router.ts +16 -0
- package/pmxt/server-manager.ts +9 -5
- package/pmxt/ws-client.ts +2 -2
|
@@ -40,6 +40,26 @@ export interface OrderBook {
|
|
|
40
40
|
* @memberof OrderBook
|
|
41
41
|
*/
|
|
42
42
|
datetime?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the venue marks this snapshot as a negative-risk market.
|
|
45
|
+
* @type {boolean}
|
|
46
|
+
* @memberof OrderBook
|
|
47
|
+
*/
|
|
48
|
+
isNegRisk?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Last traded price from venues that include it with the book snapshot.
|
|
51
|
+
* @type {number}
|
|
52
|
+
* @memberof OrderBook
|
|
53
|
+
*/
|
|
54
|
+
lastTradePrice?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Venue-specific metadata preserved from the raw order book snapshot.
|
|
57
|
+
* @type {{ [key: string]: any; }}
|
|
58
|
+
* @memberof OrderBook
|
|
59
|
+
*/
|
|
60
|
+
sourceMetadata?: {
|
|
61
|
+
[key: string]: any;
|
|
62
|
+
};
|
|
43
63
|
}
|
|
44
64
|
/**
|
|
45
65
|
* Check if a given object implements the OrderBook interface.
|
|
@@ -34,6 +34,9 @@ export function OrderBookFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
34
34
|
'asks': (json['asks'].map(OrderLevelFromJSON)),
|
|
35
35
|
'timestamp': json['timestamp'] == null ? undefined : json['timestamp'],
|
|
36
36
|
'datetime': json['datetime'] == null ? undefined : json['datetime'],
|
|
37
|
+
'isNegRisk': json['isNegRisk'] == null ? undefined : json['isNegRisk'],
|
|
38
|
+
'lastTradePrice': json['lastTradePrice'] == null ? undefined : json['lastTradePrice'],
|
|
39
|
+
'sourceMetadata': json['sourceMetadata'] == null ? undefined : json['sourceMetadata'],
|
|
37
40
|
};
|
|
38
41
|
}
|
|
39
42
|
export function OrderBookToJSON(json) {
|
|
@@ -48,5 +51,8 @@ export function OrderBookToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
48
51
|
'asks': (value['asks'].map(OrderLevelToJSON)),
|
|
49
52
|
'timestamp': value['timestamp'],
|
|
50
53
|
'datetime': value['datetime'],
|
|
54
|
+
'isNegRisk': value['isNegRisk'],
|
|
55
|
+
'lastTradePrice': value['lastTradePrice'],
|
|
56
|
+
'sourceMetadata': value['sourceMetadata'],
|
|
51
57
|
};
|
|
52
58
|
}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ import { ServerManager } from "./pmxt/server-manager.js";
|
|
|
23
23
|
import { FeedClient } from "./pmxt/feed-client.js";
|
|
24
24
|
import * as models from "./pmxt/models.js";
|
|
25
25
|
import * as errors from "./pmxt/errors.js";
|
|
26
|
-
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
26
|
+
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
27
27
|
export { FeedClient } from "./pmxt/feed-client.js";
|
|
28
28
|
export type { Ticker, Tickers, OHLCV, Market as FeedMarket, OracleRound, FeedClientOptions } from "./pmxt/feed-client.js";
|
|
29
29
|
export { Router } from "./pmxt/router.js";
|
|
@@ -95,6 +95,7 @@ declare const pmxt: {
|
|
|
95
95
|
GeminiTitan: typeof GeminiTitan;
|
|
96
96
|
Hyperliquid: typeof Hyperliquid;
|
|
97
97
|
SuiBets: typeof SuiBets;
|
|
98
|
+
Suibets: typeof SuiBets;
|
|
98
99
|
Mock: typeof Mock;
|
|
99
100
|
Router: typeof Router;
|
|
100
101
|
ServerManager: typeof ServerManager;
|
package/dist/esm/index.js
CHANGED
|
@@ -17,13 +17,13 @@
|
|
|
17
17
|
* console.log(markets[0].title);
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
|
-
import { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Mock } from "./pmxt/client.js";
|
|
20
|
+
import { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Mock } from "./pmxt/client.js";
|
|
21
21
|
import { Router } from "./pmxt/router.js";
|
|
22
22
|
import { ServerManager } from "./pmxt/server-manager.js";
|
|
23
23
|
import { FeedClient } from "./pmxt/feed-client.js";
|
|
24
24
|
import * as models from "./pmxt/models.js";
|
|
25
25
|
import * as errors from "./pmxt/errors.js";
|
|
26
|
-
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Mock } from "./pmxt/client.js";
|
|
26
|
+
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Mock } from "./pmxt/client.js";
|
|
27
27
|
export { FeedClient } from "./pmxt/feed-client.js";
|
|
28
28
|
export { Router } from "./pmxt/router.js";
|
|
29
29
|
export { ServerManager } from "./pmxt/server-manager.js";
|
|
@@ -76,6 +76,7 @@ const pmxt = {
|
|
|
76
76
|
GeminiTitan,
|
|
77
77
|
Hyperliquid,
|
|
78
78
|
SuiBets,
|
|
79
|
+
Suibets,
|
|
79
80
|
Mock,
|
|
80
81
|
Router,
|
|
81
82
|
ServerManager,
|
package/dist/esm/pmxt/client.js
CHANGED
|
@@ -10,6 +10,7 @@ import { ServerManager } from "./server-manager.js";
|
|
|
10
10
|
import { PmxtError, fromServerError, InvalidOrder, NotSupported } from "./errors.js";
|
|
11
11
|
import { resolvePmxtBaseUrl } from "./constants.js";
|
|
12
12
|
import { SidecarWsClient } from "./ws-client.js";
|
|
13
|
+
import { logger } from "./logger.js";
|
|
13
14
|
// Hosted-mode trading dispatch.
|
|
14
15
|
// These modules are introduced as part of the hosted trading mode rollout.
|
|
15
16
|
// Some of them may be authored by parallel agents; until they all land, the
|
|
@@ -364,8 +365,8 @@ export class Exchange {
|
|
|
364
365
|
try {
|
|
365
366
|
await this.serverManager.ensureServerRunning();
|
|
366
367
|
}
|
|
367
|
-
catch {
|
|
368
|
-
|
|
368
|
+
catch (err) {
|
|
369
|
+
logger.warn('PmxtClient: server restart failed during retry', { attempt, error: String(err) });
|
|
369
370
|
}
|
|
370
371
|
}
|
|
371
372
|
await new Promise(resolve => setTimeout(resolve, delays[attempt]));
|
|
@@ -405,7 +406,8 @@ export class Exchange {
|
|
|
405
406
|
throw new Error("WS handshake failed");
|
|
406
407
|
}
|
|
407
408
|
}
|
|
408
|
-
catch {
|
|
409
|
+
catch (err) {
|
|
410
|
+
logger.warn('PmxtClient: WebSocket probe failed, falling back to HTTP', { error: String(err) });
|
|
409
411
|
this._wsUnsupported = true;
|
|
410
412
|
client.close();
|
|
411
413
|
return null;
|
|
@@ -923,6 +925,9 @@ export class Exchange {
|
|
|
923
925
|
return this._hostedSubmitOrder(built);
|
|
924
926
|
}
|
|
925
927
|
await this.initPromise;
|
|
928
|
+
if (this.isHosted) {
|
|
929
|
+
throw new PmxtError("submitOrder is not available in hosted mode. Use createOrder instead.");
|
|
930
|
+
}
|
|
926
931
|
try {
|
|
927
932
|
const args = [];
|
|
928
933
|
args.push(built);
|
|
@@ -2111,7 +2116,8 @@ export class Exchange {
|
|
|
2111
2116
|
this._hostedAccount = {};
|
|
2112
2117
|
}
|
|
2113
2118
|
}
|
|
2114
|
-
catch {
|
|
2119
|
+
catch (err) {
|
|
2120
|
+
logger.warn('PmxtClient: hosted account discovery failed', { error: String(err) });
|
|
2115
2121
|
this._hostedAccount = {};
|
|
2116
2122
|
}
|
|
2117
2123
|
})();
|
|
@@ -2988,6 +2994,8 @@ export class SuiBets extends Exchange {
|
|
|
2988
2994
|
};
|
|
2989
2995
|
}
|
|
2990
2996
|
}
|
|
2997
|
+
// Backwards-compatible casing alias matching the Python SDK export.
|
|
2998
|
+
export const Suibets = SuiBets;
|
|
2991
2999
|
/**
|
|
2992
3000
|
* Mock exchange client.
|
|
2993
3001
|
*
|
|
@@ -96,7 +96,11 @@ export function userTradeFromV0(payload) {
|
|
|
96
96
|
const trade = {
|
|
97
97
|
id: strOrEmpty(payload["id"]),
|
|
98
98
|
price: floatOrZero(payload["price"]),
|
|
99
|
-
|
|
99
|
+
// The v0 wire sends trade amounts in 6-dec micro-shares (verified
|
|
100
|
+
// live: 58139533.0 == 58.139533 shares, matching the same position's
|
|
101
|
+
// decimal `shares`). Normalize so UserTrade.amount means shares,
|
|
102
|
+
// like everywhere else in the SDK.
|
|
103
|
+
amount: floatOrZero(payload["amount"]) / 1_000_000,
|
|
100
104
|
side,
|
|
101
105
|
timestamp: timestampToMs(payload["timestamp"]),
|
|
102
106
|
};
|
|
@@ -116,7 +120,8 @@ export function userTradeToV0(trade) {
|
|
|
116
120
|
const out = {
|
|
117
121
|
id: trade.id,
|
|
118
122
|
side: trade.side,
|
|
119
|
-
|
|
123
|
+
// Inverse of userTradeFromV0: decimal shares -> 6-dec micro-shares.
|
|
124
|
+
amount: Math.round(trade.amount * 1_000_000),
|
|
120
125
|
price: trade.price,
|
|
121
126
|
timestamp: msToTimestamp(trade.timestamp),
|
|
122
127
|
};
|
|
@@ -313,6 +313,18 @@ const SIX_DEC_DIVISOR = 1_000_000;
|
|
|
313
313
|
function validateWorstPrice(message, route, buildRequest, buildResponse) {
|
|
314
314
|
const worstPriceMicro = messageBigInt(message, "worst_price", "worstPrice");
|
|
315
315
|
const worstPrice = Number(worstPriceMicro) / SIX_DEC_DIVISOR;
|
|
316
|
+
// Hosted MARKET orders pin worst_price to the tick-grid extreme by
|
|
317
|
+
// design ("textbook market semantics"): the binding user protection is
|
|
318
|
+
// max_cost_usdc (buys) / shares_6dec (sells), validated above. A
|
|
319
|
+
// slippage bound on worst_price would reject every server-built market
|
|
320
|
+
// order, so only sanity-check the price domain here.
|
|
321
|
+
const orderType = String(firstPresent(getField(buildRequest, "order_type"), getField(buildRequest, "orderType"), "market")).toLowerCase();
|
|
322
|
+
if (orderType === "market") {
|
|
323
|
+
if (!(worstPrice > 0 && worstPrice < 1)) {
|
|
324
|
+
economicFail(`worst_price expected within (0, 1) got ${worstPrice}`);
|
|
325
|
+
}
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
316
328
|
const slippagePctRaw = firstPresent(getField(buildRequest, "slippage_pct"), getField(buildRequest, "slippagePct"), getField(buildResponse, "slippage_pct"), getField(buildResponse, "slippagePct"), 20);
|
|
317
329
|
const slippagePct = toFiniteNumber(slippagePctRaw, "slippage_pct");
|
|
318
330
|
if (route === "polymarket_buy") {
|
|
@@ -44,6 +44,8 @@ export declare class Router extends Exchange {
|
|
|
44
44
|
marketId?: string;
|
|
45
45
|
slug?: string;
|
|
46
46
|
url?: string;
|
|
47
|
+
query?: string;
|
|
48
|
+
category?: string;
|
|
47
49
|
relation?: MatchRelation;
|
|
48
50
|
minConfidence?: number;
|
|
49
51
|
limit?: number;
|
|
@@ -58,6 +60,8 @@ export declare class Router extends Exchange {
|
|
|
58
60
|
marketId?: string;
|
|
59
61
|
slug?: string;
|
|
60
62
|
url?: string;
|
|
63
|
+
query?: string;
|
|
64
|
+
category?: string;
|
|
61
65
|
relation?: MatchRelation;
|
|
62
66
|
minConfidence?: number;
|
|
63
67
|
limit?: number;
|
|
@@ -73,6 +77,8 @@ export declare class Router extends Exchange {
|
|
|
73
77
|
event?: UnifiedEvent;
|
|
74
78
|
eventId?: string;
|
|
75
79
|
slug?: string;
|
|
80
|
+
query?: string;
|
|
81
|
+
category?: string;
|
|
76
82
|
relation?: MatchRelation;
|
|
77
83
|
minConfidence?: number;
|
|
78
84
|
limit?: number;
|
package/dist/esm/pmxt/router.js
CHANGED
|
@@ -166,6 +166,10 @@ export class Router extends Exchange {
|
|
|
166
166
|
query.slug = params.slug ?? params.market?.slug;
|
|
167
167
|
if (params.url)
|
|
168
168
|
query.url = params.url;
|
|
169
|
+
if (params.query)
|
|
170
|
+
query.query = params.query;
|
|
171
|
+
if (params.category)
|
|
172
|
+
query.category = params.category;
|
|
169
173
|
if (params.relation)
|
|
170
174
|
query.relation = params.relation;
|
|
171
175
|
if (params.minConfidence !== undefined)
|
|
@@ -203,6 +207,10 @@ export class Router extends Exchange {
|
|
|
203
207
|
query.eventId = eventId;
|
|
204
208
|
if (params.slug ?? params.event?.slug)
|
|
205
209
|
query.slug = params.slug ?? params.event?.slug;
|
|
210
|
+
if (params.query)
|
|
211
|
+
query.query = params.query;
|
|
212
|
+
if (params.category)
|
|
213
|
+
query.category = params.category;
|
|
206
214
|
if (params.relation)
|
|
207
215
|
query.relation = params.relation;
|
|
208
216
|
if (params.minConfidence !== undefined)
|
|
@@ -7,6 +7,7 @@ import { DefaultApi, Configuration } from "../generated/src/index.js";
|
|
|
7
7
|
import { readFileSync, existsSync } from "fs";
|
|
8
8
|
import { homedir } from "os";
|
|
9
9
|
import { join, dirname } from "path";
|
|
10
|
+
import { logger } from "./logger.js";
|
|
10
11
|
export class ServerManager {
|
|
11
12
|
baseUrl;
|
|
12
13
|
maxRetries;
|
|
@@ -123,8 +124,8 @@ export class ServerManager {
|
|
|
123
124
|
return;
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
|
-
catch {
|
|
127
|
-
|
|
127
|
+
catch (err) {
|
|
128
|
+
logger.debug('server-manager: health poll error', { error: String(err) });
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
await new Promise((resolve) => setTimeout(resolve, this.retryDelayMs));
|
|
@@ -230,8 +231,8 @@ export class ServerManager {
|
|
|
230
231
|
}
|
|
231
232
|
}
|
|
232
233
|
}
|
|
233
|
-
catch {
|
|
234
|
-
|
|
234
|
+
catch (err) {
|
|
235
|
+
logger.warn('server-manager: version check failed', { error: String(err) });
|
|
235
236
|
}
|
|
236
237
|
return false;
|
|
237
238
|
}
|
|
@@ -343,6 +344,9 @@ export class ServerManager {
|
|
|
343
344
|
const { unlinkSync } = await import('fs');
|
|
344
345
|
unlinkSync(this.lockPath);
|
|
345
346
|
}
|
|
346
|
-
catch {
|
|
347
|
+
catch (err) {
|
|
348
|
+
// Best-effort — expected when file was already removed.
|
|
349
|
+
logger.debug('server-manager: lock file removal failed', { path: this.lockPath, error: String(err) });
|
|
350
|
+
}
|
|
347
351
|
}
|
|
348
352
|
}
|
|
@@ -40,6 +40,26 @@ export interface OrderBook {
|
|
|
40
40
|
* @memberof OrderBook
|
|
41
41
|
*/
|
|
42
42
|
datetime?: string;
|
|
43
|
+
/**
|
|
44
|
+
* Whether the venue marks this snapshot as a negative-risk market.
|
|
45
|
+
* @type {boolean}
|
|
46
|
+
* @memberof OrderBook
|
|
47
|
+
*/
|
|
48
|
+
isNegRisk?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Last traded price from venues that include it with the book snapshot.
|
|
51
|
+
* @type {number}
|
|
52
|
+
* @memberof OrderBook
|
|
53
|
+
*/
|
|
54
|
+
lastTradePrice?: number;
|
|
55
|
+
/**
|
|
56
|
+
* Venue-specific metadata preserved from the raw order book snapshot.
|
|
57
|
+
* @type {{ [key: string]: any; }}
|
|
58
|
+
* @memberof OrderBook
|
|
59
|
+
*/
|
|
60
|
+
sourceMetadata?: {
|
|
61
|
+
[key: string]: any;
|
|
62
|
+
};
|
|
43
63
|
}
|
|
44
64
|
/**
|
|
45
65
|
* Check if a given object implements the OrderBook interface.
|
|
@@ -41,6 +41,9 @@ function OrderBookFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
41
41
|
'asks': (json['asks'].map(OrderLevel_1.OrderLevelFromJSON)),
|
|
42
42
|
'timestamp': json['timestamp'] == null ? undefined : json['timestamp'],
|
|
43
43
|
'datetime': json['datetime'] == null ? undefined : json['datetime'],
|
|
44
|
+
'isNegRisk': json['isNegRisk'] == null ? undefined : json['isNegRisk'],
|
|
45
|
+
'lastTradePrice': json['lastTradePrice'] == null ? undefined : json['lastTradePrice'],
|
|
46
|
+
'sourceMetadata': json['sourceMetadata'] == null ? undefined : json['sourceMetadata'],
|
|
44
47
|
};
|
|
45
48
|
}
|
|
46
49
|
function OrderBookToJSON(json) {
|
|
@@ -55,5 +58,8 @@ function OrderBookToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
55
58
|
'asks': (value['asks'].map(OrderLevel_1.OrderLevelToJSON)),
|
|
56
59
|
'timestamp': value['timestamp'],
|
|
57
60
|
'datetime': value['datetime'],
|
|
61
|
+
'isNegRisk': value['isNegRisk'],
|
|
62
|
+
'lastTradePrice': value['lastTradePrice'],
|
|
63
|
+
'sourceMetadata': value['sourceMetadata'],
|
|
58
64
|
};
|
|
59
65
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ import { ServerManager } from "./pmxt/server-manager.js";
|
|
|
23
23
|
import { FeedClient } from "./pmxt/feed-client.js";
|
|
24
24
|
import * as models from "./pmxt/models.js";
|
|
25
25
|
import * as errors from "./pmxt/errors.js";
|
|
26
|
-
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
26
|
+
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
27
27
|
export { FeedClient } from "./pmxt/feed-client.js";
|
|
28
28
|
export type { Ticker, Tickers, OHLCV, Market as FeedMarket, OracleRound, FeedClientOptions } from "./pmxt/feed-client.js";
|
|
29
29
|
export { Router } from "./pmxt/router.js";
|
|
@@ -95,6 +95,7 @@ declare const pmxt: {
|
|
|
95
95
|
GeminiTitan: typeof GeminiTitan;
|
|
96
96
|
Hyperliquid: typeof Hyperliquid;
|
|
97
97
|
SuiBets: typeof SuiBets;
|
|
98
|
+
Suibets: typeof SuiBets;
|
|
98
99
|
Mock: typeof Mock;
|
|
99
100
|
Router: typeof Router;
|
|
100
101
|
ServerManager: typeof ServerManager;
|
package/dist/index.js
CHANGED
|
@@ -55,7 +55,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
55
55
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
56
56
|
};
|
|
57
57
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
-
exports.server = exports.MarketList = exports.resolvePmxtBaseUrl = exports.ENV = exports.LOCAL_URL = exports.HOSTED_URL = exports.ServerManager = exports.Router = exports.FeedClient = exports.Mock = exports.SuiBets = exports.Hyperliquid = exports.GeminiTitan = exports.PolymarketUS = exports.Smarkets = exports.Metaculus = exports.Opinion = exports.Baozi = exports.Probable = exports.Myriad = exports.Limitless = exports.KalshiDemo = exports.Kalshi = exports.Polymarket = exports.Exchange = void 0;
|
|
58
|
+
exports.server = exports.MarketList = exports.resolvePmxtBaseUrl = exports.ENV = exports.LOCAL_URL = exports.HOSTED_URL = exports.ServerManager = exports.Router = exports.FeedClient = exports.Mock = exports.Suibets = exports.SuiBets = exports.Hyperliquid = exports.GeminiTitan = exports.PolymarketUS = exports.Smarkets = exports.Metaculus = exports.Opinion = exports.Baozi = exports.Probable = exports.Myriad = exports.Limitless = exports.KalshiDemo = exports.Kalshi = exports.Polymarket = exports.Exchange = void 0;
|
|
59
59
|
const client_js_1 = require("./pmxt/client.js");
|
|
60
60
|
const router_js_1 = require("./pmxt/router.js");
|
|
61
61
|
const server_manager_js_1 = require("./pmxt/server-manager.js");
|
|
@@ -78,6 +78,7 @@ Object.defineProperty(exports, "PolymarketUS", { enumerable: true, get: function
|
|
|
78
78
|
Object.defineProperty(exports, "GeminiTitan", { enumerable: true, get: function () { return client_js_2.GeminiTitan; } });
|
|
79
79
|
Object.defineProperty(exports, "Hyperliquid", { enumerable: true, get: function () { return client_js_2.Hyperliquid; } });
|
|
80
80
|
Object.defineProperty(exports, "SuiBets", { enumerable: true, get: function () { return client_js_2.SuiBets; } });
|
|
81
|
+
Object.defineProperty(exports, "Suibets", { enumerable: true, get: function () { return client_js_2.Suibets; } });
|
|
81
82
|
Object.defineProperty(exports, "Mock", { enumerable: true, get: function () { return client_js_2.Mock; } });
|
|
82
83
|
var feed_client_js_2 = require("./pmxt/feed-client.js");
|
|
83
84
|
Object.defineProperty(exports, "FeedClient", { enumerable: true, get: function () { return feed_client_js_2.FeedClient; } });
|
|
@@ -139,6 +140,7 @@ const pmxt = {
|
|
|
139
140
|
GeminiTitan: client_js_1.GeminiTitan,
|
|
140
141
|
Hyperliquid: client_js_1.Hyperliquid,
|
|
141
142
|
SuiBets: client_js_1.SuiBets,
|
|
143
|
+
Suibets: client_js_1.Suibets,
|
|
142
144
|
Mock: client_js_1.Mock,
|
|
143
145
|
Router: router_js_1.Router,
|
|
144
146
|
ServerManager: server_manager_js_1.ServerManager,
|
package/dist/pmxt/client.d.ts
CHANGED
package/dist/pmxt/client.js
CHANGED
|
@@ -6,13 +6,14 @@
|
|
|
6
6
|
* OpenAPI client, matching the Python API exactly.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.Mock = exports.SuiBets = exports.Hyperliquid = exports.GeminiTitan = exports.PolymarketUS = exports.Smarkets = exports.Metaculus = exports.Opinion = exports.Baozi = exports.Probable = exports.Myriad = exports.KalshiDemo = exports.Limitless = exports.Kalshi = exports.Polymarket = exports.Exchange = void 0;
|
|
9
|
+
exports.Mock = exports.Suibets = exports.SuiBets = exports.Hyperliquid = exports.GeminiTitan = exports.PolymarketUS = exports.Smarkets = exports.Metaculus = exports.Opinion = exports.Baozi = exports.Probable = exports.Myriad = exports.KalshiDemo = exports.Limitless = exports.Kalshi = exports.Polymarket = exports.Exchange = void 0;
|
|
10
10
|
const index_js_1 = require("../generated/src/index.js");
|
|
11
11
|
const models_js_1 = require("./models.js");
|
|
12
12
|
const server_manager_js_1 = require("./server-manager.js");
|
|
13
13
|
const errors_js_1 = require("./errors.js");
|
|
14
14
|
const constants_js_1 = require("./constants.js");
|
|
15
15
|
const ws_client_js_1 = require("./ws-client.js");
|
|
16
|
+
const logger_js_1 = require("./logger.js");
|
|
16
17
|
// Hosted-mode trading dispatch.
|
|
17
18
|
// These modules are introduced as part of the hosted trading mode rollout.
|
|
18
19
|
// Some of them may be authored by parallel agents; until they all land, the
|
|
@@ -367,8 +368,8 @@ class Exchange {
|
|
|
367
368
|
try {
|
|
368
369
|
await this.serverManager.ensureServerRunning();
|
|
369
370
|
}
|
|
370
|
-
catch {
|
|
371
|
-
|
|
371
|
+
catch (err) {
|
|
372
|
+
logger_js_1.logger.warn('PmxtClient: server restart failed during retry', { attempt, error: String(err) });
|
|
372
373
|
}
|
|
373
374
|
}
|
|
374
375
|
await new Promise(resolve => setTimeout(resolve, delays[attempt]));
|
|
@@ -408,7 +409,8 @@ class Exchange {
|
|
|
408
409
|
throw new Error("WS handshake failed");
|
|
409
410
|
}
|
|
410
411
|
}
|
|
411
|
-
catch {
|
|
412
|
+
catch (err) {
|
|
413
|
+
logger_js_1.logger.warn('PmxtClient: WebSocket probe failed, falling back to HTTP', { error: String(err) });
|
|
412
414
|
this._wsUnsupported = true;
|
|
413
415
|
client.close();
|
|
414
416
|
return null;
|
|
@@ -926,6 +928,9 @@ class Exchange {
|
|
|
926
928
|
return this._hostedSubmitOrder(built);
|
|
927
929
|
}
|
|
928
930
|
await this.initPromise;
|
|
931
|
+
if (this.isHosted) {
|
|
932
|
+
throw new errors_js_1.PmxtError("submitOrder is not available in hosted mode. Use createOrder instead.");
|
|
933
|
+
}
|
|
929
934
|
try {
|
|
930
935
|
const args = [];
|
|
931
936
|
args.push(built);
|
|
@@ -2114,7 +2119,8 @@ class Exchange {
|
|
|
2114
2119
|
this._hostedAccount = {};
|
|
2115
2120
|
}
|
|
2116
2121
|
}
|
|
2117
|
-
catch {
|
|
2122
|
+
catch (err) {
|
|
2123
|
+
logger_js_1.logger.warn('PmxtClient: hosted account discovery failed', { error: String(err) });
|
|
2118
2124
|
this._hostedAccount = {};
|
|
2119
2125
|
}
|
|
2120
2126
|
})();
|
|
@@ -3006,6 +3012,8 @@ class SuiBets extends Exchange {
|
|
|
3006
3012
|
}
|
|
3007
3013
|
}
|
|
3008
3014
|
exports.SuiBets = SuiBets;
|
|
3015
|
+
// Backwards-compatible casing alias matching the Python SDK export.
|
|
3016
|
+
exports.Suibets = SuiBets;
|
|
3009
3017
|
/**
|
|
3010
3018
|
* Mock exchange client.
|
|
3011
3019
|
*
|
|
@@ -107,7 +107,11 @@ function userTradeFromV0(payload) {
|
|
|
107
107
|
const trade = {
|
|
108
108
|
id: strOrEmpty(payload["id"]),
|
|
109
109
|
price: floatOrZero(payload["price"]),
|
|
110
|
-
|
|
110
|
+
// The v0 wire sends trade amounts in 6-dec micro-shares (verified
|
|
111
|
+
// live: 58139533.0 == 58.139533 shares, matching the same position's
|
|
112
|
+
// decimal `shares`). Normalize so UserTrade.amount means shares,
|
|
113
|
+
// like everywhere else in the SDK.
|
|
114
|
+
amount: floatOrZero(payload["amount"]) / 1_000_000,
|
|
111
115
|
side,
|
|
112
116
|
timestamp: timestampToMs(payload["timestamp"]),
|
|
113
117
|
};
|
|
@@ -127,7 +131,8 @@ function userTradeToV0(trade) {
|
|
|
127
131
|
const out = {
|
|
128
132
|
id: trade.id,
|
|
129
133
|
side: trade.side,
|
|
130
|
-
|
|
134
|
+
// Inverse of userTradeFromV0: decimal shares -> 6-dec micro-shares.
|
|
135
|
+
amount: Math.round(trade.amount * 1_000_000),
|
|
131
136
|
price: trade.price,
|
|
132
137
|
timestamp: msToTimestamp(trade.timestamp),
|
|
133
138
|
};
|
|
@@ -352,6 +352,18 @@ const SIX_DEC_DIVISOR = 1_000_000;
|
|
|
352
352
|
function validateWorstPrice(message, route, buildRequest, buildResponse) {
|
|
353
353
|
const worstPriceMicro = messageBigInt(message, "worst_price", "worstPrice");
|
|
354
354
|
const worstPrice = Number(worstPriceMicro) / SIX_DEC_DIVISOR;
|
|
355
|
+
// Hosted MARKET orders pin worst_price to the tick-grid extreme by
|
|
356
|
+
// design ("textbook market semantics"): the binding user protection is
|
|
357
|
+
// max_cost_usdc (buys) / shares_6dec (sells), validated above. A
|
|
358
|
+
// slippage bound on worst_price would reject every server-built market
|
|
359
|
+
// order, so only sanity-check the price domain here.
|
|
360
|
+
const orderType = String(firstPresent(getField(buildRequest, "order_type"), getField(buildRequest, "orderType"), "market")).toLowerCase();
|
|
361
|
+
if (orderType === "market") {
|
|
362
|
+
if (!(worstPrice > 0 && worstPrice < 1)) {
|
|
363
|
+
economicFail(`worst_price expected within (0, 1) got ${worstPrice}`);
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
355
367
|
const slippagePctRaw = firstPresent(getField(buildRequest, "slippage_pct"), getField(buildRequest, "slippagePct"), getField(buildResponse, "slippage_pct"), getField(buildResponse, "slippagePct"), 20);
|
|
356
368
|
const slippagePct = toFiniteNumber(slippagePctRaw, "slippage_pct");
|
|
357
369
|
if (route === "polymarket_buy") {
|
package/dist/pmxt/router.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export declare class Router extends Exchange {
|
|
|
44
44
|
marketId?: string;
|
|
45
45
|
slug?: string;
|
|
46
46
|
url?: string;
|
|
47
|
+
query?: string;
|
|
48
|
+
category?: string;
|
|
47
49
|
relation?: MatchRelation;
|
|
48
50
|
minConfidence?: number;
|
|
49
51
|
limit?: number;
|
|
@@ -58,6 +60,8 @@ export declare class Router extends Exchange {
|
|
|
58
60
|
marketId?: string;
|
|
59
61
|
slug?: string;
|
|
60
62
|
url?: string;
|
|
63
|
+
query?: string;
|
|
64
|
+
category?: string;
|
|
61
65
|
relation?: MatchRelation;
|
|
62
66
|
minConfidence?: number;
|
|
63
67
|
limit?: number;
|
|
@@ -73,6 +77,8 @@ export declare class Router extends Exchange {
|
|
|
73
77
|
event?: UnifiedEvent;
|
|
74
78
|
eventId?: string;
|
|
75
79
|
slug?: string;
|
|
80
|
+
query?: string;
|
|
81
|
+
category?: string;
|
|
76
82
|
relation?: MatchRelation;
|
|
77
83
|
minConfidence?: number;
|
|
78
84
|
limit?: number;
|
package/dist/pmxt/router.js
CHANGED
|
@@ -202,6 +202,10 @@ class Router extends client_js_1.Exchange {
|
|
|
202
202
|
query.slug = params.slug ?? params.market?.slug;
|
|
203
203
|
if (params.url)
|
|
204
204
|
query.url = params.url;
|
|
205
|
+
if (params.query)
|
|
206
|
+
query.query = params.query;
|
|
207
|
+
if (params.category)
|
|
208
|
+
query.category = params.category;
|
|
205
209
|
if (params.relation)
|
|
206
210
|
query.relation = params.relation;
|
|
207
211
|
if (params.minConfidence !== undefined)
|
|
@@ -239,6 +243,10 @@ class Router extends client_js_1.Exchange {
|
|
|
239
243
|
query.eventId = eventId;
|
|
240
244
|
if (params.slug ?? params.event?.slug)
|
|
241
245
|
query.slug = params.slug ?? params.event?.slug;
|
|
246
|
+
if (params.query)
|
|
247
|
+
query.query = params.query;
|
|
248
|
+
if (params.category)
|
|
249
|
+
query.category = params.category;
|
|
242
250
|
if (params.relation)
|
|
243
251
|
query.relation = params.relation;
|
|
244
252
|
if (params.minConfidence !== undefined)
|
|
@@ -43,6 +43,7 @@ const index_js_1 = require("../generated/src/index.js");
|
|
|
43
43
|
const fs_1 = require("fs");
|
|
44
44
|
const os_1 = require("os");
|
|
45
45
|
const path_1 = require("path");
|
|
46
|
+
const logger_js_1 = require("./logger.js");
|
|
46
47
|
class ServerManager {
|
|
47
48
|
baseUrl;
|
|
48
49
|
maxRetries;
|
|
@@ -159,8 +160,8 @@ class ServerManager {
|
|
|
159
160
|
return;
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
|
-
catch {
|
|
163
|
-
|
|
163
|
+
catch (err) {
|
|
164
|
+
logger_js_1.logger.debug('server-manager: health poll error', { error: String(err) });
|
|
164
165
|
}
|
|
165
166
|
}
|
|
166
167
|
await new Promise((resolve) => setTimeout(resolve, this.retryDelayMs));
|
|
@@ -266,8 +267,8 @@ class ServerManager {
|
|
|
266
267
|
}
|
|
267
268
|
}
|
|
268
269
|
}
|
|
269
|
-
catch {
|
|
270
|
-
|
|
270
|
+
catch (err) {
|
|
271
|
+
logger_js_1.logger.warn('server-manager: version check failed', { error: String(err) });
|
|
271
272
|
}
|
|
272
273
|
return false;
|
|
273
274
|
}
|
|
@@ -379,7 +380,10 @@ class ServerManager {
|
|
|
379
380
|
const { unlinkSync } = await Promise.resolve().then(() => __importStar(require('fs')));
|
|
380
381
|
unlinkSync(this.lockPath);
|
|
381
382
|
}
|
|
382
|
-
catch {
|
|
383
|
+
catch (err) {
|
|
384
|
+
// Best-effort — expected when file was already removed.
|
|
385
|
+
logger_js_1.logger.debug('server-manager: lock file removal failed', { path: this.lockPath, error: String(err) });
|
|
386
|
+
}
|
|
383
387
|
}
|
|
384
388
|
}
|
|
385
389
|
exports.ServerManager = ServerManager;
|
package/dist/pmxt/ws-client.js
CHANGED
|
@@ -10,6 +10,9 @@ Name | Type
|
|
|
10
10
|
`asks` | [Array<OrderLevel>](OrderLevel.md)
|
|
11
11
|
`timestamp` | number
|
|
12
12
|
`datetime` | string
|
|
13
|
+
`isNegRisk` | boolean
|
|
14
|
+
`lastTradePrice` | number
|
|
15
|
+
`sourceMetadata` | { [key: string]: object; }
|
|
13
16
|
|
|
14
17
|
## Example
|
|
15
18
|
|
|
@@ -22,6 +25,9 @@ const example = {
|
|
|
22
25
|
"asks": null,
|
|
23
26
|
"timestamp": null,
|
|
24
27
|
"datetime": null,
|
|
28
|
+
"isNegRisk": null,
|
|
29
|
+
"lastTradePrice": null,
|
|
30
|
+
"sourceMetadata": null,
|
|
25
31
|
} satisfies GetExecutionPriceRequestArgsInner
|
|
26
32
|
|
|
27
33
|
console.log(example)
|
|
@@ -10,6 +10,9 @@ Name | Type
|
|
|
10
10
|
`asks` | [Array<OrderLevel>](OrderLevel.md)
|
|
11
11
|
`timestamp` | number
|
|
12
12
|
`datetime` | string
|
|
13
|
+
`isNegRisk` | boolean
|
|
14
|
+
`lastTradePrice` | number
|
|
15
|
+
`sourceMetadata` | { [key: string]: any; }
|
|
13
16
|
|
|
14
17
|
## Example
|
|
15
18
|
|
|
@@ -22,6 +25,9 @@ const example = {
|
|
|
22
25
|
"asks": null,
|
|
23
26
|
"timestamp": null,
|
|
24
27
|
"datetime": null,
|
|
28
|
+
"isNegRisk": null,
|
|
29
|
+
"lastTradePrice": null,
|
|
30
|
+
"sourceMetadata": null,
|
|
25
31
|
} satisfies OrderBook
|
|
26
32
|
|
|
27
33
|
console.log(example)
|
package/generated/package.json
CHANGED
|
@@ -51,6 +51,24 @@ export interface OrderBook {
|
|
|
51
51
|
* @memberof OrderBook
|
|
52
52
|
*/
|
|
53
53
|
datetime?: string;
|
|
54
|
+
/**
|
|
55
|
+
* Whether the venue marks this snapshot as a negative-risk market.
|
|
56
|
+
* @type {boolean}
|
|
57
|
+
* @memberof OrderBook
|
|
58
|
+
*/
|
|
59
|
+
isNegRisk?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Last traded price from venues that include it with the book snapshot.
|
|
62
|
+
* @type {number}
|
|
63
|
+
* @memberof OrderBook
|
|
64
|
+
*/
|
|
65
|
+
lastTradePrice?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Venue-specific metadata preserved from the raw order book snapshot.
|
|
68
|
+
* @type {{ [key: string]: any; }}
|
|
69
|
+
* @memberof OrderBook
|
|
70
|
+
*/
|
|
71
|
+
sourceMetadata?: { [key: string]: any; };
|
|
54
72
|
}
|
|
55
73
|
|
|
56
74
|
/**
|
|
@@ -76,6 +94,9 @@ export function OrderBookFromJSONTyped(json: any, ignoreDiscriminator: boolean):
|
|
|
76
94
|
'asks': ((json['asks'] as Array<any>).map(OrderLevelFromJSON)),
|
|
77
95
|
'timestamp': json['timestamp'] == null ? undefined : json['timestamp'],
|
|
78
96
|
'datetime': json['datetime'] == null ? undefined : json['datetime'],
|
|
97
|
+
'isNegRisk': json['isNegRisk'] == null ? undefined : json['isNegRisk'],
|
|
98
|
+
'lastTradePrice': json['lastTradePrice'] == null ? undefined : json['lastTradePrice'],
|
|
99
|
+
'sourceMetadata': json['sourceMetadata'] == null ? undefined : json['sourceMetadata'],
|
|
79
100
|
};
|
|
80
101
|
}
|
|
81
102
|
|
|
@@ -94,6 +115,9 @@ export function OrderBookToJSONTyped(value?: OrderBook | null, ignoreDiscriminat
|
|
|
94
115
|
'asks': ((value['asks'] as Array<any>).map(OrderLevelToJSON)),
|
|
95
116
|
'timestamp': value['timestamp'],
|
|
96
117
|
'datetime': value['datetime'],
|
|
118
|
+
'isNegRisk': value['isNegRisk'],
|
|
119
|
+
'lastTradePrice': value['lastTradePrice'],
|
|
120
|
+
'sourceMetadata': value['sourceMetadata'],
|
|
97
121
|
};
|
|
98
122
|
}
|
|
99
123
|
|
package/index.ts
CHANGED
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
import { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Mock } from "./pmxt/client.js";
|
|
22
|
+
import { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Mock } from "./pmxt/client.js";
|
|
23
23
|
import { Router } from "./pmxt/router.js";
|
|
24
24
|
import { ServerManager } from "./pmxt/server-manager.js";
|
|
25
25
|
import { FeedClient } from "./pmxt/feed-client.js";
|
|
26
26
|
import * as models from "./pmxt/models.js";
|
|
27
27
|
import * as errors from "./pmxt/errors.js";
|
|
28
28
|
|
|
29
|
-
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
29
|
+
export { Exchange, Polymarket, Kalshi, KalshiDemo, Limitless, Myriad, Probable, Baozi, Opinion, Metaculus, Smarkets, PolymarketUS, GeminiTitan, Hyperliquid, SuiBets, Suibets, Mock, PolymarketOptions } from "./pmxt/client.js";
|
|
30
30
|
export { FeedClient } from "./pmxt/feed-client.js";
|
|
31
31
|
export type { Ticker, Tickers, OHLCV, Market as FeedMarket, OracleRound, FeedClientOptions } from "./pmxt/feed-client.js";
|
|
32
32
|
export { Router } from "./pmxt/router.js";
|
|
@@ -88,6 +88,7 @@ const pmxt = {
|
|
|
88
88
|
GeminiTitan,
|
|
89
89
|
Hyperliquid,
|
|
90
90
|
SuiBets,
|
|
91
|
+
Suibets,
|
|
91
92
|
Mock,
|
|
92
93
|
Router,
|
|
93
94
|
ServerManager,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxtjs",
|
|
3
|
-
"version": "2.49.
|
|
3
|
+
"version": "2.49.8",
|
|
4
4
|
"description": "Unified prediction market data API - The ccxt for prediction markets",
|
|
5
5
|
"author": "PMXT Contributors",
|
|
6
6
|
"repository": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"unified"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"pmxt-core": "2.49.
|
|
46
|
+
"pmxt-core": "2.49.8",
|
|
47
47
|
"ws": "^8.18.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
package/pmxt/client.ts
CHANGED
|
@@ -53,6 +53,7 @@ import { buildArgsWithOptionalOptions } from "./args.js";
|
|
|
53
53
|
import { PmxtError, fromServerError, InvalidOrder, NotSupported } from "./errors.js";
|
|
54
54
|
import { LOCAL_URL, resolvePmxtBaseUrl } from "./constants.js";
|
|
55
55
|
import { SidecarWsClient } from "./ws-client.js";
|
|
56
|
+
import { logger } from "./logger.js";
|
|
56
57
|
|
|
57
58
|
// Hosted-mode trading dispatch.
|
|
58
59
|
// These modules are introduced as part of the hosted trading mode rollout.
|
|
@@ -547,8 +548,8 @@ export abstract class Exchange {
|
|
|
547
548
|
if (attempt === 0 && !this.isHosted) {
|
|
548
549
|
try {
|
|
549
550
|
await this.serverManager.ensureServerRunning();
|
|
550
|
-
} catch {
|
|
551
|
-
|
|
551
|
+
} catch (err) {
|
|
552
|
+
logger.warn('PmxtClient: server restart failed during retry', { attempt, error: String(err) });
|
|
552
553
|
}
|
|
553
554
|
}
|
|
554
555
|
await new Promise(resolve => setTimeout(resolve, delays[attempt]));
|
|
@@ -594,7 +595,8 @@ export abstract class Exchange {
|
|
|
594
595
|
if (!client.connected) {
|
|
595
596
|
throw new Error("WS handshake failed");
|
|
596
597
|
}
|
|
597
|
-
} catch {
|
|
598
|
+
} catch (err) {
|
|
599
|
+
logger.warn('PmxtClient: WebSocket probe failed, falling back to HTTP', { error: String(err) });
|
|
598
600
|
this._wsUnsupported = true;
|
|
599
601
|
client.close();
|
|
600
602
|
return null;
|
|
@@ -1133,6 +1135,9 @@ export abstract class Exchange {
|
|
|
1133
1135
|
return this._hostedSubmitOrder(built);
|
|
1134
1136
|
}
|
|
1135
1137
|
await this.initPromise;
|
|
1138
|
+
if (this.isHosted) {
|
|
1139
|
+
throw new PmxtError("submitOrder is not available in hosted mode. Use createOrder instead.");
|
|
1140
|
+
}
|
|
1136
1141
|
try {
|
|
1137
1142
|
const args: any[] = [];
|
|
1138
1143
|
args.push(built);
|
|
@@ -2352,7 +2357,10 @@ export abstract class Exchange {
|
|
|
2352
2357
|
const body = await res.json();
|
|
2353
2358
|
this._hostedAccount = { depositWallet: body.deposit_wallet, signatureType: body.signature_type };
|
|
2354
2359
|
} else { this._hostedAccount = {}; }
|
|
2355
|
-
} catch
|
|
2360
|
+
} catch (err) {
|
|
2361
|
+
logger.warn('PmxtClient: hosted account discovery failed', { error: String(err) });
|
|
2362
|
+
this._hostedAccount = {};
|
|
2363
|
+
}
|
|
2356
2364
|
})();
|
|
2357
2365
|
}
|
|
2358
2366
|
await this._accountDiscoveryPromise;
|
|
@@ -3362,6 +3370,9 @@ export class SuiBets extends Exchange {
|
|
|
3362
3370
|
}
|
|
3363
3371
|
}
|
|
3364
3372
|
|
|
3373
|
+
// Backwards-compatible casing alias matching the Python SDK export.
|
|
3374
|
+
export const Suibets = SuiBets;
|
|
3375
|
+
|
|
3365
3376
|
/**
|
|
3366
3377
|
* Mock exchange client.
|
|
3367
3378
|
*
|
package/pmxt/hosted-mappers.ts
CHANGED
|
@@ -108,7 +108,11 @@ export function userTradeFromV0(payload: Record<string, unknown>): UserTrade {
|
|
|
108
108
|
const trade: UserTrade = {
|
|
109
109
|
id: strOrEmpty(payload["id"]),
|
|
110
110
|
price: floatOrZero(payload["price"]),
|
|
111
|
-
|
|
111
|
+
// The v0 wire sends trade amounts in 6-dec micro-shares (verified
|
|
112
|
+
// live: 58139533.0 == 58.139533 shares, matching the same position's
|
|
113
|
+
// decimal `shares`). Normalize so UserTrade.amount means shares,
|
|
114
|
+
// like everywhere else in the SDK.
|
|
115
|
+
amount: floatOrZero(payload["amount"]) / 1_000_000,
|
|
112
116
|
side,
|
|
113
117
|
timestamp: timestampToMs(payload["timestamp"]),
|
|
114
118
|
};
|
|
@@ -130,7 +134,8 @@ export function userTradeToV0(trade: UserTrade): Record<string, unknown> {
|
|
|
130
134
|
const out: Record<string, unknown> = {
|
|
131
135
|
id: trade.id,
|
|
132
136
|
side: trade.side,
|
|
133
|
-
|
|
137
|
+
// Inverse of userTradeFromV0: decimal shares -> 6-dec micro-shares.
|
|
138
|
+
amount: Math.round(trade.amount * 1_000_000),
|
|
134
139
|
price: trade.price,
|
|
135
140
|
timestamp: msToTimestamp(trade.timestamp),
|
|
136
141
|
};
|
|
@@ -442,6 +442,28 @@ function validateWorstPrice(
|
|
|
442
442
|
): void {
|
|
443
443
|
const worstPriceMicro = messageBigInt(message, "worst_price", "worstPrice");
|
|
444
444
|
const worstPrice = Number(worstPriceMicro) / SIX_DEC_DIVISOR;
|
|
445
|
+
|
|
446
|
+
// Hosted MARKET orders pin worst_price to the tick-grid extreme by
|
|
447
|
+
// design ("textbook market semantics"): the binding user protection is
|
|
448
|
+
// max_cost_usdc (buys) / shares_6dec (sells), validated above. A
|
|
449
|
+
// slippage bound on worst_price would reject every server-built market
|
|
450
|
+
// order, so only sanity-check the price domain here.
|
|
451
|
+
const orderType = String(
|
|
452
|
+
firstPresent(
|
|
453
|
+
getField(buildRequest, "order_type"),
|
|
454
|
+
getField(buildRequest, "orderType"),
|
|
455
|
+
"market",
|
|
456
|
+
),
|
|
457
|
+
).toLowerCase();
|
|
458
|
+
if (orderType === "market") {
|
|
459
|
+
if (!(worstPrice > 0 && worstPrice < 1)) {
|
|
460
|
+
economicFail(
|
|
461
|
+
`worst_price expected within (0, 1) got ${worstPrice}`,
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
|
|
445
467
|
const slippagePctRaw = firstPresent(
|
|
446
468
|
getField(buildRequest, "slippage_pct"),
|
|
447
469
|
getField(buildRequest, "slippagePct"),
|
package/pmxt/router.ts
CHANGED
|
@@ -224,6 +224,8 @@ export class Router extends Exchange {
|
|
|
224
224
|
marketId?: string;
|
|
225
225
|
slug?: string;
|
|
226
226
|
url?: string;
|
|
227
|
+
query?: string;
|
|
228
|
+
category?: string;
|
|
227
229
|
relation?: MatchRelation;
|
|
228
230
|
minConfidence?: number;
|
|
229
231
|
limit?: number;
|
|
@@ -234,6 +236,8 @@ export class Router extends Exchange {
|
|
|
234
236
|
marketId?: string;
|
|
235
237
|
slug?: string;
|
|
236
238
|
url?: string;
|
|
239
|
+
query?: string;
|
|
240
|
+
category?: string;
|
|
237
241
|
relation?: MatchRelation;
|
|
238
242
|
minConfidence?: number;
|
|
239
243
|
limit?: number;
|
|
@@ -246,6 +250,8 @@ export class Router extends Exchange {
|
|
|
246
250
|
if (marketId) query.marketId = marketId;
|
|
247
251
|
if (params.slug ?? params.market?.slug) query.slug = params.slug ?? params.market?.slug;
|
|
248
252
|
if (params.url) query.url = params.url;
|
|
253
|
+
if (params.query) query.query = params.query;
|
|
254
|
+
if (params.category) query.category = params.category;
|
|
249
255
|
if (params.relation) query.relation = params.relation;
|
|
250
256
|
if (params.minConfidence !== undefined) query.minConfidence = params.minConfidence;
|
|
251
257
|
if (params.limit !== undefined) query.limit = params.limit;
|
|
@@ -274,6 +280,8 @@ export class Router extends Exchange {
|
|
|
274
280
|
marketId?: string;
|
|
275
281
|
slug?: string;
|
|
276
282
|
url?: string;
|
|
283
|
+
query?: string;
|
|
284
|
+
category?: string;
|
|
277
285
|
relation?: MatchRelation;
|
|
278
286
|
minConfidence?: number;
|
|
279
287
|
limit?: number;
|
|
@@ -284,6 +292,8 @@ export class Router extends Exchange {
|
|
|
284
292
|
marketId?: string;
|
|
285
293
|
slug?: string;
|
|
286
294
|
url?: string;
|
|
295
|
+
query?: string;
|
|
296
|
+
category?: string;
|
|
287
297
|
relation?: MatchRelation;
|
|
288
298
|
minConfidence?: number;
|
|
289
299
|
limit?: number;
|
|
@@ -303,6 +313,8 @@ export class Router extends Exchange {
|
|
|
303
313
|
event?: UnifiedEvent;
|
|
304
314
|
eventId?: string;
|
|
305
315
|
slug?: string;
|
|
316
|
+
query?: string;
|
|
317
|
+
category?: string;
|
|
306
318
|
relation?: MatchRelation;
|
|
307
319
|
minConfidence?: number;
|
|
308
320
|
limit?: number;
|
|
@@ -312,6 +324,8 @@ export class Router extends Exchange {
|
|
|
312
324
|
event?: UnifiedEvent;
|
|
313
325
|
eventId?: string;
|
|
314
326
|
slug?: string;
|
|
327
|
+
query?: string;
|
|
328
|
+
category?: string;
|
|
315
329
|
relation?: MatchRelation;
|
|
316
330
|
minConfidence?: number;
|
|
317
331
|
limit?: number;
|
|
@@ -323,6 +337,8 @@ export class Router extends Exchange {
|
|
|
323
337
|
const eventId = params.eventId ?? (!params.event?.slug ? params.event?.id : undefined);
|
|
324
338
|
if (eventId) query.eventId = eventId;
|
|
325
339
|
if (params.slug ?? params.event?.slug) query.slug = params.slug ?? params.event?.slug;
|
|
340
|
+
if (params.query) query.query = params.query;
|
|
341
|
+
if (params.category) query.category = params.category;
|
|
326
342
|
if (params.relation) query.relation = params.relation;
|
|
327
343
|
if (params.minConfidence !== undefined) query.minConfidence = params.minConfidence;
|
|
328
344
|
if (params.limit !== undefined) query.limit = params.limit;
|
package/pmxt/server-manager.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { DefaultApi, Configuration } from "../generated/src/index.js";
|
|
|
8
8
|
import { readFileSync, existsSync } from "fs";
|
|
9
9
|
import { homedir } from "os";
|
|
10
10
|
import { join, dirname } from "path";
|
|
11
|
+
import { logger } from "./logger.js";
|
|
11
12
|
|
|
12
13
|
export interface ServerManagerOptions {
|
|
13
14
|
baseUrl?: string;
|
|
@@ -145,8 +146,8 @@ export class ServerManager {
|
|
|
145
146
|
const data = await response.json() as any;
|
|
146
147
|
if (data.status === "ok") return;
|
|
147
148
|
}
|
|
148
|
-
} catch {
|
|
149
|
-
|
|
149
|
+
} catch (err) {
|
|
150
|
+
logger.debug('server-manager: health poll error', { error: String(err) });
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
await new Promise((resolve) => setTimeout(resolve, this.retryDelayMs));
|
|
@@ -264,8 +265,8 @@ export class ServerManager {
|
|
|
264
265
|
return true;
|
|
265
266
|
}
|
|
266
267
|
}
|
|
267
|
-
} catch {
|
|
268
|
-
|
|
268
|
+
} catch (err) {
|
|
269
|
+
logger.warn('server-manager: version check failed', { error: String(err) });
|
|
269
270
|
}
|
|
270
271
|
return false;
|
|
271
272
|
}
|
|
@@ -385,6 +386,9 @@ export class ServerManager {
|
|
|
385
386
|
try {
|
|
386
387
|
const { unlinkSync } = await import('fs');
|
|
387
388
|
unlinkSync(this.lockPath);
|
|
388
|
-
} catch {
|
|
389
|
+
} catch (err) {
|
|
390
|
+
// Best-effort — expected when file was already removed.
|
|
391
|
+
logger.debug('server-manager: lock file removal failed', { path: this.lockPath, error: String(err) });
|
|
392
|
+
}
|
|
389
393
|
}
|
|
390
394
|
}
|
package/pmxt/ws-client.ts
CHANGED