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.
@@ -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
@@ -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")
@@ -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
- market: convertMarket(r.market || {}),
333
- relation: r.relation || 'identity',
334
- confidence: r.confidence || 0,
335
- reasoning: r.reasoning,
336
- bestBid: r.bestBid,
337
- bestAsk: r.bestAsk,
338
- venue: r.venue || '',
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
- market: convertMarket(r.market || {}),
365
- relation: r.relation || 'identity',
366
- confidence: r.confidence || 0,
367
- reasoning: r.reasoning,
368
- bestBid: r.bestBid,
369
- bestAsk: r.bestAsk,
370
- venue: r.venue || '',
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)
@@ -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
@@ -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")
@@ -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
- market: convertMarket(r.market || {}),
369
- relation: r.relation || 'identity',
370
- confidence: r.confidence || 0,
371
- reasoning: r.reasoning,
372
- bestBid: r.bestBid,
373
- bestAsk: r.bestAsk,
374
- venue: r.venue || '',
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
- market: convertMarket(r.market || {}),
401
- relation: r.relation || 'identity',
402
- confidence: r.confidence || 0,
403
- reasoning: r.reasoning,
404
- bestBid: r.bestBid,
405
- bestAsk: r.bestAsk,
406
- venue: r.venue || '',
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)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxtjs",
3
- "version": "2.50.11",
3
+ "version": "2.50.13",
4
4
  "description": "OpenAPI client for pmxtjs",
5
5
  "author": "OpenAPI-Generator",
6
6
  "repository": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxtjs",
3
- "version": "2.50.11",
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.11",
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
- market: convertMarket(r.market || {}),
496
- relation: r.relation || 'identity',
497
- confidence: r.confidence || 0,
498
- reasoning: r.reasoning,
499
- bestBid: r.bestBid,
500
- bestAsk: r.bestAsk,
501
- venue: r.venue || '',
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
- market: convertMarket(r.market || {}),
545
- relation: r.relation || 'identity',
546
- confidence: r.confidence || 0,
547
- reasoning: r.reasoning,
548
- bestBid: r.bestBid,
549
- bestAsk: r.bestAsk,
550
- venue: r.venue || '',
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}`);