@catalyst-team/poly-sdk 0.2.1 → 0.4.0
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/README.md +665 -807
- package/README.zh-CN.md +645 -342
- package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.js +267 -0
- package/dist/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
- package/dist/__tests__/integration/data-api.integration.test.js +6 -3
- package/dist/__tests__/integration/data-api.integration.test.js.map +1 -1
- package/dist/__tests__/integration/market-service.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/market-service.integration.test.js +173 -0
- package/dist/__tests__/integration/market-service.integration.test.js.map +1 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
- package/dist/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
- package/dist/__tests__/integration/trading-service.integration.test.d.ts +10 -0
- package/dist/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration/trading-service.integration.test.js +58 -0
- package/dist/__tests__/integration/trading-service.integration.test.js.map +1 -0
- package/dist/clients/clob-api.d.ts +73 -0
- package/dist/clients/clob-api.d.ts.map +1 -1
- package/dist/clients/clob-api.js +60 -0
- package/dist/clients/clob-api.js.map +1 -1
- package/dist/clients/ctf-client.d.ts +6 -4
- package/dist/clients/ctf-client.d.ts.map +1 -1
- package/dist/clients/ctf-client.js.map +1 -1
- package/dist/clients/data-api.d.ts +333 -15
- package/dist/clients/data-api.d.ts.map +1 -1
- package/dist/clients/data-api.js +398 -26
- package/dist/clients/data-api.js.map +1 -1
- package/dist/clients/gamma-api.d.ts +5 -0
- package/dist/clients/gamma-api.d.ts.map +1 -1
- package/dist/clients/gamma-api.js +2 -0
- package/dist/clients/gamma-api.js.map +1 -1
- package/dist/clients/subgraph.d.ts +196 -0
- package/dist/clients/subgraph.d.ts.map +1 -0
- package/dist/clients/subgraph.js +332 -0
- package/dist/clients/subgraph.js.map +1 -0
- package/dist/clients/websocket-manager.d.ts +3 -0
- package/dist/clients/websocket-manager.d.ts.map +1 -1
- package/dist/clients/websocket-manager.js +10 -3
- package/dist/clients/websocket-manager.js.map +1 -1
- package/dist/core/cache.d.ts +3 -0
- package/dist/core/cache.d.ts.map +1 -1
- package/dist/core/cache.js +5 -0
- package/dist/core/cache.js.map +1 -1
- package/dist/core/errors.d.ts +2 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +2 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/rate-limiter.d.ts +3 -1
- package/dist/core/rate-limiter.d.ts.map +1 -1
- package/dist/core/rate-limiter.js +12 -0
- package/dist/core/rate-limiter.js.map +1 -1
- package/dist/core/types.d.ts +205 -13
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +30 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/types.test.d.ts +7 -0
- package/dist/core/types.test.d.ts.map +1 -0
- package/dist/core/types.test.js +122 -0
- package/dist/core/types.test.js.map +1 -0
- package/dist/index.d.ts +84 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +139 -132
- package/dist/index.js.map +1 -1
- package/dist/scripts/dip-arb/auto-trade.d.ts +20 -0
- package/dist/scripts/dip-arb/auto-trade.d.ts.map +1 -0
- package/dist/scripts/dip-arb/auto-trade.js +373 -0
- package/dist/scripts/dip-arb/auto-trade.js.map +1 -0
- package/dist/scripts/dip-arb/example-basic.d.ts +30 -0
- package/dist/scripts/dip-arb/example-basic.d.ts.map +1 -0
- package/dist/scripts/dip-arb/example-basic.js +222 -0
- package/dist/scripts/dip-arb/example-basic.js.map +1 -0
- package/dist/scripts/dip-arb/redeem-positions.d.ts +11 -0
- package/dist/scripts/dip-arb/redeem-positions.d.ts.map +1 -0
- package/dist/scripts/dip-arb/redeem-positions.js +201 -0
- package/dist/scripts/dip-arb/redeem-positions.js.map +1 -0
- package/dist/scripts/dip-arb/scan-markets.d.ts +6 -0
- package/dist/scripts/dip-arb/scan-markets.d.ts.map +1 -0
- package/dist/scripts/dip-arb/scan-markets.js +73 -0
- package/dist/scripts/dip-arb/scan-markets.js.map +1 -0
- package/dist/services/arbitrage-service.d.ts +3 -2
- package/dist/services/arbitrage-service.d.ts.map +1 -1
- package/dist/services/arbitrage-service.js +71 -43
- package/dist/services/arbitrage-service.js.map +1 -1
- package/dist/services/binance-service.d.ts +154 -0
- package/dist/services/binance-service.d.ts.map +1 -0
- package/dist/services/binance-service.js +266 -0
- package/dist/services/binance-service.js.map +1 -0
- package/dist/services/dip-arb-service.d.ts +209 -0
- package/dist/services/dip-arb-service.d.ts.map +1 -0
- package/dist/services/dip-arb-service.js +1602 -0
- package/dist/services/dip-arb-service.js.map +1 -0
- package/dist/services/dip-arb-types.d.ts +553 -0
- package/dist/services/dip-arb-types.d.ts.map +1 -0
- package/dist/services/dip-arb-types.js +164 -0
- package/dist/services/dip-arb-types.js.map +1 -0
- package/dist/services/market-service.d.ts +267 -8
- package/dist/services/market-service.d.ts.map +1 -1
- package/dist/services/market-service.js +771 -42
- package/dist/services/market-service.js.map +1 -1
- package/dist/services/onchain-service.d.ts +309 -0
- package/dist/services/onchain-service.d.ts.map +1 -0
- package/dist/services/onchain-service.js +417 -0
- package/dist/services/onchain-service.js.map +1 -0
- package/dist/services/realtime-service-v2.d.ts +362 -0
- package/dist/services/realtime-service-v2.d.ts.map +1 -0
- package/dist/services/realtime-service-v2.js +858 -0
- package/dist/services/realtime-service-v2.js.map +1 -0
- package/dist/services/realtime-service.d.ts +17 -17
- package/dist/services/realtime-service.d.ts.map +1 -1
- package/dist/services/realtime-service.js +91 -59
- package/dist/services/realtime-service.js.map +1 -1
- package/dist/services/smart-money-service.d.ts +352 -0
- package/dist/services/smart-money-service.d.ts.map +1 -0
- package/dist/services/smart-money-service.js +582 -0
- package/dist/services/smart-money-service.js.map +1 -0
- package/dist/services/trading-service.d.ts +177 -0
- package/dist/services/trading-service.d.ts.map +1 -0
- package/dist/services/trading-service.js +422 -0
- package/dist/services/trading-service.js.map +1 -0
- package/dist/services/wallet-service.d.ts +225 -3
- package/dist/services/wallet-service.d.ts.map +1 -1
- package/dist/services/wallet-service.js +511 -3
- package/dist/services/wallet-service.js.map +1 -1
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.js +267 -0
- package/dist/src/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.js +260 -0
- package/dist/src/__tests__/integration/bridge-client.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.js +234 -0
- package/dist/src/__tests__/integration/ctf-client.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/data-api.integration.test.d.ts +9 -0
- package/dist/src/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/data-api.integration.test.js +164 -0
- package/dist/src/__tests__/integration/data-api.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.js +170 -0
- package/dist/src/__tests__/integration/gamma-api.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/market-service.integration.test.d.ts +10 -0
- package/dist/src/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/market-service.integration.test.js +180 -0
- package/dist/src/__tests__/integration/market-service.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
- package/dist/src/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.d.ts +10 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.js +58 -0
- package/dist/src/__tests__/integration/trading-service.integration.test.js.map +1 -0
- package/dist/src/__tests__/test-utils.d.ts +92 -0
- package/dist/src/__tests__/test-utils.d.ts.map +1 -0
- package/dist/src/__tests__/test-utils.js +143 -0
- package/dist/src/__tests__/test-utils.js.map +1 -0
- package/dist/src/clients/bridge-client.d.ts +388 -0
- package/dist/src/clients/bridge-client.d.ts.map +1 -0
- package/dist/src/clients/bridge-client.js +587 -0
- package/dist/src/clients/bridge-client.js.map +1 -0
- package/dist/src/clients/ctf-client.d.ts +475 -0
- package/dist/src/clients/ctf-client.d.ts.map +1 -0
- package/dist/src/clients/ctf-client.js +915 -0
- package/dist/src/clients/ctf-client.js.map +1 -0
- package/dist/src/clients/data-api.d.ts +452 -0
- package/dist/src/clients/data-api.d.ts.map +1 -0
- package/dist/src/clients/data-api.js +637 -0
- package/dist/src/clients/data-api.js.map +1 -0
- package/dist/src/clients/gamma-api.d.ts +421 -0
- package/dist/src/clients/gamma-api.d.ts.map +1 -0
- package/dist/src/clients/gamma-api.js +359 -0
- package/dist/src/clients/gamma-api.js.map +1 -0
- package/dist/src/clients/subgraph.d.ts +196 -0
- package/dist/src/clients/subgraph.d.ts.map +1 -0
- package/dist/src/clients/subgraph.js +332 -0
- package/dist/src/clients/subgraph.js.map +1 -0
- package/dist/src/core/cache-adapter-bridge.d.ts +36 -0
- package/dist/src/core/cache-adapter-bridge.d.ts.map +1 -0
- package/dist/src/core/cache-adapter-bridge.js +81 -0
- package/dist/src/core/cache-adapter-bridge.js.map +1 -0
- package/dist/src/core/cache.d.ts +43 -0
- package/dist/src/core/cache.d.ts.map +1 -0
- package/dist/src/core/cache.js +76 -0
- package/dist/src/core/cache.js.map +1 -0
- package/dist/src/core/errors.d.ts +39 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +86 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/rate-limiter.d.ts +33 -0
- package/dist/src/core/rate-limiter.d.ts.map +1 -0
- package/dist/src/core/rate-limiter.js +82 -0
- package/dist/src/core/rate-limiter.js.map +1 -0
- package/dist/src/core/types.d.ts +506 -0
- package/dist/src/core/types.d.ts.map +1 -0
- package/dist/src/core/types.js +49 -0
- package/dist/src/core/types.js.map +1 -0
- package/dist/src/core/types.test.d.ts +7 -0
- package/dist/src/core/types.test.d.ts.map +1 -0
- package/dist/src/core/types.test.js +122 -0
- package/dist/src/core/types.test.js.map +1 -0
- package/dist/src/core/unified-cache.d.ts +63 -0
- package/dist/src/core/unified-cache.d.ts.map +1 -0
- package/dist/src/core/unified-cache.js +114 -0
- package/dist/src/core/unified-cache.js.map +1 -0
- package/dist/src/index.d.ts +159 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +262 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/services/arbitrage-service.d.ts +409 -0
- package/dist/src/services/arbitrage-service.d.ts.map +1 -0
- package/dist/src/services/arbitrage-service.js +1450 -0
- package/dist/src/services/arbitrage-service.js.map +1 -0
- package/dist/src/services/authorization-service.d.ts +97 -0
- package/dist/src/services/authorization-service.d.ts.map +1 -0
- package/dist/src/services/authorization-service.js +279 -0
- package/dist/src/services/authorization-service.js.map +1 -0
- package/dist/src/services/binance-service.d.ts +154 -0
- package/dist/src/services/binance-service.d.ts.map +1 -0
- package/dist/src/services/binance-service.js +266 -0
- package/dist/src/services/binance-service.js.map +1 -0
- package/dist/src/services/dip-arb-service.d.ts +245 -0
- package/dist/src/services/dip-arb-service.d.ts.map +1 -0
- package/dist/src/services/dip-arb-service.js +1865 -0
- package/dist/src/services/dip-arb-service.js.map +1 -0
- package/dist/src/services/dip-arb-types.d.ts +553 -0
- package/dist/src/services/dip-arb-types.d.ts.map +1 -0
- package/dist/src/services/dip-arb-types.js +164 -0
- package/dist/src/services/dip-arb-types.js.map +1 -0
- package/dist/src/services/market-service.d.ts +370 -0
- package/dist/src/services/market-service.d.ts.map +1 -0
- package/dist/src/services/market-service.js +1200 -0
- package/dist/src/services/market-service.js.map +1 -0
- package/dist/src/services/onchain-service.d.ts +309 -0
- package/dist/src/services/onchain-service.d.ts.map +1 -0
- package/dist/src/services/onchain-service.js +417 -0
- package/dist/src/services/onchain-service.js.map +1 -0
- package/dist/src/services/realtime-service-v2.d.ts +367 -0
- package/dist/src/services/realtime-service-v2.d.ts.map +1 -0
- package/dist/src/services/realtime-service-v2.js +876 -0
- package/dist/src/services/realtime-service-v2.js.map +1 -0
- package/dist/src/services/smart-money-service.d.ts +352 -0
- package/dist/src/services/smart-money-service.d.ts.map +1 -0
- package/dist/src/services/smart-money-service.js +582 -0
- package/dist/src/services/smart-money-service.js.map +1 -0
- package/dist/src/services/swap-service.d.ts +217 -0
- package/dist/src/services/swap-service.d.ts.map +1 -0
- package/dist/src/services/swap-service.js +695 -0
- package/dist/src/services/swap-service.js.map +1 -0
- package/dist/src/services/trading-service.d.ts +177 -0
- package/dist/src/services/trading-service.d.ts.map +1 -0
- package/dist/src/services/trading-service.js +422 -0
- package/dist/src/services/trading-service.js.map +1 -0
- package/dist/src/services/wallet-service.d.ts +316 -0
- package/dist/src/services/wallet-service.d.ts.map +1 -0
- package/dist/src/services/wallet-service.js +681 -0
- package/dist/src/services/wallet-service.js.map +1 -0
- package/dist/src/utils/price-utils.d.ts +153 -0
- package/dist/src/utils/price-utils.d.ts.map +1 -0
- package/dist/src/utils/price-utils.js +236 -0
- package/dist/src/utils/price-utils.js.map +1 -0
- package/dist/src/utils/price-utils.test.d.ts +5 -0
- package/dist/src/utils/price-utils.test.d.ts.map +1 -0
- package/dist/src/utils/price-utils.test.js +192 -0
- package/dist/src/utils/price-utils.test.js.map +1 -0
- package/dist/utils/price-utils.test.d.ts +5 -0
- package/dist/utils/price-utils.test.d.ts.map +1 -0
- package/dist/utils/price-utils.test.js +192 -0
- package/dist/utils/price-utils.test.js.map +1 -0
- package/package.json +6 -5
- package/README.en.md +0 -502
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data API Client for Polymarket
|
|
3
|
+
* Handles: positions, activity, trades, leaderboard
|
|
4
|
+
*/
|
|
5
|
+
import { ApiType } from '../core/rate-limiter.js';
|
|
6
|
+
import { CACHE_TTL } from '../core/unified-cache.js';
|
|
7
|
+
import { PolymarketError } from '../core/errors.js';
|
|
8
|
+
const DATA_API_BASE = 'https://data-api.polymarket.com';
|
|
9
|
+
// ===== Client =====
|
|
10
|
+
export class DataApiClient {
|
|
11
|
+
rateLimiter;
|
|
12
|
+
cache;
|
|
13
|
+
constructor(rateLimiter, cache) {
|
|
14
|
+
this.rateLimiter = rateLimiter;
|
|
15
|
+
this.cache = cache;
|
|
16
|
+
}
|
|
17
|
+
// ===== Wallet-related =====
|
|
18
|
+
/**
|
|
19
|
+
* Get positions for a wallet address
|
|
20
|
+
*
|
|
21
|
+
* @param address - Wallet address
|
|
22
|
+
* @param params - Query parameters (P0/P1: limit, offset, sortBy, sortDirection, market, etc.)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* // Get all positions
|
|
27
|
+
* const positions = await client.getPositions(address);
|
|
28
|
+
*
|
|
29
|
+
* // Get positions sorted by PnL (highest first)
|
|
30
|
+
* const topPnl = await client.getPositions(address, {
|
|
31
|
+
* sortBy: 'CASHPNL',
|
|
32
|
+
* sortDirection: 'DESC',
|
|
33
|
+
* limit: 10,
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Get only redeemable positions
|
|
37
|
+
* const redeemable = await client.getPositions(address, { redeemable: true });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
async getPositions(address, params) {
|
|
41
|
+
return this.rateLimiter.execute(ApiType.DATA_API, async () => {
|
|
42
|
+
const query = new URLSearchParams({ user: address });
|
|
43
|
+
// P0: limit, offset
|
|
44
|
+
if (params?.limit !== undefined)
|
|
45
|
+
query.set('limit', String(params.limit));
|
|
46
|
+
if (params?.offset !== undefined)
|
|
47
|
+
query.set('offset', String(params.offset));
|
|
48
|
+
// P1: sortBy, sortDirection, market
|
|
49
|
+
if (params?.sortBy)
|
|
50
|
+
query.set('sortBy', params.sortBy);
|
|
51
|
+
if (params?.sortDirection)
|
|
52
|
+
query.set('sortDirection', params.sortDirection);
|
|
53
|
+
if (params?.market) {
|
|
54
|
+
params.market.forEach((m) => query.append('market', m));
|
|
55
|
+
}
|
|
56
|
+
if (params?.eventId) {
|
|
57
|
+
params.eventId.forEach((id) => query.append('eventId', String(id)));
|
|
58
|
+
}
|
|
59
|
+
// P1: sizeThreshold, redeemable, mergeable, title
|
|
60
|
+
if (params?.sizeThreshold !== undefined)
|
|
61
|
+
query.set('sizeThreshold', String(params.sizeThreshold));
|
|
62
|
+
if (params?.redeemable !== undefined)
|
|
63
|
+
query.set('redeemable', String(params.redeemable));
|
|
64
|
+
if (params?.mergeable !== undefined)
|
|
65
|
+
query.set('mergeable', String(params.mergeable));
|
|
66
|
+
if (params?.title)
|
|
67
|
+
query.set('title', params.title);
|
|
68
|
+
const response = await fetch(`${DATA_API_BASE}/positions?${query}`);
|
|
69
|
+
if (!response.ok)
|
|
70
|
+
throw PolymarketError.fromHttpError(response.status, await response.json().catch(() => null));
|
|
71
|
+
const data = (await response.json());
|
|
72
|
+
return this.normalizePositions(data);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get closed positions for a wallet address
|
|
77
|
+
*
|
|
78
|
+
* @param address - Wallet address
|
|
79
|
+
* @param params - Query parameters
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // Get closed positions sorted by realized PnL
|
|
84
|
+
* const closed = await client.getClosedPositions(address);
|
|
85
|
+
*
|
|
86
|
+
* // Get recent settlements
|
|
87
|
+
* const recent = await client.getClosedPositions(address, {
|
|
88
|
+
* sortBy: 'TIMESTAMP',
|
|
89
|
+
* sortDirection: 'DESC',
|
|
90
|
+
* limit: 20,
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
async getClosedPositions(address, params) {
|
|
95
|
+
return this.rateLimiter.execute(ApiType.DATA_API, async () => {
|
|
96
|
+
const query = new URLSearchParams({ user: address });
|
|
97
|
+
// Pagination
|
|
98
|
+
if (params?.limit !== undefined)
|
|
99
|
+
query.set('limit', String(params.limit));
|
|
100
|
+
if (params?.offset !== undefined)
|
|
101
|
+
query.set('offset', String(params.offset));
|
|
102
|
+
// Filters
|
|
103
|
+
if (params?.market) {
|
|
104
|
+
params.market.forEach((m) => query.append('market', m));
|
|
105
|
+
}
|
|
106
|
+
if (params?.eventId) {
|
|
107
|
+
params.eventId.forEach((id) => query.append('eventId', String(id)));
|
|
108
|
+
}
|
|
109
|
+
if (params?.title)
|
|
110
|
+
query.set('title', params.title);
|
|
111
|
+
// Sorting
|
|
112
|
+
if (params?.sortBy)
|
|
113
|
+
query.set('sortBy', params.sortBy);
|
|
114
|
+
if (params?.sortDirection)
|
|
115
|
+
query.set('sortDirection', params.sortDirection);
|
|
116
|
+
const response = await fetch(`${DATA_API_BASE}/closed-positions?${query}`);
|
|
117
|
+
if (!response.ok)
|
|
118
|
+
throw PolymarketError.fromHttpError(response.status, await response.json().catch(() => null));
|
|
119
|
+
const data = (await response.json());
|
|
120
|
+
return this.normalizeClosedPositions(data);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get activity for a wallet address
|
|
125
|
+
*
|
|
126
|
+
* @param address - Wallet address
|
|
127
|
+
* @param params - Query parameters (P0: start, end, offset; P1: market, sortBy, etc.)
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* // Get recent activity
|
|
132
|
+
* const activity = await client.getActivity(address, { limit: 50 });
|
|
133
|
+
*
|
|
134
|
+
* // Get activity in a time range (Unix seconds)
|
|
135
|
+
* const dayAgo = Math.floor(Date.now() / 1000) - 86400;
|
|
136
|
+
* const recent = await client.getActivity(address, {
|
|
137
|
+
* start: dayAgo,
|
|
138
|
+
* limit: 100,
|
|
139
|
+
* });
|
|
140
|
+
*
|
|
141
|
+
* // Paginate through all activity
|
|
142
|
+
* const page2 = await client.getActivity(address, { offset: 100, limit: 100 });
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
async getActivity(address, params) {
|
|
146
|
+
return this.rateLimiter.execute(ApiType.DATA_API, async () => {
|
|
147
|
+
const query = new URLSearchParams({ user: address });
|
|
148
|
+
// Basic params
|
|
149
|
+
query.set('limit', String(params?.limit ?? 100));
|
|
150
|
+
// P0: offset, start, end (time filtering and pagination)
|
|
151
|
+
if (params?.offset !== undefined)
|
|
152
|
+
query.set('offset', String(params.offset));
|
|
153
|
+
if (params?.start !== undefined)
|
|
154
|
+
query.set('start', String(params.start));
|
|
155
|
+
if (params?.end !== undefined)
|
|
156
|
+
query.set('end', String(params.end));
|
|
157
|
+
// P1: type, side, market, eventId
|
|
158
|
+
if (params?.type)
|
|
159
|
+
query.set('type', params.type);
|
|
160
|
+
if (params?.side)
|
|
161
|
+
query.set('side', params.side);
|
|
162
|
+
if (params?.market) {
|
|
163
|
+
params.market.forEach((m) => query.append('market', m));
|
|
164
|
+
}
|
|
165
|
+
if (params?.eventId) {
|
|
166
|
+
params.eventId.forEach((id) => query.append('eventId', String(id)));
|
|
167
|
+
}
|
|
168
|
+
// P2: sortBy, sortDirection
|
|
169
|
+
if (params?.sortBy)
|
|
170
|
+
query.set('sortBy', params.sortBy);
|
|
171
|
+
if (params?.sortDirection)
|
|
172
|
+
query.set('sortDirection', params.sortDirection);
|
|
173
|
+
const response = await fetch(`${DATA_API_BASE}/activity?${query}`);
|
|
174
|
+
if (!response.ok)
|
|
175
|
+
throw PolymarketError.fromHttpError(response.status, await response.json().catch(() => null));
|
|
176
|
+
const data = (await response.json());
|
|
177
|
+
return this.normalizeActivities(data);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get all activity for a wallet (auto-pagination)
|
|
182
|
+
*
|
|
183
|
+
* **⚠️ IMPORTANT: API Limitation**
|
|
184
|
+
* The Polymarket API has a hard offset limit of 10,000. This means:
|
|
185
|
+
* - Maximum ~10,500 records can be retrieved via offset pagination
|
|
186
|
+
* - For active traders, this may only cover a few hours of history
|
|
187
|
+
* - Use `start` and `end` params for time-based filtering to access older data
|
|
188
|
+
*
|
|
189
|
+
* @param address - Wallet address
|
|
190
|
+
* @param params - Query parameters (use `start`/`end` for time filtering)
|
|
191
|
+
* @param maxItems - Maximum items to fetch (default: 10000, capped by API offset limit)
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* // Get all recent activity (limited by API offset)
|
|
196
|
+
* const allActivity = await client.getAllActivity(address);
|
|
197
|
+
*
|
|
198
|
+
* // Get activity for a specific time window (recommended for complete history)
|
|
199
|
+
* const oneWeekAgo = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60;
|
|
200
|
+
* const weekActivity = await client.getAllActivity(address, { start: oneWeekAgo });
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
async getAllActivity(address, params, maxItems = 10000) {
|
|
204
|
+
const all = [];
|
|
205
|
+
const limit = 500; // Max allowed by API
|
|
206
|
+
const API_OFFSET_LIMIT = 10000; // Hard limit from Polymarket API
|
|
207
|
+
let offset = 0;
|
|
208
|
+
while (all.length < maxItems && offset < API_OFFSET_LIMIT) {
|
|
209
|
+
const page = await this.getActivity(address, { ...params, limit, offset });
|
|
210
|
+
all.push(...page);
|
|
211
|
+
if (page.length < limit)
|
|
212
|
+
break; // No more data
|
|
213
|
+
offset += limit;
|
|
214
|
+
}
|
|
215
|
+
// Warn if we hit the API offset limit
|
|
216
|
+
if (offset >= API_OFFSET_LIMIT && all.length >= API_OFFSET_LIMIT) {
|
|
217
|
+
console.warn(`[DataApiClient] Hit API offset limit (${API_OFFSET_LIMIT}). ` +
|
|
218
|
+
'Use time filtering (start/end params) to access older activity data.');
|
|
219
|
+
}
|
|
220
|
+
return all.slice(0, maxItems);
|
|
221
|
+
}
|
|
222
|
+
// ===== Trade-related =====
|
|
223
|
+
/**
|
|
224
|
+
* Get recent trades
|
|
225
|
+
*
|
|
226
|
+
* @param params - Query parameters (P2: user, side, takerOnly, etc.)
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```typescript
|
|
230
|
+
* // Get market trades
|
|
231
|
+
* const trades = await client.getTrades({ market: conditionId, limit: 100 });
|
|
232
|
+
*
|
|
233
|
+
* // Get user trades (P2)
|
|
234
|
+
* const userTrades = await client.getTrades({ user: address, limit: 50 });
|
|
235
|
+
*
|
|
236
|
+
* // Get only buy trades
|
|
237
|
+
* const buys = await client.getTrades({ market: conditionId, side: 'BUY' });
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
async getTrades(params) {
|
|
241
|
+
return this.rateLimiter.execute(ApiType.DATA_API, async () => {
|
|
242
|
+
const query = new URLSearchParams();
|
|
243
|
+
// Request more if we need to filter by time (to ensure we get enough after filtering)
|
|
244
|
+
const requestLimit = (params?.startTimestamp || params?.endTimestamp)
|
|
245
|
+
? Math.min((params?.limit ?? 500) * 3, 1000)
|
|
246
|
+
: (params?.limit ?? 500);
|
|
247
|
+
query.set('limit', String(requestLimit));
|
|
248
|
+
// Basic filters
|
|
249
|
+
if (params?.market)
|
|
250
|
+
query.set('market', params.market);
|
|
251
|
+
// P2: user filter
|
|
252
|
+
if (params?.user)
|
|
253
|
+
query.set('user', params.user);
|
|
254
|
+
// P2: additional filters
|
|
255
|
+
if (params?.side)
|
|
256
|
+
query.set('side', params.side);
|
|
257
|
+
if (params?.takerOnly !== undefined)
|
|
258
|
+
query.set('takerOnly', String(params.takerOnly));
|
|
259
|
+
if (params?.filterType)
|
|
260
|
+
query.set('filterType', params.filterType);
|
|
261
|
+
if (params?.filterAmount !== undefined)
|
|
262
|
+
query.set('filterAmount', String(params.filterAmount));
|
|
263
|
+
const response = await fetch(`${DATA_API_BASE}/trades?${query}`);
|
|
264
|
+
if (!response.ok)
|
|
265
|
+
throw PolymarketError.fromHttpError(response.status, await response.json().catch(() => null));
|
|
266
|
+
const data = (await response.json());
|
|
267
|
+
let trades = this.normalizeTrades(data);
|
|
268
|
+
// Apply timestamp filters client-side (API may not support these directly)
|
|
269
|
+
if (params?.startTimestamp) {
|
|
270
|
+
trades = trades.filter(t => t.timestamp >= params.startTimestamp);
|
|
271
|
+
}
|
|
272
|
+
if (params?.endTimestamp) {
|
|
273
|
+
trades = trades.filter(t => t.timestamp <= params.endTimestamp);
|
|
274
|
+
}
|
|
275
|
+
// Apply limit after filtering
|
|
276
|
+
if (params?.limit && trades.length > params.limit) {
|
|
277
|
+
trades = trades.slice(0, params.limit);
|
|
278
|
+
}
|
|
279
|
+
return trades;
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Get trades for a specific market
|
|
284
|
+
*/
|
|
285
|
+
async getTradesByMarket(conditionId, limit = 500) {
|
|
286
|
+
return this.getTrades({ market: conditionId, limit });
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Get trades for a specific user (P2)
|
|
290
|
+
*/
|
|
291
|
+
async getTradesByUser(address, params) {
|
|
292
|
+
return this.getTrades({ ...params, user: address });
|
|
293
|
+
}
|
|
294
|
+
// ===== Leaderboard =====
|
|
295
|
+
/**
|
|
296
|
+
* Get leaderboard page with time period and ordering support
|
|
297
|
+
*
|
|
298
|
+
* @param params - Query parameters
|
|
299
|
+
* @param params.timePeriod - Time period: 'DAY', 'WEEK', 'MONTH', 'ALL' (default: 'ALL' for backward compatibility)
|
|
300
|
+
* @param params.orderBy - Order by: 'PNL', 'VOL' (default: 'PNL')
|
|
301
|
+
* @param params.category - Category filter (default: 'OVERALL')
|
|
302
|
+
* @param params.limit - Max entries per page (1-50, default: 50)
|
|
303
|
+
* @param params.offset - Pagination offset (0-1000, default: 0)
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* ```typescript
|
|
307
|
+
* // Get today's top traders by PnL
|
|
308
|
+
* const daily = await client.getLeaderboard({ timePeriod: 'DAY', orderBy: 'PNL' });
|
|
309
|
+
*
|
|
310
|
+
* // Get this week's top traders by volume
|
|
311
|
+
* const weekly = await client.getLeaderboard({ timePeriod: 'WEEK', orderBy: 'VOL' });
|
|
312
|
+
*
|
|
313
|
+
* // Get politics category leaderboard
|
|
314
|
+
* const politics = await client.getLeaderboard({ category: 'POLITICS' });
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
async getLeaderboard(params) {
|
|
318
|
+
const { timePeriod = 'ALL', // Default to ALL for backward compatibility
|
|
319
|
+
orderBy = 'PNL', category = 'OVERALL', limit = 50, offset = 0, user, userName, } = params || {};
|
|
320
|
+
const cacheKey = `leaderboard:${timePeriod}:${orderBy}:${category}:${offset}:${limit}`;
|
|
321
|
+
return this.cache.getOrSet(cacheKey, CACHE_TTL.LEADERBOARD, async () => {
|
|
322
|
+
const query = new URLSearchParams({
|
|
323
|
+
timePeriod,
|
|
324
|
+
orderBy,
|
|
325
|
+
category,
|
|
326
|
+
limit: String(limit),
|
|
327
|
+
offset: String(offset),
|
|
328
|
+
});
|
|
329
|
+
if (user)
|
|
330
|
+
query.set('user', user);
|
|
331
|
+
if (userName)
|
|
332
|
+
query.set('userName', userName);
|
|
333
|
+
return this.rateLimiter.execute(ApiType.DATA_API, async () => {
|
|
334
|
+
const response = await fetch(`${DATA_API_BASE}/v1/leaderboard?${query}`);
|
|
335
|
+
if (!response.ok)
|
|
336
|
+
throw PolymarketError.fromHttpError(response.status, await response.json().catch(() => null));
|
|
337
|
+
const data = (await response.json());
|
|
338
|
+
const entries = this.normalizeLeaderboardEntries(data);
|
|
339
|
+
return {
|
|
340
|
+
entries,
|
|
341
|
+
total: entries.length + offset, // Approximate - API doesn't provide total
|
|
342
|
+
offset,
|
|
343
|
+
limit,
|
|
344
|
+
};
|
|
345
|
+
});
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Get all leaderboard entries up to a max count
|
|
350
|
+
*/
|
|
351
|
+
async getAllLeaderboard(maxEntries = 500) {
|
|
352
|
+
const all = [];
|
|
353
|
+
let offset = 0;
|
|
354
|
+
const limit = 50;
|
|
355
|
+
while (all.length < maxEntries) {
|
|
356
|
+
const page = await this.getLeaderboard({ limit, offset });
|
|
357
|
+
all.push(...page.entries);
|
|
358
|
+
if (page.entries.length < limit)
|
|
359
|
+
break;
|
|
360
|
+
offset += limit;
|
|
361
|
+
}
|
|
362
|
+
return all.slice(0, maxEntries);
|
|
363
|
+
}
|
|
364
|
+
// ===== Value & Holders (P1/P2) =====
|
|
365
|
+
/**
|
|
366
|
+
* Get account total value (P1)
|
|
367
|
+
*
|
|
368
|
+
* @param address - Wallet address
|
|
369
|
+
* @param markets - Optional: filter by specific markets
|
|
370
|
+
*
|
|
371
|
+
* @example
|
|
372
|
+
* ```typescript
|
|
373
|
+
* const { value } = await client.getAccountValue(address);
|
|
374
|
+
* console.log(`Total account value: $${value.toFixed(2)}`);
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
async getAccountValue(address, markets) {
|
|
378
|
+
return this.rateLimiter.execute(ApiType.DATA_API, async () => {
|
|
379
|
+
const query = new URLSearchParams({ user: address });
|
|
380
|
+
if (markets) {
|
|
381
|
+
markets.forEach((m) => query.append('market', m));
|
|
382
|
+
}
|
|
383
|
+
const response = await fetch(`${DATA_API_BASE}/value?${query}`);
|
|
384
|
+
if (!response.ok)
|
|
385
|
+
throw PolymarketError.fromHttpError(response.status, await response.json().catch(() => null));
|
|
386
|
+
// API returns array: [{ user, value }]
|
|
387
|
+
const data = (await response.json());
|
|
388
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
389
|
+
return {
|
|
390
|
+
user: String(data[0].user),
|
|
391
|
+
value: Number(data[0].value) || 0,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
return { user: address, value: 0 };
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Get market holders (P2)
|
|
399
|
+
*
|
|
400
|
+
* Returns top holders for a specific market. Note: This endpoint can timeout
|
|
401
|
+
* for large markets.
|
|
402
|
+
*
|
|
403
|
+
* @param params - Query parameters (market is required)
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* ```typescript
|
|
407
|
+
* const holders = await client.getMarketHolders({
|
|
408
|
+
* market: conditionId,
|
|
409
|
+
* limit: 20,
|
|
410
|
+
* });
|
|
411
|
+
* ```
|
|
412
|
+
*/
|
|
413
|
+
async getMarketHolders(params) {
|
|
414
|
+
return this.rateLimiter.execute(ApiType.DATA_API, async () => {
|
|
415
|
+
const query = new URLSearchParams({ market: params.market });
|
|
416
|
+
if (params.limit !== undefined)
|
|
417
|
+
query.set('limit', String(params.limit));
|
|
418
|
+
const response = await fetch(`${DATA_API_BASE}/holders?${query}`);
|
|
419
|
+
if (!response.ok)
|
|
420
|
+
throw PolymarketError.fromHttpError(response.status, await response.json().catch(() => null));
|
|
421
|
+
const data = (await response.json());
|
|
422
|
+
return this.normalizeHolders(data);
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
// ===== Data Normalization =====
|
|
426
|
+
normalizePositions(data) {
|
|
427
|
+
if (!Array.isArray(data))
|
|
428
|
+
return [];
|
|
429
|
+
return data.map((item) => {
|
|
430
|
+
const p = item;
|
|
431
|
+
return {
|
|
432
|
+
// Wallet identifier
|
|
433
|
+
proxyWallet: p.proxyWallet !== undefined ? String(p.proxyWallet) : undefined,
|
|
434
|
+
// Core identifiers
|
|
435
|
+
asset: String(p.asset || ''),
|
|
436
|
+
conditionId: String(p.conditionId || ''),
|
|
437
|
+
outcome: String(p.outcome || ''),
|
|
438
|
+
// Only use outcomeIndex if provided by API - don't infer from outcome name
|
|
439
|
+
// (non-binary markets have arbitrary outcome names)
|
|
440
|
+
outcomeIndex: typeof p.outcomeIndex === 'number' ? p.outcomeIndex : 0,
|
|
441
|
+
// Position data
|
|
442
|
+
size: Number(p.size),
|
|
443
|
+
avgPrice: Number(p.avgPrice),
|
|
444
|
+
curPrice: p.curPrice !== undefined ? Number(p.curPrice) : undefined,
|
|
445
|
+
totalBought: p.totalBought !== undefined ? Number(p.totalBought) : undefined,
|
|
446
|
+
// Value calculations
|
|
447
|
+
initialValue: p.initialValue !== undefined ? Number(p.initialValue) : undefined,
|
|
448
|
+
currentValue: p.currentValue !== undefined ? Number(p.currentValue) : undefined,
|
|
449
|
+
cashPnl: p.cashPnl !== undefined ? Number(p.cashPnl) : undefined,
|
|
450
|
+
percentPnl: p.percentPnl !== undefined ? Number(p.percentPnl) : undefined,
|
|
451
|
+
realizedPnl: p.realizedPnl !== undefined ? Number(p.realizedPnl) : undefined,
|
|
452
|
+
percentRealizedPnl: p.percentRealizedPnl !== undefined ? Number(p.percentRealizedPnl) : undefined,
|
|
453
|
+
// Market metadata
|
|
454
|
+
title: String(p.title || ''),
|
|
455
|
+
slug: p.slug !== undefined ? String(p.slug) : undefined,
|
|
456
|
+
icon: p.icon !== undefined ? String(p.icon) : undefined,
|
|
457
|
+
eventId: p.eventId !== undefined ? String(p.eventId) : undefined,
|
|
458
|
+
eventSlug: p.eventSlug !== undefined ? String(p.eventSlug) : undefined,
|
|
459
|
+
// Opposite side info
|
|
460
|
+
oppositeOutcome: p.oppositeOutcome !== undefined ? String(p.oppositeOutcome) : undefined,
|
|
461
|
+
oppositeAsset: p.oppositeAsset !== undefined ? String(p.oppositeAsset) : undefined,
|
|
462
|
+
// Status fields
|
|
463
|
+
redeemable: p.redeemable !== undefined ? Boolean(p.redeemable) : undefined,
|
|
464
|
+
mergeable: p.mergeable !== undefined ? Boolean(p.mergeable) : undefined,
|
|
465
|
+
endDate: p.endDate !== undefined ? String(p.endDate) : undefined,
|
|
466
|
+
negativeRisk: p.negativeRisk !== undefined ? Boolean(p.negativeRisk) : undefined,
|
|
467
|
+
};
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
normalizeClosedPositions(data) {
|
|
471
|
+
if (!Array.isArray(data))
|
|
472
|
+
return [];
|
|
473
|
+
return data.map((item) => {
|
|
474
|
+
const p = item;
|
|
475
|
+
return {
|
|
476
|
+
proxyWallet: String(p.proxyWallet || ''),
|
|
477
|
+
asset: String(p.asset || ''),
|
|
478
|
+
conditionId: String(p.conditionId || ''),
|
|
479
|
+
// Trade data
|
|
480
|
+
avgPrice: Number(p.avgPrice) || 0,
|
|
481
|
+
totalBought: Number(p.totalBought) || 0,
|
|
482
|
+
realizedPnl: Number(p.realizedPnl) || 0,
|
|
483
|
+
curPrice: Number(p.curPrice) || 0,
|
|
484
|
+
timestamp: this.normalizeTimestamp(p.timestamp),
|
|
485
|
+
// Market info
|
|
486
|
+
title: String(p.title || ''),
|
|
487
|
+
slug: p.slug !== undefined ? String(p.slug) : undefined,
|
|
488
|
+
icon: p.icon !== undefined ? String(p.icon) : undefined,
|
|
489
|
+
eventSlug: p.eventSlug !== undefined ? String(p.eventSlug) : undefined,
|
|
490
|
+
outcome: String(p.outcome || ''),
|
|
491
|
+
// Only use outcomeIndex if provided by API - don't infer from outcome name
|
|
492
|
+
outcomeIndex: typeof p.outcomeIndex === 'number' ? p.outcomeIndex : 0,
|
|
493
|
+
oppositeOutcome: p.oppositeOutcome !== undefined ? String(p.oppositeOutcome) : undefined,
|
|
494
|
+
oppositeAsset: p.oppositeAsset !== undefined ? String(p.oppositeAsset) : undefined,
|
|
495
|
+
endDate: p.endDate !== undefined ? String(p.endDate) : undefined,
|
|
496
|
+
};
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
normalizeActivities(data) {
|
|
500
|
+
if (!Array.isArray(data))
|
|
501
|
+
return [];
|
|
502
|
+
return data.map((item) => {
|
|
503
|
+
const a = item;
|
|
504
|
+
return {
|
|
505
|
+
// Transaction type
|
|
506
|
+
type: String(a.type),
|
|
507
|
+
side: String(a.side),
|
|
508
|
+
// Trade data
|
|
509
|
+
size: Number(a.size),
|
|
510
|
+
price: Number(a.price),
|
|
511
|
+
usdcSize: a.usdcSize !== undefined
|
|
512
|
+
? Number(a.usdcSize)
|
|
513
|
+
: Number(a.size) * Number(a.price),
|
|
514
|
+
// Market identifiers
|
|
515
|
+
asset: String(a.asset || ''),
|
|
516
|
+
conditionId: String(a.conditionId || ''),
|
|
517
|
+
outcome: String(a.outcome || ''),
|
|
518
|
+
outcomeIndex: a.outcomeIndex !== undefined ? Number(a.outcomeIndex) : undefined,
|
|
519
|
+
// Transaction info
|
|
520
|
+
timestamp: this.normalizeTimestamp(a.timestamp),
|
|
521
|
+
transactionHash: String(a.transactionHash || ''),
|
|
522
|
+
// Market metadata
|
|
523
|
+
title: a.title !== undefined ? String(a.title) : undefined,
|
|
524
|
+
slug: a.slug !== undefined ? String(a.slug) : undefined,
|
|
525
|
+
// Trader info
|
|
526
|
+
name: a.name !== undefined ? String(a.name) : undefined,
|
|
527
|
+
};
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
normalizeTrades(data) {
|
|
531
|
+
if (!Array.isArray(data))
|
|
532
|
+
return [];
|
|
533
|
+
return data.map((item) => {
|
|
534
|
+
const t = item;
|
|
535
|
+
return {
|
|
536
|
+
// Identifiers
|
|
537
|
+
id: t.id !== undefined ? String(t.id) : undefined,
|
|
538
|
+
market: String(t.market || t.conditionId || ''),
|
|
539
|
+
asset: String(t.asset || ''),
|
|
540
|
+
// Trade data
|
|
541
|
+
side: String(t.side),
|
|
542
|
+
price: Number(t.price),
|
|
543
|
+
size: Number(t.size),
|
|
544
|
+
outcome: String(t.outcome || ''),
|
|
545
|
+
// Only use outcomeIndex if provided by API - don't infer from outcome name
|
|
546
|
+
outcomeIndex: typeof t.outcomeIndex === 'number' ? t.outcomeIndex : 0,
|
|
547
|
+
// Transaction info
|
|
548
|
+
timestamp: this.normalizeTimestamp(t.timestamp),
|
|
549
|
+
transactionHash: String(t.transactionHash || ''),
|
|
550
|
+
proxyWallet: t.proxyWallet !== undefined ? String(t.proxyWallet) : undefined,
|
|
551
|
+
// Market metadata
|
|
552
|
+
title: t.title !== undefined ? String(t.title) : undefined,
|
|
553
|
+
slug: t.slug !== undefined ? String(t.slug) : undefined,
|
|
554
|
+
icon: t.icon !== undefined ? String(t.icon) : undefined,
|
|
555
|
+
eventSlug: t.eventSlug !== undefined ? String(t.eventSlug) : undefined,
|
|
556
|
+
// Trader info
|
|
557
|
+
name: t.name !== undefined ? String(t.name) : undefined,
|
|
558
|
+
pseudonym: t.pseudonym !== undefined ? String(t.pseudonym) : undefined,
|
|
559
|
+
bio: t.bio !== undefined ? String(t.bio) : undefined,
|
|
560
|
+
profileImage: t.profileImage !== undefined ? String(t.profileImage) : undefined,
|
|
561
|
+
profileImageOptimized: t.profileImageOptimized !== undefined ? String(t.profileImageOptimized) : undefined,
|
|
562
|
+
};
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
normalizeTimestamp(ts) {
|
|
566
|
+
if (typeof ts === 'number') {
|
|
567
|
+
// If timestamp is in seconds, convert to milliseconds
|
|
568
|
+
return ts < 1e12 ? ts * 1000 : ts;
|
|
569
|
+
}
|
|
570
|
+
if (typeof ts === 'string') {
|
|
571
|
+
const num = parseInt(ts, 10);
|
|
572
|
+
return num < 1e12 ? num * 1000 : num;
|
|
573
|
+
}
|
|
574
|
+
return Date.now();
|
|
575
|
+
}
|
|
576
|
+
normalizeLeaderboardEntries(data) {
|
|
577
|
+
if (!Array.isArray(data))
|
|
578
|
+
return [];
|
|
579
|
+
return data.map((item) => {
|
|
580
|
+
const e = item;
|
|
581
|
+
return {
|
|
582
|
+
// Wallet identifier
|
|
583
|
+
address: String(e.proxyWallet || e.address || ''),
|
|
584
|
+
// Ranking data
|
|
585
|
+
rank: typeof e.rank === 'number' ? e.rank : parseInt(String(e.rank), 10) || 0,
|
|
586
|
+
pnl: Number(e.pnl) || 0,
|
|
587
|
+
volume: Number(e.vol || e.volume) || 0,
|
|
588
|
+
// User profile
|
|
589
|
+
userName: e.userName !== undefined ? String(e.userName) : undefined,
|
|
590
|
+
xUsername: e.xUsername !== undefined ? String(e.xUsername) : undefined,
|
|
591
|
+
verifiedBadge: Boolean(e.verifiedBadge),
|
|
592
|
+
profileImage: e.profileImage !== undefined ? String(e.profileImage) : undefined,
|
|
593
|
+
// Activity counts (optional - API often returns null)
|
|
594
|
+
positions: e.positions != null ? Number(e.positions) : undefined,
|
|
595
|
+
trades: e.trades != null ? Number(e.trades) : undefined,
|
|
596
|
+
};
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
normalizeHolders(data) {
|
|
600
|
+
if (!Array.isArray(data))
|
|
601
|
+
return [];
|
|
602
|
+
// The API returns grouped by token: [{ token, holders: [...] }, { token, holders: [...] }]
|
|
603
|
+
// We need to flatten this and normalize each holder
|
|
604
|
+
const result = [];
|
|
605
|
+
for (const item of data) {
|
|
606
|
+
const tokenGroup = item;
|
|
607
|
+
// Check if this is the grouped format (has 'holders' array)
|
|
608
|
+
if (Array.isArray(tokenGroup.holders)) {
|
|
609
|
+
for (const holder of tokenGroup.holders) {
|
|
610
|
+
result.push({
|
|
611
|
+
proxyWallet: String(holder.proxyWallet || holder.address || ''),
|
|
612
|
+
size: Number(holder.amount || holder.size) || 0,
|
|
613
|
+
// Map outcomeIndex to outcome name (0 = Yes/Up, 1 = No/Down)
|
|
614
|
+
outcome: holder.outcomeIndex === 0 ? 'Yes' : holder.outcomeIndex === 1 ? 'No' : String(holder.outcome || ''),
|
|
615
|
+
value: holder.value !== undefined ? Number(holder.value) : undefined,
|
|
616
|
+
userName: holder.name !== undefined ? String(holder.name) : (holder.userName !== undefined ? String(holder.userName) : undefined),
|
|
617
|
+
profileImage: holder.profileImage !== undefined ? String(holder.profileImage) : undefined,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
// Fallback: flat format (for backwards compatibility)
|
|
623
|
+
const h = tokenGroup;
|
|
624
|
+
result.push({
|
|
625
|
+
proxyWallet: String(h.proxyWallet || h.address || ''),
|
|
626
|
+
size: Number(h.amount || h.size) || 0,
|
|
627
|
+
outcome: h.outcomeIndex === 0 ? 'Yes' : h.outcomeIndex === 1 ? 'No' : String(h.outcome || ''),
|
|
628
|
+
value: h.value !== undefined ? Number(h.value) : undefined,
|
|
629
|
+
userName: h.name !== undefined ? String(h.name) : (h.userName !== undefined ? String(h.userName) : undefined),
|
|
630
|
+
profileImage: h.profileImage !== undefined ? String(h.profileImage) : undefined,
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return result;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
//# sourceMappingURL=data-api.js.map
|