pmxt-core 2.30.5 → 2.30.7
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/myriad/api.d.ts +1 -1
- package/dist/exchanges/myriad/api.js +1 -1
- package/dist/exchanges/opinion/api.d.ts +1 -1
- package/dist/exchanges/opinion/api.js +1 -1
- package/dist/exchanges/polymarket/api-clob.d.ts +1 -1
- package/dist/exchanges/polymarket/api-clob.js +1 -1
- package/dist/exchanges/polymarket/api-data.d.ts +1 -1
- package/dist/exchanges/polymarket/api-data.js +1 -1
- package/dist/exchanges/polymarket/api-gamma.d.ts +1 -1
- package/dist/exchanges/polymarket/api-gamma.js +1 -1
- package/dist/exchanges/polymarket/fetcher.d.ts +8 -0
- package/dist/exchanges/polymarket/fetcher.js +31 -1
- package/dist/exchanges/polymarket/index.js +3 -22
- package/dist/exchanges/polymarket/normalizer.js +1 -1
- package/dist/exchanges/probable/api.d.ts +1 -1
- package/dist/exchanges/probable/api.js +1 -1
- package/dist/subscriber/external/goldsky.d.ts +3 -13
- package/dist/subscriber/external/goldsky.js +19 -126
- package/dist/subscriber/watcher.js +13 -1
- 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-14T07:59:58.462Z
|
|
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-14T07:59:58.462Z
|
|
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-14T07:59:58.505Z
|
|
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-14T07:59:58.505Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.limitlessApiSpec = {
|
|
@@ -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-14T07:59:58.515Z
|
|
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-14T07:59:58.515Z
|
|
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-14T07:59:58.521Z
|
|
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-14T07:59:58.521Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.opinionApiSpec = {
|
|
@@ -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-14T07:59:58.468Z
|
|
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-14T07:59:58.468Z
|
|
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-14T07:59:58.486Z
|
|
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-14T07:59:58.486Z
|
|
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-14T07:59:58.483Z
|
|
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-14T07:59:58.483Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.polymarketGammaSpec = {
|
|
@@ -68,6 +68,8 @@ export interface PolymarketRawTrade {
|
|
|
68
68
|
}
|
|
69
69
|
export interface PolymarketRawPosition {
|
|
70
70
|
conditionId?: string;
|
|
71
|
+
/** Gamma market ID resolved from conditionId. Set by enrichPositionsWithMarketIds. */
|
|
72
|
+
resolvedMarketId?: string;
|
|
71
73
|
asset?: string;
|
|
72
74
|
outcome?: string;
|
|
73
75
|
size: string;
|
|
@@ -89,6 +91,12 @@ export declare class PolymarketFetcher implements IExchangeFetcher<PolymarketRaw
|
|
|
89
91
|
fetchRawTrades(id: string, params: TradesParams): Promise<PolymarketRawTrade[]>;
|
|
90
92
|
fetchRawMyTrades(params: MyTradesParams, walletAddress: string): Promise<PolymarketRawTrade[]>;
|
|
91
93
|
fetchRawPositions(walletAddress: string): Promise<PolymarketRawPosition[]>;
|
|
94
|
+
/**
|
|
95
|
+
* Resolve conditionIds to Gamma market IDs in a single batch request.
|
|
96
|
+
* Throws if the Gamma lookup fails — positions must have correct market IDs.
|
|
97
|
+
*/
|
|
98
|
+
private enrichPositionsWithMarketIds;
|
|
99
|
+
private resolveConditionIds;
|
|
92
100
|
private fetchRawMarketById;
|
|
93
101
|
private fetchRawMarketsByEventId;
|
|
94
102
|
private fetchRawMarketsBySlug;
|
|
@@ -180,7 +180,37 @@ class PolymarketFetcher {
|
|
|
180
180
|
// ------------------------------------------------------------------------
|
|
181
181
|
async fetchRawPositions(walletAddress) {
|
|
182
182
|
const result = await this.ctx.callApi('getPositions', { user: walletAddress, limit: 100 });
|
|
183
|
-
|
|
183
|
+
const raw = Array.isArray(result) ? result : [];
|
|
184
|
+
return this.enrichPositionsWithMarketIds(raw);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Resolve conditionIds to Gamma market IDs in a single batch request.
|
|
188
|
+
* Throws if the Gamma lookup fails — positions must have correct market IDs.
|
|
189
|
+
*/
|
|
190
|
+
async enrichPositionsWithMarketIds(positions) {
|
|
191
|
+
const conditionIds = [...new Set(positions.map(p => p.conditionId).filter((id) => !!id))];
|
|
192
|
+
if (conditionIds.length === 0)
|
|
193
|
+
return positions;
|
|
194
|
+
const conditionToMarketId = await this.resolveConditionIds(conditionIds);
|
|
195
|
+
return positions
|
|
196
|
+
.map(p => ({
|
|
197
|
+
...p,
|
|
198
|
+
resolvedMarketId: conditionToMarketId.get(p.conditionId ?? ''),
|
|
199
|
+
}))
|
|
200
|
+
.filter(p => p.resolvedMarketId !== undefined);
|
|
201
|
+
}
|
|
202
|
+
async resolveConditionIds(conditionIds) {
|
|
203
|
+
const response = await this.http.get(GAMMA_MARKETS_URL, {
|
|
204
|
+
params: { condition_ids: conditionIds.join(',') },
|
|
205
|
+
});
|
|
206
|
+
const markets = Array.isArray(response.data) ? response.data : [];
|
|
207
|
+
const result = new Map();
|
|
208
|
+
for (const market of markets) {
|
|
209
|
+
if (market.conditionId && market.id) {
|
|
210
|
+
result.set(market.conditionId, String(market.id));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return result;
|
|
184
214
|
}
|
|
185
215
|
// ------------------------------------------------------------------------
|
|
186
216
|
// Private helpers -- Markets
|
|
@@ -571,37 +571,18 @@ class PolymarketExchange extends BaseExchange_1.PredictionMarketExchange {
|
|
|
571
571
|
: 'unknown',
|
|
572
572
|
outcomeId: t.asset ?? undefined,
|
|
573
573
|
}));
|
|
574
|
-
})
|
|
575
|
-
.catch(() => {
|
|
576
|
-
result.trades = [];
|
|
577
574
|
}));
|
|
578
575
|
}
|
|
579
576
|
if (types.includes('positions')) {
|
|
580
|
-
fetches.push(this.
|
|
581
|
-
.then((
|
|
582
|
-
|
|
583
|
-
result.positions = raw.map((p) => ({
|
|
584
|
-
marketId: p.conditionId,
|
|
585
|
-
outcomeId: p.asset,
|
|
586
|
-
outcomeLabel: p.outcome || 'Unknown',
|
|
587
|
-
size: parseFloat(p.size),
|
|
588
|
-
entryPrice: parseFloat(p.avgPrice),
|
|
589
|
-
currentPrice: parseFloat(p.curPrice || '0'),
|
|
590
|
-
unrealizedPnL: parseFloat(p.cashPnl || '0'),
|
|
591
|
-
realizedPnL: parseFloat(p.realizedPnl || '0'),
|
|
592
|
-
}));
|
|
593
|
-
})
|
|
594
|
-
.catch(() => {
|
|
595
|
-
result.positions = [];
|
|
577
|
+
fetches.push(this.fetcher.fetchRawPositions(address)
|
|
578
|
+
.then((rawPositions) => {
|
|
579
|
+
result.positions = rawPositions.map((p) => this.normalizer.normalizePosition(p));
|
|
596
580
|
}));
|
|
597
581
|
}
|
|
598
582
|
if (types.includes('balances')) {
|
|
599
583
|
fetches.push(this.getAddressOnChainBalance(address)
|
|
600
584
|
.then(b => {
|
|
601
585
|
result.balances = b;
|
|
602
|
-
})
|
|
603
|
-
.catch(() => {
|
|
604
|
-
result.balances = [];
|
|
605
586
|
}));
|
|
606
587
|
}
|
|
607
588
|
await Promise.all(fetches);
|
|
@@ -112,7 +112,7 @@ class PolymarketNormalizer {
|
|
|
112
112
|
}
|
|
113
113
|
normalizePosition(raw) {
|
|
114
114
|
return {
|
|
115
|
-
marketId: raw.
|
|
115
|
+
marketId: raw.resolvedMarketId || '',
|
|
116
116
|
outcomeId: raw.asset || '',
|
|
117
117
|
outcomeLabel: raw.outcome || 'Unknown',
|
|
118
118
|
size: parseFloat(raw.size),
|
|
@@ -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-14T07:59:58.510Z
|
|
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-14T07:59:58.510Z
|
|
7
7
|
* Do not edit manually -- run "npm run fetch:openapi" to regenerate.
|
|
8
8
|
*/
|
|
9
9
|
exports.probableApiSpec = {
|
|
@@ -51,21 +51,11 @@ export declare const LIMITLESS_DEFAULT_SUBSCRIPTION: GoldSkySubscriptionBuilder;
|
|
|
51
51
|
* Derives `Trade[]` from Polymarket CTF Exchange `OrderFilled` event data.
|
|
52
52
|
*/
|
|
53
53
|
export declare const buildPolymarketTradesActivity: SubscribedActivityBuilder;
|
|
54
|
-
/**
|
|
55
|
-
* Derives `Position[]` from the joined PNL + positions-metadata event data.
|
|
56
|
-
*
|
|
57
|
-
* `userPositions` (PNL) and `userBalances` (positions) are guaranteed
|
|
58
|
-
* to share the same tokenIds since step 2 is filtered by step 1's results.
|
|
59
|
-
*
|
|
60
|
-
* `currentPrice` and `unrealizedPnL` are left at 0 (not available on-chain).
|
|
61
|
-
*/
|
|
62
|
-
/**
|
|
63
|
-
* Derives `Position[]` from joined PNL (`userPositions`) + metadata (`userBalances`).
|
|
64
|
-
* `currentPrice` and `unrealizedPnL` are left at 0 (not available on-chain).
|
|
65
|
-
*/
|
|
66
|
-
export declare const buildPolymarketPositionsActivity: SubscribedActivityBuilder;
|
|
67
54
|
/**
|
|
68
55
|
* Combined activity builder for Polymarket. Pair with `POLYMARKET_DEFAULT_SUBSCRIPTION`.
|
|
56
|
+
*
|
|
57
|
+
* Only handles trades from GoldSky on-chain data. Positions are always fetched
|
|
58
|
+
* via the REST fallback because on-chain data lacks real market IDs and outcome labels.
|
|
69
59
|
*/
|
|
70
60
|
export declare const buildPolymarketActivity: SubscribedActivityBuilder;
|
|
71
61
|
/**
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.GoldSkySubscriber = exports.buildLimitlessBalanceActivity = exports.buildPolymarketActivity = exports.
|
|
3
|
+
exports.GoldSkySubscriber = exports.buildLimitlessBalanceActivity = exports.buildPolymarketActivity = exports.buildPolymarketTradesActivity = exports.LIMITLESS_DEFAULT_SUBSCRIPTION = exports.POLYMARKET_DEFAULT_SUBSCRIPTION = void 0;
|
|
4
4
|
// ----------------------------------------------------------------------------
|
|
5
5
|
// Polymarket endpoints
|
|
6
6
|
// ----------------------------------------------------------------------------
|
|
7
7
|
// Reference: https://docs.polymarket.com/market-data/subgraph
|
|
8
8
|
const POLYMARKET_TRADES_ENDPOINT = 'https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/orderbook-subgraph/prod/gn';
|
|
9
|
-
const POLYMARKET_POSITIONS_ENDPOINT = 'https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/positions-subgraph/0.0.7/gn';
|
|
10
|
-
const POLYMARKET_PNL_ENDPOINT = 'https://api.goldsky.com/api/public/project_cl6mb8i9h0003e201j6li0diw/subgraphs/pnl-subgraph/0.0.14/gn';
|
|
11
9
|
// NOTE: orderBy must use `id` (primary key) on pnl-subgraph and positions-subgraph.
|
|
12
10
|
// Sorting by any unindexed column (e.g. amount, balance) causes a statement timeout.
|
|
13
11
|
// ----------------------------------------------------------------------------
|
|
@@ -52,45 +50,6 @@ const BUILD_POLYMARKET_TRADES_AS_TAKER_QUERY = (address, url) => ({
|
|
|
52
50
|
`,
|
|
53
51
|
variables: { address: address.toLowerCase() },
|
|
54
52
|
});
|
|
55
|
-
const BUILD_POLYMARKET_PNL_QUERY = (address, url) => ({
|
|
56
|
-
url: url ?? POLYMARKET_PNL_ENDPOINT,
|
|
57
|
-
query: `
|
|
58
|
-
query GetPolymarketPnl($address: String!) {
|
|
59
|
-
userPositions(
|
|
60
|
-
where: { user: $address, amount_gt: "0" }
|
|
61
|
-
first: 1000
|
|
62
|
-
orderBy: id
|
|
63
|
-
orderDirection: asc
|
|
64
|
-
) {
|
|
65
|
-
tokenId
|
|
66
|
-
amount
|
|
67
|
-
avgPrice
|
|
68
|
-
realizedPnl
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
`,
|
|
72
|
-
variables: { address: address.toLowerCase() },
|
|
73
|
-
});
|
|
74
|
-
const BUILD_POLYMARKET_POSITIONS_QUERY = (_address, tokenIds, url) => ({
|
|
75
|
-
url: url ?? POLYMARKET_POSITIONS_ENDPOINT,
|
|
76
|
-
query: `
|
|
77
|
-
query GetPolymarketPositions($tokenIds: [ID!]!) {
|
|
78
|
-
tokenIdConditions(
|
|
79
|
-
where: { id_in: $tokenIds }
|
|
80
|
-
first: 1000
|
|
81
|
-
orderBy: id
|
|
82
|
-
orderDirection: asc
|
|
83
|
-
) {
|
|
84
|
-
id
|
|
85
|
-
outcomeIndex
|
|
86
|
-
condition {
|
|
87
|
-
id
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
`,
|
|
92
|
-
variables: { tokenIds },
|
|
93
|
-
});
|
|
94
53
|
// ----------------------------------------------------------------------------
|
|
95
54
|
// Exported subscription builders
|
|
96
55
|
// ----------------------------------------------------------------------------
|
|
@@ -107,39 +66,22 @@ const BUILD_POLYMARKET_POSITIONS_QUERY = (_address, tokenIds, url) => ({
|
|
|
107
66
|
* Pair with `buildPolymarketActivity`.
|
|
108
67
|
*/
|
|
109
68
|
const POLYMARKET_DEFAULT_SUBSCRIPTION = async (address, types, goldSkyFetch, baseUrl) => {
|
|
110
|
-
if (!types.includes('trades')
|
|
69
|
+
if (!types.includes('trades'))
|
|
111
70
|
return null;
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
types.includes('trades') ? goldSkyFetch(BUILD_POLYMARKET_TRADES_AS_TAKER_QUERY(address, baseUrl)) : null,
|
|
116
|
-
types.includes('positions') ? goldSkyFetch(BUILD_POLYMARKET_PNL_QUERY(address, baseUrl)) : null,
|
|
71
|
+
const [makerData, takerData] = await Promise.all([
|
|
72
|
+
goldSkyFetch(BUILD_POLYMARKET_TRADES_AS_MAKER_QUERY(address, baseUrl)),
|
|
73
|
+
goldSkyFetch(BUILD_POLYMARKET_TRADES_AS_TAKER_QUERY(address, baseUrl)),
|
|
117
74
|
]);
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
seen.add(row.id);
|
|
125
|
-
trades.push(row);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
trades.sort((a, b) => Number(b.timestamp) - Number(a.timestamp));
|
|
129
|
-
result.orderFilledEvents = trades;
|
|
130
|
-
}
|
|
131
|
-
if (pnlData) {
|
|
132
|
-
const sorted = (pnlData.userPositions ?? [])
|
|
133
|
-
.sort((a, b) => parseFloat(b.amount ?? '0') - parseFloat(a.amount ?? '0'));
|
|
134
|
-
result.userPositions = sorted;
|
|
135
|
-
const tokenIds = sorted.map((p) => String(p.tokenId));
|
|
136
|
-
if (tokenIds.length > 0) {
|
|
137
|
-
const metaData = await goldSkyFetch(BUILD_POLYMARKET_POSITIONS_QUERY(address, tokenIds, baseUrl));
|
|
138
|
-
if (metaData)
|
|
139
|
-
Object.assign(result, metaData);
|
|
75
|
+
const seen = new Set();
|
|
76
|
+
const trades = [];
|
|
77
|
+
for (const row of [...(makerData?.orderFilledEvents ?? []), ...(takerData?.orderFilledEvents ?? [])]) {
|
|
78
|
+
if (!seen.has(row.id)) {
|
|
79
|
+
seen.add(row.id);
|
|
80
|
+
trades.push(row);
|
|
140
81
|
}
|
|
141
82
|
}
|
|
142
|
-
|
|
83
|
+
trades.sort((a, b) => Number(b.timestamp) - Number(a.timestamp));
|
|
84
|
+
return { orderFilledEvents: trades };
|
|
143
85
|
};
|
|
144
86
|
exports.POLYMARKET_DEFAULT_SUBSCRIPTION = POLYMARKET_DEFAULT_SUBSCRIPTION;
|
|
145
87
|
/**
|
|
@@ -224,65 +166,16 @@ const buildPolymarketTradesActivity = (data, address, types) => {
|
|
|
224
166
|
return { trades };
|
|
225
167
|
};
|
|
226
168
|
exports.buildPolymarketTradesActivity = buildPolymarketTradesActivity;
|
|
227
|
-
/**
|
|
228
|
-
* Derives `Position[]` from the joined PNL + positions-metadata event data.
|
|
229
|
-
*
|
|
230
|
-
* `userPositions` (PNL) and `userBalances` (positions) are guaranteed
|
|
231
|
-
* to share the same tokenIds since step 2 is filtered by step 1's results.
|
|
232
|
-
*
|
|
233
|
-
* `currentPrice` and `unrealizedPnL` are left at 0 (not available on-chain).
|
|
234
|
-
*/
|
|
235
|
-
/**
|
|
236
|
-
* Derives `Position[]` from joined PNL (`userPositions`) + metadata (`userBalances`).
|
|
237
|
-
* `currentPrice` and `unrealizedPnL` are left at 0 (not available on-chain).
|
|
238
|
-
*/
|
|
239
|
-
const buildPolymarketPositionsActivity = (data, _address, types) => {
|
|
240
|
-
if (!types.includes('positions'))
|
|
241
|
-
return null;
|
|
242
|
-
const pnlRows = data?.userPositions ?? [];
|
|
243
|
-
if (pnlRows.length === 0)
|
|
244
|
-
return null;
|
|
245
|
-
const conditionRows = data?.tokenIdConditions ?? [];
|
|
246
|
-
const metaByToken = new Map();
|
|
247
|
-
for (const c of conditionRows) {
|
|
248
|
-
metaByToken.set(c.id ?? '', {
|
|
249
|
-
marketId: c.condition?.id ?? '',
|
|
250
|
-
outcomeIndex: Number(c.outcomeIndex ?? 0),
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
const positions = pnlRows.map((p) => {
|
|
254
|
-
const tokenId = String(p.tokenId ?? '');
|
|
255
|
-
const meta = metaByToken.get(tokenId);
|
|
256
|
-
return {
|
|
257
|
-
marketId: meta?.marketId ?? '',
|
|
258
|
-
outcomeId: tokenId,
|
|
259
|
-
outcomeLabel: (meta?.outcomeIndex ?? 0) === 1 ? 'Yes' : 'No',
|
|
260
|
-
size: parseFloat(p.amount ?? '0') / 1e6,
|
|
261
|
-
entryPrice: parseFloat(p.avgPrice ?? '0') / 1e6,
|
|
262
|
-
currentPrice: 0, // Not available on-chain
|
|
263
|
-
unrealizedPnL: 0, // Not available on-chain
|
|
264
|
-
realizedPnL: parseFloat(p.realizedPnl ?? '0') / 1e6,
|
|
265
|
-
};
|
|
266
|
-
});
|
|
267
|
-
return { positions };
|
|
268
|
-
};
|
|
269
|
-
exports.buildPolymarketPositionsActivity = buildPolymarketPositionsActivity;
|
|
270
169
|
/**
|
|
271
170
|
* Combined activity builder for Polymarket. Pair with `POLYMARKET_DEFAULT_SUBSCRIPTION`.
|
|
171
|
+
*
|
|
172
|
+
* Only handles trades from GoldSky on-chain data. Positions are always fetched
|
|
173
|
+
* via the REST fallback because on-chain data lacks real market IDs and outcome labels.
|
|
272
174
|
*/
|
|
273
175
|
const buildPolymarketActivity = (data, address, types, lastSnapshot) => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (r?.trades)
|
|
278
|
-
result.trades = r.trades;
|
|
279
|
-
}
|
|
280
|
-
if (types.includes('positions')) {
|
|
281
|
-
const r = (0, exports.buildPolymarketPositionsActivity)(data, address, types, lastSnapshot);
|
|
282
|
-
if (r?.positions)
|
|
283
|
-
result.positions = r.positions;
|
|
284
|
-
}
|
|
285
|
-
return Object.keys(result).length > 0 ? result : null;
|
|
176
|
+
if (!types.includes('trades'))
|
|
177
|
+
return null;
|
|
178
|
+
return (0, exports.buildPolymarketTradesActivity)(data, address, types, lastSnapshot);
|
|
286
179
|
};
|
|
287
180
|
exports.buildPolymarketActivity = buildPolymarketActivity;
|
|
288
181
|
/**
|
|
@@ -136,7 +136,19 @@ class AddressWatcher {
|
|
|
136
136
|
this.dispatchAssetResolvers(key, value);
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
-
catch {
|
|
139
|
+
catch (err) {
|
|
140
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
141
|
+
const resolvers = this.resolvers.get(key);
|
|
142
|
+
if (resolvers?.length) {
|
|
143
|
+
resolvers.forEach(r => r.reject(error));
|
|
144
|
+
this.resolvers.set(key, []);
|
|
145
|
+
}
|
|
146
|
+
for (const [assetKey, assetResolvers] of this.assetIdResolvers) {
|
|
147
|
+
if (assetKey.startsWith(`${key} `) && assetResolvers.length > 0) {
|
|
148
|
+
assetResolvers.forEach(r => r.reject(error));
|
|
149
|
+
this.assetIdResolvers.set(assetKey, []);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
140
152
|
}
|
|
141
153
|
}
|
|
142
154
|
dispatchAssetResolvers(addrKey, activity) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmxt-core",
|
|
3
|
-
"version": "2.30.
|
|
3
|
+
"version": "2.30.7",
|
|
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.7,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.7,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",
|