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.
- package/dist/BaseExchange.d.ts +50 -11
- package/dist/BaseExchange.js +50 -8
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/polymarket/auth.d.ts +2 -2
- package/dist/exchanges/polymarket/auth.js +14 -3
- package/dist/exchanges/polymarket/errors.d.ts +18 -3
- package/dist/exchanges/polymarket/errors.js +48 -15
- package/dist/exchanges/polymarket/index.d.ts +1 -1
- package/dist/exchanges/polymarket/index.js +13 -15
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/router/Router.d.ts +16 -3
- package/dist/router/Router.js +75 -5
- package/dist/router/Router.test.js +23 -2
- package/dist/router/types.d.ts +42 -0
- package/dist/server/method-verbs.json +32 -2
- package/dist/server/openapi.yaml +375 -15
- package/package.json +4 -4
|
@@ -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-
|
|
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 = {
|
package/dist/router/Router.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
*/
|
package/dist/router/Router.js
CHANGED
|
@@ -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
|
-
//
|
|
123
|
+
// Related markets: subset/superset matches with live prices
|
|
95
124
|
// -----------------------------------------------------------------------
|
|
96
|
-
async
|
|
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
|
-
//
|
|
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('
|
|
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.
|
|
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
|
});
|
package/dist/router/types.d.ts
CHANGED
|
@@ -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":
|
|
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":
|
|
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": [
|