@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.
Files changed (277) hide show
  1. package/README.md +665 -807
  2. package/README.zh-CN.md +645 -342
  3. package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
  4. package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
  5. package/dist/__tests__/integration/arbitrage-service.integration.test.js +267 -0
  6. package/dist/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
  7. package/dist/__tests__/integration/data-api.integration.test.js +6 -3
  8. package/dist/__tests__/integration/data-api.integration.test.js.map +1 -1
  9. package/dist/__tests__/integration/market-service.integration.test.d.ts +10 -0
  10. package/dist/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
  11. package/dist/__tests__/integration/market-service.integration.test.js +173 -0
  12. package/dist/__tests__/integration/market-service.integration.test.js.map +1 -0
  13. package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
  14. package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
  15. package/dist/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
  16. package/dist/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
  17. package/dist/__tests__/integration/trading-service.integration.test.d.ts +10 -0
  18. package/dist/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
  19. package/dist/__tests__/integration/trading-service.integration.test.js +58 -0
  20. package/dist/__tests__/integration/trading-service.integration.test.js.map +1 -0
  21. package/dist/clients/clob-api.d.ts +73 -0
  22. package/dist/clients/clob-api.d.ts.map +1 -1
  23. package/dist/clients/clob-api.js +60 -0
  24. package/dist/clients/clob-api.js.map +1 -1
  25. package/dist/clients/ctf-client.d.ts +6 -4
  26. package/dist/clients/ctf-client.d.ts.map +1 -1
  27. package/dist/clients/ctf-client.js.map +1 -1
  28. package/dist/clients/data-api.d.ts +333 -15
  29. package/dist/clients/data-api.d.ts.map +1 -1
  30. package/dist/clients/data-api.js +398 -26
  31. package/dist/clients/data-api.js.map +1 -1
  32. package/dist/clients/gamma-api.d.ts +5 -0
  33. package/dist/clients/gamma-api.d.ts.map +1 -1
  34. package/dist/clients/gamma-api.js +2 -0
  35. package/dist/clients/gamma-api.js.map +1 -1
  36. package/dist/clients/subgraph.d.ts +196 -0
  37. package/dist/clients/subgraph.d.ts.map +1 -0
  38. package/dist/clients/subgraph.js +332 -0
  39. package/dist/clients/subgraph.js.map +1 -0
  40. package/dist/clients/websocket-manager.d.ts +3 -0
  41. package/dist/clients/websocket-manager.d.ts.map +1 -1
  42. package/dist/clients/websocket-manager.js +10 -3
  43. package/dist/clients/websocket-manager.js.map +1 -1
  44. package/dist/core/cache.d.ts +3 -0
  45. package/dist/core/cache.d.ts.map +1 -1
  46. package/dist/core/cache.js +5 -0
  47. package/dist/core/cache.js.map +1 -1
  48. package/dist/core/errors.d.ts +2 -1
  49. package/dist/core/errors.d.ts.map +1 -1
  50. package/dist/core/errors.js +2 -0
  51. package/dist/core/errors.js.map +1 -1
  52. package/dist/core/rate-limiter.d.ts +3 -1
  53. package/dist/core/rate-limiter.d.ts.map +1 -1
  54. package/dist/core/rate-limiter.js +12 -0
  55. package/dist/core/rate-limiter.js.map +1 -1
  56. package/dist/core/types.d.ts +205 -13
  57. package/dist/core/types.d.ts.map +1 -1
  58. package/dist/core/types.js +30 -0
  59. package/dist/core/types.js.map +1 -1
  60. package/dist/core/types.test.d.ts +7 -0
  61. package/dist/core/types.test.d.ts.map +1 -0
  62. package/dist/core/types.test.js +122 -0
  63. package/dist/core/types.test.js.map +1 -0
  64. package/dist/index.d.ts +84 -18
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +139 -132
  67. package/dist/index.js.map +1 -1
  68. package/dist/scripts/dip-arb/auto-trade.d.ts +20 -0
  69. package/dist/scripts/dip-arb/auto-trade.d.ts.map +1 -0
  70. package/dist/scripts/dip-arb/auto-trade.js +373 -0
  71. package/dist/scripts/dip-arb/auto-trade.js.map +1 -0
  72. package/dist/scripts/dip-arb/example-basic.d.ts +30 -0
  73. package/dist/scripts/dip-arb/example-basic.d.ts.map +1 -0
  74. package/dist/scripts/dip-arb/example-basic.js +222 -0
  75. package/dist/scripts/dip-arb/example-basic.js.map +1 -0
  76. package/dist/scripts/dip-arb/redeem-positions.d.ts +11 -0
  77. package/dist/scripts/dip-arb/redeem-positions.d.ts.map +1 -0
  78. package/dist/scripts/dip-arb/redeem-positions.js +201 -0
  79. package/dist/scripts/dip-arb/redeem-positions.js.map +1 -0
  80. package/dist/scripts/dip-arb/scan-markets.d.ts +6 -0
  81. package/dist/scripts/dip-arb/scan-markets.d.ts.map +1 -0
  82. package/dist/scripts/dip-arb/scan-markets.js +73 -0
  83. package/dist/scripts/dip-arb/scan-markets.js.map +1 -0
  84. package/dist/services/arbitrage-service.d.ts +3 -2
  85. package/dist/services/arbitrage-service.d.ts.map +1 -1
  86. package/dist/services/arbitrage-service.js +71 -43
  87. package/dist/services/arbitrage-service.js.map +1 -1
  88. package/dist/services/binance-service.d.ts +154 -0
  89. package/dist/services/binance-service.d.ts.map +1 -0
  90. package/dist/services/binance-service.js +266 -0
  91. package/dist/services/binance-service.js.map +1 -0
  92. package/dist/services/dip-arb-service.d.ts +209 -0
  93. package/dist/services/dip-arb-service.d.ts.map +1 -0
  94. package/dist/services/dip-arb-service.js +1602 -0
  95. package/dist/services/dip-arb-service.js.map +1 -0
  96. package/dist/services/dip-arb-types.d.ts +553 -0
  97. package/dist/services/dip-arb-types.d.ts.map +1 -0
  98. package/dist/services/dip-arb-types.js +164 -0
  99. package/dist/services/dip-arb-types.js.map +1 -0
  100. package/dist/services/market-service.d.ts +267 -8
  101. package/dist/services/market-service.d.ts.map +1 -1
  102. package/dist/services/market-service.js +771 -42
  103. package/dist/services/market-service.js.map +1 -1
  104. package/dist/services/onchain-service.d.ts +309 -0
  105. package/dist/services/onchain-service.d.ts.map +1 -0
  106. package/dist/services/onchain-service.js +417 -0
  107. package/dist/services/onchain-service.js.map +1 -0
  108. package/dist/services/realtime-service-v2.d.ts +362 -0
  109. package/dist/services/realtime-service-v2.d.ts.map +1 -0
  110. package/dist/services/realtime-service-v2.js +858 -0
  111. package/dist/services/realtime-service-v2.js.map +1 -0
  112. package/dist/services/realtime-service.d.ts +17 -17
  113. package/dist/services/realtime-service.d.ts.map +1 -1
  114. package/dist/services/realtime-service.js +91 -59
  115. package/dist/services/realtime-service.js.map +1 -1
  116. package/dist/services/smart-money-service.d.ts +352 -0
  117. package/dist/services/smart-money-service.d.ts.map +1 -0
  118. package/dist/services/smart-money-service.js +582 -0
  119. package/dist/services/smart-money-service.js.map +1 -0
  120. package/dist/services/trading-service.d.ts +177 -0
  121. package/dist/services/trading-service.d.ts.map +1 -0
  122. package/dist/services/trading-service.js +422 -0
  123. package/dist/services/trading-service.js.map +1 -0
  124. package/dist/services/wallet-service.d.ts +225 -3
  125. package/dist/services/wallet-service.d.ts.map +1 -1
  126. package/dist/services/wallet-service.js +511 -3
  127. package/dist/services/wallet-service.js.map +1 -1
  128. package/dist/src/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
  129. package/dist/src/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
  130. package/dist/src/__tests__/integration/arbitrage-service.integration.test.js +267 -0
  131. package/dist/src/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
  132. package/dist/src/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
  133. package/dist/src/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
  134. package/dist/src/__tests__/integration/bridge-client.integration.test.js +260 -0
  135. package/dist/src/__tests__/integration/bridge-client.integration.test.js.map +1 -0
  136. package/dist/src/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
  137. package/dist/src/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
  138. package/dist/src/__tests__/integration/ctf-client.integration.test.js +234 -0
  139. package/dist/src/__tests__/integration/ctf-client.integration.test.js.map +1 -0
  140. package/dist/src/__tests__/integration/data-api.integration.test.d.ts +9 -0
  141. package/dist/src/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
  142. package/dist/src/__tests__/integration/data-api.integration.test.js +164 -0
  143. package/dist/src/__tests__/integration/data-api.integration.test.js.map +1 -0
  144. package/dist/src/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
  145. package/dist/src/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
  146. package/dist/src/__tests__/integration/gamma-api.integration.test.js +170 -0
  147. package/dist/src/__tests__/integration/gamma-api.integration.test.js.map +1 -0
  148. package/dist/src/__tests__/integration/market-service.integration.test.d.ts +10 -0
  149. package/dist/src/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
  150. package/dist/src/__tests__/integration/market-service.integration.test.js +180 -0
  151. package/dist/src/__tests__/integration/market-service.integration.test.js.map +1 -0
  152. package/dist/src/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
  153. package/dist/src/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
  154. package/dist/src/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
  155. package/dist/src/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
  156. package/dist/src/__tests__/integration/trading-service.integration.test.d.ts +10 -0
  157. package/dist/src/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
  158. package/dist/src/__tests__/integration/trading-service.integration.test.js +58 -0
  159. package/dist/src/__tests__/integration/trading-service.integration.test.js.map +1 -0
  160. package/dist/src/__tests__/test-utils.d.ts +92 -0
  161. package/dist/src/__tests__/test-utils.d.ts.map +1 -0
  162. package/dist/src/__tests__/test-utils.js +143 -0
  163. package/dist/src/__tests__/test-utils.js.map +1 -0
  164. package/dist/src/clients/bridge-client.d.ts +388 -0
  165. package/dist/src/clients/bridge-client.d.ts.map +1 -0
  166. package/dist/src/clients/bridge-client.js +587 -0
  167. package/dist/src/clients/bridge-client.js.map +1 -0
  168. package/dist/src/clients/ctf-client.d.ts +475 -0
  169. package/dist/src/clients/ctf-client.d.ts.map +1 -0
  170. package/dist/src/clients/ctf-client.js +915 -0
  171. package/dist/src/clients/ctf-client.js.map +1 -0
  172. package/dist/src/clients/data-api.d.ts +452 -0
  173. package/dist/src/clients/data-api.d.ts.map +1 -0
  174. package/dist/src/clients/data-api.js +637 -0
  175. package/dist/src/clients/data-api.js.map +1 -0
  176. package/dist/src/clients/gamma-api.d.ts +421 -0
  177. package/dist/src/clients/gamma-api.d.ts.map +1 -0
  178. package/dist/src/clients/gamma-api.js +359 -0
  179. package/dist/src/clients/gamma-api.js.map +1 -0
  180. package/dist/src/clients/subgraph.d.ts +196 -0
  181. package/dist/src/clients/subgraph.d.ts.map +1 -0
  182. package/dist/src/clients/subgraph.js +332 -0
  183. package/dist/src/clients/subgraph.js.map +1 -0
  184. package/dist/src/core/cache-adapter-bridge.d.ts +36 -0
  185. package/dist/src/core/cache-adapter-bridge.d.ts.map +1 -0
  186. package/dist/src/core/cache-adapter-bridge.js +81 -0
  187. package/dist/src/core/cache-adapter-bridge.js.map +1 -0
  188. package/dist/src/core/cache.d.ts +43 -0
  189. package/dist/src/core/cache.d.ts.map +1 -0
  190. package/dist/src/core/cache.js +76 -0
  191. package/dist/src/core/cache.js.map +1 -0
  192. package/dist/src/core/errors.d.ts +39 -0
  193. package/dist/src/core/errors.d.ts.map +1 -0
  194. package/dist/src/core/errors.js +86 -0
  195. package/dist/src/core/errors.js.map +1 -0
  196. package/dist/src/core/rate-limiter.d.ts +33 -0
  197. package/dist/src/core/rate-limiter.d.ts.map +1 -0
  198. package/dist/src/core/rate-limiter.js +82 -0
  199. package/dist/src/core/rate-limiter.js.map +1 -0
  200. package/dist/src/core/types.d.ts +506 -0
  201. package/dist/src/core/types.d.ts.map +1 -0
  202. package/dist/src/core/types.js +49 -0
  203. package/dist/src/core/types.js.map +1 -0
  204. package/dist/src/core/types.test.d.ts +7 -0
  205. package/dist/src/core/types.test.d.ts.map +1 -0
  206. package/dist/src/core/types.test.js +122 -0
  207. package/dist/src/core/types.test.js.map +1 -0
  208. package/dist/src/core/unified-cache.d.ts +63 -0
  209. package/dist/src/core/unified-cache.d.ts.map +1 -0
  210. package/dist/src/core/unified-cache.js +114 -0
  211. package/dist/src/core/unified-cache.js.map +1 -0
  212. package/dist/src/index.d.ts +159 -0
  213. package/dist/src/index.d.ts.map +1 -0
  214. package/dist/src/index.js +262 -0
  215. package/dist/src/index.js.map +1 -0
  216. package/dist/src/services/arbitrage-service.d.ts +409 -0
  217. package/dist/src/services/arbitrage-service.d.ts.map +1 -0
  218. package/dist/src/services/arbitrage-service.js +1450 -0
  219. package/dist/src/services/arbitrage-service.js.map +1 -0
  220. package/dist/src/services/authorization-service.d.ts +97 -0
  221. package/dist/src/services/authorization-service.d.ts.map +1 -0
  222. package/dist/src/services/authorization-service.js +279 -0
  223. package/dist/src/services/authorization-service.js.map +1 -0
  224. package/dist/src/services/binance-service.d.ts +154 -0
  225. package/dist/src/services/binance-service.d.ts.map +1 -0
  226. package/dist/src/services/binance-service.js +266 -0
  227. package/dist/src/services/binance-service.js.map +1 -0
  228. package/dist/src/services/dip-arb-service.d.ts +245 -0
  229. package/dist/src/services/dip-arb-service.d.ts.map +1 -0
  230. package/dist/src/services/dip-arb-service.js +1865 -0
  231. package/dist/src/services/dip-arb-service.js.map +1 -0
  232. package/dist/src/services/dip-arb-types.d.ts +553 -0
  233. package/dist/src/services/dip-arb-types.d.ts.map +1 -0
  234. package/dist/src/services/dip-arb-types.js +164 -0
  235. package/dist/src/services/dip-arb-types.js.map +1 -0
  236. package/dist/src/services/market-service.d.ts +370 -0
  237. package/dist/src/services/market-service.d.ts.map +1 -0
  238. package/dist/src/services/market-service.js +1200 -0
  239. package/dist/src/services/market-service.js.map +1 -0
  240. package/dist/src/services/onchain-service.d.ts +309 -0
  241. package/dist/src/services/onchain-service.d.ts.map +1 -0
  242. package/dist/src/services/onchain-service.js +417 -0
  243. package/dist/src/services/onchain-service.js.map +1 -0
  244. package/dist/src/services/realtime-service-v2.d.ts +367 -0
  245. package/dist/src/services/realtime-service-v2.d.ts.map +1 -0
  246. package/dist/src/services/realtime-service-v2.js +876 -0
  247. package/dist/src/services/realtime-service-v2.js.map +1 -0
  248. package/dist/src/services/smart-money-service.d.ts +352 -0
  249. package/dist/src/services/smart-money-service.d.ts.map +1 -0
  250. package/dist/src/services/smart-money-service.js +582 -0
  251. package/dist/src/services/smart-money-service.js.map +1 -0
  252. package/dist/src/services/swap-service.d.ts +217 -0
  253. package/dist/src/services/swap-service.d.ts.map +1 -0
  254. package/dist/src/services/swap-service.js +695 -0
  255. package/dist/src/services/swap-service.js.map +1 -0
  256. package/dist/src/services/trading-service.d.ts +177 -0
  257. package/dist/src/services/trading-service.d.ts.map +1 -0
  258. package/dist/src/services/trading-service.js +422 -0
  259. package/dist/src/services/trading-service.js.map +1 -0
  260. package/dist/src/services/wallet-service.d.ts +316 -0
  261. package/dist/src/services/wallet-service.d.ts.map +1 -0
  262. package/dist/src/services/wallet-service.js +681 -0
  263. package/dist/src/services/wallet-service.js.map +1 -0
  264. package/dist/src/utils/price-utils.d.ts +153 -0
  265. package/dist/src/utils/price-utils.d.ts.map +1 -0
  266. package/dist/src/utils/price-utils.js +236 -0
  267. package/dist/src/utils/price-utils.js.map +1 -0
  268. package/dist/src/utils/price-utils.test.d.ts +5 -0
  269. package/dist/src/utils/price-utils.test.d.ts.map +1 -0
  270. package/dist/src/utils/price-utils.test.js +192 -0
  271. package/dist/src/utils/price-utils.test.js.map +1 -0
  272. package/dist/utils/price-utils.test.d.ts +5 -0
  273. package/dist/utils/price-utils.test.d.ts.map +1 -0
  274. package/dist/utils/price-utils.test.js +192 -0
  275. package/dist/utils/price-utils.test.js.map +1 -0
  276. package/package.json +6 -5
  277. 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