pmxt-core 2.8.0 → 2.9.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 +48 -0
- package/dist/BaseExchange.js +116 -0
- package/dist/exchanges/kalshi/api.d.ts +1763 -0
- package/dist/exchanges/kalshi/api.js +2554 -0
- package/dist/exchanges/kalshi/fetchEvents.d.ts +3 -2
- package/dist/exchanges/kalshi/fetchEvents.js +9 -16
- package/dist/exchanges/kalshi/fetchMarkets.d.ts +3 -2
- package/dist/exchanges/kalshi/fetchMarkets.js +24 -32
- package/dist/exchanges/kalshi/fetchOHLCV.d.ts +1 -2
- package/dist/exchanges/kalshi/fetchOHLCV.js +9 -11
- package/dist/exchanges/kalshi/index.d.ts +2 -1
- package/dist/exchanges/kalshi/index.js +161 -183
- package/dist/exchanges/kalshi/kalshi.test.js +51 -31
- package/dist/exchanges/limitless/api.d.ts +555 -0
- package/dist/exchanges/limitless/api.js +863 -0
- package/dist/exchanges/limitless/fetchEvents.d.ts +1 -2
- package/dist/exchanges/limitless/fetchEvents.js +9 -15
- package/dist/exchanges/limitless/fetchMarkets.d.ts +1 -2
- package/dist/exchanges/limitless/fetchMarkets.js +9 -16
- package/dist/exchanges/limitless/fetchOHLCV.d.ts +1 -2
- package/dist/exchanges/limitless/fetchOHLCV.js +2 -11
- package/dist/exchanges/limitless/fetchOrderBook.d.ts +1 -2
- package/dist/exchanges/limitless/fetchOrderBook.js +2 -11
- package/dist/exchanges/limitless/index.d.ts +1 -0
- package/dist/exchanges/limitless/index.js +28 -7
- package/dist/exchanges/limitless/websocket.d.ts +2 -1
- package/dist/exchanges/limitless/websocket.js +6 -4
- package/dist/exchanges/myriad/api.d.ts +294 -0
- package/dist/exchanges/myriad/api.js +690 -0
- package/dist/exchanges/myriad/fetchOHLCV.d.ts +1 -2
- package/dist/exchanges/myriad/fetchOHLCV.js +3 -11
- package/dist/exchanges/myriad/fetchOrderBook.d.ts +1 -2
- package/dist/exchanges/myriad/fetchOrderBook.js +3 -11
- package/dist/exchanges/myriad/index.d.ts +2 -0
- package/dist/exchanges/myriad/index.js +116 -103
- package/dist/exchanges/myriad/websocket.d.ts +2 -2
- package/dist/exchanges/myriad/websocket.js +28 -6
- package/dist/exchanges/polymarket/api-clob.d.ts +346 -0
- package/dist/exchanges/polymarket/api-clob.js +517 -0
- package/dist/exchanges/polymarket/api-data.d.ts +789 -0
- package/dist/exchanges/polymarket/api-data.js +860 -0
- package/dist/exchanges/polymarket/api-gamma.d.ts +556 -0
- package/dist/exchanges/polymarket/api-gamma.js +1161 -0
- package/dist/exchanges/polymarket/fetchEvents.js +0 -68
- package/dist/exchanges/polymarket/fetchOHLCV.d.ts +1 -2
- package/dist/exchanges/polymarket/fetchOHLCV.js +4 -10
- package/dist/exchanges/polymarket/fetchOrderBook.d.ts +1 -2
- package/dist/exchanges/polymarket/fetchOrderBook.js +2 -10
- package/dist/exchanges/polymarket/fetchTrades.d.ts +1 -2
- package/dist/exchanges/polymarket/fetchTrades.js +2 -11
- package/dist/exchanges/polymarket/index.d.ts +10 -0
- package/dist/exchanges/polymarket/index.js +110 -5
- package/dist/exchanges/probable/api.d.ts +605 -0
- package/dist/exchanges/probable/api.js +887 -0
- package/dist/exchanges/probable/fetchEvents.d.ts +3 -3
- package/dist/exchanges/probable/fetchEvents.js +28 -25
- package/dist/exchanges/probable/fetchMarkets.d.ts +1 -1
- package/dist/exchanges/probable/fetchMarkets.js +25 -21
- package/dist/exchanges/probable/index.d.ts +1 -0
- package/dist/exchanges/probable/index.js +92 -10
- package/dist/exchanges/probable/utils.d.ts +1 -2
- package/dist/exchanges/probable/utils.js +4 -11
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/utils/openapi.d.ts +9 -0
- package/dist/utils/openapi.js +59 -0
- package/package.json +4 -3
- package/dist/exchanges/kalshi/fetchOrderBook.d.ts +0 -3
- package/dist/exchanges/kalshi/fetchOrderBook.js +0 -59
- package/dist/exchanges/kalshi/fetchTrades.d.ts +0 -4
- package/dist/exchanges/kalshi/fetchTrades.js +0 -31
- package/dist/exchanges/limitless/fetchPositions.d.ts +0 -2
- package/dist/exchanges/limitless/fetchPositions.js +0 -34
- package/dist/exchanges/myriad/fetchTrades.d.ts +0 -4
- package/dist/exchanges/myriad/fetchTrades.js +0 -62
- package/dist/exchanges/polymarket/fetchPositions.d.ts +0 -2
- package/dist/exchanges/polymarket/fetchPositions.js +0 -34
- package/dist/exchanges/probable/fetchOHLCV.d.ts +0 -4
- package/dist/exchanges/probable/fetchOHLCV.js +0 -83
- package/dist/exchanges/probable/fetchOrderBook.d.ts +0 -3
- package/dist/exchanges/probable/fetchOrderBook.js +0 -37
- package/dist/exchanges/probable/fetchPositions.d.ts +0 -2
- package/dist/exchanges/probable/fetchPositions.js +0 -33
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EventFetchParams } from '../../BaseExchange';
|
|
2
2
|
import { UnifiedEvent } from '../../types';
|
|
3
3
|
import { AxiosInstance } from 'axios';
|
|
4
|
-
export declare function fetchEvents(params: EventFetchParams, http?: AxiosInstance): Promise<UnifiedEvent[]>;
|
|
5
|
-
export declare function fetchEventById(id: string, http?: AxiosInstance): Promise<UnifiedEvent | null>;
|
|
6
|
-
export declare function fetchEventBySlug(slug: string, http?: AxiosInstance): Promise<UnifiedEvent | null>;
|
|
4
|
+
export declare function fetchEvents(params: EventFetchParams, http?: AxiosInstance, callMidpoint?: (tokenId: string) => Promise<any>, callSearch?: (params: any) => Promise<any>): Promise<UnifiedEvent[]>;
|
|
5
|
+
export declare function fetchEventById(id: string, http?: AxiosInstance, callMidpoint?: (tokenId: string) => Promise<any>): Promise<UnifiedEvent | null>;
|
|
6
|
+
export declare function fetchEventBySlug(slug: string, http?: AxiosInstance, callMidpoint?: (tokenId: string) => Promise<any>): Promise<UnifiedEvent | null>;
|
|
@@ -9,38 +9,38 @@ exports.fetchEventBySlug = fetchEventBySlug;
|
|
|
9
9
|
const axios_1 = __importDefault(require("axios"));
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
11
|
const errors_1 = require("./errors");
|
|
12
|
-
async function fetchEvents(params, http = axios_1.default) {
|
|
12
|
+
async function fetchEvents(params, http = axios_1.default, callMidpoint, callSearch) {
|
|
13
13
|
try {
|
|
14
14
|
// Handle eventId lookup
|
|
15
15
|
if (params.eventId) {
|
|
16
|
-
const event = await fetchEventById(params.eventId, http);
|
|
16
|
+
const event = await fetchEventById(params.eventId, http, callMidpoint);
|
|
17
17
|
return event ? [event] : [];
|
|
18
18
|
}
|
|
19
19
|
// Handle slug lookup
|
|
20
20
|
if (params.slug) {
|
|
21
|
-
const event = await fetchEventBySlug(params.slug, http);
|
|
21
|
+
const event = await fetchEventBySlug(params.slug, http, callMidpoint);
|
|
22
22
|
return event ? [event] : [];
|
|
23
23
|
}
|
|
24
24
|
// Query-based search: use the search endpoint (only endpoint with text search)
|
|
25
25
|
if (params.query) {
|
|
26
|
-
return await searchEvents(params, http);
|
|
26
|
+
return await searchEvents(params, http, callMidpoint, callSearch);
|
|
27
27
|
}
|
|
28
28
|
// Default: use the dedicated events API for listing
|
|
29
|
-
return await fetchEventsList(params, http);
|
|
29
|
+
return await fetchEventsList(params, http, callMidpoint);
|
|
30
30
|
}
|
|
31
31
|
catch (error) {
|
|
32
32
|
throw errors_1.probableErrorMapper.mapError(error);
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
async function fetchEventById(id, http = axios_1.default) {
|
|
35
|
+
async function fetchEventById(id, http = axios_1.default, callMidpoint) {
|
|
36
36
|
try {
|
|
37
37
|
const numericId = Number(id);
|
|
38
38
|
if (isNaN(numericId))
|
|
39
39
|
return null;
|
|
40
40
|
const response = await http.get(`${utils_1.BASE_URL}${utils_1.EVENTS_PATH}${numericId}`);
|
|
41
41
|
const event = (0, utils_1.mapEventToUnified)(response.data);
|
|
42
|
-
if (event)
|
|
43
|
-
await (0, utils_1.enrichMarketsWithPrices)(event.markets);
|
|
42
|
+
if (event && callMidpoint)
|
|
43
|
+
await (0, utils_1.enrichMarketsWithPrices)(event.markets, callMidpoint);
|
|
44
44
|
return event;
|
|
45
45
|
}
|
|
46
46
|
catch (error) {
|
|
@@ -49,12 +49,12 @@ async function fetchEventById(id, http = axios_1.default) {
|
|
|
49
49
|
throw errors_1.probableErrorMapper.mapError(error);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
async function fetchEventBySlug(slug, http = axios_1.default) {
|
|
52
|
+
async function fetchEventBySlug(slug, http = axios_1.default, callMidpoint) {
|
|
53
53
|
try {
|
|
54
54
|
const response = await http.get(`${utils_1.BASE_URL}${utils_1.EVENTS_PATH}slug/${slug}`);
|
|
55
55
|
const event = (0, utils_1.mapEventToUnified)(response.data);
|
|
56
|
-
if (event)
|
|
57
|
-
await (0, utils_1.enrichMarketsWithPrices)(event.markets);
|
|
56
|
+
if (event && callMidpoint)
|
|
57
|
+
await (0, utils_1.enrichMarketsWithPrices)(event.markets, callMidpoint);
|
|
58
58
|
return event;
|
|
59
59
|
}
|
|
60
60
|
catch (error) {
|
|
@@ -63,7 +63,7 @@ async function fetchEventBySlug(slug, http = axios_1.default) {
|
|
|
63
63
|
throw errors_1.probableErrorMapper.mapError(error);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
async function fetchEventsList(params, http) {
|
|
66
|
+
async function fetchEventsList(params, http, callMidpoint) {
|
|
67
67
|
const limit = params.limit || 20;
|
|
68
68
|
const page = params.offset ? Math.floor(params.offset / limit) + 1 : 1;
|
|
69
69
|
const queryParams = {
|
|
@@ -99,27 +99,30 @@ async function fetchEventsList(params, http) {
|
|
|
99
99
|
.map((event) => (0, utils_1.mapEventToUnified)(event))
|
|
100
100
|
.filter((e) => e !== null);
|
|
101
101
|
const allMarkets = result.flatMap((e) => e.markets);
|
|
102
|
-
|
|
102
|
+
if (callMidpoint)
|
|
103
|
+
await (0, utils_1.enrichMarketsWithPrices)(allMarkets, callMidpoint);
|
|
103
104
|
return result;
|
|
104
105
|
}
|
|
105
|
-
async function searchEvents(params, http) {
|
|
106
|
+
async function searchEvents(params, http, callMidpoint, callSearch) {
|
|
106
107
|
const limit = params.limit || 20;
|
|
107
108
|
const page = params.offset ? Math.floor(params.offset / limit) + 1 : 1;
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
109
|
+
const queryParams = {
|
|
110
|
+
q: params.query,
|
|
111
|
+
page,
|
|
112
|
+
limit,
|
|
113
|
+
events_status: mapStatus(params.status),
|
|
114
|
+
keep_closed_markets: params.status === 'all' || params.status === 'inactive' || params.status === 'closed' ? 1 : 0,
|
|
115
|
+
};
|
|
116
|
+
const searchData = callSearch
|
|
117
|
+
? await callSearch(queryParams)
|
|
118
|
+
: (await http.get(`${utils_1.BASE_URL}${utils_1.SEARCH_PATH}`, { params: queryParams })).data;
|
|
119
|
+
const events = searchData?.events || [];
|
|
118
120
|
const result = events
|
|
119
121
|
.map((event) => (0, utils_1.mapEventToUnified)(event))
|
|
120
122
|
.filter((e) => e !== null);
|
|
121
123
|
const allMarkets = result.flatMap((e) => e.markets);
|
|
122
|
-
|
|
124
|
+
if (callMidpoint)
|
|
125
|
+
await (0, utils_1.enrichMarketsWithPrices)(allMarkets, callMidpoint);
|
|
123
126
|
return result;
|
|
124
127
|
}
|
|
125
128
|
function isNotFoundError(error) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { MarketFetchParams } from '../../BaseExchange';
|
|
2
2
|
import { UnifiedMarket } from '../../types';
|
|
3
3
|
import { AxiosInstance } from 'axios';
|
|
4
|
-
export declare function fetchMarkets(params?: MarketFetchParams, http?: AxiosInstance): Promise<UnifiedMarket[]>;
|
|
4
|
+
export declare function fetchMarkets(params?: MarketFetchParams, http?: AxiosInstance, callMidpoint?: (tokenId: string) => Promise<any>, callSearch?: (params: any) => Promise<any>): Promise<UnifiedMarket[]>;
|
|
@@ -7,37 +7,37 @@ exports.fetchMarkets = fetchMarkets;
|
|
|
7
7
|
const axios_1 = __importDefault(require("axios"));
|
|
8
8
|
const utils_1 = require("./utils");
|
|
9
9
|
const errors_1 = require("./errors");
|
|
10
|
-
async function fetchMarkets(params, http = axios_1.default) {
|
|
10
|
+
async function fetchMarkets(params, http = axios_1.default, callMidpoint, callSearch) {
|
|
11
11
|
try {
|
|
12
12
|
// Handle marketId lookup (numeric ID or slug)
|
|
13
13
|
if (params?.marketId) {
|
|
14
|
-
return await fetchMarketByIdOrSlug(params.marketId, http);
|
|
14
|
+
return await fetchMarketByIdOrSlug(params.marketId, http, callMidpoint, callSearch);
|
|
15
15
|
}
|
|
16
16
|
// Slug-based lookup: try market ID or slug via dedicated endpoint
|
|
17
17
|
if (params?.slug) {
|
|
18
|
-
return await fetchMarketByIdOrSlug(params.slug, http);
|
|
18
|
+
return await fetchMarketByIdOrSlug(params.slug, http, callMidpoint, callSearch);
|
|
19
19
|
}
|
|
20
20
|
// Handle outcomeId lookup (no direct API, fetch and filter client-side)
|
|
21
21
|
if (params?.outcomeId) {
|
|
22
|
-
const markets = await fetchMarketsList(params, http);
|
|
22
|
+
const markets = await fetchMarketsList(params, http, callMidpoint);
|
|
23
23
|
return markets.filter(m => m.outcomes.some(o => o.outcomeId === params.outcomeId));
|
|
24
24
|
}
|
|
25
25
|
// Handle eventId lookup (use markets list with eventId param)
|
|
26
26
|
if (params?.eventId) {
|
|
27
|
-
return await fetchMarketsList(params, http);
|
|
27
|
+
return await fetchMarketsList(params, http, callMidpoint);
|
|
28
28
|
}
|
|
29
29
|
// Query-based search: use the search endpoint (only endpoint with text search)
|
|
30
30
|
if (params?.query) {
|
|
31
|
-
return await searchAndExtractMarkets(params.query, params, http);
|
|
31
|
+
return await searchAndExtractMarkets(params.query, params, http, callMidpoint, callSearch);
|
|
32
32
|
}
|
|
33
33
|
// Default: use the dedicated markets API for listing
|
|
34
|
-
return await fetchMarketsList(params, http);
|
|
34
|
+
return await fetchMarketsList(params, http, callMidpoint);
|
|
35
35
|
}
|
|
36
36
|
catch (error) {
|
|
37
37
|
throw errors_1.probableErrorMapper.mapError(error);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
async function fetchMarketByIdOrSlug(slug, http) {
|
|
40
|
+
async function fetchMarketByIdOrSlug(slug, http, callMidpoint, callSearch) {
|
|
41
41
|
let cleanSlug = slug;
|
|
42
42
|
let marketIdFromQuery = null;
|
|
43
43
|
// Handle URLs or partial URLs with query params (e.g., opinion-...-launch?market=584)
|
|
@@ -50,7 +50,7 @@ async function fetchMarketByIdOrSlug(slug, http) {
|
|
|
50
50
|
marketIdFromQuery = params.get('market');
|
|
51
51
|
// If we have a market ID from the query, try that first
|
|
52
52
|
if (marketIdFromQuery) {
|
|
53
|
-
const result = await fetchMarketByIdOrSlug(marketIdFromQuery, http);
|
|
53
|
+
const result = await fetchMarketByIdOrSlug(marketIdFromQuery, http, callMidpoint);
|
|
54
54
|
if (result.length > 0)
|
|
55
55
|
return result;
|
|
56
56
|
}
|
|
@@ -66,13 +66,14 @@ async function fetchMarketByIdOrSlug(slug, http) {
|
|
|
66
66
|
const response = await http.get(`${utils_1.BASE_URL}${utils_1.MARKETS_PATH}${numericId}`);
|
|
67
67
|
const mapped = (0, utils_1.mapMarketToUnified)(response.data, response.data?.event);
|
|
68
68
|
const results = mapped ? [mapped] : [];
|
|
69
|
-
|
|
69
|
+
if (callMidpoint)
|
|
70
|
+
await (0, utils_1.enrichMarketsWithPrices)(results, callMidpoint);
|
|
70
71
|
return results;
|
|
71
72
|
}
|
|
72
73
|
catch (error) {
|
|
73
74
|
if (isMarketNotFoundError(error)) {
|
|
74
75
|
// Individual market endpoint returned 500/404; fall back to list and filter
|
|
75
|
-
const allMarkets = await fetchMarketsList({ limit: 100 }, http);
|
|
76
|
+
const allMarkets = await fetchMarketsList({ limit: 100 }, http, callMidpoint);
|
|
76
77
|
const match = allMarkets.filter(m => m.marketId === cleanSlug);
|
|
77
78
|
if (match.length > 0)
|
|
78
79
|
return match;
|
|
@@ -83,9 +84,9 @@ async function fetchMarketByIdOrSlug(slug, http) {
|
|
|
83
84
|
}
|
|
84
85
|
}
|
|
85
86
|
// Fall back to search for slug-based matching
|
|
86
|
-
return await searchAndExtractMarkets(cleanSlug, { slug: cleanSlug }, http);
|
|
87
|
+
return await searchAndExtractMarkets(cleanSlug, { slug: cleanSlug }, http, callMidpoint, callSearch);
|
|
87
88
|
}
|
|
88
|
-
async function fetchMarketsList(params, http) {
|
|
89
|
+
async function fetchMarketsList(params, http, callMidpoint) {
|
|
89
90
|
const limit = params?.limit || 20;
|
|
90
91
|
const page = params?.offset ? Math.floor(params.offset / limit) + 1 : 1;
|
|
91
92
|
const queryParams = {
|
|
@@ -124,10 +125,11 @@ async function fetchMarketsList(params, http) {
|
|
|
124
125
|
if (mapped)
|
|
125
126
|
allMarkets.push(mapped);
|
|
126
127
|
}
|
|
127
|
-
|
|
128
|
+
if (callMidpoint)
|
|
129
|
+
await (0, utils_1.enrichMarketsWithPrices)(allMarkets, callMidpoint);
|
|
128
130
|
return allMarkets;
|
|
129
131
|
}
|
|
130
|
-
async function searchAndExtractMarkets(query, params, http) {
|
|
132
|
+
async function searchAndExtractMarkets(query, params, http, callMidpoint, callSearch) {
|
|
131
133
|
const limit = params?.limit || 20;
|
|
132
134
|
const page = params?.offset ? Math.floor(params.offset / limit) + 1 : 1;
|
|
133
135
|
// Improve search for slugs: if the query looks like a slug (has dashes),
|
|
@@ -184,10 +186,10 @@ async function searchAndExtractMarkets(query, params, http) {
|
|
|
184
186
|
break;
|
|
185
187
|
}
|
|
186
188
|
}
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const events =
|
|
189
|
+
const searchData = callSearch
|
|
190
|
+
? await callSearch(queryParams)
|
|
191
|
+
: (await http.get(`${utils_1.BASE_URL}${utils_1.SEARCH_PATH}`, { params: queryParams })).data;
|
|
192
|
+
const events = searchData?.events || [];
|
|
191
193
|
const allMarkets = [];
|
|
192
194
|
for (const event of events) {
|
|
193
195
|
if (event.markets && Array.isArray(event.markets)) {
|
|
@@ -211,7 +213,8 @@ async function searchAndExtractMarkets(query, params, http) {
|
|
|
211
213
|
delete m._eventSlug;
|
|
212
214
|
}
|
|
213
215
|
if (exact.length > 0) {
|
|
214
|
-
|
|
216
|
+
if (callMidpoint)
|
|
217
|
+
await (0, utils_1.enrichMarketsWithPrices)(exact, callMidpoint);
|
|
215
218
|
return exact;
|
|
216
219
|
}
|
|
217
220
|
}
|
|
@@ -219,7 +222,8 @@ async function searchAndExtractMarkets(query, params, http) {
|
|
|
219
222
|
for (const m of allMarkets) {
|
|
220
223
|
delete m._eventSlug;
|
|
221
224
|
}
|
|
222
|
-
|
|
225
|
+
if (callMidpoint)
|
|
226
|
+
await (0, utils_1.enrichMarketsWithPrices)(allMarkets, callMidpoint);
|
|
223
227
|
return allMarkets;
|
|
224
228
|
}
|
|
225
229
|
function isMarketNotFoundError(error) {
|
|
@@ -22,6 +22,7 @@ export declare class ProbableExchange extends PredictionMarketExchange {
|
|
|
22
22
|
private wsConfig?;
|
|
23
23
|
constructor(credentials?: ExchangeCredentials, wsConfig?: ProbableWebSocketConfig);
|
|
24
24
|
get name(): string;
|
|
25
|
+
protected mapImplicitApiError(error: any): any;
|
|
25
26
|
private ensureAuth;
|
|
26
27
|
protected fetchMarketsImpl(params?: MarketFetchParams): Promise<UnifiedMarket[]>;
|
|
27
28
|
protected fetchEventsImpl(params: EventFetchParams): Promise<UnifiedEvent[]>;
|
|
@@ -4,16 +4,34 @@ exports.ProbableExchange = void 0;
|
|
|
4
4
|
const BaseExchange_1 = require("../../BaseExchange");
|
|
5
5
|
const fetchMarkets_1 = require("./fetchMarkets");
|
|
6
6
|
const fetchEvents_1 = require("./fetchEvents");
|
|
7
|
-
const fetchOrderBook_1 = require("./fetchOrderBook");
|
|
8
|
-
const fetchOHLCV_1 = require("./fetchOHLCV");
|
|
9
|
-
const fetchPositions_1 = require("./fetchPositions");
|
|
10
7
|
const fetchTrades_1 = require("./fetchTrades");
|
|
11
8
|
const auth_1 = require("./auth");
|
|
12
9
|
const websocket_1 = require("./websocket");
|
|
13
10
|
const errors_1 = require("./errors");
|
|
14
11
|
const errors_2 = require("../../errors");
|
|
15
12
|
const clob_1 = require("@prob/clob");
|
|
13
|
+
const openapi_1 = require("../../utils/openapi");
|
|
14
|
+
const api_1 = require("./api");
|
|
15
|
+
const utils_1 = require("./utils");
|
|
16
16
|
const BSC_USDT_ADDRESS = '0x55d398326f99059fF775485246999027B3197955';
|
|
17
|
+
function aggregateCandles(candles, intervalMs) {
|
|
18
|
+
if (candles.length === 0)
|
|
19
|
+
return [];
|
|
20
|
+
const buckets = new Map();
|
|
21
|
+
for (const c of candles) {
|
|
22
|
+
const key = Math.floor(c.timestamp / intervalMs) * intervalMs;
|
|
23
|
+
const existing = buckets.get(key);
|
|
24
|
+
if (!existing) {
|
|
25
|
+
buckets.set(key, { ...c, timestamp: key });
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
existing.high = Math.max(existing.high, c.high);
|
|
29
|
+
existing.low = Math.min(existing.low, c.low);
|
|
30
|
+
existing.close = c.close;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return Array.from(buckets.values()).sort((a, b) => a.timestamp - b.timestamp);
|
|
34
|
+
}
|
|
17
35
|
class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
18
36
|
has = {
|
|
19
37
|
fetchMarkets: true,
|
|
@@ -39,10 +57,15 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
39
57
|
if (credentials?.privateKey && credentials?.apiKey && credentials?.apiSecret && credentials?.passphrase) {
|
|
40
58
|
this.auth = new auth_1.ProbableAuth(credentials);
|
|
41
59
|
}
|
|
60
|
+
const descriptor = (0, openapi_1.parseOpenApiSpec)(api_1.probableApiSpec, utils_1.BASE_URL);
|
|
61
|
+
this.defineImplicitApi(descriptor);
|
|
42
62
|
}
|
|
43
63
|
get name() {
|
|
44
64
|
return 'Probable';
|
|
45
65
|
}
|
|
66
|
+
mapImplicitApiError(error) {
|
|
67
|
+
throw errors_1.probableErrorMapper.mapError(error);
|
|
68
|
+
}
|
|
46
69
|
ensureAuth() {
|
|
47
70
|
if (!this.auth) {
|
|
48
71
|
throw new errors_2.AuthenticationError('Trading operations require authentication. ' +
|
|
@@ -54,22 +77,70 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
54
77
|
// Market Data (read-only, no auth needed)
|
|
55
78
|
// --------------------------------------------------------------------------
|
|
56
79
|
async fetchMarketsImpl(params) {
|
|
57
|
-
return (0, fetchMarkets_1.fetchMarkets)(params, this.http);
|
|
80
|
+
return (0, fetchMarkets_1.fetchMarkets)(params, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }), (queryParams) => this.callApi('getPublicApiV1PublicSearch', queryParams));
|
|
58
81
|
}
|
|
59
82
|
async fetchEventsImpl(params) {
|
|
60
|
-
return (0, fetchEvents_1.fetchEvents)(params, this.http);
|
|
83
|
+
return (0, fetchEvents_1.fetchEvents)(params, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }), (queryParams) => this.callApi('getPublicApiV1PublicSearch', queryParams));
|
|
61
84
|
}
|
|
62
85
|
async getEventById(id) {
|
|
63
|
-
return (0, fetchEvents_1.fetchEventById)(id, this.http);
|
|
86
|
+
return (0, fetchEvents_1.fetchEventById)(id, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
|
|
64
87
|
}
|
|
65
88
|
async getEventBySlug(slug) {
|
|
66
|
-
return (0, fetchEvents_1.fetchEventBySlug)(slug, this.http);
|
|
89
|
+
return (0, fetchEvents_1.fetchEventBySlug)(slug, this.http, (tokenId) => this.callApi('getPublicApiV1Midpoint', { token_id: tokenId }));
|
|
67
90
|
}
|
|
68
91
|
async fetchOrderBook(id) {
|
|
69
|
-
|
|
92
|
+
const data = await this.callApi('getPublicApiV1Book', { token_id: id });
|
|
93
|
+
const bids = (data.bids || [])
|
|
94
|
+
.map((level) => ({ price: parseFloat(level.price), size: parseFloat(level.size) }))
|
|
95
|
+
.sort((a, b) => b.price - a.price);
|
|
96
|
+
const asks = (data.asks || [])
|
|
97
|
+
.map((level) => ({ price: parseFloat(level.price), size: parseFloat(level.size) }))
|
|
98
|
+
.sort((a, b) => a.price - b.price);
|
|
99
|
+
return {
|
|
100
|
+
bids,
|
|
101
|
+
asks,
|
|
102
|
+
timestamp: data.timestamp ? new Date(data.timestamp).getTime() : Date.now(),
|
|
103
|
+
};
|
|
70
104
|
}
|
|
71
105
|
async fetchOHLCV(id, params) {
|
|
72
|
-
|
|
106
|
+
if (!params.resolution) {
|
|
107
|
+
throw new Error('fetchOHLCV requires a resolution parameter.');
|
|
108
|
+
}
|
|
109
|
+
const INTERVAL_MAP = {
|
|
110
|
+
'1m': '1m',
|
|
111
|
+
'5m': '1m',
|
|
112
|
+
'15m': '1m',
|
|
113
|
+
'1h': '1h',
|
|
114
|
+
'6h': '6h',
|
|
115
|
+
'1d': '1d',
|
|
116
|
+
};
|
|
117
|
+
const queryParams = {
|
|
118
|
+
market: id,
|
|
119
|
+
interval: INTERVAL_MAP[params.resolution] || '1h',
|
|
120
|
+
};
|
|
121
|
+
if (params.start)
|
|
122
|
+
queryParams.startTs = Math.floor(params.start.getTime() / 1000);
|
|
123
|
+
if (params.end)
|
|
124
|
+
queryParams.endTs = Math.floor(params.end.getTime() / 1000);
|
|
125
|
+
const data = await this.callApi('getPublicApiV1PricesHistory', queryParams);
|
|
126
|
+
const points = data?.history || data || [];
|
|
127
|
+
let candles = points
|
|
128
|
+
.map((p) => {
|
|
129
|
+
const price = Number(p.p);
|
|
130
|
+
const ts = Number(p.t) * 1000;
|
|
131
|
+
return { timestamp: ts, open: price, high: price, low: price, close: price, volume: 0 };
|
|
132
|
+
})
|
|
133
|
+
.sort((a, b) => a.timestamp - b.timestamp);
|
|
134
|
+
if (params.resolution === '5m') {
|
|
135
|
+
candles = aggregateCandles(candles, 5 * 60 * 1000);
|
|
136
|
+
}
|
|
137
|
+
else if (params.resolution === '15m') {
|
|
138
|
+
candles = aggregateCandles(candles, 15 * 60 * 1000);
|
|
139
|
+
}
|
|
140
|
+
if (params.limit) {
|
|
141
|
+
candles = candles.slice(-params.limit);
|
|
142
|
+
}
|
|
143
|
+
return candles;
|
|
73
144
|
}
|
|
74
145
|
// --------------------------------------------------------------------------
|
|
75
146
|
// Trading Methods
|
|
@@ -231,7 +302,18 @@ class ProbableExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
231
302
|
try {
|
|
232
303
|
const auth = this.ensureAuth();
|
|
233
304
|
const address = auth.getAddress();
|
|
234
|
-
|
|
305
|
+
const result = await this.callApi('getPublicApiV1PositionCurrent', { user: address, limit: 500 });
|
|
306
|
+
const data = Array.isArray(result) ? result : (result?.data || []);
|
|
307
|
+
return data.map((p) => ({
|
|
308
|
+
marketId: String(p.conditionId || p.condition_id || ''),
|
|
309
|
+
outcomeId: String(p.asset || p.token_id || ''),
|
|
310
|
+
outcomeLabel: p.outcome || p.title || 'Unknown',
|
|
311
|
+
size: parseFloat(p.size || '0'),
|
|
312
|
+
entryPrice: parseFloat(p.avgPrice || p.avg_price || '0'),
|
|
313
|
+
currentPrice: parseFloat(p.curPrice || p.cur_price || '0'),
|
|
314
|
+
unrealizedPnL: parseFloat(p.cashPnl || p.cash_pnl || '0'),
|
|
315
|
+
realizedPnL: parseFloat(p.realizedPnl || p.realized_pnl || '0'),
|
|
316
|
+
}));
|
|
235
317
|
}
|
|
236
318
|
catch (error) {
|
|
237
319
|
throw errors_1.probableErrorMapper.mapError(error);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { UnifiedMarket, UnifiedEvent } from '../../types';
|
|
2
2
|
export declare const BASE_URL = "https://market-api.probable.markets";
|
|
3
|
-
export declare const CLOB_BASE_URL = "https://api.probable.markets/public/api/v1";
|
|
4
3
|
export declare const SEARCH_PATH = "/public/api/v1/public-search/";
|
|
5
4
|
export declare const EVENTS_PATH = "/public/api/v1/events/";
|
|
6
5
|
export declare const MARKETS_PATH = "/public/api/v1/markets/";
|
|
7
6
|
export declare function mapMarketToUnified(market: any, event?: any): UnifiedMarket | null;
|
|
8
7
|
export declare function mapEventToUnified(event: any): UnifiedEvent | null;
|
|
9
|
-
export declare function enrichMarketsWithPrices(markets: UnifiedMarket[]): Promise<void>;
|
|
8
|
+
export declare function enrichMarketsWithPrices(markets: UnifiedMarket[], callMidpoint: (tokenId: string) => Promise<any>): Promise<void>;
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.MARKETS_PATH = exports.EVENTS_PATH = exports.SEARCH_PATH = exports.
|
|
3
|
+
exports.MARKETS_PATH = exports.EVENTS_PATH = exports.SEARCH_PATH = exports.BASE_URL = void 0;
|
|
7
4
|
exports.mapMarketToUnified = mapMarketToUnified;
|
|
8
5
|
exports.mapEventToUnified = mapEventToUnified;
|
|
9
6
|
exports.enrichMarketsWithPrices = enrichMarketsWithPrices;
|
|
10
7
|
const market_utils_1 = require("../../utils/market-utils");
|
|
11
|
-
const axios_1 = __importDefault(require("axios"));
|
|
12
8
|
exports.BASE_URL = 'https://market-api.probable.markets';
|
|
13
|
-
exports.CLOB_BASE_URL = 'https://api.probable.markets/public/api/v1';
|
|
14
9
|
exports.SEARCH_PATH = '/public/api/v1/public-search/';
|
|
15
10
|
exports.EVENTS_PATH = '/public/api/v1/events/';
|
|
16
11
|
exports.MARKETS_PATH = '/public/api/v1/markets/';
|
|
@@ -73,7 +68,7 @@ function mapEventToUnified(event) {
|
|
|
73
68
|
tags: event.tags || [],
|
|
74
69
|
};
|
|
75
70
|
}
|
|
76
|
-
async function enrichMarketsWithPrices(markets) {
|
|
71
|
+
async function enrichMarketsWithPrices(markets, callMidpoint) {
|
|
77
72
|
const outcomes = [];
|
|
78
73
|
for (const market of markets) {
|
|
79
74
|
for (const outcome of market.outcomes) {
|
|
@@ -84,10 +79,8 @@ async function enrichMarketsWithPrices(markets) {
|
|
|
84
79
|
if (outcomes.length === 0)
|
|
85
80
|
return;
|
|
86
81
|
const results = await Promise.allSettled(outcomes.map(async (outcome) => {
|
|
87
|
-
const response = await
|
|
88
|
-
|
|
89
|
-
});
|
|
90
|
-
return { outcomeId: outcome.outcomeId, mid: Number(response.data?.mid ?? 0) };
|
|
82
|
+
const response = await callMidpoint(outcome.outcomeId);
|
|
83
|
+
return { outcomeId: outcome.outcomeId, mid: Number(response?.mid ?? 0) };
|
|
91
84
|
}));
|
|
92
85
|
const priceMap = {};
|
|
93
86
|
for (const result of results) {
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -14,10 +14,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.Myriad = exports.Baozi = exports.Probable = exports.Kalshi = exports.Limitless = exports.Polymarket = void 0;
|
|
17
|
+
exports.Myriad = exports.Baozi = exports.Probable = exports.Kalshi = exports.Limitless = exports.Polymarket = exports.parseOpenApiSpec = void 0;
|
|
18
18
|
__exportStar(require("./BaseExchange"), exports);
|
|
19
19
|
__exportStar(require("./types"), exports);
|
|
20
20
|
__exportStar(require("./utils/math"), exports);
|
|
21
|
+
var openapi_1 = require("./utils/openapi");
|
|
22
|
+
Object.defineProperty(exports, "parseOpenApiSpec", { enumerable: true, get: function () { return openapi_1.parseOpenApiSpec; } });
|
|
21
23
|
__exportStar(require("./errors"), exports);
|
|
22
24
|
__exportStar(require("./exchanges/polymarket"), exports);
|
|
23
25
|
__exportStar(require("./exchanges/limitless"), exports);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ApiDescriptor } from '../BaseExchange';
|
|
2
|
+
/**
|
|
3
|
+
* Parses an OpenAPI 3.x-shaped spec object into a simplified ApiDescriptor.
|
|
4
|
+
*
|
|
5
|
+
* @param spec - An OpenAPI-like spec object with `paths` and optionally `servers`
|
|
6
|
+
* @param baseUrl - The base URL for the API. If omitted, extracted from spec.servers[0].url
|
|
7
|
+
* @returns A simplified ApiDescriptor with method names mapped to endpoints
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseOpenApiSpec(spec: any, baseUrl?: string): ApiDescriptor;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseOpenApiSpec = parseOpenApiSpec;
|
|
4
|
+
/**
|
|
5
|
+
* Converts a path segment like "orderbook" or "market-trades" to PascalCase.
|
|
6
|
+
* e.g. "orderbook" -> "Orderbook", "market-trades" -> "MarketTrades"
|
|
7
|
+
*/
|
|
8
|
+
function toPascalCase(segment) {
|
|
9
|
+
return segment
|
|
10
|
+
.split(/[-_]/)
|
|
11
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
12
|
+
.join('');
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Generates a method name from an HTTP method and path.
|
|
16
|
+
* e.g. GET /markets/{ticker}/orderbook -> getMarketsOrderbook
|
|
17
|
+
*/
|
|
18
|
+
function generateMethodName(httpMethod, path) {
|
|
19
|
+
const segments = path
|
|
20
|
+
.split('/')
|
|
21
|
+
.filter(s => s && !s.startsWith('{'));
|
|
22
|
+
const pascalPath = segments.map(toPascalCase).join('');
|
|
23
|
+
return httpMethod.toLowerCase() + pascalPath;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parses an OpenAPI 3.x-shaped spec object into a simplified ApiDescriptor.
|
|
27
|
+
*
|
|
28
|
+
* @param spec - An OpenAPI-like spec object with `paths` and optionally `servers`
|
|
29
|
+
* @param baseUrl - The base URL for the API. If omitted, extracted from spec.servers[0].url
|
|
30
|
+
* @returns A simplified ApiDescriptor with method names mapped to endpoints
|
|
31
|
+
*/
|
|
32
|
+
function parseOpenApiSpec(spec, baseUrl) {
|
|
33
|
+
const resolvedBaseUrl = baseUrl
|
|
34
|
+
|| (spec.servers && spec.servers[0] && spec.servers[0].url)
|
|
35
|
+
|| '';
|
|
36
|
+
const endpoints = {};
|
|
37
|
+
// Inherit top-level security when operations don't define their own
|
|
38
|
+
const topLevelSecurity = !!(spec.security && spec.security.length > 0);
|
|
39
|
+
const paths = spec.paths || {};
|
|
40
|
+
for (const [path, methods] of Object.entries(paths)) {
|
|
41
|
+
for (const [httpMethod, operation] of Object.entries(methods)) {
|
|
42
|
+
// Skip non-HTTP-method keys like "parameters"
|
|
43
|
+
if (!['get', 'post', 'put', 'patch', 'delete'].includes(httpMethod.toLowerCase())) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const name = operation.operationId || generateMethodName(httpMethod, path);
|
|
47
|
+
const isPrivate = operation.security !== undefined
|
|
48
|
+
? !!(operation.security && operation.security.length > 0)
|
|
49
|
+
: topLevelSecurity;
|
|
50
|
+
endpoints[name] = {
|
|
51
|
+
method: httpMethod.toUpperCase(),
|
|
52
|
+
path,
|
|
53
|
+
isPrivate,
|
|
54
|
+
operationId: operation.operationId,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return { baseUrl: resolvedBaseUrl, endpoints };
|
|
59
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.1",
|
|
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,9 @@
|
|
|
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.
|
|
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.
|
|
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.9.1,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.9.1,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
|
|
34
|
+
"fetch:openapi": "node scripts/fetch-openapi-specs.js",
|
|
34
35
|
"extract:jsdoc": "node ../scripts/extract-jsdoc.js",
|
|
35
36
|
"generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",
|
|
36
37
|
"generate:sdk:all": "npm run generate:sdk:python && npm run generate:sdk:typescript && npm run generate:docs"
|