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.
Files changed (83) hide show
  1. package/dist/BaseExchange.d.ts +48 -0
  2. package/dist/BaseExchange.js +116 -0
  3. package/dist/exchanges/kalshi/api.d.ts +1763 -0
  4. package/dist/exchanges/kalshi/api.js +2554 -0
  5. package/dist/exchanges/kalshi/fetchEvents.d.ts +3 -2
  6. package/dist/exchanges/kalshi/fetchEvents.js +9 -16
  7. package/dist/exchanges/kalshi/fetchMarkets.d.ts +3 -2
  8. package/dist/exchanges/kalshi/fetchMarkets.js +24 -32
  9. package/dist/exchanges/kalshi/fetchOHLCV.d.ts +1 -2
  10. package/dist/exchanges/kalshi/fetchOHLCV.js +9 -11
  11. package/dist/exchanges/kalshi/index.d.ts +2 -1
  12. package/dist/exchanges/kalshi/index.js +161 -183
  13. package/dist/exchanges/kalshi/kalshi.test.js +51 -31
  14. package/dist/exchanges/limitless/api.d.ts +555 -0
  15. package/dist/exchanges/limitless/api.js +863 -0
  16. package/dist/exchanges/limitless/fetchEvents.d.ts +1 -2
  17. package/dist/exchanges/limitless/fetchEvents.js +9 -15
  18. package/dist/exchanges/limitless/fetchMarkets.d.ts +1 -2
  19. package/dist/exchanges/limitless/fetchMarkets.js +9 -16
  20. package/dist/exchanges/limitless/fetchOHLCV.d.ts +1 -2
  21. package/dist/exchanges/limitless/fetchOHLCV.js +2 -11
  22. package/dist/exchanges/limitless/fetchOrderBook.d.ts +1 -2
  23. package/dist/exchanges/limitless/fetchOrderBook.js +2 -11
  24. package/dist/exchanges/limitless/index.d.ts +1 -0
  25. package/dist/exchanges/limitless/index.js +28 -7
  26. package/dist/exchanges/limitless/websocket.d.ts +2 -1
  27. package/dist/exchanges/limitless/websocket.js +6 -4
  28. package/dist/exchanges/myriad/api.d.ts +294 -0
  29. package/dist/exchanges/myriad/api.js +690 -0
  30. package/dist/exchanges/myriad/fetchOHLCV.d.ts +1 -2
  31. package/dist/exchanges/myriad/fetchOHLCV.js +3 -11
  32. package/dist/exchanges/myriad/fetchOrderBook.d.ts +1 -2
  33. package/dist/exchanges/myriad/fetchOrderBook.js +3 -11
  34. package/dist/exchanges/myriad/index.d.ts +2 -0
  35. package/dist/exchanges/myriad/index.js +116 -103
  36. package/dist/exchanges/myriad/websocket.d.ts +2 -2
  37. package/dist/exchanges/myriad/websocket.js +28 -6
  38. package/dist/exchanges/polymarket/api-clob.d.ts +346 -0
  39. package/dist/exchanges/polymarket/api-clob.js +517 -0
  40. package/dist/exchanges/polymarket/api-data.d.ts +789 -0
  41. package/dist/exchanges/polymarket/api-data.js +860 -0
  42. package/dist/exchanges/polymarket/api-gamma.d.ts +556 -0
  43. package/dist/exchanges/polymarket/api-gamma.js +1161 -0
  44. package/dist/exchanges/polymarket/fetchEvents.js +0 -68
  45. package/dist/exchanges/polymarket/fetchOHLCV.d.ts +1 -2
  46. package/dist/exchanges/polymarket/fetchOHLCV.js +4 -10
  47. package/dist/exchanges/polymarket/fetchOrderBook.d.ts +1 -2
  48. package/dist/exchanges/polymarket/fetchOrderBook.js +2 -10
  49. package/dist/exchanges/polymarket/fetchTrades.d.ts +1 -2
  50. package/dist/exchanges/polymarket/fetchTrades.js +2 -11
  51. package/dist/exchanges/polymarket/index.d.ts +10 -0
  52. package/dist/exchanges/polymarket/index.js +110 -5
  53. package/dist/exchanges/probable/api.d.ts +605 -0
  54. package/dist/exchanges/probable/api.js +887 -0
  55. package/dist/exchanges/probable/fetchEvents.d.ts +3 -3
  56. package/dist/exchanges/probable/fetchEvents.js +28 -25
  57. package/dist/exchanges/probable/fetchMarkets.d.ts +1 -1
  58. package/dist/exchanges/probable/fetchMarkets.js +25 -21
  59. package/dist/exchanges/probable/index.d.ts +1 -0
  60. package/dist/exchanges/probable/index.js +92 -10
  61. package/dist/exchanges/probable/utils.d.ts +1 -2
  62. package/dist/exchanges/probable/utils.js +4 -11
  63. package/dist/index.d.ts +1 -0
  64. package/dist/index.js +3 -1
  65. package/dist/utils/openapi.d.ts +9 -0
  66. package/dist/utils/openapi.js +59 -0
  67. package/package.json +4 -3
  68. package/dist/exchanges/kalshi/fetchOrderBook.d.ts +0 -3
  69. package/dist/exchanges/kalshi/fetchOrderBook.js +0 -59
  70. package/dist/exchanges/kalshi/fetchTrades.d.ts +0 -4
  71. package/dist/exchanges/kalshi/fetchTrades.js +0 -31
  72. package/dist/exchanges/limitless/fetchPositions.d.ts +0 -2
  73. package/dist/exchanges/limitless/fetchPositions.js +0 -34
  74. package/dist/exchanges/myriad/fetchTrades.d.ts +0 -4
  75. package/dist/exchanges/myriad/fetchTrades.js +0 -62
  76. package/dist/exchanges/polymarket/fetchPositions.d.ts +0 -2
  77. package/dist/exchanges/polymarket/fetchPositions.js +0 -34
  78. package/dist/exchanges/probable/fetchOHLCV.d.ts +0 -4
  79. package/dist/exchanges/probable/fetchOHLCV.js +0 -83
  80. package/dist/exchanges/probable/fetchOrderBook.d.ts +0 -3
  81. package/dist/exchanges/probable/fetchOrderBook.js +0 -37
  82. package/dist/exchanges/probable/fetchPositions.d.ts +0 -2
  83. 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
