pmxt-core 2.30.7 → 2.30.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/exchanges/kalshi/api.d.ts +1 -1
- package/dist/exchanges/kalshi/api.js +1 -1
- package/dist/exchanges/limitless/api.d.ts +1 -1
- package/dist/exchanges/limitless/api.js +1 -1
- package/dist/exchanges/limitless/fetcher.js +2 -1
- package/dist/exchanges/limitless/index.js +0 -6
- package/dist/exchanges/limitless/normalizer.js +5 -1
- package/dist/exchanges/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/opinion/normalizer.js +17 -5
- 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_us/index.js +21 -25
- package/dist/exchanges/polymarket_us/normalizer.js +3 -2
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/exchanges/probable/fetcher.d.ts +0 -9
- package/dist/exchanges/probable/fetcher.js +40 -12
- package/dist/exchanges/probable/normalizer.js +52 -20
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.525Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const kalshiApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.kalshiApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/kalshi/Kalshi.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.525Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.kalshiApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.579Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const limitlessApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.limitlessApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/limitless/Limitless.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.579Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.limitlessApiSpec = {
|
|
@@ -139,7 +139,8 @@ class LimitlessFetcher {
|
|
|
139
139
|
}
|
|
140
140
|
async fetchRawPositions(account) {
|
|
141
141
|
const result = await this.ctx.callApi('PublicPortfolioController_getPositions', { account });
|
|
142
|
-
|
|
142
|
+
const raw = Array.isArray(result?.data) ? result.data : Array.isArray(result) ? result : [];
|
|
143
|
+
return raw.filter((p) => p.market?.slug);
|
|
143
144
|
}
|
|
144
145
|
// -- Private helpers -------------------------------------------------------
|
|
145
146
|
async fetchRawMarketBySlug(marketFetcher, slug) {
|
|
@@ -432,18 +432,12 @@ class LimitlessExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
432
432
|
fetches.push(this.fetchPositions(address)
|
|
433
433
|
.then((positions) => {
|
|
434
434
|
result.positions = positions;
|
|
435
|
-
})
|
|
436
|
-
.catch(() => {
|
|
437
|
-
result.positions = [];
|
|
438
435
|
}));
|
|
439
436
|
}
|
|
440
437
|
if (types.includes('balances')) {
|
|
441
438
|
fetches.push(this.getAddressOnChainBalance(address)
|
|
442
439
|
.then((balances) => {
|
|
443
440
|
result.balances = balances;
|
|
444
|
-
})
|
|
445
|
-
.catch(() => {
|
|
446
|
-
result.balances = [];
|
|
447
441
|
}));
|
|
448
442
|
}
|
|
449
443
|
await Promise.all(fetches);
|
|
@@ -98,8 +98,12 @@ class LimitlessNormalizer {
|
|
|
98
98
|
}
|
|
99
99
|
normalizePosition(raw) {
|
|
100
100
|
const p = raw;
|
|
101
|
+
const slug = p.market?.slug;
|
|
102
|
+
if (!slug) {
|
|
103
|
+
throw new Error(`Position missing market.slug (conditionId=${p.conditionId})`);
|
|
104
|
+
}
|
|
101
105
|
return {
|
|
102
|
-
marketId:
|
|
106
|
+
marketId: slug,
|
|
103
107
|
outcomeId: p.asset,
|
|
104
108
|
outcomeLabel: p.outcome || 'Unknown',
|
|
105
109
|
size: parseFloat(p.size || '0'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.591Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const myriadApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.myriadApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/myriad/myriad.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.591Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.myriadApiSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.596Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const opinionApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.opinionApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/opinion/opinion-openapi.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.596Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.opinionApiSpec = {
|
|
@@ -154,7 +154,7 @@ class OpinionNormalizer {
|
|
|
154
154
|
return {
|
|
155
155
|
id: raw.orderId || '',
|
|
156
156
|
marketId: String(raw.marketId),
|
|
157
|
-
outcomeId:
|
|
157
|
+
outcomeId: raw.outcome || (raw.outcomeSide === 1 ? 'Yes' : 'No'),
|
|
158
158
|
side: raw.side === 1 ? 'buy' : 'sell',
|
|
159
159
|
type: raw.tradingMethod === 2 ? 'limit' : 'market',
|
|
160
160
|
price: (0, utils_1.parseNumStr)(raw.price),
|
|
@@ -170,14 +170,20 @@ class OpinionNormalizer {
|
|
|
170
170
|
if (!raw || raw.marketType !== 0)
|
|
171
171
|
return null;
|
|
172
172
|
const marketId = String(raw.marketId);
|
|
173
|
+
if (!raw.yesTokenId) {
|
|
174
|
+
throw new Error(`Opinion market ${marketId} is missing yesTokenId`);
|
|
175
|
+
}
|
|
176
|
+
if (!raw.noTokenId) {
|
|
177
|
+
throw new Error(`Opinion market ${marketId} is missing noTokenId`);
|
|
178
|
+
}
|
|
173
179
|
const yesOutcome = {
|
|
174
|
-
outcomeId: raw.yesTokenId
|
|
180
|
+
outcomeId: raw.yesTokenId,
|
|
175
181
|
marketId,
|
|
176
182
|
label: raw.yesLabel || 'Yes',
|
|
177
183
|
price: 0.5,
|
|
178
184
|
};
|
|
179
185
|
const noOutcome = {
|
|
180
|
-
outcomeId: raw.noTokenId
|
|
186
|
+
outcomeId: raw.noTokenId,
|
|
181
187
|
marketId,
|
|
182
188
|
label: raw.noLabel || 'No',
|
|
183
189
|
price: 0.5,
|
|
@@ -200,14 +206,20 @@ class OpinionNormalizer {
|
|
|
200
206
|
if (!child)
|
|
201
207
|
return null;
|
|
202
208
|
const marketId = String(child.marketId);
|
|
209
|
+
if (!child.yesTokenId) {
|
|
210
|
+
throw new Error(`Opinion child market ${marketId} is missing yesTokenId`);
|
|
211
|
+
}
|
|
212
|
+
if (!child.noTokenId) {
|
|
213
|
+
throw new Error(`Opinion child market ${marketId} is missing noTokenId`);
|
|
214
|
+
}
|
|
203
215
|
const yesOutcome = {
|
|
204
|
-
outcomeId: child.yesTokenId
|
|
216
|
+
outcomeId: child.yesTokenId,
|
|
205
217
|
marketId,
|
|
206
218
|
label: child.yesLabel || 'Yes',
|
|
207
219
|
price: 0.5,
|
|
208
220
|
};
|
|
209
221
|
const noOutcome = {
|
|
210
|
-
outcomeId: child.noTokenId
|
|
222
|
+
outcomeId: child.noTokenId,
|
|
211
223
|
marketId,
|
|
212
224
|
label: child.noLabel || 'No',
|
|
213
225
|
price: 0.5,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.533Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketClobSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketClobSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketClobAPI.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.533Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketClobSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.555Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketDataSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketDataSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/Polymarket_Data_API.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.555Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketDataSpec = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.551Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const polymarketGammaSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.polymarketGammaSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/polymarket/PolymarketGammaAPI.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.551Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketGammaSpec = {
|
|
@@ -130,7 +130,10 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
130
130
|
limit: params?.limit ?? 250,
|
|
131
131
|
offset: params?.offset ?? 0,
|
|
132
132
|
});
|
|
133
|
-
|
|
133
|
+
if (!resp.markets) {
|
|
134
|
+
throw new Error('PolymarketUS markets.list response missing required "markets" field');
|
|
135
|
+
}
|
|
136
|
+
let markets = resp.markets.map(m => this.normalizer.normalizeMarket(m));
|
|
134
137
|
if (params?.query) {
|
|
135
138
|
const q = params.query.toLowerCase();
|
|
136
139
|
markets = markets.filter(m => m.title.toLowerCase().includes(q) ||
|
|
@@ -151,7 +154,10 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
151
154
|
limit: params?.limit ?? 100,
|
|
152
155
|
offset: params?.offset ?? 0,
|
|
153
156
|
});
|
|
154
|
-
|
|
157
|
+
if (!resp.events) {
|
|
158
|
+
throw new Error('PolymarketUS events.list response missing required "events" field');
|
|
159
|
+
}
|
|
160
|
+
let events = resp.events.map(e => this.normalizer.normalizeEvent(e));
|
|
155
161
|
if (params?.query) {
|
|
156
162
|
const q = params.query.toLowerCase();
|
|
157
163
|
events = events.filter(e => e.title.toLowerCase().includes(q) ||
|
|
@@ -184,7 +190,10 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
184
190
|
this.requireAuth();
|
|
185
191
|
return this.run(async () => {
|
|
186
192
|
const resp = await this.client.portfolio.positions({});
|
|
187
|
-
|
|
193
|
+
if (!resp.positions) {
|
|
194
|
+
throw new Error('PolymarketUS portfolio.positions response missing required "positions" field');
|
|
195
|
+
}
|
|
196
|
+
return this.normalizer.normalizePositions(resp.positions);
|
|
188
197
|
});
|
|
189
198
|
}
|
|
190
199
|
async fetchMyTrades(params) {
|
|
@@ -195,7 +204,10 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
195
204
|
limit: params?.limit ?? 100,
|
|
196
205
|
marketSlug: params?.marketId,
|
|
197
206
|
});
|
|
198
|
-
|
|
207
|
+
if (!resp.activities) {
|
|
208
|
+
throw new Error('PolymarketUS portfolio.activities response missing required "activities" field');
|
|
209
|
+
}
|
|
210
|
+
const activities = resp.activities;
|
|
199
211
|
const trades = [];
|
|
200
212
|
activities.forEach((activity, idx) => {
|
|
201
213
|
const trade = this.normalizer.normalizeUserTradeFromActivity(activity, idx);
|
|
@@ -214,7 +226,10 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
214
226
|
const resp = await this.client.orders.list({
|
|
215
227
|
slugs: marketId ? [marketId] : undefined,
|
|
216
228
|
});
|
|
217
|
-
|
|
229
|
+
if (!resp.orders) {
|
|
230
|
+
throw new Error('PolymarketUS orders.list response missing required "orders" field');
|
|
231
|
+
}
|
|
232
|
+
const raws = resp.orders;
|
|
218
233
|
return raws.map(raw => {
|
|
219
234
|
const normalized = this.normalizer.normalizeOrder(raw);
|
|
220
235
|
this.cacheOrder(normalized.id, raw.marketSlug);
|
|
@@ -274,26 +289,7 @@ class PolymarketUSExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
274
289
|
const response = await this.run(() => this.client.orders.create(sdkParams));
|
|
275
290
|
const newId = response.id;
|
|
276
291
|
this.cacheOrder(newId, built.params.marketId);
|
|
277
|
-
|
|
278
|
-
return await this.fetchOrder(newId);
|
|
279
|
-
}
|
|
280
|
-
catch {
|
|
281
|
-
// Order may not yet be visible via retrieve. Fall back to a
|
|
282
|
-
// synthetic Order built from the original params.
|
|
283
|
-
return {
|
|
284
|
-
id: newId,
|
|
285
|
-
marketId: built.params.marketId,
|
|
286
|
-
outcomeId: built.params.outcomeId,
|
|
287
|
-
side: built.params.side,
|
|
288
|
-
type: built.params.type,
|
|
289
|
-
price: built.params.price ?? 0,
|
|
290
|
-
amount: built.params.amount,
|
|
291
|
-
status: 'open',
|
|
292
|
-
filled: 0,
|
|
293
|
-
remaining: built.params.amount,
|
|
294
|
-
timestamp: Date.now(),
|
|
295
|
-
};
|
|
296
|
-
}
|
|
292
|
+
return await this.fetchOrder(newId);
|
|
297
293
|
}
|
|
298
294
|
async createOrder(params) {
|
|
299
295
|
const built = await this.buildOrder(params);
|
|
@@ -274,11 +274,12 @@ class PolymarketUSNormalizer {
|
|
|
274
274
|
* needing the short-side view must invert prices themselves.
|
|
275
275
|
*/
|
|
276
276
|
normalizeOrderBook(book, _marketId) {
|
|
277
|
-
|
|
277
|
+
// Missing bids/offers is a valid state (no liquidity), not broken data
|
|
278
|
+
const bids = (book.bids ?? []).map(level => ({
|
|
278
279
|
price: (0, price_1.fromAmount)(level.px),
|
|
279
280
|
size: parseFloat(level.qty || '0'),
|
|
280
281
|
}));
|
|
281
|
-
const asks = (book.offers
|
|
282
|
+
const asks = (book.offers ?? []).map(level => ({
|
|
282
283
|
price: (0, price_1.fromAmount)(level.px),
|
|
283
284
|
size: parseFloat(level.qty || '0'),
|
|
284
285
|
}));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
3
|
-
* Generated at: 2026-04-
|
|
3
|
+
* Generated at: 2026-04-14T11:50:08.583Z
|
|
4
4
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const probableApiSpec: {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.probableApiSpec = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Auto-generated from /home/runner/work/pmxt/pmxt/core/specs/probable/probable.yaml
|
|
6
|
-
* Generated at: 2026-04-
|
|
6
|
+
* Generated at: 2026-04-14T11:50:08.583Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.probableApiSpec = {
|
|
@@ -57,30 +57,21 @@ export interface ProbableRawTrade {
|
|
|
57
57
|
id?: string | number;
|
|
58
58
|
tradeId?: string | number;
|
|
59
59
|
time?: number;
|
|
60
|
-
timestamp?: number;
|
|
61
60
|
price?: string | number;
|
|
62
|
-
qty?: string | number;
|
|
63
61
|
size?: string | number;
|
|
64
|
-
amount?: string | number;
|
|
65
62
|
side?: string;
|
|
66
63
|
orderId?: string;
|
|
67
64
|
[key: string]: unknown;
|
|
68
65
|
}
|
|
69
66
|
export interface ProbableRawPosition {
|
|
70
|
-
conditionId?: string;
|
|
71
67
|
condition_id?: string;
|
|
72
|
-
asset?: string;
|
|
73
68
|
token_id?: string;
|
|
74
69
|
outcome?: string;
|
|
75
70
|
title?: string;
|
|
76
71
|
size?: string | number;
|
|
77
|
-
avgPrice?: string | number;
|
|
78
72
|
avg_price?: string | number;
|
|
79
|
-
curPrice?: string | number;
|
|
80
73
|
cur_price?: string | number;
|
|
81
|
-
cashPnl?: string | number;
|
|
82
74
|
cash_pnl?: string | number;
|
|
83
|
-
realizedPnl?: string | number;
|
|
84
75
|
realized_pnl?: string | number;
|
|
85
76
|
[key: string]: unknown;
|
|
86
77
|
}
|
|
@@ -109,7 +109,14 @@ class ProbableFetcher {
|
|
|
109
109
|
if (params.end)
|
|
110
110
|
queryParams.endTs = Math.floor(params.end.getTime() / 1000);
|
|
111
111
|
const data = await this.ctx.callApi('getPublicApiV1PricesHistory', queryParams);
|
|
112
|
-
|
|
112
|
+
if (data != null && typeof data === 'object' && !Array.isArray(data) && Array.isArray(data.history)) {
|
|
113
|
+
return data.history;
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(data)) {
|
|
116
|
+
return data;
|
|
117
|
+
}
|
|
118
|
+
throw new Error(`Probable OHLCV: unexpected response shape (got ${typeof data}). ` +
|
|
119
|
+
`Expected { history: [...] } or an array.`);
|
|
113
120
|
}
|
|
114
121
|
// -----------------------------------------------------------------------
|
|
115
122
|
// Trades
|
|
@@ -122,23 +129,30 @@ class ProbableFetcher {
|
|
|
122
129
|
// client's getTrades through callApi or directly. For now, this goes
|
|
123
130
|
// through the implicit API.
|
|
124
131
|
const data = await this.ctx.callApi('getPublicApiV1Trades', queryParams);
|
|
125
|
-
|
|
126
|
-
|
|
132
|
+
if (!Array.isArray(data)) {
|
|
133
|
+
throw new Error(`Probable trades: unexpected response shape (got ${typeof data}). Expected an array.`);
|
|
134
|
+
}
|
|
135
|
+
return data;
|
|
127
136
|
}
|
|
128
137
|
async fetchRawMyTrades(params, walletAddress) {
|
|
129
138
|
const queryParams = { user: walletAddress };
|
|
130
139
|
if (params?.limit)
|
|
131
140
|
queryParams.limit = params.limit;
|
|
132
141
|
const data = await this.ctx.callApi('getPublicApiV1Trades', queryParams);
|
|
133
|
-
|
|
134
|
-
|
|
142
|
+
if (!Array.isArray(data)) {
|
|
143
|
+
throw new Error(`Probable myTrades: unexpected response shape (got ${typeof data}). Expected an array.`);
|
|
144
|
+
}
|
|
145
|
+
return data;
|
|
135
146
|
}
|
|
136
147
|
// -----------------------------------------------------------------------
|
|
137
148
|
// Positions & Balance
|
|
138
149
|
// -----------------------------------------------------------------------
|
|
139
150
|
async fetchRawPositions(walletAddress) {
|
|
140
151
|
const result = await this.ctx.callApi('getPublicApiV1PositionCurrent', { user: walletAddress, limit: 500 });
|
|
141
|
-
|
|
152
|
+
if (!Array.isArray(result)) {
|
|
153
|
+
throw new Error(`Probable positions: unexpected response shape (got ${typeof result}). Expected an array.`);
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
142
156
|
}
|
|
143
157
|
// -----------------------------------------------------------------------
|
|
144
158
|
// Midpoint (price enrichment)
|
|
@@ -183,7 +197,10 @@ class ProbableFetcher {
|
|
|
183
197
|
const response = await this.ctx.http.get(`${utils_1.BASE_URL}${utils_1.MARKETS_PATH}`, {
|
|
184
198
|
params: { page: 1, limit: 100, active: true },
|
|
185
199
|
});
|
|
186
|
-
|
|
200
|
+
if (!response.data?.markets || !Array.isArray(response.data.markets)) {
|
|
201
|
+
throw new Error(`Probable markets list: unexpected response shape. Expected { markets: [...] }.`);
|
|
202
|
+
}
|
|
203
|
+
const markets = response.data.markets;
|
|
187
204
|
return markets.filter(m => String(m.id) === cleanSlug);
|
|
188
205
|
}
|
|
189
206
|
throw error;
|
|
@@ -215,7 +232,10 @@ class ProbableFetcher {
|
|
|
215
232
|
queryParams.event_id = params.eventId;
|
|
216
233
|
}
|
|
217
234
|
const response = await this.ctx.http.get(`${utils_1.BASE_URL}${utils_1.MARKETS_PATH}`, { params: queryParams });
|
|
218
|
-
|
|
235
|
+
if (!response.data?.markets || !Array.isArray(response.data.markets)) {
|
|
236
|
+
throw new Error(`Probable markets list: unexpected response shape. Expected { markets: [...] }.`);
|
|
237
|
+
}
|
|
238
|
+
return response.data.markets;
|
|
219
239
|
}
|
|
220
240
|
async fetchRawMarketsViaSearch(query, params) {
|
|
221
241
|
const limit = params?.limit || 20;
|
|
@@ -264,7 +284,10 @@ class ProbableFetcher {
|
|
|
264
284
|
}
|
|
265
285
|
}
|
|
266
286
|
const searchData = await this.ctx.callApi('getPublicApiV1PublicSearch', queryParams);
|
|
267
|
-
|
|
287
|
+
if (!searchData?.events || !Array.isArray(searchData.events)) {
|
|
288
|
+
throw new Error(`Probable search: unexpected response shape. Expected { events: [...] }.`);
|
|
289
|
+
}
|
|
290
|
+
const events = searchData.events;
|
|
268
291
|
const rawMarkets = [];
|
|
269
292
|
for (const event of events) {
|
|
270
293
|
if (event.markets && Array.isArray(event.markets)) {
|
|
@@ -300,8 +323,10 @@ class ProbableFetcher {
|
|
|
300
323
|
queryParams.ascending = false;
|
|
301
324
|
const response = await this.ctx.http.get(`${utils_1.BASE_URL}${utils_1.EVENTS_PATH}`, { params: queryParams });
|
|
302
325
|
const data = response.data;
|
|
303
|
-
|
|
304
|
-
|
|
326
|
+
if (!Array.isArray(data)) {
|
|
327
|
+
throw new Error(`Probable events list: unexpected response shape (got ${typeof data}). Expected an array.`);
|
|
328
|
+
}
|
|
329
|
+
return data;
|
|
305
330
|
}
|
|
306
331
|
async fetchRawEventsViaSearch(params) {
|
|
307
332
|
const limit = params.limit || 20;
|
|
@@ -314,7 +339,10 @@ class ProbableFetcher {
|
|
|
314
339
|
keep_closed_markets: params.status === 'all' || params.status === 'inactive' || params.status === 'closed' ? 1 : 0,
|
|
315
340
|
};
|
|
316
341
|
const searchData = await this.ctx.callApi('getPublicApiV1PublicSearch', queryParams);
|
|
317
|
-
|
|
342
|
+
if (!searchData?.events || !Array.isArray(searchData.events)) {
|
|
343
|
+
throw new Error(`Probable event search: unexpected response shape. Expected { events: [...] }.`);
|
|
344
|
+
}
|
|
345
|
+
return searchData.events;
|
|
318
346
|
}
|
|
319
347
|
}
|
|
320
348
|
exports.ProbableFetcher = ProbableFetcher;
|
|
@@ -65,40 +65,72 @@ class ProbableNormalizer {
|
|
|
65
65
|
return candles;
|
|
66
66
|
}
|
|
67
67
|
normalizeTrade(raw, index) {
|
|
68
|
+
if (raw.id == null && raw.tradeId == null) {
|
|
69
|
+
throw new Error(`Probable trade at index ${index}: missing required field "id" or "tradeId".`);
|
|
70
|
+
}
|
|
71
|
+
if (raw.price == null) {
|
|
72
|
+
throw new Error(`Probable trade at index ${index}: missing required field "price".`);
|
|
73
|
+
}
|
|
74
|
+
if (raw.size == null) {
|
|
75
|
+
throw new Error(`Probable trade at index ${index}: missing required field "size".`);
|
|
76
|
+
}
|
|
77
|
+
if (raw.time == null) {
|
|
78
|
+
throw new Error(`Probable trade at index ${index}: missing required field "time".`);
|
|
79
|
+
}
|
|
68
80
|
return {
|
|
69
|
-
id: String(raw.id
|
|
70
|
-
timestamp:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
price: parseFloat(String(raw.price || '0')),
|
|
74
|
-
amount: parseFloat(String(raw.qty || raw.size || raw.amount || '0')),
|
|
81
|
+
id: String(raw.id ?? raw.tradeId),
|
|
82
|
+
timestamp: raw.time < 1e12 ? raw.time * 1000 : raw.time,
|
|
83
|
+
price: parseFloat(String(raw.price)),
|
|
84
|
+
amount: parseFloat(String(raw.size)),
|
|
75
85
|
side: raw.side === 'BUY' ? 'buy'
|
|
76
86
|
: raw.side === 'SELL' ? 'sell'
|
|
77
87
|
: 'unknown',
|
|
78
88
|
};
|
|
79
89
|
}
|
|
80
90
|
normalizeUserTrade(raw, index) {
|
|
91
|
+
if (raw.tradeId == null && raw.id == null) {
|
|
92
|
+
throw new Error(`Probable user trade at index ${index}: missing required field "tradeId" or "id".`);
|
|
93
|
+
}
|
|
94
|
+
if (raw.price == null) {
|
|
95
|
+
throw new Error(`Probable user trade at index ${index}: missing required field "price".`);
|
|
96
|
+
}
|
|
97
|
+
if (raw.size == null) {
|
|
98
|
+
throw new Error(`Probable user trade at index ${index}: missing required field "size".`);
|
|
99
|
+
}
|
|
100
|
+
if (raw.time == null) {
|
|
101
|
+
throw new Error(`Probable user trade at index ${index}: missing required field "time".`);
|
|
102
|
+
}
|
|
103
|
+
if (raw.side == null) {
|
|
104
|
+
throw new Error(`Probable user trade at index ${index}: missing required field "side".`);
|
|
105
|
+
}
|
|
81
106
|
return {
|
|
82
|
-
id: String(raw.tradeId
|
|
83
|
-
timestamp:
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
amount: parseFloat(String(raw.qty || raw.size || raw.amount || '0')),
|
|
88
|
-
side: (String(raw.side || '')).toLowerCase() === 'buy' ? 'buy' : 'sell',
|
|
107
|
+
id: String(raw.tradeId ?? raw.id),
|
|
108
|
+
timestamp: raw.time > 1e12 ? raw.time : raw.time * 1000,
|
|
109
|
+
price: parseFloat(String(raw.price)),
|
|
110
|
+
amount: parseFloat(String(raw.size)),
|
|
111
|
+
side: String(raw.side).toLowerCase() === 'buy' ? 'buy' : 'sell',
|
|
89
112
|
orderId: raw.orderId,
|
|
90
113
|
};
|
|
91
114
|
}
|
|
92
115
|
normalizePosition(raw) {
|
|
116
|
+
if (raw.condition_id == null) {
|
|
117
|
+
throw new Error(`Probable position: missing required field "condition_id".`);
|
|
118
|
+
}
|
|
119
|
+
if (raw.token_id == null) {
|
|
120
|
+
throw new Error(`Probable position: missing required field "token_id".`);
|
|
121
|
+
}
|
|
122
|
+
if (raw.size == null) {
|
|
123
|
+
throw new Error(`Probable position: missing required field "size".`);
|
|
124
|
+
}
|
|
93
125
|
return {
|
|
94
|
-
marketId: String(raw.
|
|
95
|
-
outcomeId: String(raw.
|
|
126
|
+
marketId: String(raw.condition_id),
|
|
127
|
+
outcomeId: String(raw.token_id),
|
|
96
128
|
outcomeLabel: raw.outcome || raw.title || 'Unknown',
|
|
97
|
-
size: parseFloat(String(raw.size
|
|
98
|
-
entryPrice: parseFloat(String(raw.
|
|
99
|
-
currentPrice: parseFloat(String(raw.
|
|
100
|
-
unrealizedPnL: parseFloat(String(raw.
|
|
101
|
-
realizedPnL: parseFloat(String(raw.
|
|
129
|
+
size: parseFloat(String(raw.size)),
|
|
130
|
+
entryPrice: parseFloat(String(raw.avg_price ?? '0')),
|
|
131
|
+
currentPrice: parseFloat(String(raw.cur_price ?? '0')),
|
|
132
|
+
unrealizedPnL: parseFloat(String(raw.cash_pnl ?? '0')),
|
|
133
|
+
realizedPnL: parseFloat(String(raw.realized_pnl ?? '0')),
|
|
102
134
|
};
|
|
103
135
|
}
|
|
104
136
|
// -- Price enrichment helper (used by SDK class) --
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.30.
|
|
3
|
+
"version": "2.30.9",
|
|
4
4
|
"description": "pmxt is a unified prediction market data API. The ccxt for prediction markets.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"test": "jest -c jest.config.js",
|
|
30
30
|
"server": "tsx watch src/server/index.ts",
|
|
31
31
|
"server:prod": "node dist/server/index.js",
|
|
32
|
-
"generate:sdk:python": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g python -o ../sdks/python/generated --package-name pmxt_internal --additional-properties=projectName=pmxt-internal,packageVersion=2.30.
|
|
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.30.
|
|
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.30.9,library=urllib3",
|
|
33
|
+
"generate:sdk:typescript": "npx @openapitools/openapi-generator-cli generate -i src/server/openapi.yaml -g typescript-fetch -o ../sdks/typescript/generated --additional-properties=npmName=pmxtjs,npmVersion=2.30.9,supportsES6=true,typescriptThreePlus=true && node ../sdks/typescript/scripts/fix-generated.js",
|
|
34
34
|
"fetch:openapi": "node scripts/fetch-openapi-specs.js",
|
|
35
35
|
"extract:jsdoc": "node ../scripts/extract-jsdoc.js",
|
|
36
36
|
"generate:docs": "npm run extract:jsdoc && node ../scripts/generate-api-docs.js",
|