pmxt-core 2.35.8 → 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-27T11:35:58.810Z
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-27T11:35:58.810Z
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-27T11:35:58.852Z
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-27T11:35:58.852Z
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-27T11:35:58.865Z
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-27T11:35:58.865Z
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-27T11:35:58.871Z
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-27T11:35:58.871Z
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-27T11:35:58.818Z
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-27T11:35:58.818Z
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-27T11:35:58.832Z
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-27T11:35:58.832Z
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-27T11:35:58.829Z
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-27T11:35:58.829Z
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,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-27T11:35:58.858Z
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: {
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.probableApiSpec = void 0;
4
4
  /**
5
5
  * Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
6
- * Generated at: 2026-04-27T11:35:58.858Z
6
+ * Generated at: 2026-04-27T12:43:03.895Z
7
7
  * Do not edit manually -- run "npm run fetch:openapi" to regenerate.
8
8
  */
9
9
  exports.probableApiSpec = {
@@ -1,19 +1,32 @@
1
1
  import { PredictionMarketExchange, type MarketFetchParams, type EventFetchParams } from '../BaseExchange';
2
2
  import type { UnifiedMarket, UnifiedEvent } from '../types';
3
- import type { RouterOptions, MatchResult, EventMatchResult, PriceComparison, ArbitrageOpportunity, FetchMarketMatchesParams, FetchMatchesParams, FetchEventMatchesParams, FetchArbitrageParams } from './types';
3
+ import type { RouterOptions, MatchResult, EventMatchResult, PriceComparison, ArbitrageOpportunity, MatchedMarketPair, MatchedPricePair, FetchMarketMatchesParams, FetchMatchesParams, FetchEventMatchesParams, FetchArbitrageParams, FetchMatchedMarketsParams, FetchMatchedPricesParams } from './types';
4
4
  export declare class Router extends PredictionMarketExchange {
5
5
  private readonly client;
6
6
  constructor(options: RouterOptions);
7
7
  get name(): string;
8
8
  protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
9
9
  protected fetchEventsImpl(params?: EventFetchParams): Promise<UnifiedEvent[]>;
10
- fetchMarketMatches(params: FetchMarketMatchesParams): Promise<MatchResult[]>;
10
+ fetchMarketMatches(params?: FetchMarketMatchesParams): Promise<MatchResult[]>;
11
+ /**
12
+ * Browse mode: fetch all matched market pairs from the catalog.
13
+ * Each result includes sourceMarket (one side) and market (the other).
14
+ */
15
+ private fetchMarketMatchesBrowse;
11
16
  /** @deprecated Use {@link fetchMarketMatches} instead. */
12
17
  fetchMatches(params: FetchMatchesParams): Promise<MatchResult[]>;
13
- fetchEventMatches(params: FetchEventMatchesParams): Promise<EventMatchResult[]>;
18
+ fetchEventMatches(params?: FetchEventMatchesParams): Promise<EventMatchResult[]>;
14
19
  compareMarketPrices(params: FetchMarketMatchesParams): Promise<PriceComparison[]>;
20
+ fetchRelatedMarkets(params: FetchMarketMatchesParams): Promise<PriceComparison[]>;
21
+ /** @deprecated Use {@link fetchRelatedMarkets} instead. */
15
22
  fetchHedges(params: FetchMarketMatchesParams): Promise<PriceComparison[]>;
23
+ /** @deprecated Use {@link fetchMarketMatches} without a marketId instead. */
24
+ fetchMatchedMarkets(params?: FetchMatchedMarketsParams): Promise<MatchedMarketPair[]>;
25
+ /** @deprecated Use {@link fetchMatchedMarkets} instead. */
26
+ fetchMatchedPrices(params?: FetchMatchedPricesParams): Promise<MatchedPricePair[]>;
27
+ /** @deprecated Use {@link fetchMatchedMarkets} instead. */
16
28
  fetchArbitrage(params?: FetchArbitrageParams): Promise<ArbitrageOpportunity[]>;
29
+ private fetchArbitrageInternal;
17
30
  /**
18
31
  * Bulk arbitrage via `GET /v0/arbitrage`. One round-trip.
19
32
  */
@@ -38,10 +38,17 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
38
38
  // -----------------------------------------------------------------------
39
39
  // Cross-exchange market matches
40
40
  // -----------------------------------------------------------------------
41
- async fetchMarketMatches(params) {
41
+ async fetchMarketMatches(params = {}) {
42
42
  if (params.market && !params.marketId) {
43
43
  params = { ...params, marketId: params.market.marketId };
44
44
  }
45
+ // Browse mode: no specific market identifier → return all matches
46
+ // from the catalog, with both sides of each pair.
47
+ const hasIdentifier = params.marketId || params.slug || params.url;
48
+ if (!hasIdentifier) {
49
+ return this.fetchMarketMatchesBrowse(params);
50
+ }
51
+ // Lookup mode: find matches for a specific market.
45
52
  const response = await this.client.getMarketMatches(params);
46
53
  const matches = response.matches ?? [];
47
54
  return matches.map((m) => ({
@@ -53,6 +60,28 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
53
60
  bestAsk: m.market?.bestAsk ?? null,
54
61
  }));
55
62
  }
63
+ /**
64
+ * Browse mode: fetch all matched market pairs from the catalog.
65
+ * Each result includes sourceMarket (one side) and market (the other).
66
+ */
67
+ async fetchMarketMatchesBrowse(params) {
68
+ const bulkParams = {
69
+ minSpread: params.minDifference,
70
+ category: params.category,
71
+ limit: params.limit,
72
+ relations: params.relation ? [params.relation] : undefined,
73
+ };
74
+ const pairs = await this.fetchArbitrageInternal(bulkParams);
75
+ return pairs.map((opp) => ({
76
+ sourceMarket: opp.marketA,
77
+ market: opp.marketB,
78
+ relation: opp.relation ?? 'identity',
79
+ confidence: opp.confidence ?? 0,
80
+ reasoning: opp.reasoning ?? null,
81
+ bestBid: opp.sellPrice ?? null,
82
+ bestAsk: null,
83
+ }));
84
+ }
56
85
  /** @deprecated Use {@link fetchMarketMatches} instead. */
57
86
  async fetchMatches(params) {
58
87
  console.warn('[pmxt] fetchMatches is deprecated, use fetchMarketMatches instead');
@@ -61,7 +90,7 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
61
90
  // -----------------------------------------------------------------------
62
91
  // Cross-exchange event matches
63
92
  // -----------------------------------------------------------------------
64
- async fetchEventMatches(params) {
93
+ async fetchEventMatches(params = {}) {
65
94
  if (params.event && !params.eventId) {
66
95
  params = { ...params, eventId: params.event.id };
67
96
  }
@@ -91,9 +120,9 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
91
120
  }));
92
121
  }
93
122
  // -----------------------------------------------------------------------
94
- // Hedging: subset/superset matches with live prices
123
+ // Related markets: subset/superset matches with live prices
95
124
  // -----------------------------------------------------------------------
96
- async fetchHedges(params) {
125
+ async fetchRelatedMarkets(params) {
97
126
  if (params.market && !params.marketId) {
98
127
  params = { ...params, marketId: params.market.marketId };
99
128
  }
@@ -113,10 +142,51 @@ class Router extends BaseExchange_1.PredictionMarketExchange {
113
142
  venue: m.market.sourceExchange ?? '',
114
143
  }));
115
144
  }
145
+ /** @deprecated Use {@link fetchRelatedMarkets} instead. */
146
+ async fetchHedges(params) {
147
+ console.warn('[pmxt] fetchHedges is deprecated, use fetchRelatedMarkets instead');
148
+ return this.fetchRelatedMarkets(params);
149
+ }
116
150
  // -----------------------------------------------------------------------
117
- // Arbitrage: scan matches for price spreads
151
+ // Matched markets (deprecated use fetchMarketMatches without a
152
+ // marketId for browse mode instead)
118
153
  // -----------------------------------------------------------------------
154
+ /** @deprecated Use {@link fetchMarketMatches} without a marketId instead. */
155
+ async fetchMatchedMarkets(params) {
156
+ // Convert params: minDifference -> minSpread for internal use
157
+ const legacyParams = params
158
+ ? {
159
+ minSpread: params.minDifference,
160
+ category: params.category,
161
+ limit: params.limit,
162
+ relations: params.relations,
163
+ }
164
+ : undefined;
165
+ const legacy = await this.fetchArbitrageInternal(legacyParams);
166
+ return legacy.map((opp) => ({
167
+ marketA: opp.marketA,
168
+ marketB: opp.marketB,
169
+ priceDifference: opp.spread,
170
+ venueA: opp.buyVenue,
171
+ venueB: opp.sellVenue,
172
+ priceA: opp.buyPrice,
173
+ priceB: opp.sellPrice,
174
+ relation: opp.relation,
175
+ confidence: opp.confidence,
176
+ reasoning: opp.reasoning ?? null,
177
+ }));
178
+ }
179
+ /** @deprecated Use {@link fetchMatchedMarkets} instead. */
180
+ async fetchMatchedPrices(params) {
181
+ console.warn('[pmxt] fetchMatchedPrices is deprecated, use fetchMatchedMarkets instead');
182
+ return this.fetchMatchedMarkets(params);
183
+ }
184
+ /** @deprecated Use {@link fetchMatchedMarkets} instead. */
119
185
  async fetchArbitrage(params) {
186
+ console.warn('[pmxt] fetchArbitrage is deprecated, use fetchMatchedPrices instead');
187
+ return this.fetchArbitrageInternal(params);
188
+ }
189
+ async fetchArbitrageInternal(params) {
120
190
  // Try the dedicated bulk endpoint first (single DB query).
121
191
  try {
122
192
  return await this.fetchArbitrageBulk(params);
@@ -102,7 +102,7 @@ describe('Router', () => {
102
102
  expect(result[0].reasoning).toBe('Same market.');
103
103
  });
104
104
  });
105
- describe('fetchHedges', () => {
105
+ describe('fetchRelatedMarkets', () => {
106
106
  it('returns only subset/superset matches with reasoning', async () => {
107
107
  const mockMatches = [
108
108
  {
@@ -125,13 +125,31 @@ describe('Router', () => {
125
125
  },
126
126
  ];
127
127
  clientInstance.getMarketMatches = jest.fn().mockResolvedValue({ matches: mockMatches });
128
- const result = await router.fetchHedges({ marketId: 'm1' });
128
+ const result = await router.fetchRelatedMarkets({ marketId: 'm1' });
129
129
  expect(result).toHaveLength(2);
130
130
  expect(result[0].relation).toBe('subset');
131
131
  expect(result[0].reasoning).toBe('Narrower market — nomination implies candidacy.');
132
132
  expect(result[1].relation).toBe('superset');
133
133
  });
134
134
  });
135
+ describe('fetchHedges (deprecated)', () => {
136
+ it('delegates to fetchRelatedMarkets and logs deprecation warning', async () => {
137
+ const mockMatches = [
138
+ {
139
+ market: { marketId: 'k2', sourceExchange: 'kalshi', bestBid: 0.40, bestAsk: 0.45 },
140
+ relation: 'subset',
141
+ confidence: 0.8,
142
+ reasoning: 'Narrower market.',
143
+ },
144
+ ];
145
+ clientInstance.getMarketMatches = jest.fn().mockResolvedValue({ matches: mockMatches });
146
+ const warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => { });
147
+ const result = await router.fetchHedges({ marketId: 'm1' });
148
+ expect(warnSpy).toHaveBeenCalledWith('[pmxt] fetchHedges is deprecated, use fetchRelatedMarkets instead');
149
+ expect(result).toHaveLength(1);
150
+ warnSpy.mockRestore();
151
+ });
152
+ });
135
153
  describe('fetchMarkets', () => {
136
154
  it('returns markets from the API', async () => {
137
155
  const mockMarkets = [{ marketId: 'm1', title: 'BTC' }];
@@ -161,6 +179,9 @@ describe('Router', () => {
161
179
  expect(router.has.fetchMatches).toBe(true);
162
180
  expect(router.has.fetchEventMatches).toBe(true);
163
181
  expect(router.has.compareMarketPrices).toBe(true);
182
+ expect(router.has.fetchRelatedMarkets).toBe(true);
183
+ expect(router.has.fetchMatchedMarkets).toBe(true);
184
+ expect(router.has.fetchMatchedPrices).toBe(true);
164
185
  expect(router.has.fetchHedges).toBe(true);
165
186
  expect(router.has.fetchArbitrage).toBe(true);
166
187
  });
@@ -6,6 +6,8 @@ export interface RouterOptions {
6
6
  }
7
7
  export interface MatchResult {
8
8
  market: UnifiedMarket;
9
+ /** The source market this was matched against. Present in browse mode (no marketId), absent in lookup mode. */
10
+ sourceMarket?: UnifiedMarket;
9
11
  relation: MatchRelation;
10
12
  confidence: number;
11
13
  reasoning: string | null;
@@ -39,8 +41,13 @@ export interface ArbitrageOpportunity {
39
41
  confidence?: number;
40
42
  }
41
43
  export interface FetchMarketMatchesParams {
44
+ /** Keyword search across matched market titles. */
45
+ query?: string;
46
+ /** Filter matches by category. */
47
+ category?: string;
42
48
  /** Pass a UnifiedMarket directly instead of marketId/slug/url. */
43
49
  market?: UnifiedMarket;
50
+ /** Lookup a specific market by ID. Omit for browse mode. */
44
51
  marketId?: string;
45
52
  slug?: string;
46
53
  url?: string;
@@ -48,12 +55,21 @@ export interface FetchMarketMatchesParams {
48
55
  minConfidence?: number;
49
56
  limit?: number;
50
57
  includePrices?: boolean;
58
+ /** Minimum price difference between venues. Browse mode only. */
59
+ minDifference?: number;
60
+ /** Sort order. Browse mode only. */
61
+ sort?: 'confidence' | 'volume' | 'priceDifference';
51
62
  }
52
63
  /** @deprecated Use {@link FetchMarketMatchesParams} instead. */
53
64
  export type FetchMatchesParams = FetchMarketMatchesParams;
54
65
  export interface FetchEventMatchesParams {
66
+ /** Keyword search across matched event titles. */
67
+ query?: string;
68
+ /** Filter matches by category. */
69
+ category?: string;
55
70
  /** Pass a UnifiedEvent directly instead of eventId/slug. */
56
71
  event?: UnifiedEvent;
72
+ /** Lookup a specific event by ID. Omit for browse mode. */
57
73
  eventId?: string;
58
74
  slug?: string;
59
75
  relation?: MatchRelation;
@@ -68,6 +84,32 @@ export interface FetchArbitrageParams {
68
84
  /** Comma-separated relation types to include (default: 'identity'). */
69
85
  relations?: MatchRelation[];
70
86
  }
87
+ export interface MatchedMarketPair {
88
+ marketA: UnifiedMarket;
89
+ marketB: UnifiedMarket;
90
+ priceDifference: number;
91
+ venueA: string;
92
+ venueB: string;
93
+ priceA: number;
94
+ priceB: number;
95
+ /** The set-theoretic relation between the two markets (e.g. identity, subset). */
96
+ relation?: MatchRelation;
97
+ /** Match confidence score (0.0 to 1.0). */
98
+ confidence?: number;
99
+ /** Why the two markets were matched. */
100
+ reasoning?: string | null;
101
+ }
102
+ /** @deprecated Use {@link MatchedMarketPair} instead. */
103
+ export type MatchedPricePair = MatchedMarketPair;
104
+ export interface FetchMatchedMarketsParams {
105
+ minDifference?: number;
106
+ category?: string;
107
+ limit?: number;
108
+ /** Comma-separated relation types to include (default: 'identity'). */
109
+ relations?: MatchRelation[];
110
+ }
111
+ /** @deprecated Use {@link FetchMatchedMarketsParams} instead. */
112
+ export type FetchMatchedPricesParams = FetchMatchedMarketsParams;
71
113
  export interface RouterMarketSearchParams {
72
114
  query?: string;
73
115
  sourceExchange?: string;
@@ -374,7 +374,7 @@
374
374
  {
375
375
  "name": "params",
376
376
  "kind": "object",
377
- "optional": false
377
+ "optional": true
378
378
  }
379
379
  ]
380
380
  },
@@ -384,7 +384,7 @@
384
384
  {
385
385
  "name": "params",
386
386
  "kind": "object",
387
- "optional": false
387
+ "optional": true
388
388
  }
389
389
  ]
390
390
  },
@@ -398,6 +398,36 @@
398
398
  }
399
399
  ]
400
400
  },
401
+ "fetchRelatedMarkets": {
402
+ "verb": "get",
403
+ "args": [
404
+ {
405
+ "name": "params",
406
+ "kind": "object",
407
+ "optional": false
408
+ }
409
+ ]
410
+ },
411
+ "fetchMatchedMarkets": {
412
+ "verb": "get",
413
+ "args": [
414
+ {
415
+ "name": "params",
416
+ "kind": "object",
417
+ "optional": true
418
+ }
419
+ ]
420
+ },
421
+ "fetchMatchedPrices": {
422
+ "verb": "get",
423
+ "args": [
424
+ {
425
+ "name": "params",
426
+ "kind": "object",
427
+ "optional": true
428
+ }
429
+ ]
430
+ },
401
431
  "fetchHedges": {
402
432
  "verb": "get",
403
433
  "args": [
@@ -1505,10 +1505,22 @@ paths:
1505
1505
  connections.
1506
1506
  '/api/{exchange}/fetchMarketMatches':
1507
1507
  get:
1508
- summary: Find Similar Markets
1508
+ summary: Market Matches
1509
1509
  operationId: fetchMarketMatches
1510
1510
  parameters:
1511
1511
  - $ref: '#/components/parameters/ExchangeParam'
1512
+ - in: query
1513
+ name: query
1514
+ required: false
1515
+ schema:
1516
+ type: string
1517
+ description: Keyword search across matched market titles.
1518
+ - in: query
1519
+ name: category
1520
+ required: false
1521
+ schema:
1522
+ type: string
1523
+ description: Filter matches by category.
1512
1524
  - in: query
1513
1525
  name: market
1514
1526
  required: false
@@ -1521,6 +1533,7 @@ paths:
1521
1533
  required: false
1522
1534
  schema:
1523
1535
  type: string
1536
+ description: Lookup a specific market by ID. Omit for browse mode.
1524
1537
  - in: query
1525
1538
  name: slug
1526
1539
  required: false
@@ -1557,9 +1570,25 @@ paths:
1557
1570
  required: false
1558
1571
  schema:
1559
1572
  type: boolean
1573
+ - in: query
1574
+ name: minDifference
1575
+ required: false
1576
+ schema:
1577
+ type: number
1578
+ description: Minimum price difference between venues. Browse mode only.
1579
+ - in: query
1580
+ name: sort
1581
+ required: false
1582
+ schema:
1583
+ type: string
1584
+ enum:
1585
+ - confidence
1586
+ - volume
1587
+ - priceDifference
1588
+ description: Sort order. Browse mode only.
1560
1589
  responses:
1561
1590
  '200':
1562
- description: Find Similar Markets response
1591
+ description: Market Matches response
1563
1592
  content:
1564
1593
  application/json:
1565
1594
  schema:
@@ -1572,15 +1601,28 @@ paths:
1572
1601
  items:
1573
1602
  $ref: '#/components/schemas/MatchResult'
1574
1603
  description: >-
1575
- Find the same or related market on other venues. Given a market on one venue, discover semantically equivalent
1576
- markets across every other venue PMXT ingests each with a relation type (identity, subset, superset, overlap,
1577
- disjoint), confidence score, and reasoning.
1604
+ Find the same or related market on other venues. Two modes: **Lookup mode** (marketId/slug/url provided): Given
1605
+ a market on one venue, discover semantically equivalent markets across every other venue PMXT ingests. **Browse
1606
+ mode** (no identifier): Returns all matched market pairs from the catalog. Supports query, category,
1607
+ minDifference, and sort params for filtering.
1578
1608
  '/api/{exchange}/fetchEventMatches':
1579
1609
  get:
1580
- summary: Find Similar Events
1610
+ summary: Event Matches
1581
1611
  operationId: fetchEventMatches
1582
1612
  parameters:
1583
1613
  - $ref: '#/components/parameters/ExchangeParam'
1614
+ - in: query
1615
+ name: query
1616
+ required: false
1617
+ schema:
1618
+ type: string
1619
+ description: Keyword search across matched event titles.
1620
+ - in: query
1621
+ name: category
1622
+ required: false
1623
+ schema:
1624
+ type: string
1625
+ description: Filter matches by category.
1584
1626
  - in: query
1585
1627
  name: event
1586
1628
  required: false
@@ -1593,6 +1635,7 @@ paths:
1593
1635
  required: false
1594
1636
  schema:
1595
1637
  type: string
1638
+ description: Lookup a specific event by ID. Omit for browse mode.
1596
1639
  - in: query
1597
1640
  name: slug
1598
1641
  required: false
@@ -1626,7 +1669,7 @@ paths:
1626
1669
  type: boolean
1627
1670
  responses:
1628
1671
  '200':
1629
- description: Find Similar Events response
1672
+ description: Event Matches response
1630
1673
  content:
1631
1674
  application/json:
1632
1675
  schema:
@@ -1639,8 +1682,10 @@ paths:
1639
1682
  items:
1640
1683
  $ref: '#/components/schemas/EventMatchResult'
1641
1684
  description: >-
1642
- Find the same or related event on other venues. Given an event on one venue, discover semantically equivalent
1643
- events across every other venue PMXT ingests including market-level match details for each child market.
1685
+ Find the same or related event on other venues. Two modes: **Lookup mode** (eventId/slug provided): Given an
1686
+ event on one venue, discover semantically equivalent events across every other venue PMXT ingests. **Browse
1687
+ mode** (no identifier): Returns all matched event pairs from the catalog. Supports query and category params for
1688
+ filtering.
1644
1689
  '/api/{exchange}/compareMarketPrices':
1645
1690
  post:
1646
1691
  summary: Compare Prices Across Venues
@@ -1681,12 +1726,224 @@ paths:
1681
1726
  description: >-
1682
1727
  Compare live prices for the same market across venues. Finds identity matches and returns side-by-side best
1683
1728
  bid/ask prices so you can spot price differences at a glance.
1729
+ '/api/{exchange}/fetchRelatedMarkets':
1730
+ get:
1731
+ summary: Find Related Markets
1732
+ operationId: fetchRelatedMarkets
1733
+ parameters:
1734
+ - $ref: '#/components/parameters/ExchangeParam'
1735
+ - in: query
1736
+ name: query
1737
+ required: false
1738
+ schema:
1739
+ type: string
1740
+ description: Keyword search across matched market titles.
1741
+ - in: query
1742
+ name: category
1743
+ required: false
1744
+ schema:
1745
+ type: string
1746
+ description: Filter matches by category.
1747
+ - in: query
1748
+ name: market
1749
+ required: false
1750
+ schema:
1751
+ allOf:
1752
+ - $ref: '#/components/schemas/UnifiedMarket'
1753
+ description: Pass a UnifiedMarket directly instead of marketId/slug/url.
1754
+ - in: query
1755
+ name: marketId
1756
+ required: false
1757
+ schema:
1758
+ type: string
1759
+ description: Lookup a specific market by ID. Omit for browse mode.
1760
+ - in: query
1761
+ name: slug
1762
+ required: false
1763
+ schema:
1764
+ type: string
1765
+ - in: query
1766
+ name: url
1767
+ required: false
1768
+ schema:
1769
+ type: string
1770
+ - in: query
1771
+ name: relation
1772
+ required: false
1773
+ schema:
1774
+ type: string
1775
+ enum:
1776
+ - identity
1777
+ - subset
1778
+ - superset
1779
+ - overlap
1780
+ - disjoint
1781
+ - in: query
1782
+ name: minConfidence
1783
+ required: false
1784
+ schema:
1785
+ type: number
1786
+ - in: query
1787
+ name: limit
1788
+ required: false
1789
+ schema:
1790
+ type: number
1791
+ - in: query
1792
+ name: includePrices
1793
+ required: false
1794
+ schema:
1795
+ type: boolean
1796
+ - in: query
1797
+ name: minDifference
1798
+ required: false
1799
+ schema:
1800
+ type: number
1801
+ description: Minimum price difference between venues. Browse mode only.
1802
+ - in: query
1803
+ name: sort
1804
+ required: false
1805
+ schema:
1806
+ type: string
1807
+ enum:
1808
+ - confidence
1809
+ - volume
1810
+ - priceDifference
1811
+ description: Sort order. Browse mode only.
1812
+ responses:
1813
+ '200':
1814
+ description: Find Related Markets response
1815
+ content:
1816
+ application/json:
1817
+ schema:
1818
+ allOf:
1819
+ - $ref: '#/components/schemas/BaseResponse'
1820
+ - type: object
1821
+ properties:
1822
+ data:
1823
+ type: array
1824
+ items:
1825
+ $ref: '#/components/schemas/PriceComparison'
1826
+ description: >-
1827
+ Find related markets across venues. Discovers subset/superset market relationships where one market's outcome
1828
+ implies another, with live prices.
1829
+ '/api/{exchange}/fetchMatchedMarkets':
1830
+ get:
1831
+ summary: Matched Markets
1832
+ operationId: fetchMatchedMarkets
1833
+ parameters:
1834
+ - $ref: '#/components/parameters/ExchangeParam'
1835
+ - in: query
1836
+ name: minDifference
1837
+ required: false
1838
+ schema:
1839
+ type: number
1840
+ - in: query
1841
+ name: category
1842
+ required: false
1843
+ schema:
1844
+ type: string
1845
+ - in: query
1846
+ name: limit
1847
+ required: false
1848
+ schema:
1849
+ type: number
1850
+ - in: query
1851
+ name: relations
1852
+ required: false
1853
+ schema:
1854
+ type: array
1855
+ items:
1856
+ type: string
1857
+ enum:
1858
+ - identity
1859
+ - subset
1860
+ - superset
1861
+ - overlap
1862
+ - disjoint
1863
+ description: 'Comma-separated relation types to include (default: ''identity'').'
1864
+ responses:
1865
+ '200':
1866
+ description: Matched Markets response
1867
+ content:
1868
+ application/json:
1869
+ schema:
1870
+ allOf:
1871
+ - $ref: '#/components/schemas/BaseResponse'
1872
+ - type: object
1873
+ properties:
1874
+ data:
1875
+ type: array
1876
+ items:
1877
+ $ref: '#/components/schemas/MatchedMarketPair'
1878
+ deprecated: true
1879
+ '/api/{exchange}/fetchMatchedPrices':
1880
+ get:
1881
+ summary: Compare Matched Market Prices
1882
+ operationId: fetchMatchedPrices
1883
+ parameters:
1884
+ - $ref: '#/components/parameters/ExchangeParam'
1885
+ - in: query
1886
+ name: minDifference
1887
+ required: false
1888
+ schema:
1889
+ type: number
1890
+ - in: query
1891
+ name: category
1892
+ required: false
1893
+ schema:
1894
+ type: string
1895
+ - in: query
1896
+ name: limit
1897
+ required: false
1898
+ schema:
1899
+ type: number
1900
+ - in: query
1901
+ name: relations
1902
+ required: false
1903
+ schema:
1904
+ type: array
1905
+ items:
1906
+ type: string
1907
+ enum:
1908
+ - identity
1909
+ - subset
1910
+ - superset
1911
+ - overlap
1912
+ - disjoint
1913
+ description: 'Comma-separated relation types to include (default: ''identity'').'
1914
+ responses:
1915
+ '200':
1916
+ description: Compare Matched Market Prices response
1917
+ content:
1918
+ application/json:
1919
+ schema:
1920
+ allOf:
1921
+ - $ref: '#/components/schemas/BaseResponse'
1922
+ - type: object
1923
+ properties:
1924
+ data:
1925
+ type: array
1926
+ items:
1927
+ $ref: '#/components/schemas/MatchedMarketPair'
1928
+ deprecated: true
1684
1929
  '/api/{exchange}/fetchHedges':
1685
1930
  get:
1686
1931
  summary: Find Hedging Opportunities
1687
1932
  operationId: fetchHedges
1688
1933
  parameters:
1689
1934
  - $ref: '#/components/parameters/ExchangeParam'
1935
+ - in: query
1936
+ name: query
1937
+ required: false
1938
+ schema:
1939
+ type: string
1940
+ description: Keyword search across matched market titles.
1941
+ - in: query
1942
+ name: category
1943
+ required: false
1944
+ schema:
1945
+ type: string
1946
+ description: Filter matches by category.
1690
1947
  - in: query
1691
1948
  name: market
1692
1949
  required: false
@@ -1699,6 +1956,7 @@ paths:
1699
1956
  required: false
1700
1957
  schema:
1701
1958
  type: string
1959
+ description: Lookup a specific market by ID. Omit for browse mode.
1702
1960
  - in: query
1703
1961
  name: slug
1704
1962
  required: false
@@ -1735,6 +1993,22 @@ paths:
1735
1993
  required: false
1736
1994
  schema:
1737
1995
  type: boolean
1996
+ - in: query
1997
+ name: minDifference
1998
+ required: false
1999
+ schema:
2000
+ type: number
2001
+ description: Minimum price difference between venues. Browse mode only.
2002
+ - in: query
2003
+ name: sort
2004
+ required: false
2005
+ schema:
2006
+ type: string
2007
+ enum:
2008
+ - confidence
2009
+ - volume
2010
+ - priceDifference
2011
+ description: Sort order. Browse mode only.
1738
2012
  responses:
1739
2013
  '200':
1740
2014
  description: Find Hedging Opportunities response
@@ -1749,9 +2023,7 @@ paths:
1749
2023
  type: array
1750
2024
  items:
1751
2025
  $ref: '#/components/schemas/PriceComparison'
1752
- description: >-
1753
- Find hedging opportunities across venues. Discovers subset/superset market relationships where one market's
1754
- outcome implies another, enabling cross-venue hedging strategies with live prices.
2026
+ deprecated: true
1755
2027
  '/api/{exchange}/fetchArbitrage':
1756
2028
  get:
1757
2029
  summary: Find Arbitrage Opportunities
@@ -1801,9 +2073,7 @@ paths:
1801
2073
  type: array
1802
2074
  items:
1803
2075
  $ref: '#/components/schemas/ArbitrageOpportunity'
1804
- description: >-
1805
- Scan for arbitrage opportunities across venues. Finds identity matches where the same market is priced
1806
- differently on different venues, returning opportunities sorted by spread size.
2076
+ deprecated: true
1807
2077
  components:
1808
2078
  parameters:
1809
2079
  ExchangeParam:
@@ -2740,12 +3010,19 @@ components:
2740
3010
  FetchMarketMatchesParams:
2741
3011
  type: object
2742
3012
  properties:
3013
+ query:
3014
+ type: string
3015
+ description: Keyword search across matched market titles.
3016
+ category:
3017
+ type: string
3018
+ description: Filter matches by category.
2743
3019
  market:
2744
3020
  allOf:
2745
3021
  - $ref: '#/components/schemas/UnifiedMarket'
2746
3022
  description: Pass a UnifiedMarket directly instead of marketId/slug/url.
2747
3023
  marketId:
2748
3024
  type: string
3025
+ description: Lookup a specific market by ID. Omit for browse mode.
2749
3026
  slug:
2750
3027
  type: string
2751
3028
  url:
@@ -2764,15 +3041,32 @@ components:
2764
3041
  type: number
2765
3042
  includePrices:
2766
3043
  type: boolean
3044
+ minDifference:
3045
+ type: number
3046
+ description: Minimum price difference between venues. Browse mode only.
3047
+ sort:
3048
+ type: string
3049
+ enum:
3050
+ - confidence
3051
+ - volume
3052
+ - priceDifference
3053
+ description: Sort order. Browse mode only.
2767
3054
  FetchEventMatchesParams:
2768
3055
  type: object
2769
3056
  properties:
3057
+ query:
3058
+ type: string
3059
+ description: Keyword search across matched event titles.
3060
+ category:
3061
+ type: string
3062
+ description: Filter matches by category.
2770
3063
  event:
2771
3064
  allOf:
2772
3065
  - $ref: '#/components/schemas/UnifiedEvent'
2773
3066
  description: Pass a UnifiedEvent directly instead of eventId/slug.
2774
3067
  eventId:
2775
3068
  type: string
3069
+ description: Lookup a specific event by ID. Omit for browse mode.
2776
3070
  slug:
2777
3071
  type: string
2778
3072
  relation:
@@ -2814,6 +3108,10 @@ components:
2814
3108
  properties:
2815
3109
  market:
2816
3110
  $ref: '#/components/schemas/UnifiedMarket'
3111
+ sourceMarket:
3112
+ allOf:
3113
+ - $ref: '#/components/schemas/UnifiedMarket'
3114
+ description: 'The source market this was matched against. Present in browse mode (no marketId), absent in lookup mode.'
2817
3115
  relation:
2818
3116
  type: string
2819
3117
  enum:
@@ -2929,6 +3227,68 @@ components:
2929
3227
  - sellVenue
2930
3228
  - buyPrice
2931
3229
  - sellPrice
3230
+ FetchMatchedMarketsParams:
3231
+ type: object
3232
+ properties:
3233
+ minDifference:
3234
+ type: number
3235
+ category:
3236
+ type: string
3237
+ limit:
3238
+ type: number
3239
+ relations:
3240
+ type: array
3241
+ items:
3242
+ type: string
3243
+ enum:
3244
+ - identity
3245
+ - subset
3246
+ - superset
3247
+ - overlap
3248
+ - disjoint
3249
+ description: 'Comma-separated relation types to include (default: ''identity'').'
3250
+ MatchedMarketPair:
3251
+ type: object
3252
+ properties:
3253
+ marketA:
3254
+ $ref: '#/components/schemas/UnifiedMarket'
3255
+ marketB:
3256
+ $ref: '#/components/schemas/UnifiedMarket'
3257
+ priceDifference:
3258
+ type: number
3259
+ venueA:
3260
+ type: string
3261
+ venueB:
3262
+ type: string
3263
+ priceA:
3264
+ type: number
3265
+ priceB:
3266
+ type: number
3267
+ relation:
3268
+ type: string
3269
+ enum:
3270
+ - identity
3271
+ - subset
3272
+ - superset
3273
+ - overlap
3274
+ - disjoint
3275
+ description: 'The set-theoretic relation between the two markets (e.g. identity, subset).'
3276
+ confidence:
3277
+ type: number
3278
+ description: Match confidence score (0.0 to 1.0).
3279
+ reasoning:
3280
+ oneOf:
3281
+ - type: string
3282
+ - {}
3283
+ description: Why the two markets were matched.
3284
+ required:
3285
+ - marketA
3286
+ - marketB
3287
+ - priceDifference
3288
+ - venueA
3289
+ - venueB
3290
+ - priceA
3291
+ - priceB
2932
3292
  ExchangeCredentials:
2933
3293
  type: object
2934
3294
  description: Optional authentication credentials for exchange operations.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pmxt-core",
3
- "version": "2.35.8",
3
+ "version": "2.35.9",
4
4
  "description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -29,8 +29,8 @@
29
29
  "test": "jest -c jest.config.js",
30
30
  "server": "tsx watch src/server/index.ts",
31
31
  "server:prod": "node dist/server/index.js",
32
- "generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.35.8,library=urllib3",
33
- "generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.35.8,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
32
+ "generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.35.9,library=urllib3",
33
+ "generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.35.9,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
34
34
  "fetch:openapi": "node scripts/fetch-openapi-specs.js",
35
35
  "extract:jsdoc": "node ../scripts/extract-jsdoc.js",
36
36
  "generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",