- await (0, utils_1.enrichMarketsWithPrices)(allMarkets);
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 response = await http.get(`${utils_1.BASE_URL}${utils_1.SEARCH_PATH}`, {
109
- params: {
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
- });
117
- const events = response.data?.events || [];
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
- await (0, utils_1.enrichMarketsWithPrices)(allMarkets);
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
- await (0, utils_1.enrichMarketsWithPrices)(results);
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
- await (0, utils_1.enrichMarketsWithPrices)(allMarkets);
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 response = await http.get(`${utils_1.BASE_URL}${utils_1.SEARCH_PATH}`, {
188
- params: queryParams,
189
- });
190
- const events = response.data?.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
- await (0, utils_1.enrichMarketsWithPrices)(exact);
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
- await (0, utils_1.enrichMarketsWithPrices)(allMarkets);
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
- return (0, fetchOrderBook_1.fetchOrderBook)(id, this.http);
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
- return (0, fetchOHLCV_1.fetchOHLCV)(id, params, this.http);
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
- return (0, fetchPositions_1.fetchPositions)(address);
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.CLOB_BASE_URL = exports.BASE_URL = void 0;
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 axios_1.default.get(`${exports.CLOB_BASE_URL}/midpoint`, {
88
- params: { token_id: outcome.outcomeId },
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
@@ -1,6 +1,7 @@
1
1
  export * from './BaseExchange';
2
2
  export * from './types';
3
3
  export * from './utils/math';
4
+ export { parseOpenApiSpec } from './utils/openapi';
4
5
  export * from './errors';
5
6
  export * from './exchanges/polymarket';
6
7
  export * from './exchanges/limitless';
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.8.0",
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.8.0,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.8.0,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.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"
@@ -1,3 +0,0 @@
1
- import { AxiosInstance } from 'axios';
2
- import { OrderBook } from '../../types';
3
- export declare function fetchOrderBook(id: string, http?: AxiosInstance): Promise<OrderBook>;