pmxt-core 2.35.7 → 2.35.9

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.
@@ -2,7 +2,7 @@ import { AxiosInstance } from 'axios';
2
2
  import { SubscribedAddressSnapshot, SubscriptionOption } from './subscriber/base';
3
3
  import { Balance, BuiltOrder, CandleInterval, CreateOrderParams, Order, OrderBook, Position, PriceCandle, Trade, UnifiedEvent, UnifiedMarket, UserTrade } from './types';
4
4
  import { ExecutionPriceResult } from './utils/math';
5
- import type { FetchMarketMatchesParams, FetchMatchesParams, FetchEventMatchesParams, FetchArbitrageParams, MatchResult, EventMatchResult, PriceComparison, ArbitrageOpportunity } from './router/types';
5
+ import type { FetchMarketMatchesParams, FetchMatchesParams, FetchEventMatchesParams, FetchArbitrageParams, FetchMatchedMarketsParams, FetchMatchedPricesParams, MatchResult, EventMatchResult, PriceComparison, ArbitrageOpportunity, MatchedMarketPair, MatchedPricePair } from './router/types';
6
6
  export interface ApiEndpoint {
7
7
  /** HTTP verb for the endpoint (e.g. GET, POST). */
8
8
  method: string;
@@ -236,9 +236,15 @@ export interface ExchangeHas {
236
236
  fetchEventMatches: ExchangeCapability;
237
237
  /** Whether this exchange supports comparing prices across venues. */
238
238
  compareMarketPrices: ExchangeCapability;
239
- /** Whether this exchange supports finding hedging opportunities across venues. */
239
+ /** Whether this exchange supports finding related markets across venues. */
240
+ fetchRelatedMarkets: ExchangeCapability;
241
+ /** Whether this exchange supports fetching matched markets across venues. */
242
+ fetchMatchedMarkets: ExchangeCapability;
243
+ /** @deprecated Use {@link fetchMatchedMarkets} instead. */
244
+ fetchMatchedPrices: ExchangeCapability;
245
+ /** @deprecated Use {@link fetchRelatedMarkets} instead. */
240
246
  fetchHedges: ExchangeCapability;
241
- /** Whether this exchange supports scanning for arbitrage opportunities. */
247
+ /** @deprecated Use {@link fetchMatchedMarkets} instead. */
242
248
  fetchArbitrage: ExchangeCapability;
243
249
  }
244
250
  /**
@@ -604,23 +610,35 @@ export declare abstract class PredictionMarketExchange {
604
610
  */
605
611
  close(): Promise<void>;
606
612
  /**
607
- * Find the same or related market on other venues. Given a market on one venue, discover semantically equivalent markets across every other venue PMXT ingests — each with a relation type (identity, subset, superset, overlap, disjoint), confidence score, and reasoning.
613
+ * Find the same or related market on other venues. Two modes:
608
614
  *
609
- * @param params - Match filter parameters (marketId, relation, minConfidence, etc.)
615
+ * **Lookup mode** (marketId/slug/url provided): Given a market on one venue, discover
616
+ * semantically equivalent markets across every other venue PMXT ingests.
617
+ *
618
+ * **Browse mode** (no identifier): Returns all matched market pairs from the catalog.
619
+ * Supports query, category, minDifference, and sort params for filtering.
620
+ *
621
+ * @param params - Match filter parameters
610
622
  * @returns Array of matched markets with relation and confidence
611
623
  */
612
- fetchMarketMatches(params: FetchMarketMatchesParams): Promise<MatchResult[]>;
624
+ fetchMarketMatches(params?: FetchMarketMatchesParams): Promise<MatchResult[]>;
613
625
  /**
614
626
  * @deprecated Use {@link fetchMarketMatches} instead.
615
627
  */
616
628
  fetchMatches(params: FetchMatchesParams): Promise<MatchResult[]>;
617
629
  /**
618
- * Find the same or related event on other venues. Given an event on one venue, discover semantically equivalent events across every other venue PMXT ingests — including market-level match details for each child market.
630
+ * Find the same or related event on other venues. Two modes:
631
+ *
632
+ * **Lookup mode** (eventId/slug provided): Given an event on one venue, discover
633
+ * semantically equivalent events across every other venue PMXT ingests.
619
634
  *
620
- * @param params - Event match filter parameters (eventId, relation, etc.)
635
+ * **Browse mode** (no identifier): Returns all matched event pairs from the catalog.
636
+ * Supports query and category params for filtering.
637
+ *
638
+ * @param params - Event match filter parameters
621
639
  * @returns Array of matched events with market-level match details
622
640
  */
623
- fetchEventMatches(params: FetchEventMatchesParams): Promise<EventMatchResult[]>;
641
+ fetchEventMatches(params?: FetchEventMatchesParams): Promise<EventMatchResult[]>;
624
642
  /**
625
643
  * Compare live prices for the same market across venues. Finds identity matches and returns side-by-side best bid/ask prices so you can spot price differences at a glance.
626
644
  *
@@ -629,14 +647,35 @@ export declare abstract class PredictionMarketExchange {
629
647
  */
630
648
  compareMarketPrices(params: FetchMatchesParams): Promise<PriceComparison[]>;
631
649
  /**
632
- * Find hedging opportunities across venues. Discovers subset/superset market relationships where one market's outcome implies another, enabling cross-venue hedging strategies with live prices.
650
+ * Find related markets across venues. Discovers subset/superset market relationships
651
+ * where one market's outcome implies another, with live prices.
652
+ *
653
+ * @param params - Match filter parameters
654
+ * @returns Array of subset/superset matches with live prices
655
+ */
656
+ fetchRelatedMarkets(params: FetchMatchesParams): Promise<PriceComparison[]>;
657
+ /**
658
+ * @deprecated Use {@link fetchMarketMatches} without a marketId instead.
659
+ * Fetch matched markets across venues.
660
+ */
661
+ fetchMatchedMarkets(params?: FetchMatchedMarketsParams): Promise<MatchedMarketPair[]>;
662
+ /**
663
+ * @deprecated Use {@link fetchMatchedMarkets} instead. Compare matched market prices across venues. Finds markets listed on multiple venues
664
+ * and returns side-by-side pricing data.
665
+ *
666
+ * @param params - Price comparison parameters (minDifference, category, limit)
667
+ * @returns Array of matched market pairs with prices from each venue
668
+ */
669
+ fetchMatchedPrices(params?: FetchMatchedPricesParams): Promise<MatchedPricePair[]>;
670
+ /**
671
+ * @deprecated Use {@link fetchRelatedMarkets} instead. Find hedging opportunities across venues. Discovers subset/superset market relationships where one market's outcome implies another, enabling cross-venue hedging strategies with live prices.
633
672
  *
634
673
  * @param params - Match filter parameters
635
674
  * @returns Array of subset/superset matches with live prices
636
675
  */
637
676
  fetchHedges(params: FetchMatchesParams): Promise<PriceComparison[]>;
638
677
  /**
639
- * Scan for arbitrage opportunities across venues. Finds identity matches where the same market is priced differently on different venues, returning opportunities sorted by spread size.
678
+ * @deprecated Use {@link fetchMatchedPrices} instead. Scan for arbitrage opportunities across venues. Finds identity matches where the same market is priced differently on different venues, returning opportunities sorted by spread size.
640
679
  *
641
680
  * @param params - Arbitrage scan parameters (minSpread, category, limit)
642
681
  * @returns Array of arbitrage opportunities sorted by spread
@@ -820,9 +820,15 @@ class PredictionMarketExchange {
820
820
  // Matching Methods (Router-only; stubs throw for standard exchanges)
821
821
  // ----------------------------------------------------------------------------
822
822
  /**
823
- * Find the same or related market on other venues. Given a market on one venue, discover semantically equivalent markets across every other venue PMXT ingests — each with a relation type (identity, subset, superset, overlap, disjoint), confidence score, and reasoning.
823
+ * Find the same or related market on other venues. Two modes:
824
824
  *
825
- * @param params - Match filter parameters (marketId, relation, minConfidence, etc.)
825
+ * **Lookup mode** (marketId/slug/url provided): Given a market on one venue, discover
826
+ * semantically equivalent markets across every other venue PMXT ingests.
827
+ *
828
+ * **Browse mode** (no identifier): Returns all matched market pairs from the catalog.
829
+ * Supports query, category, minDifference, and sort params for filtering.
830
+ *
831
+ * @param params - Match filter parameters
826
832
  * @returns Array of matched markets with relation and confidence
827
833
  */
828
834
  async fetchMarketMatches(params) {
@@ -836,9 +842,15 @@ class PredictionMarketExchange {
836
842
  return this.fetchMarketMatches(params);
837
843
  }
838
844
  /**
839
- * Find the same or related event on other venues. Given an event on one venue, discover semantically equivalent events across every other venue PMXT ingests — including market-level match details for each child market.
845
+ * Find the same or related event on other venues. Two modes:
846
+ *
847
+ * **Lookup mode** (eventId/slug provided): Given an event on one venue, discover
848
+ * semantically equivalent events across every other venue PMXT ingests.
849
+ *
850
+ * **Browse mode** (no identifier): Returns all matched event pairs from the catalog.
851
+ * Supports query and category params for filtering.
840
852
  *
841
- * @param params - Event match filter parameters (eventId, relation, etc.)
853
+ * @param params - Event match filter parameters
842
854
  * @returns Array of matched events with market-level match details
843
855
  */
844
856
  async fetchEventMatches(params) {
@@ -854,7 +866,34 @@ class PredictionMarketExchange {
854
866
  throw new Error("Method compareMarketPrices not implemented.");
855
867
  }
856
868
  /**
857
- * Find hedging opportunities across venues. Discovers subset/superset market relationships where one market's outcome implies another, enabling cross-venue hedging strategies with live prices.
869
+ * Find related markets across venues. Discovers subset/superset market relationships
870
+ * where one market's outcome implies another, with live prices.
871
+ *
872
+ * @param params - Match filter parameters
873
+ * @returns Array of subset/superset matches with live prices
874
+ */
875
+ async fetchRelatedMarkets(params) {
876
+ throw new Error("Method fetchRelatedMarkets not implemented.");
877
+ }
878
+ /**
879
+ * @deprecated Use {@link fetchMarketMatches} without a marketId instead.
880
+ * Fetch matched markets across venues.
881
+ */
882
+ async fetchMatchedMarkets(params) {
883
+ throw new Error("Method fetchMatchedMarkets not implemented.");
884
+ }
885
+ /**
886
+ * @deprecated Use {@link fetchMatchedMarkets} instead. Compare matched market prices across venues. Finds markets listed on multiple venues
887
+ * and returns side-by-side pricing data.
888
+ *
889
+ * @param params - Price comparison parameters (minDifference, category, limit)
890
+ * @returns Array of matched market pairs with prices from each venue
891
+ */
892
+ async fetchMatchedPrices(params) {
893
+ throw new Error("Method fetchMatchedPrices not implemented.");
894
+ }
895
+ /**
896
+ * @deprecated Use {@link fetchRelatedMarkets} instead. Find hedging opportunities across venues. Discovers subset/superset market relationships where one market's outcome implies another, enabling cross-venue hedging strategies with live prices.
858
897
  *
859
898
  * @param params - Match filter parameters
860
899
  * @returns Array of subset/superset matches with live prices
@@ -863,7 +902,7 @@ class PredictionMarketExchange {
863
902
  throw new Error("Method fetchHedges not implemented.");
864
903
  }
865
904
  /**
866
- * Scan for arbitrage opportunities across venues. Finds identity matches where the same market is priced differently on different venues, returning opportunities sorted by spread size.
905
+ * @deprecated Use {@link fetchMatchedPrices} instead. Scan for arbitrage opportunities across venues. Finds identity matches where the same market is priced differently on different venues, returning opportunities sorted by spread size.
867
906
  *
868
907
  * @param params - Arbitrage scan parameters (minSpread, category, limit)
869
908
  * @returns Array of arbitrage opportunities sorted by spread
@@ -998,7 +1037,7 @@ class PredictionMarketExchange {
998
1037
  'unwatchOrderBook', 'watchTrades', 'fetchMyTrades',
999
1038
  'fetchClosedOrders', 'fetchAllOrders', 'buildOrder', 'submitOrder',
1000
1039
  'fetchMarketMatches', 'fetchMatches', 'fetchEventMatches', 'compareMarketPrices',
1001
- 'fetchHedges', 'fetchArbitrage',
1040
+ 'fetchRelatedMarkets', 'fetchMatchedMarkets', 'fetchMatchedPrices', 'fetchHedges', 'fetchArbitrage',
1002
1041
  ];
1003
1042
  // Compile-time exhaustiveness check: fails tsc if a key exists in
1004
1043
  // ExchangeHas but is missing from _capabilityKeys above.
@@ -1011,7 +1050,7 @@ class PredictionMarketExchange {
1011
1050
  watchTrades: true, fetchMyTrades: true, fetchClosedOrders: true,
1012
1051
  fetchAllOrders: true, buildOrder: true, submitOrder: true,
1013
1052
  fetchMarketMatches: true, fetchMatches: true, fetchEventMatches: true, compareMarketPrices: true,
1014
- fetchHedges: true, fetchArbitrage: true,
1053
+ fetchRelatedMarkets: true, fetchMatchedMarkets: true, fetchMatchedPrices: true, fetchHedges: true, fetchArbitrage: true,
1015
1054
  };
1016
1055
  /**
1017
1056
  * Map from capability keys to the actual method(s) whose override status
@@ -1023,6 +1062,9 @@ class PredictionMarketExchange {
1023
1062
  fetchMarkets: 'fetchMarketsImpl',
1024
1063
  fetchEvents: 'fetchEventsImpl',
1025
1064
  fetchMatches: 'fetchMarketMatches',
1065
+ fetchHedges: 'fetchRelatedMarkets',
1066
+ fetchMatchedPrices: 'fetchMatchedMarkets',
1067
+ fetchArbitrage: 'fetchMatchedMarkets',
1026
1068
  };
1027
1069
  /**
1028
1070
  * Derive the capability map by comparing this instance's prototype chain
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
3
- * Generated at: 2026-04-27T07:41:03.202Z
3
+ * Generated at: 2026-04-27T12:43:03.854Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const kalshiApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.kalshiApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
6
- * Generated at: 2026-04-27T07:41:03.202Z
6
+ * Generated at: 2026-04-27T12:43:03.854Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.kalshiApiSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
3
- * Generated at: 2026-04-27T07:41:03.258Z
3
+ * Generated at: 2026-04-27T12:43:03.891Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const limitlessApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.limitlessApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
6
- * Generated at: 2026-04-27T07:41:03.258Z
6
+ * Generated at: 2026-04-27T12:43:03.891Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.limitlessApiSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
3
- * Generated at: 2026-04-27T07:41:03.282Z
3
+ * Generated at: 2026-04-27T12:43:03.902Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const myriadApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.myriadApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
6
- * Generated at: 2026-04-27T07:41:03.282Z
6
+ * Generated at: 2026-04-27T12:43:03.902Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.myriadApiSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
3
- * Generated at: 2026-04-27T07:41:03.289Z
3
+ * Generated at: 2026-04-27T12:43:03.908Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const opinionApiSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.opinionApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
6
- * Generated at: 2026-04-27T07:41:03.289Z
6
+ * Generated at: 2026-04-27T12:43:03.908Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.opinionApiSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
3
- * Generated at: 2026-04-27T07:41:03.209Z
3
+ * Generated at: 2026-04-27T12:43:03.861Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const polymarketClobSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.polymarketClobSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
6
- * Generated at: 2026-04-27T07:41:03.209Z
6
+ * Generated at: 2026-04-27T12:43:03.861Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketClobSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
3
- * Generated at: 2026-04-27T07:41:03.231Z
3
+ * Generated at: 2026-04-27T12:43:03.873Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const polymarketDataSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.polymarketDataSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
6
- * Generated at: 2026-04-27T07:41:03.231Z
6
+ * Generated at: 2026-04-27T12:43:03.873Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketDataSpec = {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
3
- * Generated at: 2026-04-27T07:41:03.224Z
3
+ * Generated at: 2026-04-27T12:43:03.871Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const polymarketGammaSpec: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.polymarketGammaSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
6
- * Generated at: 2026-04-27T07:41:03.224Z
6
+ * Generated at: 2026-04-27T12:43:03.871Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.polymarketGammaSpec = {
@@ -1,5 +1,5 @@
1
- import { ClobClient } from '@polymarket/clob-client';
2
- import type { ApiKeyCreds } from '@polymarket/clob-client';
1
+ import { ClobClient } from '@polymarket/clob-client-v2';
2
+ import type { ApiKeyCreds } from '@polymarket/clob-client-v2';
3
3
  import { ExchangeCredentials } from '../../BaseExchange';
4
4
  /**
5
5
  * Manages Polymarket authentication and CLOB client initialization.
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.PolymarketAuth = void 0;
7
- const clob_client_1 = require("@polymarket/clob-client");
7
+ const clob_client_v2_1 = require("@polymarket/clob-client-v2");
8
8
  const ethers_1 = require("ethers");
9
9
  const axios_1 = __importDefault(require("axios"));
10
10
  const errors_1 = require("./errors");
@@ -68,7 +68,11 @@ class PolymarketAuth {
68
68
  return this.apiCreds;
69
69
  }
70
70
  // Otherwise, derive/create them using L1 auth
71
- const l1Client = new clob_client_1.ClobClient(POLYMARKET_HOST, POLYGON_CHAIN_ID, this.signer);
71
+ const l1Client = new clob_client_v2_1.ClobClient({
72
+ host: POLYMARKET_HOST,
73
+ chain: POLYGON_CHAIN_ID,
74
+ signer: this.signer,
75
+ });
72
76
  // Robust derivation strategy:
73
77
  // 1. Try to DERIVE existing credentials first (most common case).
74
78
  // 2. If that fails (e.g. 404 or 400), try to CREATE new ones.
@@ -219,7 +223,14 @@ class PolymarketAuth {
219
223
  const finalSignatureType = signatureType;
220
224
  // Create L2-authenticated client
221
225
  // console.log(`[PolymarketAuth] Initializing ClobClient | Signer: ${signerAddress} | Funder: ${finalProxyAddress} | SigType: ${finalSignatureType}`);
222
- this.clobClient = new clob_client_1.ClobClient(POLYMARKET_HOST, POLYGON_CHAIN_ID, this.signer, apiCreds, finalSignatureType, finalProxyAddress);
226
+ this.clobClient = new clob_client_v2_1.ClobClient({
227
+ host: POLYMARKET_HOST,
228
+ chain: POLYGON_CHAIN_ID,
229
+ signer: this.signer,
230
+ creds: apiCreds,
231
+ signatureType: finalSignatureType,
232
+ funderAddress: finalProxyAddress,
233
+ });
223
234
  return this.clobClient;
224
235
  }
225
236
  /**
@@ -1,18 +1,33 @@
1
1
  import { ErrorMapper } from '../../utils/error-mapper';
2
- import { BadRequest } from '../../errors';
2
+ import { BaseError, BadRequest } from '../../errors';
3
3
  /**
4
4
  * Polymarket-specific error mapper
5
5
  *
6
- * Handles CLOB-specific error patterns and message formats.
6
+ * Handles CLOB V2 error patterns. V2 returns `{ "error": "<message>" }` on all
7
+ * error responses. The base ErrorMapper already extracts `data.error` when it is
8
+ * a string, so no extractErrorMessage override is needed.
9
+ *
10
+ * V2-specific status codes handled here:
11
+ * 425 Too Early -- matching engine restarting (retryable)
12
+ * 503 Service Unavailable -- exchange paused / cancel-only mode
7
13
  */
8
14
  export declare class PolymarketErrorMapper extends ErrorMapper {
9
15
  constructor();
10
16
  /**
11
17
  * Override to handle Polymarket-specific error patterns
18
+ *
19
+ * V2 returns `{ "error": "<message>" }` as a plain string. The base class
20
+ * handles this natively via `data.error` (string path). We keep the legacy
21
+ * `errorMsg` path for any residual V1 responses (order submission still
22
+ * returns `errorMsg` in some batch flows).
12
23
  */
13
24
  protected extractErrorMessage(error: any): string;
14
25
  /**
15
- * Override to detect Polymarket-specific error patterns
26
+ * Override to handle V2 status code 425 (Too Early -- matching engine restarting)
27
+ */
28
+ protected mapByStatusCode(status: number, message: string, data: any, response?: any): BaseError;
29
+ /**
30
+ * Override to detect Polymarket-specific error patterns in 400 responses
16
31
  */
17
32
  protected mapBadRequestError(message: string, data: any): BadRequest;
18
33
  }
@@ -10,7 +10,13 @@ const errors_1 = require("../../errors");
10
10
  /**
11
11
  * Polymarket-specific error mapper
12
12
  *
13
- * Handles CLOB-specific error patterns and message formats.
13
+ * Handles CLOB V2 error patterns. V2 returns `{ "error": "<message>" }` on all
14
+ * error responses. The base ErrorMapper already extracts `data.error` when it is
15
+ * a string, so no extractErrorMessage override is needed.
16
+ *
17
+ * V2-specific status codes handled here:
18
+ * 425 Too Early -- matching engine restarting (retryable)
19
+ * 503 Service Unavailable -- exchange paused / cancel-only mode
14
20
  */
15
21
  class PolymarketErrorMapper extends error_mapper_1.ErrorMapper {
16
22
  constructor() {
@@ -18,38 +24,65 @@ class PolymarketErrorMapper extends error_mapper_1.ErrorMapper {
18
24
  }
19
25
  /**
20
26
  * Override to handle Polymarket-specific error patterns
27
+ *
28
+ * V2 returns `{ "error": "<message>" }` as a plain string. The base class
29
+ * handles this natively via `data.error` (string path). We keep the legacy
30
+ * `errorMsg` path for any residual V1 responses (order submission still
31
+ * returns `errorMsg` in some batch flows).
21
32
  */
22
33
  extractErrorMessage(error) {
23
- // Handle Polymarket CLOB errors
24
34
  if (axios_1.default.isAxiosError(error) && error.response?.data) {
25
35
  const data = error.response.data;
26
- // Polymarket uses errorMsg field
36
+ // V2 format: { "error": "<message>" }
37
+ if (typeof data.error === 'string') {
38
+ return data.error;
39
+ }
40
+ // Legacy V1 format: { "errorMsg": "<message>" }
27
41
  if (data.errorMsg) {
28
42
  return data.errorMsg;
29
43
  }
30
- // Also check standard error paths
31
- if (data.error?.message) {
32
- return data.error.message;
33
- }
34
- if (data.message) {
35
- return data.message;
36
- }
37
44
  }
38
45
  return super.extractErrorMessage(error);
39
46
  }
40
47
  /**
41
- * Override to detect Polymarket-specific error patterns
48
+ * Override to handle V2 status code 425 (Too Early -- matching engine restarting)
49
+ */
50
+ mapByStatusCode(status, message, data, response) {
51
+ if (status === 425) {
52
+ return new errors_1.ExchangeNotAvailable(`Matching engine restarting: ${message}`, this.exchangeName);
53
+ }
54
+ return super.mapByStatusCode(status, message, data, response);
55
+ }
56
+ /**
57
+ * Override to detect Polymarket-specific error patterns in 400 responses
42
58
  */
43
59
  mapBadRequestError(message, data) {
44
60
  const lowerMessage = message.toLowerCase();
45
- // Polymarket-specific authentication errors (400 status)
61
+ // Authentication errors surfaced as 400
46
62
  if (lowerMessage.includes('api key') ||
47
63
  lowerMessage.includes('proxy') ||
48
- lowerMessage.includes('signature type')) {
64
+ lowerMessage.includes('signature type') ||
65
+ lowerMessage.includes('l1 request headers')) {
49
66
  return new errors_1.AuthenticationError(message, this.exchangeName);
50
67
  }
51
- // Polymarket-specific order validation
52
- if (lowerMessage.includes('tick size')) {
68
+ // Trading disabled / cancel-only mode -- exchange-level unavailability
69
+ if (lowerMessage.includes('trading is currently disabled') ||
70
+ lowerMessage.includes('trading is currently cancel-only')) {
71
+ return new errors_1.ExchangeNotAvailable(message, this.exchangeName);
72
+ }
73
+ // Address banned or restricted
74
+ if (lowerMessage.includes('address banned') ||
75
+ lowerMessage.includes('closed only mode')) {
76
+ return new errors_1.PermissionDenied(message, this.exchangeName);
77
+ }
78
+ // Order validation errors
79
+ if (lowerMessage.includes('tick size') ||
80
+ lowerMessage.includes('post-only order') ||
81
+ lowerMessage.includes('duplicated') ||
82
+ lowerMessage.includes('size lower than') ||
83
+ lowerMessage.includes('invalid expiration') ||
84
+ lowerMessage.includes('fok order') ||
85
+ lowerMessage.includes('fak order')) {
53
86
  return new errors_1.InvalidOrder(message, this.exchangeName);
54
87
  }
55
88
  // Fall back to base error mapping
@@ -63,7 +63,7 @@ export declare class PolymarketExchange extends PredictionMarketExchange {
63
63
  * Ensure authentication is initialized before trading operations.
64
64
  */
65
65
  private ensureAuth;
66
- /** Fetch on-chain USDC balance on Polygon for any address without requiring credentials. */
66
+ /** Fetch on-chain pUSD balance on Polygon for any address without requiring credentials. */
67
67
  private getAddressOnChainBalance;
68
68
  private ensureWs;
69
69
  private fetchWatchedAddressActivity;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PolymarketExchange = exports.buildPolymarketTradesActivity = exports.POLYMARKET_DEFAULT_SUBSCRIPTION = void 0;
4
- const clob_client_1 = require("@polymarket/clob-client");
4
+ const clob_client_v2_1 = require("@polymarket/clob-client-v2");
5
5
  const crypto_1 = require("crypto");
6
6
  const BaseExchange_1 = require("../../BaseExchange");
7
7
  const errors_1 = require("../../errors");
@@ -152,8 +152,8 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
152
152
  try {
153
153
  const auth = this.ensureAuth();
154
154
  const client = await auth.getClobClient();
155
- const side = params.side.toUpperCase() === 'BUY' ? clob_client_1.Side.BUY : clob_client_1.Side.SELL;
156
- const price = params.price || (side === clob_client_1.Side.BUY ? 0.99 : 0.01);
155
+ const side = params.side.toUpperCase() === 'BUY' ? clob_client_v2_1.Side.BUY : clob_client_v2_1.Side.SELL;
156
+ const price = params.price || (side === clob_client_v2_1.Side.BUY ? 0.99 : 0.01);
157
157
  const tickSize = params.tickSize ? params.tickSize.toString() : undefined;
158
158
  const orderArgs = {
159
159
  tokenID: params.outcomeId,
@@ -161,8 +161,6 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
161
161
  side,
162
162
  size: params.amount,
163
163
  };
164
- if (params.fee != null)
165
- orderArgs.feeRateBps = params.fee;
166
164
  const options = {};
167
165
  if (tickSize)
168
166
  options.tickSize = tickSize;
@@ -188,8 +186,8 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
188
186
  if (!response || !response.success) {
189
187
  throw new Error(`${response?.errorMsg || 'Order submission failed'} (Response: ${JSON.stringify(response)})`);
190
188
  }
191
- const side = built.params.side.toUpperCase() === 'BUY' ? clob_client_1.Side.BUY : clob_client_1.Side.SELL;
192
- const price = built.params.price || (side === clob_client_1.Side.BUY ? 0.99 : 0.01);
189
+ const side = built.params.side.toUpperCase() === 'BUY' ? clob_client_v2_1.Side.BUY : clob_client_v2_1.Side.SELL;
190
+ const price = built.params.price || (side === clob_client_v2_1.Side.BUY ? 0.99 : 0.01);
193
191
  return {
194
192
  id: response.orderID,
195
193
  marketId: built.params.marketId,
@@ -334,7 +332,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
334
332
  let clobBalanceAvailable = false;
335
333
  try {
336
334
  const balRes = await client.getBalanceAllowance({
337
- asset_type: clob_client_1.AssetType.COLLATERAL,
335
+ asset_type: clob_client_v2_1.AssetType.COLLATERAL,
338
336
  });
339
337
  if (balRes && typeof balRes.balance === 'string') {
340
338
  const rawBalance = parseFloat(balRes.balance);
@@ -378,7 +376,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
378
376
  const openOrders = await client.getOpenOrders({});
379
377
  if (Array.isArray(openOrders)) {
380
378
  for (const order of openOrders) {
381
- if (order.side === clob_client_1.Side.BUY) {
379
+ if (order.side === clob_client_v2_1.Side.BUY) {
382
380
  const remainingSize = parseFloat(order.original_size) - parseFloat(order.size_matched);
383
381
  const price = parseFloat(order.price);
384
382
  locked += remainingSize * price;
@@ -528,7 +526,7 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
528
526
  }
529
527
  return this.auth;
530
528
  }
531
- /** Fetch on-chain USDC balance on Polygon for any address without requiring credentials. */
529
+ /** Fetch on-chain pUSD balance on Polygon for any address without requiring credentials. */
532
530
  async getAddressOnChainBalance(address) {
533
531
  const { ethers } = require('ethers');
534
532
  if (!ethers.utils.isAddress(address)) {
@@ -540,14 +538,14 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
540
538
  chainId: 137,
541
539
  name: 'matic',
542
540
  });
543
- const usdcAddress = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174'; // USDC.e (Bridged)
544
- const usdcAbi = [
541
+ const pusdAddress = '0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB'; // pUSD (Polymarket USD)
542
+ const erc20Abi = [
545
543
  'function balanceOf(address) view returns (uint256)',
546
544
  'function decimals() view returns (uint8)',
547
545
  ];
548
- const usdcContract = new ethers.Contract(usdcAddress, usdcAbi, provider);
549
- const rawBalance = await usdcContract.balanceOf(address);
550
- const decimals = await usdcContract.decimals();
546
+ const pusdContract = new ethers.Contract(pusdAddress, erc20Abi, provider);
547
+ const rawBalance = await pusdContract.balanceOf(address);
548
+ const decimals = await pusdContract.decimals();
551
549
  const total = parseFloat(ethers.utils.formatUnits(rawBalance, decimals));
552
550
  return [{ currency: 'USDC', total, available: total, locked: 0 }];
553
551
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
3
- * Generated at: 2026-04-27T07:41:03.268Z
3
+ * Generated at: 2026-04-27T12:43:03.895Z
4
4
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
5
5
  */
6
6
  export declare const probableApiSpec: {