pmxt-core 2.47.0 → 2.48.1
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 +42 -1
- package/dist/BaseExchange.js +29 -2
- package/dist/exchanges/baozi/index.d.ts +1 -0
- package/dist/exchanges/baozi/index.js +5 -0
- package/dist/exchanges/gemini-titan/index.d.ts +6 -2
- package/dist/exchanges/gemini-titan/index.js +81 -1
- package/dist/exchanges/gemini-titan/normalizer.d.ts +7 -1
- package/dist/exchanges/gemini-titan/normalizer.js +23 -0
- package/dist/exchanges/hyperliquid/index.d.ts +3 -0
- package/dist/exchanges/hyperliquid/index.js +7 -0
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/kalshi/fetcher.d.ts +10 -0
- package/dist/exchanges/kalshi/fetcher.js +36 -0
- package/dist/exchanges/kalshi/index.d.ts +3 -2
- package/dist/exchanges/kalshi/index.js +33 -0
- package/dist/exchanges/kalshi/normalizer.d.ts +3 -2
- package/dist/exchanges/kalshi/normalizer.js +14 -0
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/limitless/index.d.ts +1 -0
- package/dist/exchanges/limitless/index.js +5 -0
- package/dist/exchanges/metaculus/fetchEvents.js +4 -0
- package/dist/exchanges/metaculus/index.d.ts +3 -0
- package/dist/exchanges/metaculus/index.js +3 -0
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/myriad/index.d.ts +1 -0
- package/dist/exchanges/myriad/index.js +5 -0
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/opinion/index.d.ts +6 -2
- package/dist/exchanges/opinion/index.js +54 -1
- package/dist/exchanges/opinion/normalizer.d.ts +8 -2
- package/dist/exchanges/opinion/normalizer.js +16 -0
- 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/index.d.ts +13 -2
- package/dist/exchanges/polymarket/index.js +49 -0
- package/dist/exchanges/polymarket/normalizer.d.ts +2 -1
- package/dist/exchanges/polymarket/normalizer.js +33 -0
- package/dist/exchanges/polymarket_us/index.d.ts +3 -2
- package/dist/exchanges/polymarket_us/index.js +57 -0
- package/dist/exchanges/polymarket_us/normalizer.d.ts +9 -2
- package/dist/exchanges/polymarket_us/normalizer.js +27 -0
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/probable/index.d.ts +3 -0
- package/dist/exchanges/probable/index.js +7 -0
- package/dist/exchanges/smarkets/index.d.ts +1 -0
- package/dist/exchanges/smarkets/index.js +5 -0
- package/dist/exchanges/suibets/index.d.ts +1 -0
- package/dist/exchanges/suibets/index.js +5 -0
- package/dist/router/Router.d.ts +29 -2
- package/dist/router/Router.js +145 -0
- package/dist/router/index.d.ts +1 -0
- package/dist/router/index.js +1 -0
- package/dist/router/series-map.d.ts +32 -0
- package/dist/router/series-map.js +146 -0
- package/dist/server/app.js +20 -3
- package/dist/server/method-verbs.json +10 -0
- package/dist/server/openapi.yaml +106 -0
- package/dist/types.d.ts +31 -0
- package/package.json +3 -3
|
@@ -37,6 +37,9 @@ import { UnifiedMarket, UnifiedEvent, CreateOrderParams, Order } from "../../typ
|
|
|
37
37
|
* | Continuous/numeric/date | Yes (read-only HIGHER/LOWER) | No (requires 201-point CDF) |
|
|
38
38
|
*/
|
|
39
39
|
export declare class MetaculusExchange extends PredictionMarketExchange {
|
|
40
|
+
protected readonly capabilityOverrides: {
|
|
41
|
+
fetchSeries: false;
|
|
42
|
+
};
|
|
40
43
|
private readonly apiToken?;
|
|
41
44
|
private readonly baseUrl;
|
|
42
45
|
constructor(credentials?: ExchangeCredentials);
|
|
@@ -48,6 +48,9 @@ const cancelOrder_1 = require("./cancelOrder");
|
|
|
48
48
|
* | Continuous/numeric/date | Yes (read-only HIGHER/LOWER) | No (requires 201-point CDF) |
|
|
49
49
|
*/
|
|
50
50
|
class MetaculusExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
51
|
+
capabilityOverrides = {
|
|
52
|
+
fetchSeries: false,
|
|
53
|
+
};
|
|
51
54
|
apiToken;
|
|
52
55
|
baseUrl;
|
|
53
56
|
constructor(credentials) {
|
|
@@ -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-05-
|
|
3
|
+
* Generated at: 2026-05-30T14:04:36.439Z
|
|
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-05-
|
|
6
|
+
* Generated at: 2026-05-30T14:04:36.439Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.myriadApiSpec = {
|
|
@@ -23,6 +23,7 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
23
23
|
fetchBalance: 'emulated',
|
|
24
24
|
watchOrderBook: 'emulated',
|
|
25
25
|
watchTrades: 'emulated',
|
|
26
|
+
fetchSeries: false,
|
|
26
27
|
};
|
|
27
28
|
auth;
|
|
28
29
|
ws;
|
|
@@ -76,6 +77,10 @@ class MyriadExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
76
77
|
.filter((m) => m !== null);
|
|
77
78
|
}
|
|
78
79
|
async fetchEventsImpl(params) {
|
|
80
|
+
// Venue does not expose a series concept; honoring `params.series` by
|
|
81
|
+
// returning [] rather than ignoring the filter.
|
|
82
|
+
if (params.series !== undefined)
|
|
83
|
+
return [];
|
|
79
84
|
const rawQuestions = await this.fetcher.fetchRawEvents(params);
|
|
80
85
|
return rawQuestions
|
|
81
86
|
.map((raw) => this.normalizer.normalizeEvent(raw))
|
|
@@ -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-05-
|
|
3
|
+
* Generated at: 2026-05-30T14:04:36.444Z
|
|
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-05-
|
|
6
|
+
* Generated at: 2026-05-30T14:04:36.444Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.opinionApiSpec = {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PredictionMarketExchange, MarketFilterParams, OHLCVParams, ExchangeCredentials, EventFetchParams, MyTradesParams, OrderHistoryParams } from '../../BaseExchange';
|
|
2
|
-
import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, Order, Position, UserTrade, CreateOrderParams, BuiltOrder } from '../../types';
|
|
1
|
+
import { PredictionMarketExchange, MarketFilterParams, OHLCVParams, ExchangeCredentials, EventFetchParams, SeriesFetchParams, MyTradesParams, OrderHistoryParams } from '../../BaseExchange';
|
|
2
|
+
import { UnifiedMarket, UnifiedEvent, UnifiedSeries, PriceCandle, OrderBook, Trade, Order, Position, UserTrade, CreateOrderParams, BuiltOrder } from '../../types';
|
|
3
3
|
import { OpinionWebSocketConfig } from './websocket';
|
|
4
4
|
export type { OpinionWebSocketConfig };
|
|
5
5
|
export interface OpinionExchangeOptions {
|
|
@@ -15,12 +15,16 @@ export declare class OpinionExchange extends PredictionMarketExchange {
|
|
|
15
15
|
private readonly normalizer;
|
|
16
16
|
private ws?;
|
|
17
17
|
private readonly outcomeToMarketId;
|
|
18
|
+
protected readonly capabilityOverrides: {
|
|
19
|
+
fetchSeries: "emulated";
|
|
20
|
+
};
|
|
18
21
|
constructor(options?: ExchangeCredentials | OpinionExchangeOptions);
|
|
19
22
|
get name(): string;
|
|
20
23
|
protected sign(_method: string, _path: string, _params: Record<string, any>): Record<string, string>;
|
|
21
24
|
protected mapImplicitApiError(error: any): any;
|
|
22
25
|
protected fetchMarketsImpl(params?: MarketFilterParams): Promise<UnifiedMarket[]>;
|
|
23
26
|
protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
|
|
27
|
+
protected fetchSeriesImpl(params: SeriesFetchParams): Promise<UnifiedSeries[]>;
|
|
24
28
|
fetchOHLCV(outcomeId: string, params: OHLCVParams): Promise<PriceCandle[]>;
|
|
25
29
|
fetchOrderBook(outcomeId: string, _limit?: number, _params?: Record<string, any>): Promise<OrderBook>;
|
|
26
30
|
fetchMyTrades(params?: MyTradesParams): Promise<UserTrade[]>;
|
|
@@ -60,6 +60,9 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
60
60
|
ws;
|
|
61
61
|
// Maps outcomeId (token ID) → numeric marketId for WebSocket subscriptions
|
|
62
62
|
outcomeToMarketId = new Map();
|
|
63
|
+
capabilityOverrides = {
|
|
64
|
+
fetchSeries: 'emulated',
|
|
65
|
+
};
|
|
63
66
|
constructor(options) {
|
|
64
67
|
let credentials;
|
|
65
68
|
let walletAddress;
|
|
@@ -154,9 +157,15 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
154
157
|
const rawEvents = await this.fetcher.fetchRawEvents(params);
|
|
155
158
|
const limit = params.limit || 250000;
|
|
156
159
|
const query = (params.query || '').toLowerCase();
|
|
157
|
-
|
|
160
|
+
let filtered = query
|
|
158
161
|
? rawEvents.filter((raw) => (raw.marketTitle || '').toLowerCase().includes(query))
|
|
159
162
|
: rawEvents;
|
|
163
|
+
// Client-side series filter: keep only events whose collection symbol
|
|
164
|
+
// matches the requested series identifier.
|
|
165
|
+
if (params.series) {
|
|
166
|
+
const seriesId = params.series;
|
|
167
|
+
filtered = filtered.filter((raw) => raw.collection?.symbol === seriesId);
|
|
168
|
+
}
|
|
160
169
|
const events = filtered
|
|
161
170
|
.map((raw) => this.normalizer.normalizeEvent(raw))
|
|
162
171
|
.filter((e) => e !== null)
|
|
@@ -165,6 +174,50 @@ class OpinionExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
165
174
|
await this.enrichPrices(allMarkets);
|
|
166
175
|
return events;
|
|
167
176
|
}
|
|
177
|
+
async fetchSeriesImpl(params) {
|
|
178
|
+
// Opinion has no dedicated /series endpoint. Derive the catalog by
|
|
179
|
+
// fetching all markets and grouping by collection.symbol.
|
|
180
|
+
const rawMarkets = await this.fetcher.fetchRawMarkets();
|
|
181
|
+
// Build a map from collection.symbol -> { collection, rawEvents[] }
|
|
182
|
+
const seriesMap = new Map();
|
|
183
|
+
for (const raw of rawMarkets) {
|
|
184
|
+
if (!raw.collection)
|
|
185
|
+
continue;
|
|
186
|
+
const sym = raw.collection.symbol;
|
|
187
|
+
const existing = seriesMap.get(sym);
|
|
188
|
+
if (existing) {
|
|
189
|
+
existing.raws.push(raw);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
seriesMap.set(sym, { collection: raw.collection, raws: [raw] });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
let entries = Array.from(seriesMap.values());
|
|
196
|
+
// Apply params.id filter
|
|
197
|
+
if (params.id) {
|
|
198
|
+
entries = entries.filter((e) => e.collection.symbol === params.id);
|
|
199
|
+
}
|
|
200
|
+
// Apply params.query filter (title match)
|
|
201
|
+
if (params.query) {
|
|
202
|
+
const lowerQuery = params.query.toLowerCase();
|
|
203
|
+
entries = entries.filter((e) => e.collection.title.toLowerCase().includes(lowerQuery));
|
|
204
|
+
}
|
|
205
|
+
// Apply params.recurrence filter
|
|
206
|
+
if (params.recurrence) {
|
|
207
|
+
const recurrence = params.recurrence;
|
|
208
|
+
entries = entries.filter((e) => e.collection.frequency === recurrence);
|
|
209
|
+
}
|
|
210
|
+
return entries.map((e) => {
|
|
211
|
+
let events;
|
|
212
|
+
// When fetching by id, populate the events field.
|
|
213
|
+
if (params.id) {
|
|
214
|
+
events = e.raws
|
|
215
|
+
.map((raw) => this.normalizer.normalizeEvent(raw))
|
|
216
|
+
.filter((ev) => ev !== null);
|
|
217
|
+
}
|
|
218
|
+
return this.normalizer.normalizeSeries(e.collection, events);
|
|
219
|
+
});
|
|
220
|
+
}
|
|
168
221
|
async fetchOHLCV(outcomeId, params) {
|
|
169
222
|
const rawPoints = await this.fetcher.fetchRawOHLCV(outcomeId, params);
|
|
170
223
|
return this.normalizer.normalizeOHLCV({ history: rawPoints }, params);
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { OHLCVParams } from '../../BaseExchange';
|
|
2
|
-
import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, UserTrade, Position, Order } from '../../types';
|
|
2
|
+
import { UnifiedMarket, UnifiedEvent, UnifiedSeries, PriceCandle, OrderBook, Trade, UserTrade, Position, Order } from '../../types';
|
|
3
3
|
import { IExchangeNormalizer } from '../interfaces';
|
|
4
|
-
import { OpinionRawMarket, OpinionRawOrderBook, OpinionRawPricePoint, OpinionRawLatestPrice, OpinionRawUserTrade, OpinionRawPosition, OpinionRawOrder } from './fetcher';
|
|
4
|
+
import { OpinionRawMarket, OpinionRawCollection, OpinionRawOrderBook, OpinionRawPricePoint, OpinionRawLatestPrice, OpinionRawUserTrade, OpinionRawPosition, OpinionRawOrder } from './fetcher';
|
|
5
5
|
export declare class OpinionNormalizer implements IExchangeNormalizer<OpinionRawMarket, OpinionRawMarket> {
|
|
6
6
|
normalizeMarket(raw: OpinionRawMarket): UnifiedMarket | null;
|
|
7
7
|
normalizeMarketsFromEvent(raw: OpinionRawMarket): UnifiedMarket[];
|
|
8
|
+
/**
|
|
9
|
+
* Produce a UnifiedSeries from an Opinion `collection` object.
|
|
10
|
+
* `id` is the canonical series identifier (collection.symbol).
|
|
11
|
+
* `events` is optionally injected by the caller when doing a single-id lookup.
|
|
12
|
+
*/
|
|
13
|
+
normalizeSeries(raw: OpinionRawCollection, events?: UnifiedEvent[]): UnifiedSeries;
|
|
8
14
|
normalizeEvent(raw: OpinionRawMarket): UnifiedEvent | null;
|
|
9
15
|
normalizeOHLCV(raw: {
|
|
10
16
|
history: OpinionRawPricePoint[];
|
|
@@ -59,6 +59,22 @@ class OpinionNormalizer {
|
|
|
59
59
|
}
|
|
60
60
|
return results;
|
|
61
61
|
}
|
|
62
|
+
// -- Series ---------------------------------------------------------------
|
|
63
|
+
/**
|
|
64
|
+
* Produce a UnifiedSeries from an Opinion `collection` object.
|
|
65
|
+
* `id` is the canonical series identifier (collection.symbol).
|
|
66
|
+
* `events` is optionally injected by the caller when doing a single-id lookup.
|
|
67
|
+
*/
|
|
68
|
+
normalizeSeries(raw, events) {
|
|
69
|
+
return {
|
|
70
|
+
id: raw.symbol,
|
|
71
|
+
ticker: raw.symbol,
|
|
72
|
+
title: raw.title,
|
|
73
|
+
recurrence: raw.frequency || null,
|
|
74
|
+
events,
|
|
75
|
+
sourceMetadata: (0, metadata_1.buildSourceMetadata)(raw, ['title', 'symbol', 'frequency']),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
62
78
|
// -- Events ---------------------------------------------------------------
|
|
63
79
|
normalizeEvent(raw) {
|
|
64
80
|
if (!raw)
|
|
@@ -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-05-
|
|
3
|
+
* Generated at: 2026-05-30T14:04:36.368Z
|
|
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-05-
|
|
6
|
+
* Generated at: 2026-05-30T14:04:36.368Z
|
|
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-05-
|
|
3
|
+
* Generated at: 2026-05-30T14:04:36.391Z
|
|
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-05-
|
|
6
|
+
* Generated at: 2026-05-30T14:04:36.391Z
|
|
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-05-
|
|
3
|
+
* Generated at: 2026-05-30T14:04:36.385Z
|
|
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-05-
|
|
6
|
+
* Generated at: 2026-05-30T14:04:36.385Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketGammaSpec = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { EventFetchParams, ExchangeCredentials, HistoryFilterParams, MarketFilterParams, MyTradesParams, OHLCVParams, PredictionMarketExchange, TradesParams } from '../../BaseExchange';
|
|
1
|
+
import { EventFetchParams, ExchangeCredentials, HistoryFilterParams, MarketFilterParams, MyTradesParams, OHLCVParams, PredictionMarketExchange, SeriesFetchParams, TradesParams } from '../../BaseExchange';
|
|
2
2
|
import { SubscribedAddressSnapshot, SubscriptionOption } from '../../subscriber/base';
|
|
3
3
|
import { buildPolymarketTradesActivity, POLYMARKET_DEFAULT_SUBSCRIPTION } from '../../subscriber/external/goldsky';
|
|
4
4
|
import { WatcherConfig } from '../../subscriber/watcher';
|
|
5
|
-
import { Balance, BuiltOrder, CreateOrderParams, Order, OrderBook, Position, PriceCandle, Trade, UnifiedEvent, UnifiedMarket, UserTrade } from '../../types';
|
|
5
|
+
import { Balance, BuiltOrder, CreateOrderParams, Order, OrderBook, Position, PriceCandle, Trade, UnifiedEvent, UnifiedMarket, UnifiedSeries, UserTrade } from '../../types';
|
|
6
6
|
import { PolymarketWebSocketConfig, UserChannelCallback, UserChannelEvent, PolymarketUserChannelCreds } from './websocket';
|
|
7
7
|
export type { PolymarketWebSocketConfig, WatcherConfig, UserChannelCallback, UserChannelEvent, PolymarketUserChannelCreds };
|
|
8
8
|
export { POLYMARKET_DEFAULT_SUBSCRIPTION, buildPolymarketTradesActivity };
|
|
@@ -11,6 +11,9 @@ export interface PolymarketExchangeOptions {
|
|
|
11
11
|
websocket?: PolymarketWebSocketConfig;
|
|
12
12
|
}
|
|
13
13
|
export declare class PolymarketExchange extends PredictionMarketExchange {
|
|
14
|
+
protected readonly capabilityOverrides: {
|
|
15
|
+
fetchSeries: true;
|
|
16
|
+
};
|
|
14
17
|
private auth?;
|
|
15
18
|
private wsConfig?;
|
|
16
19
|
private cachedApiCreds?;
|
|
@@ -60,6 +63,14 @@ export declare class PolymarketExchange extends PredictionMarketExchange {
|
|
|
60
63
|
protected mapImplicitApiError(error: any): any;
|
|
61
64
|
protected fetchMarketsImpl(params?: MarketFilterParams): Promise<UnifiedMarket[]>;
|
|
62
65
|
protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Resolve a series id or slug string to a numeric Gamma series id.
|
|
68
|
+
* If the value is already numeric, returns it unchanged.
|
|
69
|
+
* Otherwise, calls `listSeries` with the value as `slug` and returns the
|
|
70
|
+
* first matching series id.
|
|
71
|
+
*/
|
|
72
|
+
private resolveSeriesId;
|
|
73
|
+
protected fetchSeriesImpl(params: SeriesFetchParams): Promise<UnifiedSeries[]>;
|
|
63
74
|
/**
|
|
64
75
|
* Ensure authentication is initialized before trading operations.
|
|
65
76
|
*/
|
|
@@ -20,6 +20,9 @@ const fetcher_1 = require("./fetcher");
|
|
|
20
20
|
const normalizer_1 = require("./normalizer");
|
|
21
21
|
const websocket_1 = require("./websocket");
|
|
22
22
|
class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
23
|
+
capabilityOverrides = {
|
|
24
|
+
fetchSeries: true,
|
|
25
|
+
};
|
|
23
26
|
auth;
|
|
24
27
|
wsConfig;
|
|
25
28
|
cachedApiCreds;
|
|
@@ -555,12 +558,58 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
555
558
|
const events = await this.callApi('listEvents', queryParams);
|
|
556
559
|
return (events || []).map((event) => this.normalizer.normalizeEvent(event)).filter((e) => e !== null);
|
|
557
560
|
}
|
|
561
|
+
if (params.series) {
|
|
562
|
+
const seriesId = await this.resolveSeriesId(params.series);
|
|
563
|
+
const events = await this.callApi('listEvents', { series_id: seriesId });
|
|
564
|
+
return (events || []).map((event) => this.normalizer.normalizeEvent(event)).filter((e) => e !== null);
|
|
565
|
+
}
|
|
558
566
|
const rawEvents = await this.fetcher.fetchRawEvents(params);
|
|
559
567
|
return rawEvents
|
|
560
568
|
.map((raw) => this.normalizer.normalizeEvent(raw))
|
|
561
569
|
.filter((e) => e !== null)
|
|
562
570
|
.slice(0, params.limit || 250000);
|
|
563
571
|
}
|
|
572
|
+
/**
|
|
573
|
+
* Resolve a series id or slug string to a numeric Gamma series id.
|
|
574
|
+
* If the value is already numeric, returns it unchanged.
|
|
575
|
+
* Otherwise, calls `listSeries` with the value as `slug` and returns the
|
|
576
|
+
* first matching series id.
|
|
577
|
+
*/
|
|
578
|
+
async resolveSeriesId(seriesValue) {
|
|
579
|
+
const numericId = Number(seriesValue);
|
|
580
|
+
if (Number.isInteger(numericId) && numericId > 0) {
|
|
581
|
+
return numericId;
|
|
582
|
+
}
|
|
583
|
+
// Slug path: look up via listSeries
|
|
584
|
+
const results = await this.callApi('listSeries', { slug: [seriesValue] });
|
|
585
|
+
const first = Array.isArray(results) ? results[0] : undefined;
|
|
586
|
+
if (!first || first.id == null) {
|
|
587
|
+
throw new Error(`Polymarket: no series found for slug "${seriesValue}"`);
|
|
588
|
+
}
|
|
589
|
+
return Number(first.id);
|
|
590
|
+
}
|
|
591
|
+
async fetchSeriesImpl(params) {
|
|
592
|
+
if (params.id) {
|
|
593
|
+
const raw = await this.callApi('getSeries', { id: params.id });
|
|
594
|
+
if (!raw || raw.id == null)
|
|
595
|
+
return [];
|
|
596
|
+
return [this.normalizer.normalizeSeries(raw)];
|
|
597
|
+
}
|
|
598
|
+
const queryParams = {};
|
|
599
|
+
if (params.slug)
|
|
600
|
+
queryParams['slug'] = [params.slug];
|
|
601
|
+
if (params.recurrence)
|
|
602
|
+
queryParams['recurrence'] = params.recurrence;
|
|
603
|
+
const results = await this.callApi('listSeries', queryParams);
|
|
604
|
+
const list = Array.isArray(results) ? results : [];
|
|
605
|
+
const normalized = list.map((raw) => this.normalizer.normalizeSeries(raw));
|
|
606
|
+
if (params.query) {
|
|
607
|
+
const lowerQuery = params.query.toLowerCase();
|
|
608
|
+
return normalized.filter((s) => (s.title || '').toLowerCase().includes(lowerQuery) ||
|
|
609
|
+
(s.description || '').toLowerCase().includes(lowerQuery));
|
|
610
|
+
}
|
|
611
|
+
return normalized;
|
|
612
|
+
}
|
|
564
613
|
/**
|
|
565
614
|
* Ensure authentication is initialized before trading operations.
|
|
566
615
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { OHLCVParams } from '../../BaseExchange';
|
|
2
|
-
import { UnifiedMarket, UnifiedEvent, PriceCandle, OrderBook, Trade, UserTrade, Position } from '../../types';
|
|
2
|
+
import { UnifiedMarket, UnifiedEvent, UnifiedSeries, PriceCandle, OrderBook, Trade, UserTrade, Position } from '../../types';
|
|
3
3
|
import { IExchangeNormalizer } from '../interfaces';
|
|
4
4
|
import { PolymarketRawEvent, PolymarketRawOHLCVPoint, PolymarketRawOrderBook, PolymarketRawTrade, PolymarketRawPosition } from './fetcher';
|
|
5
5
|
export declare class PolymarketNormalizer implements IExchangeNormalizer<PolymarketRawEvent, PolymarketRawEvent> {
|
|
@@ -8,6 +8,7 @@ export declare class PolymarketNormalizer implements IExchangeNormalizer<Polymar
|
|
|
8
8
|
useQuestionAsCandidateFallback?: boolean;
|
|
9
9
|
}): UnifiedMarket[];
|
|
10
10
|
normalizeEvent(raw: PolymarketRawEvent): UnifiedEvent | null;
|
|
11
|
+
normalizeSeries(raw: Record<string, unknown>): UnifiedSeries;
|
|
11
12
|
normalizeOHLCV(raw: {
|
|
12
13
|
history: PolymarketRawOHLCVPoint[];
|
|
13
14
|
}, params: OHLCVParams): PriceCandle[];
|
|
@@ -11,6 +11,12 @@ const POLYMARKET_PROMOTED_EVENT_KEYS = [
|
|
|
11
11
|
// 'markets' is the child-markets array — promoted to UnifiedEvent.markets
|
|
12
12
|
'markets',
|
|
13
13
|
];
|
|
14
|
+
// Raw Polymarket Gamma series fields promoted to first-class UnifiedSeries columns.
|
|
15
|
+
const POLYMARKET_PROMOTED_SERIES_KEYS = [
|
|
16
|
+
'id', 'ticker', 'slug', 'title', 'description', 'image', 'recurrence',
|
|
17
|
+
// 'events' is promoted to UnifiedSeries.events
|
|
18
|
+
'events',
|
|
19
|
+
];
|
|
14
20
|
class PolymarketNormalizer {
|
|
15
21
|
normalizeMarket(raw) {
|
|
16
22
|
if (!raw)
|
|
@@ -57,6 +63,33 @@ class PolymarketNormalizer {
|
|
|
57
63
|
sourceMetadata: (0, metadata_1.buildSourceMetadata)(raw, POLYMARKET_PROMOTED_EVENT_KEYS),
|
|
58
64
|
};
|
|
59
65
|
}
|
|
66
|
+
normalizeSeries(raw) {
|
|
67
|
+
const id = String(raw['id'] ?? '');
|
|
68
|
+
const slug = typeof raw['slug'] === 'string' ? raw['slug'] : undefined;
|
|
69
|
+
const ticker = typeof raw['ticker'] === 'string' ? raw['ticker'] : undefined;
|
|
70
|
+
const title = typeof raw['title'] === 'string' ? raw['title'] : (slug ?? id);
|
|
71
|
+
const description = raw['description'] != null ? String(raw['description']) : null;
|
|
72
|
+
const recurrence = raw['recurrence'] != null ? String(raw['recurrence']) : null;
|
|
73
|
+
const image = raw['image'] != null ? String(raw['image']) : null;
|
|
74
|
+
const rawEvents = Array.isArray(raw['events']) ? raw['events'] : undefined;
|
|
75
|
+
const events = rawEvents !== undefined
|
|
76
|
+
? rawEvents
|
|
77
|
+
.map((e) => this.normalizeEvent(e))
|
|
78
|
+
.filter((e) => e !== null)
|
|
79
|
+
: undefined;
|
|
80
|
+
return {
|
|
81
|
+
id,
|
|
82
|
+
ticker,
|
|
83
|
+
slug,
|
|
84
|
+
title,
|
|
85
|
+
description,
|
|
86
|
+
recurrence,
|
|
87
|
+
image,
|
|
88
|
+
url: slug != null ? `https://polymarket.com/series/${slug}` : null,
|
|
89
|
+
events,
|
|
90
|
+
sourceMetadata: (0, metadata_1.buildSourceMetadata)(raw, POLYMARKET_PROMOTED_SERIES_KEYS),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
60
93
|
normalizeOHLCV(raw, params) {
|
|
61
94
|
const history = raw.history || [];
|
|
62
95
|
const fidelity = (0, utils_1.mapIntervalToFidelity)(params.resolution);
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* `cancelOrder(orderId)` does not. We maintain an in-memory cache mapping
|
|
14
14
|
* orderId -> marketSlug populated whenever we observe an order.
|
|
15
15
|
*/
|
|
16
|
-
import { PredictionMarketExchange, ExchangeCredentials, MarketFetchParams, EventFetchParams, MyTradesParams } from '../../BaseExchange';
|
|
17
|
-
import { UnifiedMarket, UnifiedEvent, OrderBook, Trade, UserTrade, Order, Position, Balance, CreateOrderParams, BuiltOrder } from '../../types';
|
|
16
|
+
import { PredictionMarketExchange, ExchangeCredentials, MarketFetchParams, EventFetchParams, SeriesFetchParams, MyTradesParams } from '../../BaseExchange';
|
|
17
|
+
import { UnifiedMarket, UnifiedEvent, UnifiedSeries, OrderBook, Trade, UserTrade, Order, Position, Balance, CreateOrderParams, BuiltOrder } from '../../types';
|
|
18
18
|
export * from './config';
|
|
19
19
|
export * from './price';
|
|
20
20
|
export * from './errors';
|
|
@@ -46,6 +46,7 @@ export declare class PolymarketUSExchange extends PredictionMarketExchange {
|
|
|
46
46
|
private slugFromId;
|
|
47
47
|
protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
|
|
48
48
|
protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
|
|
49
|
+
protected fetchSeriesImpl(params: SeriesFetchParams): Promise<UnifiedSeries[]>;
|
|
49
50
|
fetchOrderBook(outcomeId: string, _limit?: number, _params?: Record<string, any>): Promise<OrderBook>;
|
|
50
51
|
fetchBalance(_address?: string): Promise<Balance[]>;
|
|
51
52
|
fetchPositions(_address?: string): Promise<Position[]>;
|
|
@@ -149,10 +149,33 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
149
149
|
const resp = await this.client.events.retrieveBySlug(directSlug);
|
|
150
150
|
return resp.event ? [this.normalizer.normalizeEvent(resp.event)] : [];
|
|
151
151
|
}
|
|
152
|
+
// When filtering by series, the SDK accepts seriesId as an array of
|
|
153
|
+
// numeric ids. The PMXT series param is a string (id or slug); we
|
|
154
|
+
// attempt numeric parsing first and fall back to slug resolution below.
|
|
155
|
+
let seriesIdFilter;
|
|
156
|
+
if (params?.series != null) {
|
|
157
|
+
const numericId = Number(params.series);
|
|
158
|
+
if (Number.isFinite(numericId) && numericId > 0) {
|
|
159
|
+
seriesIdFilter = [numericId];
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
// Non-numeric: attempt to resolve the slug to a numeric series id
|
|
163
|
+
// by listing series and finding a slug match.
|
|
164
|
+
const slugResp = await this.client.series.list({ slug: [params.series] });
|
|
165
|
+
const matched = slugResp.series?.[0];
|
|
166
|
+
if (!matched) {
|
|
167
|
+
// Unknown series slug — return empty rather than silently
|
|
168
|
+
// ignoring the filter and returning all events.
|
|
169
|
+
return [];
|
|
170
|
+
}
|
|
171
|
+
seriesIdFilter = [matched.id];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
152
174
|
const resp = await this.client.events.list({
|
|
153
175
|
active: true,
|
|
154
176
|
limit: params?.limit ?? 100,
|
|
155
177
|
offset: params?.offset ?? 0,
|
|
178
|
+
...(seriesIdFilter !== undefined ? { seriesId: seriesIdFilter } : {}),
|
|
156
179
|
});
|
|
157
180
|
if (!resp.events) {
|
|
158
181
|
throw new Error('PolymarketUS events.list response missing required "events" field');
|
|
@@ -166,6 +189,40 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
166
189
|
return events;
|
|
167
190
|
});
|
|
168
191
|
}
|
|
192
|
+
async fetchSeriesImpl(params) {
|
|
193
|
+
return this.run(async () => {
|
|
194
|
+
// Direct lookup by numeric id
|
|
195
|
+
if (params?.id != null) {
|
|
196
|
+
const numericId = Number(params.id);
|
|
197
|
+
if (!Number.isFinite(numericId) || numericId <= 0) {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
const resp = await this.client.series.retrieve(numericId);
|
|
201
|
+
if (!resp.series) {
|
|
202
|
+
throw new Error('PolymarketUS series.retrieve response missing required "series" field');
|
|
203
|
+
}
|
|
204
|
+
return [this.normalizer.normalizeSeries(resp.series)];
|
|
205
|
+
}
|
|
206
|
+
const listParams = { active: true };
|
|
207
|
+
if (params?.slug != null) {
|
|
208
|
+
listParams.slug = [params.slug];
|
|
209
|
+
}
|
|
210
|
+
if (params?.recurrence != null) {
|
|
211
|
+
listParams.recurrence = params.recurrence;
|
|
212
|
+
}
|
|
213
|
+
const resp = await this.client.series.list(listParams);
|
|
214
|
+
if (!resp.series) {
|
|
215
|
+
throw new Error('PolymarketUS series.list response missing required "series" field');
|
|
216
|
+
}
|
|
217
|
+
let series = resp.series.map(s => this.normalizer.normalizeSeries(s));
|
|
218
|
+
if (params?.query) {
|
|
219
|
+
const q = params.query.toLowerCase();
|
|
220
|
+
series = series.filter(s => s.title.toLowerCase().includes(q) ||
|
|
221
|
+
(s.description || '').toLowerCase().includes(q));
|
|
222
|
+
}
|
|
223
|
+
return series;
|
|
224
|
+
});
|
|
225
|
+
}
|
|
169
226
|
async fetchOrderBook(outcomeId, _limit, _params) {
|
|
170
227
|
const resolved = await this.resolveOutcomeAlias(outcomeId, _params);
|
|
171
228
|
outcomeId = resolved.outcomeId;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import type { Event as SdkEvent, MarketDetail, MarketBook, Order as SdkOrder, UserPosition, UserBalance, Activity } from 'polymarket-us';
|
|
2
|
-
import { UnifiedMarket, UnifiedEvent, OrderBook, Order, Position, Balance, UserTrade } from '../../types';
|
|
1
|
+
import type { Event as SdkEvent, MarketDetail, MarketBook, Order as SdkOrder, UserPosition, UserBalance, Activity, Series as SdkSeries } from 'polymarket-us';
|
|
2
|
+
import { UnifiedMarket, UnifiedEvent, UnifiedSeries, OrderBook, Order, Position, Balance, UserTrade } from '../../types';
|
|
3
3
|
export declare class PolymarketUSNormalizer {
|
|
4
|
+
/**
|
|
5
|
+
* Normalize a Polymarket US SDK Series into a UnifiedSeries.
|
|
6
|
+
*
|
|
7
|
+
* The SDK's Series type is exported as `Series` from `polymarket-us`;
|
|
8
|
+
* the `id` field is numeric and is stringified for the unified identifier.
|
|
9
|
+
*/
|
|
10
|
+
normalizeSeries(raw: SdkSeries): UnifiedSeries;
|
|
4
11
|
/**
|
|
5
12
|
* Normalize a single MarketDetail into a UnifiedMarket.
|
|
6
13
|
* The slug is the canonical PMXT marketId for Polymarket US.
|
|
@@ -9,6 +9,10 @@ const price_1 = require("./price");
|
|
|
9
9
|
const POLYMARKET_US_PROMOTED_EVENT_KEYS = [
|
|
10
10
|
'slug', 'title', 'description', 'category', 'tags', 'volume', 'markets',
|
|
11
11
|
];
|
|
12
|
+
// Series fields promoted to first-class UnifiedSeries columns.
|
|
13
|
+
const POLYMARKET_US_PROMOTED_SERIES_KEYS = [
|
|
14
|
+
'id', 'slug', 'title', 'description', 'recurrence',
|
|
15
|
+
];
|
|
12
16
|
// marketSides and outcomePrices feed the outcomes array and are therefore
|
|
13
17
|
// treated as promoted. orderPriceMinTickSize maps to tickSize.
|
|
14
18
|
const POLYMARKET_US_PROMOTED_MARKET_KEYS = [
|
|
@@ -193,6 +197,29 @@ function mapOrderStatus(state) {
|
|
|
193
197
|
// Normalizer
|
|
194
198
|
// ----------------------------------------------------------------------------
|
|
195
199
|
class PolymarketUSNormalizer {
|
|
200
|
+
/**
|
|
201
|
+
* Normalize a Polymarket US SDK Series into a UnifiedSeries.
|
|
202
|
+
*
|
|
203
|
+
* The SDK's Series type is exported as `Series` from `polymarket-us`;
|
|
204
|
+
* the `id` field is numeric and is stringified for the unified identifier.
|
|
205
|
+
*/
|
|
206
|
+
normalizeSeries(raw) {
|
|
207
|
+
const id = String(raw.id);
|
|
208
|
+
const slug = raw.slug || undefined;
|
|
209
|
+
const title = raw.title || slug || id;
|
|
210
|
+
const description = raw.description != null ? raw.description : null;
|
|
211
|
+
const recurrence = raw.recurrence != null ? raw.recurrence : null;
|
|
212
|
+
const url = slug != null ? `https://polymarket.us/series/${slug}` : null;
|
|
213
|
+
return {
|
|
214
|
+
id,
|
|
215
|
+
slug,
|
|
216
|
+
title,
|
|
217
|
+
description,
|
|
218
|
+
recurrence,
|
|
219
|
+
url,
|
|
220
|
+
sourceMetadata: (0, metadata_1.buildSourceMetadata)(raw, POLYMARKET_US_PROMOTED_SERIES_KEYS),
|
|
221
|
+
};
|
|
222
|
+
}
|
|
196
223
|
/**
|
|
197
224
|
* Normalize a single MarketDetail into a UnifiedMarket.
|
|
198
225
|
* The slug is the canonical PMXT marketId for Polymarket US.
|
|
@@ -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-05-
|
|
3
|
+
* Generated at: 2026-05-30T14:04:36.430Z
|
|
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-05-
|
|
6
|
+
* Generated at: 2026-05-30T14:04:36.430Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.probableApiSpec = {
|