pmxtjs 2.50.11 → 2.50.13
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/pmxt/client.d.ts +5 -0
- package/dist/esm/pmxt/client.js +57 -1
- package/dist/esm/pmxt/router.js +37 -18
- package/dist/pmxt/client.d.ts +5 -0
- package/dist/pmxt/client.js +56 -0
- package/dist/pmxt/router.js +37 -18
- package/generated/package.json +1 -1
- package/package.json +2 -2
- package/pmxt/client.ts +61 -0
- package/pmxt/router.ts +43 -18
|
@@ -449,6 +449,11 @@ export declare abstract class Exchange {
|
|
|
449
449
|
* pull-leg route name for Opinion sells and Limitless cross-chain orders.
|
|
450
450
|
*/
|
|
451
451
|
private _hostedTypedDataRoute;
|
|
452
|
+
/**
|
|
453
|
+
* Hosted-mode cancelOrder: build → sign → cancel single-call wrapper.
|
|
454
|
+
* Mirrors the Python SDK's `_hosted_cancel_order`.
|
|
455
|
+
*/
|
|
456
|
+
private _hostedCancelOrder;
|
|
452
457
|
private _hostedCancelTypedDataRoute;
|
|
453
458
|
/**
|
|
454
459
|
* Construct the hosted build-order request body and validate inputs
|
package/dist/esm/pmxt/client.js
CHANGED
|
@@ -18,7 +18,7 @@ import { logger } from "./logger.js";
|
|
|
18
18
|
// "Cannot find module" errors during the parallel landing window resolve
|
|
19
19
|
// once the matching files exist.
|
|
20
20
|
import { HOSTED_TRADING_VENUES, _tradingRequest, resolveWalletAddress, formatRoutePath, HOSTED_METHOD_ROUTES, } from "./hosted-routing.js";
|
|
21
|
-
import { orderFromV0, positionFromV0, balanceFromV0, to6dec, } from "./hosted-mappers.js";
|
|
21
|
+
import { orderFromV0, positionFromV0, balanceFromV0, userTradeFromV0, to6dec, } from "./hosted-mappers.js";
|
|
22
22
|
import { validateTypedData, validateEconomics, verifySignature, } from "./hosted-typed-data.js";
|
|
23
23
|
import { EthersSigner } from "./signers.js";
|
|
24
24
|
import { Escrow } from "./escrow.js";
|
|
@@ -952,6 +952,9 @@ export class Exchange {
|
|
|
952
952
|
}
|
|
953
953
|
async cancelOrder(orderId) {
|
|
954
954
|
await this.initPromise;
|
|
955
|
+
if (this.isHosted) {
|
|
956
|
+
return this._hostedCancelOrder(orderId);
|
|
957
|
+
}
|
|
955
958
|
try {
|
|
956
959
|
const args = [];
|
|
957
960
|
args.push(orderId);
|
|
@@ -1040,6 +1043,14 @@ export class Exchange {
|
|
|
1040
1043
|
}
|
|
1041
1044
|
async fetchMyTrades(params) {
|
|
1042
1045
|
await this.initPromise;
|
|
1046
|
+
if (this.isHosted) {
|
|
1047
|
+
const resolvedAddress = resolveWalletAddress(this, undefined);
|
|
1048
|
+
const route = HOSTED_METHOD_ROUTES.get("fetchMyTrades");
|
|
1049
|
+
const path = formatRoutePath(route, { address: resolvedAddress });
|
|
1050
|
+
const data = await _tradingRequest(this, { method: route.method, path });
|
|
1051
|
+
const list = Array.isArray(data) ? data : (data && Array.isArray(data.trades) ? data.trades : []);
|
|
1052
|
+
return list.map((t) => userTradeFromV0(t));
|
|
1053
|
+
}
|
|
1043
1054
|
try {
|
|
1044
1055
|
const args = [];
|
|
1045
1056
|
if (params !== undefined)
|
|
@@ -2102,6 +2113,51 @@ export class Exchange {
|
|
|
2102
2113
|
return "opinion_buy";
|
|
2103
2114
|
return isPull ? "opinion_sell_bsc_pull" : "opinion_sell_polygon";
|
|
2104
2115
|
}
|
|
2116
|
+
/**
|
|
2117
|
+
* Hosted-mode cancelOrder: build → sign → cancel single-call wrapper.
|
|
2118
|
+
* Mirrors the Python SDK's `_hosted_cancel_order`.
|
|
2119
|
+
*/
|
|
2120
|
+
async _hostedCancelOrder(orderId) {
|
|
2121
|
+
const signer = this.requireHostedSigner();
|
|
2122
|
+
if (!this.walletAddress) {
|
|
2123
|
+
throw new MissingWalletAddress("hosted cancelOrder requires walletAddress");
|
|
2124
|
+
}
|
|
2125
|
+
const buildRequest = { order_id: orderId, user_address: this.walletAddress };
|
|
2126
|
+
const buildRoute = HOSTED_METHOD_ROUTES.get("cancelOrderBuild");
|
|
2127
|
+
const buildPayload = await _tradingRequest(this, {
|
|
2128
|
+
method: buildRoute.method,
|
|
2129
|
+
path: buildRoute.path,
|
|
2130
|
+
body: buildRequest,
|
|
2131
|
+
});
|
|
2132
|
+
const typedData = buildPayload["typed_data"];
|
|
2133
|
+
if (!typedData) {
|
|
2134
|
+
throw new HostedInvalidSignature(0, "typed_data missing from hosted cancel build response");
|
|
2135
|
+
}
|
|
2136
|
+
const primaryRoute = this._hostedCancelTypedDataRoute(false);
|
|
2137
|
+
validateTypedData(typedData, primaryRoute, this.walletAddress);
|
|
2138
|
+
const signature = await signer.signTypedData(typedData);
|
|
2139
|
+
verifySignature(typedData, signature, signer.address);
|
|
2140
|
+
const cancelId = buildPayload["cancel_id"];
|
|
2141
|
+
if (!cancelId) {
|
|
2142
|
+
throw new HostedInvalidSignature(0, "cancel_id missing from hosted cancel build response");
|
|
2143
|
+
}
|
|
2144
|
+
const body = { cancel_id: cancelId, signature };
|
|
2145
|
+
const pullTypedData = buildPayload["pull_typed_data"];
|
|
2146
|
+
if (pullTypedData) {
|
|
2147
|
+
const pullRoute = this._hostedCancelTypedDataRoute(true);
|
|
2148
|
+
validateTypedData(pullTypedData, pullRoute, this.walletAddress);
|
|
2149
|
+
const pullSig = await signer.signTypedData(pullTypedData);
|
|
2150
|
+
verifySignature(pullTypedData, pullSig, signer.address);
|
|
2151
|
+
body["pull_signature"] = pullSig;
|
|
2152
|
+
}
|
|
2153
|
+
const cancelRoute = HOSTED_METHOD_ROUTES.get("cancelOrder");
|
|
2154
|
+
const data = await _tradingRequest(this, {
|
|
2155
|
+
method: cancelRoute.method,
|
|
2156
|
+
path: cancelRoute.path,
|
|
2157
|
+
body,
|
|
2158
|
+
});
|
|
2159
|
+
return orderFromV0(data);
|
|
2160
|
+
}
|
|
2105
2161
|
_hostedCancelTypedDataRoute(isPull) {
|
|
2106
2162
|
const venue = this.exchangeName;
|
|
2107
2163
|
if (venue === "polymarket")
|
package/dist/esm/pmxt/router.js
CHANGED
|
@@ -328,15 +328,27 @@ export class Router extends Exchange {
|
|
|
328
328
|
const data = this.handleResponse(json);
|
|
329
329
|
if (!data)
|
|
330
330
|
return [];
|
|
331
|
-
return data.map((r) =>
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
bestBid
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
331
|
+
return data.map((r) => {
|
|
332
|
+
const marketPayload = r.market || {};
|
|
333
|
+
const market = convertMarket(marketPayload);
|
|
334
|
+
// Hosted /api/router response carries the live bid/ask on the
|
|
335
|
+
// nested market (and the venue via market.sourceExchange). The
|
|
336
|
+
// top-level bestBid/bestAsk/venue fields are legacy and often
|
|
337
|
+
// null on the wire, so prefer the market fields and fall back
|
|
338
|
+
// to the top-level only when needed.
|
|
339
|
+
const bestBid = r.bestBid ?? market.bestBid ?? marketPayload.bestBid ?? null;
|
|
340
|
+
const bestAsk = r.bestAsk ?? market.bestAsk ?? marketPayload.bestAsk ?? null;
|
|
341
|
+
const venue = r.venue || market.sourceExchange || marketPayload.sourceExchange || '';
|
|
342
|
+
return {
|
|
343
|
+
market,
|
|
344
|
+
relation: r.relation || 'identity',
|
|
345
|
+
confidence: r.confidence || 0,
|
|
346
|
+
reasoning: r.reasoning,
|
|
347
|
+
bestBid,
|
|
348
|
+
bestAsk,
|
|
349
|
+
venue,
|
|
350
|
+
};
|
|
351
|
+
});
|
|
340
352
|
}
|
|
341
353
|
catch (error) {
|
|
342
354
|
if (error instanceof Error)
|
|
@@ -360,15 +372,22 @@ export class Router extends Exchange {
|
|
|
360
372
|
const data = this.handleResponse(json);
|
|
361
373
|
if (!data)
|
|
362
374
|
return [];
|
|
363
|
-
return data.map((r) =>
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
375
|
+
return data.map((r) => {
|
|
376
|
+
const marketPayload = r.market || {};
|
|
377
|
+
const market = convertMarket(marketPayload);
|
|
378
|
+
const bestBid = r.bestBid ?? market.bestBid ?? marketPayload.bestBid ?? null;
|
|
379
|
+
const bestAsk = r.bestAsk ?? market.bestAsk ?? marketPayload.bestAsk ?? null;
|
|
380
|
+
const venue = r.venue || market.sourceExchange || marketPayload.sourceExchange || '';
|
|
381
|
+
return {
|
|
382
|
+
market,
|
|
383
|
+
relation: r.relation || 'identity',
|
|
384
|
+
confidence: r.confidence || 0,
|
|
385
|
+
reasoning: r.reasoning,
|
|
386
|
+
bestBid,
|
|
387
|
+
bestAsk,
|
|
388
|
+
venue,
|
|
389
|
+
};
|
|
390
|
+
});
|
|
372
391
|
}
|
|
373
392
|
catch (error) {
|
|
374
393
|
if (error instanceof Error)
|
package/dist/pmxt/client.d.ts
CHANGED
|
@@ -449,6 +449,11 @@ export declare abstract class Exchange {
|
|
|
449
449
|
* pull-leg route name for Opinion sells and Limitless cross-chain orders.
|
|
450
450
|
*/
|
|
451
451
|
private _hostedTypedDataRoute;
|
|
452
|
+
/**
|
|
453
|
+
* Hosted-mode cancelOrder: build → sign → cancel single-call wrapper.
|
|
454
|
+
* Mirrors the Python SDK's `_hosted_cancel_order`.
|
|
455
|
+
*/
|
|
456
|
+
private _hostedCancelOrder;
|
|
452
457
|
private _hostedCancelTypedDataRoute;
|
|
453
458
|
/**
|
|
454
459
|
* Construct the hosted build-order request body and validate inputs
|
package/dist/pmxt/client.js
CHANGED
|
@@ -955,6 +955,9 @@ class Exchange {
|
|
|
955
955
|
}
|
|
956
956
|
async cancelOrder(orderId) {
|
|
957
957
|
await this.initPromise;
|
|
958
|
+
if (this.isHosted) {
|
|
959
|
+
return this._hostedCancelOrder(orderId);
|
|
960
|
+
}
|
|
958
961
|
try {
|
|
959
962
|
const args = [];
|
|
960
963
|
args.push(orderId);
|
|
@@ -1043,6 +1046,14 @@ class Exchange {
|
|
|
1043
1046
|
}
|
|
1044
1047
|
async fetchMyTrades(params) {
|
|
1045
1048
|
await this.initPromise;
|
|
1049
|
+
if (this.isHosted) {
|
|
1050
|
+
const resolvedAddress = (0, hosted_routing_js_1.resolveWalletAddress)(this, undefined);
|
|
1051
|
+
const route = hosted_routing_js_1.HOSTED_METHOD_ROUTES.get("fetchMyTrades");
|
|
1052
|
+
const path = (0, hosted_routing_js_1.formatRoutePath)(route, { address: resolvedAddress });
|
|
1053
|
+
const data = await (0, hosted_routing_js_1._tradingRequest)(this, { method: route.method, path });
|
|
1054
|
+
const list = Array.isArray(data) ? data : (data && Array.isArray(data.trades) ? data.trades : []);
|
|
1055
|
+
return list.map((t) => (0, hosted_mappers_js_1.userTradeFromV0)(t));
|
|
1056
|
+
}
|
|
1046
1057
|
try {
|
|
1047
1058
|
const args = [];
|
|
1048
1059
|
if (params !== undefined)
|
|
@@ -2105,6 +2116,51 @@ class Exchange {
|
|
|
2105
2116
|
return "opinion_buy";
|
|
2106
2117
|
return isPull ? "opinion_sell_bsc_pull" : "opinion_sell_polygon";
|
|
2107
2118
|
}
|
|
2119
|
+
/**
|
|
2120
|
+
* Hosted-mode cancelOrder: build → sign → cancel single-call wrapper.
|
|
2121
|
+
* Mirrors the Python SDK's `_hosted_cancel_order`.
|
|
2122
|
+
*/
|
|
2123
|
+
async _hostedCancelOrder(orderId) {
|
|
2124
|
+
const signer = this.requireHostedSigner();
|
|
2125
|
+
if (!this.walletAddress) {
|
|
2126
|
+
throw new hosted_errors_js_1.MissingWalletAddress("hosted cancelOrder requires walletAddress");
|
|
2127
|
+
}
|
|
2128
|
+
const buildRequest = { order_id: orderId, user_address: this.walletAddress };
|
|
2129
|
+
const buildRoute = hosted_routing_js_1.HOSTED_METHOD_ROUTES.get("cancelOrderBuild");
|
|
2130
|
+
const buildPayload = await (0, hosted_routing_js_1._tradingRequest)(this, {
|
|
2131
|
+
method: buildRoute.method,
|
|
2132
|
+
path: buildRoute.path,
|
|
2133
|
+
body: buildRequest,
|
|
2134
|
+
});
|
|
2135
|
+
const typedData = buildPayload["typed_data"];
|
|
2136
|
+
if (!typedData) {
|
|
2137
|
+
throw new hosted_errors_js_1.InvalidSignature(0, "typed_data missing from hosted cancel build response");
|
|
2138
|
+
}
|
|
2139
|
+
const primaryRoute = this._hostedCancelTypedDataRoute(false);
|
|
2140
|
+
(0, hosted_typed_data_js_1.validateTypedData)(typedData, primaryRoute, this.walletAddress);
|
|
2141
|
+
const signature = await signer.signTypedData(typedData);
|
|
2142
|
+
(0, hosted_typed_data_js_1.verifySignature)(typedData, signature, signer.address);
|
|
2143
|
+
const cancelId = buildPayload["cancel_id"];
|
|
2144
|
+
if (!cancelId) {
|
|
2145
|
+
throw new hosted_errors_js_1.InvalidSignature(0, "cancel_id missing from hosted cancel build response");
|
|
2146
|
+
}
|
|
2147
|
+
const body = { cancel_id: cancelId, signature };
|
|
2148
|
+
const pullTypedData = buildPayload["pull_typed_data"];
|
|
2149
|
+
if (pullTypedData) {
|
|
2150
|
+
const pullRoute = this._hostedCancelTypedDataRoute(true);
|
|
2151
|
+
(0, hosted_typed_data_js_1.validateTypedData)(pullTypedData, pullRoute, this.walletAddress);
|
|
2152
|
+
const pullSig = await signer.signTypedData(pullTypedData);
|
|
2153
|
+
(0, hosted_typed_data_js_1.verifySignature)(pullTypedData, pullSig, signer.address);
|
|
2154
|
+
body["pull_signature"] = pullSig;
|
|
2155
|
+
}
|
|
2156
|
+
const cancelRoute = hosted_routing_js_1.HOSTED_METHOD_ROUTES.get("cancelOrder");
|
|
2157
|
+
const data = await (0, hosted_routing_js_1._tradingRequest)(this, {
|
|
2158
|
+
method: cancelRoute.method,
|
|
2159
|
+
path: cancelRoute.path,
|
|
2160
|
+
body,
|
|
2161
|
+
});
|
|
2162
|
+
return (0, hosted_mappers_js_1.orderFromV0)(data);
|
|
2163
|
+
}
|
|
2108
2164
|
_hostedCancelTypedDataRoute(isPull) {
|
|
2109
2165
|
const venue = this.exchangeName;
|
|
2110
2166
|
if (venue === "polymarket")
|
package/dist/pmxt/router.js
CHANGED
|
@@ -364,15 +364,27 @@ class Router extends client_js_1.Exchange {
|
|
|
364
364
|
const data = this.handleResponse(json);
|
|
365
365
|
if (!data)
|
|
366
366
|
return [];
|
|
367
|
-
return data.map((r) =>
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
bestBid
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
367
|
+
return data.map((r) => {
|
|
368
|
+
const marketPayload = r.market || {};
|
|
369
|
+
const market = convertMarket(marketPayload);
|
|
370
|
+
// Hosted /api/router response carries the live bid/ask on the
|
|
371
|
+
// nested market (and the venue via market.sourceExchange). The
|
|
372
|
+
// top-level bestBid/bestAsk/venue fields are legacy and often
|
|
373
|
+
// null on the wire, so prefer the market fields and fall back
|
|
374
|
+
// to the top-level only when needed.
|
|
375
|
+
const bestBid = r.bestBid ?? market.bestBid ?? marketPayload.bestBid ?? null;
|
|
376
|
+
const bestAsk = r.bestAsk ?? market.bestAsk ?? marketPayload.bestAsk ?? null;
|
|
377
|
+
const venue = r.venue || market.sourceExchange || marketPayload.sourceExchange || '';
|
|
378
|
+
return {
|
|
379
|
+
market,
|
|
380
|
+
relation: r.relation || 'identity',
|
|
381
|
+
confidence: r.confidence || 0,
|
|
382
|
+
reasoning: r.reasoning,
|
|
383
|
+
bestBid,
|
|
384
|
+
bestAsk,
|
|
385
|
+
venue,
|
|
386
|
+
};
|
|
387
|
+
});
|
|
376
388
|
}
|
|
377
389
|
catch (error) {
|
|
378
390
|
if (error instanceof Error)
|
|
@@ -396,15 +408,22 @@ class Router extends client_js_1.Exchange {
|
|
|
396
408
|
const data = this.handleResponse(json);
|
|
397
409
|
if (!data)
|
|
398
410
|
return [];
|
|
399
|
-
return data.map((r) =>
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
411
|
+
return data.map((r) => {
|
|
412
|
+
const marketPayload = r.market || {};
|
|
413
|
+
const market = convertMarket(marketPayload);
|
|
414
|
+
const bestBid = r.bestBid ?? market.bestBid ?? marketPayload.bestBid ?? null;
|
|
415
|
+
const bestAsk = r.bestAsk ?? market.bestAsk ?? marketPayload.bestAsk ?? null;
|
|
416
|
+
const venue = r.venue || market.sourceExchange || marketPayload.sourceExchange || '';
|
|
417
|
+
return {
|
|
418
|
+
market,
|
|
419
|
+
relation: r.relation || 'identity',
|
|
420
|
+
confidence: r.confidence || 0,
|
|
421
|
+
reasoning: r.reasoning,
|
|
422
|
+
bestBid,
|
|
423
|
+
bestAsk,
|
|
424
|
+
venue,
|
|
425
|
+
};
|
|
426
|
+
});
|
|
408
427
|
}
|
|
409
428
|
catch (error) {
|
|
410
429
|
if (error instanceof Error)
|
package/generated/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxtjs",
|
|
3
|
-
"version": "2.50.
|
|
3
|
+
"version": "2.50.13",
|
|
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.50.
|
|
46
|
+
"pmxt-core": "2.50.13",
|
|
47
47
|
"ws": "^8.18.0"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
package/pmxt/client.ts
CHANGED
|
@@ -1162,6 +1162,9 @@ export abstract class Exchange {
|
|
|
1162
1162
|
|
|
1163
1163
|
async cancelOrder(orderId: string): Promise<Order> {
|
|
1164
1164
|
await this.initPromise;
|
|
1165
|
+
if (this.isHosted) {
|
|
1166
|
+
return this._hostedCancelOrder(orderId);
|
|
1167
|
+
}
|
|
1165
1168
|
try {
|
|
1166
1169
|
const args: any[] = [];
|
|
1167
1170
|
args.push(orderId);
|
|
@@ -1246,6 +1249,14 @@ export abstract class Exchange {
|
|
|
1246
1249
|
|
|
1247
1250
|
async fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]> {
|
|
1248
1251
|
await this.initPromise;
|
|
1252
|
+
if (this.isHosted) {
|
|
1253
|
+
const resolvedAddress = resolveWalletAddress(this, undefined);
|
|
1254
|
+
const route = HOSTED_METHOD_ROUTES.get("fetchMyTrades")!;
|
|
1255
|
+
const path = formatRoutePath(route, { address: resolvedAddress });
|
|
1256
|
+
const data = await _tradingRequest(this, { method: route.method, path });
|
|
1257
|
+
const list = Array.isArray(data) ? data : (data && Array.isArray((data as any).trades) ? (data as any).trades : []);
|
|
1258
|
+
return list.map((t: unknown) => userTradeFromV0(t as Record<string, unknown>));
|
|
1259
|
+
}
|
|
1249
1260
|
try {
|
|
1250
1261
|
const args: any[] = [];
|
|
1251
1262
|
if (params !== undefined) args.push(params);
|
|
@@ -2333,6 +2344,56 @@ export abstract class Exchange {
|
|
|
2333
2344
|
return isPull ? "opinion_sell_bsc_pull" : "opinion_sell_polygon";
|
|
2334
2345
|
}
|
|
2335
2346
|
|
|
2347
|
+
/**
|
|
2348
|
+
* Hosted-mode cancelOrder: build → sign → cancel single-call wrapper.
|
|
2349
|
+
* Mirrors the Python SDK's `_hosted_cancel_order`.
|
|
2350
|
+
*/
|
|
2351
|
+
private async _hostedCancelOrder(orderId: string): Promise<Order> {
|
|
2352
|
+
const signer = this.requireHostedSigner();
|
|
2353
|
+
if (!this.walletAddress) {
|
|
2354
|
+
throw new MissingWalletAddress("hosted cancelOrder requires walletAddress");
|
|
2355
|
+
}
|
|
2356
|
+
const buildRequest = { order_id: orderId, user_address: this.walletAddress };
|
|
2357
|
+
const buildRoute = HOSTED_METHOD_ROUTES.get("cancelOrderBuild")!;
|
|
2358
|
+
const buildPayload = await _tradingRequest(this, {
|
|
2359
|
+
method: buildRoute.method,
|
|
2360
|
+
path: buildRoute.path,
|
|
2361
|
+
body: buildRequest,
|
|
2362
|
+
}) as Record<string, unknown>;
|
|
2363
|
+
|
|
2364
|
+
const typedData = buildPayload["typed_data"] as TypedData | undefined;
|
|
2365
|
+
if (!typedData) {
|
|
2366
|
+
throw new HostedInvalidSignature(0, "typed_data missing from hosted cancel build response");
|
|
2367
|
+
}
|
|
2368
|
+
const primaryRoute = this._hostedCancelTypedDataRoute(false);
|
|
2369
|
+
validateTypedData(typedData, primaryRoute, this.walletAddress);
|
|
2370
|
+
const signature = await signer.signTypedData(typedData);
|
|
2371
|
+
verifySignature(typedData, signature, signer.address);
|
|
2372
|
+
|
|
2373
|
+
const cancelId = buildPayload["cancel_id"];
|
|
2374
|
+
if (!cancelId) {
|
|
2375
|
+
throw new HostedInvalidSignature(0, "cancel_id missing from hosted cancel build response");
|
|
2376
|
+
}
|
|
2377
|
+
const body: Record<string, unknown> = { cancel_id: cancelId, signature };
|
|
2378
|
+
|
|
2379
|
+
const pullTypedData = buildPayload["pull_typed_data"] as TypedData | undefined;
|
|
2380
|
+
if (pullTypedData) {
|
|
2381
|
+
const pullRoute = this._hostedCancelTypedDataRoute(true);
|
|
2382
|
+
validateTypedData(pullTypedData, pullRoute, this.walletAddress);
|
|
2383
|
+
const pullSig = await signer.signTypedData(pullTypedData);
|
|
2384
|
+
verifySignature(pullTypedData, pullSig, signer.address);
|
|
2385
|
+
body["pull_signature"] = pullSig;
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
const cancelRoute = HOSTED_METHOD_ROUTES.get("cancelOrder")!;
|
|
2389
|
+
const data = await _tradingRequest(this, {
|
|
2390
|
+
method: cancelRoute.method,
|
|
2391
|
+
path: cancelRoute.path,
|
|
2392
|
+
body,
|
|
2393
|
+
});
|
|
2394
|
+
return orderFromV0(data as Record<string, unknown>);
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2336
2397
|
private _hostedCancelTypedDataRoute(isPull: boolean): string {
|
|
2337
2398
|
const venue = this.exchangeName;
|
|
2338
2399
|
if (venue === "polymarket") return "cancel_polymarket";
|
package/pmxt/router.ts
CHANGED
|
@@ -491,15 +491,30 @@ export class Router extends Exchange {
|
|
|
491
491
|
const json = await response.json();
|
|
492
492
|
const data = this.handleResponse(json);
|
|
493
493
|
if (!data) return [];
|
|
494
|
-
return (data as any[]).map((r) =>
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
bestBid
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
494
|
+
return (data as any[]).map((r) => {
|
|
495
|
+
const marketPayload = r.market || {};
|
|
496
|
+
const market = convertMarket(marketPayload);
|
|
497
|
+
// Hosted /api/router response carries the live bid/ask on the
|
|
498
|
+
// nested market (and the venue via market.sourceExchange). The
|
|
499
|
+
// top-level bestBid/bestAsk/venue fields are legacy and often
|
|
500
|
+
// null on the wire, so prefer the market fields and fall back
|
|
501
|
+
// to the top-level only when needed.
|
|
502
|
+
const bestBid =
|
|
503
|
+
r.bestBid ?? (market as any).bestBid ?? marketPayload.bestBid ?? null;
|
|
504
|
+
const bestAsk =
|
|
505
|
+
r.bestAsk ?? (market as any).bestAsk ?? marketPayload.bestAsk ?? null;
|
|
506
|
+
const venue =
|
|
507
|
+
r.venue || (market as any).sourceExchange || marketPayload.sourceExchange || '';
|
|
508
|
+
return {
|
|
509
|
+
market,
|
|
510
|
+
relation: r.relation || 'identity',
|
|
511
|
+
confidence: r.confidence || 0,
|
|
512
|
+
reasoning: r.reasoning,
|
|
513
|
+
bestBid,
|
|
514
|
+
bestAsk,
|
|
515
|
+
venue,
|
|
516
|
+
};
|
|
517
|
+
});
|
|
503
518
|
} catch (error) {
|
|
504
519
|
if (error instanceof Error) throw error;
|
|
505
520
|
throw new Error(`Failed to compareMarketPrices: ${error}`);
|
|
@@ -540,15 +555,25 @@ export class Router extends Exchange {
|
|
|
540
555
|
const json = await this.sidecarReadRequest('fetchHedges', query, [query]);
|
|
541
556
|
const data = this.handleResponse(json);
|
|
542
557
|
if (!data) return [];
|
|
543
|
-
return (data as any[]).map((r) =>
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
558
|
+
return (data as any[]).map((r) => {
|
|
559
|
+
const marketPayload = r.market || {};
|
|
560
|
+
const market = convertMarket(marketPayload);
|
|
561
|
+
const bestBid =
|
|
562
|
+
r.bestBid ?? (market as any).bestBid ?? marketPayload.bestBid ?? null;
|
|
563
|
+
const bestAsk =
|
|
564
|
+
r.bestAsk ?? (market as any).bestAsk ?? marketPayload.bestAsk ?? null;
|
|
565
|
+
const venue =
|
|
566
|
+
r.venue || (market as any).sourceExchange || marketPayload.sourceExchange || '';
|
|
567
|
+
return {
|
|
568
|
+
market,
|
|
569
|
+
relation: r.relation || 'identity',
|
|
570
|
+
confidence: r.confidence || 0,
|
|
571
|
+
reasoning: r.reasoning,
|
|
572
|
+
bestBid,
|
|
573
|
+
bestAsk,
|
|
574
|
+
venue,
|
|
575
|
+
};
|
|
576
|
+
});
|
|
552
577
|
} catch (error) {
|
|
553
578
|
if (error instanceof Error) throw error;
|
|
554
579
|
throw new Error(`Failed to fetchHedges: ${error}`);
|