@catalyst-team/poly-sdk 0.1.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 (244) hide show
  1. package/.env +0 -0
  2. package/README.md +803 -0
  3. package/dist/__tests__/clob-api.test.d.ts +5 -0
  4. package/dist/__tests__/clob-api.test.d.ts.map +1 -0
  5. package/dist/__tests__/clob-api.test.js +240 -0
  6. package/dist/__tests__/clob-api.test.js.map +1 -0
  7. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
  8. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
  9. package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
  10. package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
  11. package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
  12. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
  13. package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
  14. package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
  15. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
  16. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
  17. package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
  18. package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
  19. package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
  20. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
  21. package/dist/__tests__/integration/data-api.integration.test.js +161 -0
  22. package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
  23. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
  24. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
  25. package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
  26. package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
  27. package/dist/__tests__/test-utils.d.ts +92 -0
  28. package/dist/__tests__/test-utils.d.ts.map +1 -0
  29. package/dist/__tests__/test-utils.js +143 -0
  30. package/dist/__tests__/test-utils.js.map +1 -0
  31. package/dist/clients/bridge-client.d.ts +388 -0
  32. package/dist/clients/bridge-client.d.ts.map +1 -0
  33. package/dist/clients/bridge-client.js +587 -0
  34. package/dist/clients/bridge-client.js.map +1 -0
  35. package/dist/clients/clob-api.d.ts +318 -0
  36. package/dist/clients/clob-api.d.ts.map +1 -0
  37. package/dist/clients/clob-api.js +388 -0
  38. package/dist/clients/clob-api.js.map +1 -0
  39. package/dist/clients/ctf-client.d.ts +473 -0
  40. package/dist/clients/ctf-client.d.ts.map +1 -0
  41. package/dist/clients/ctf-client.js +915 -0
  42. package/dist/clients/ctf-client.js.map +1 -0
  43. package/dist/clients/data-api.d.ts +134 -0
  44. package/dist/clients/data-api.d.ts.map +1 -0
  45. package/dist/clients/data-api.js +265 -0
  46. package/dist/clients/data-api.js.map +1 -0
  47. package/dist/clients/gamma-api.d.ts +401 -0
  48. package/dist/clients/gamma-api.d.ts.map +1 -0
  49. package/dist/clients/gamma-api.js +352 -0
  50. package/dist/clients/gamma-api.js.map +1 -0
  51. package/dist/clients/trading-client.d.ts +252 -0
  52. package/dist/clients/trading-client.d.ts.map +1 -0
  53. package/dist/clients/trading-client.js +543 -0
  54. package/dist/clients/trading-client.js.map +1 -0
  55. package/dist/clients/websocket-manager.d.ts +100 -0
  56. package/dist/clients/websocket-manager.d.ts.map +1 -0
  57. package/dist/clients/websocket-manager.js +193 -0
  58. package/dist/clients/websocket-manager.js.map +1 -0
  59. package/dist/core/cache-adapter-bridge.d.ts +36 -0
  60. package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
  61. package/dist/core/cache-adapter-bridge.js +81 -0
  62. package/dist/core/cache-adapter-bridge.js.map +1 -0
  63. package/dist/core/cache.d.ts +40 -0
  64. package/dist/core/cache.d.ts.map +1 -0
  65. package/dist/core/cache.js +71 -0
  66. package/dist/core/cache.js.map +1 -0
  67. package/dist/core/errors.d.ts +38 -0
  68. package/dist/core/errors.d.ts.map +1 -0
  69. package/dist/core/errors.js +84 -0
  70. package/dist/core/errors.js.map +1 -0
  71. package/dist/core/rate-limiter.d.ts +31 -0
  72. package/dist/core/rate-limiter.d.ts.map +1 -0
  73. package/dist/core/rate-limiter.js +70 -0
  74. package/dist/core/rate-limiter.js.map +1 -0
  75. package/dist/core/types.d.ts +314 -0
  76. package/dist/core/types.d.ts.map +1 -0
  77. package/dist/core/types.js +19 -0
  78. package/dist/core/types.js.map +1 -0
  79. package/dist/core/unified-cache.d.ts +63 -0
  80. package/dist/core/unified-cache.d.ts.map +1 -0
  81. package/dist/core/unified-cache.js +114 -0
  82. package/dist/core/unified-cache.js.map +1 -0
  83. package/dist/index.d.ts +94 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +258 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/mcp/errors.d.ts +33 -0
  88. package/dist/mcp/errors.d.ts.map +1 -0
  89. package/dist/mcp/errors.js +86 -0
  90. package/dist/mcp/errors.js.map +1 -0
  91. package/dist/mcp/index.d.ts +62 -0
  92. package/dist/mcp/index.d.ts.map +1 -0
  93. package/dist/mcp/index.js +173 -0
  94. package/dist/mcp/index.js.map +1 -0
  95. package/dist/mcp/server.d.ts +17 -0
  96. package/dist/mcp/server.d.ts.map +1 -0
  97. package/dist/mcp/server.js +155 -0
  98. package/dist/mcp/server.js.map +1 -0
  99. package/dist/mcp/tools/guide.d.ts +12 -0
  100. package/dist/mcp/tools/guide.d.ts.map +1 -0
  101. package/dist/mcp/tools/guide.js +801 -0
  102. package/dist/mcp/tools/guide.js.map +1 -0
  103. package/dist/mcp/tools/index.d.ts +11 -0
  104. package/dist/mcp/tools/index.d.ts.map +1 -0
  105. package/dist/mcp/tools/index.js +27 -0
  106. package/dist/mcp/tools/index.js.map +1 -0
  107. package/dist/mcp/tools/market.d.ts +11 -0
  108. package/dist/mcp/tools/market.d.ts.map +1 -0
  109. package/dist/mcp/tools/market.js +314 -0
  110. package/dist/mcp/tools/market.js.map +1 -0
  111. package/dist/mcp/tools/order.d.ts +10 -0
  112. package/dist/mcp/tools/order.d.ts.map +1 -0
  113. package/dist/mcp/tools/order.js +258 -0
  114. package/dist/mcp/tools/order.js.map +1 -0
  115. package/dist/mcp/tools/trade.d.ts +38 -0
  116. package/dist/mcp/tools/trade.d.ts.map +1 -0
  117. package/dist/mcp/tools/trade.js +314 -0
  118. package/dist/mcp/tools/trade.js.map +1 -0
  119. package/dist/mcp/tools/trader.d.ts +11 -0
  120. package/dist/mcp/tools/trader.d.ts.map +1 -0
  121. package/dist/mcp/tools/trader.js +277 -0
  122. package/dist/mcp/tools/trader.js.map +1 -0
  123. package/dist/mcp/tools/wallet.d.ts +274 -0
  124. package/dist/mcp/tools/wallet.d.ts.map +1 -0
  125. package/dist/mcp/tools/wallet.js +579 -0
  126. package/dist/mcp/tools/wallet.js.map +1 -0
  127. package/dist/mcp/types.d.ts +413 -0
  128. package/dist/mcp/types.d.ts.map +1 -0
  129. package/dist/mcp/types.js +5 -0
  130. package/dist/mcp/types.js.map +1 -0
  131. package/dist/services/authorization-service.d.ts +97 -0
  132. package/dist/services/authorization-service.d.ts.map +1 -0
  133. package/dist/services/authorization-service.js +279 -0
  134. package/dist/services/authorization-service.js.map +1 -0
  135. package/dist/services/market-service.d.ts +108 -0
  136. package/dist/services/market-service.d.ts.map +1 -0
  137. package/dist/services/market-service.js +458 -0
  138. package/dist/services/market-service.js.map +1 -0
  139. package/dist/services/realtime-service.d.ts +82 -0
  140. package/dist/services/realtime-service.d.ts.map +1 -0
  141. package/dist/services/realtime-service.js +150 -0
  142. package/dist/services/realtime-service.js.map +1 -0
  143. package/dist/services/swap-service.d.ts +217 -0
  144. package/dist/services/swap-service.d.ts.map +1 -0
  145. package/dist/services/swap-service.js +695 -0
  146. package/dist/services/swap-service.js.map +1 -0
  147. package/dist/services/wallet-service.d.ts +94 -0
  148. package/dist/services/wallet-service.d.ts.map +1 -0
  149. package/dist/services/wallet-service.js +173 -0
  150. package/dist/services/wallet-service.js.map +1 -0
  151. package/dist/utils/price-utils.d.ts +153 -0
  152. package/dist/utils/price-utils.d.ts.map +1 -0
  153. package/dist/utils/price-utils.js +236 -0
  154. package/dist/utils/price-utils.js.map +1 -0
  155. package/docs/00-design.md +760 -0
  156. package/docs/01-mcp.md +2041 -0
  157. package/docs/02-API.md +1148 -0
  158. package/docs/e2e/01-trader-tools.md +159 -0
  159. package/docs/e2e/02-market-tools.md +180 -0
  160. package/docs/e2e/03-order-tools.md +166 -0
  161. package/docs/e2e/04-wallet-tools.md +224 -0
  162. package/docs/e2e/05-trading-tools.md +327 -0
  163. package/docs/e2e/06-integration-scenarios.md +481 -0
  164. package/docs/e2e/coordinator.md +376 -0
  165. package/examples/01-basic-usage.ts +68 -0
  166. package/examples/02-smart-money.ts +95 -0
  167. package/examples/03-market-analysis.ts +108 -0
  168. package/examples/04-kline-aggregation.ts +158 -0
  169. package/examples/05-follow-wallet-strategy.ts +156 -0
  170. package/examples/06-services-demo.ts +124 -0
  171. package/examples/07-realtime-websocket.ts +117 -0
  172. package/examples/08-trading-orders.ts +278 -0
  173. package/examples/09-rewards-tracking.ts +187 -0
  174. package/examples/10-ctf-operations.ts +336 -0
  175. package/examples/11-live-arbitrage-scan.ts +221 -0
  176. package/examples/12-trending-arb-monitor.ts +406 -0
  177. package/examples/README.md +179 -0
  178. package/package.json +62 -0
  179. package/scripts/README.md +163 -0
  180. package/scripts/approvals/approve-erc1155.ts +129 -0
  181. package/scripts/approvals/approve-neg-risk-erc1155.ts +149 -0
  182. package/scripts/approvals/approve-neg-risk.ts +102 -0
  183. package/scripts/approvals/check-all-allowances.ts +150 -0
  184. package/scripts/approvals/check-allowance.ts +129 -0
  185. package/scripts/approvals/check-ctf-approval.ts +158 -0
  186. package/scripts/datas/001-report.md +486 -0
  187. package/scripts/datas/clone-modal-screenshot.png +0 -0
  188. package/scripts/deposit/deposit-native-usdc.ts +179 -0
  189. package/scripts/deposit/deposit-usdc.ts +155 -0
  190. package/scripts/deposit/swap-usdc-to-usdce.ts +375 -0
  191. package/scripts/research/research-markets.ts +166 -0
  192. package/scripts/trading/check-orders.ts +50 -0
  193. package/scripts/trading/sell-nvidia-positions.ts +206 -0
  194. package/scripts/trading/test-order.ts +172 -0
  195. package/scripts/truth.md +440 -0
  196. package/scripts/verify/test-approve-trading.ts +98 -0
  197. package/scripts/verify/test-provider-fix.ts +43 -0
  198. package/scripts/verify/test-search-mcp.ts +113 -0
  199. package/scripts/verify/verify-all-apis.ts +160 -0
  200. package/scripts/wallet/check-wallet-balances.ts +75 -0
  201. package/scripts/wallet/test-wallet-operations.ts +191 -0
  202. package/scripts/wallet/verify-wallet-tools.ts +124 -0
  203. package/src/__tests__/clob-api.test.ts +301 -0
  204. package/src/__tests__/integration/bridge-client.integration.test.ts +314 -0
  205. package/src/__tests__/integration/clob-api.integration.test.ts +218 -0
  206. package/src/__tests__/integration/ctf-client.integration.test.ts +331 -0
  207. package/src/__tests__/integration/data-api.integration.test.ts +194 -0
  208. package/src/__tests__/integration/gamma-api.integration.test.ts +206 -0
  209. package/src/__tests__/test-utils.ts +170 -0
  210. package/src/clients/bridge-client.ts +841 -0
  211. package/src/clients/clob-api.ts +629 -0
  212. package/src/clients/ctf-client.ts +1216 -0
  213. package/src/clients/data-api.ts +469 -0
  214. package/src/clients/gamma-api.ts +597 -0
  215. package/src/clients/trading-client.ts +749 -0
  216. package/src/clients/websocket-manager.ts +267 -0
  217. package/src/core/cache-adapter-bridge.ts +94 -0
  218. package/src/core/cache.ts +85 -0
  219. package/src/core/errors.ts +117 -0
  220. package/src/core/rate-limiter.ts +74 -0
  221. package/src/core/types.ts +360 -0
  222. package/src/core/unified-cache.ts +153 -0
  223. package/src/index.ts +455 -0
  224. package/src/mcp/README.md +380 -0
  225. package/src/mcp/errors.ts +124 -0
  226. package/src/mcp/index.ts +309 -0
  227. package/src/mcp/server.ts +183 -0
  228. package/src/mcp/tools/guide.ts +821 -0
  229. package/src/mcp/tools/index.ts +73 -0
  230. package/src/mcp/tools/market.ts +363 -0
  231. package/src/mcp/tools/order.ts +326 -0
  232. package/src/mcp/tools/trade.ts +417 -0
  233. package/src/mcp/tools/trader.ts +322 -0
  234. package/src/mcp/tools/wallet.ts +683 -0
  235. package/src/mcp/types.ts +472 -0
  236. package/src/services/authorization-service.ts +357 -0
  237. package/src/services/market-service.ts +544 -0
  238. package/src/services/realtime-service.ts +196 -0
  239. package/src/services/swap-service.ts +896 -0
  240. package/src/services/wallet-service.ts +259 -0
  241. package/src/utils/price-utils.ts +307 -0
  242. package/tsconfig.json +8 -0
  243. package/vitest.config.ts +19 -0
  244. package/vitest.integration.config.ts +18 -0
package/README.md ADDED
@@ -0,0 +1,803 @@
1
+ # @prediction-router/poly-sdk
2
+
3
+ Unified SDK for Polymarket APIs - Data API, Gamma API, CLOB API, and WebSocket real-time updates.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @prediction-router/poly-sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { PolymarketSDK } from '@prediction-router/poly-sdk';
15
+
16
+ const sdk = new PolymarketSDK();
17
+
18
+ // Get market by slug or condition ID
19
+ const market = await sdk.getMarket('will-trump-win-2024');
20
+ console.log(market.tokens.yes.price); // 0.65
21
+
22
+ // Get processed orderbook with analytics
23
+ const orderbook = await sdk.getOrderbook(market.conditionId);
24
+ console.log(orderbook.summary.longArbProfit); // Arbitrage opportunity
25
+
26
+ // Detect arbitrage
27
+ const arb = await sdk.detectArbitrage(market.conditionId);
28
+ if (arb) {
29
+ console.log(`${arb.type} arb: ${arb.profit * 100}% profit`);
30
+ }
31
+ ```
32
+
33
+ ## Architecture
34
+
35
+ ```
36
+ ┌─────────────────────────────────────────────────────────────┐
37
+ │ PolymarketSDK │
38
+ ├─────────────────────────────────────────────────────────────┤
39
+ │ Layer 3: Services │
40
+ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
41
+ │ │WalletService│ │MarketService│ │ RealtimeService │ │
42
+ │ │ - profiles │ │ - K-Lines │ │ - subscriptions │ │
43
+ │ │ - sell det. │ │ - signals │ │ - price cache │ │
44
+ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │
45
+ ├─────────────────────────────────────────────────────────────┤
46
+ │ Layer 2: API Clients │
47
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │
48
+ │ │ DataAPI │ │ GammaAPI │ │ CLOB API │ │ WebSocket │ │
49
+ │ │positions │ │ markets │ │ orderbook│ │ real-time │ │
50
+ │ │ trades │ │ events │ │ trading │ │ prices │ │
51
+ │ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ │
52
+ ├─────────────────────────────────────────────────────────────┤
53
+ │ Layer 1: Infrastructure │
54
+ │ ┌────────────┐ ┌─────────┐ ┌──────────┐ ┌────────────┐ │
55
+ │ │RateLimiter │ │ Cache │ │ Errors │ │ Types │ │
56
+ │ │per-API │ │TTL-based│ │ retry │ │ unified │ │
57
+ │ └────────────┘ └─────────┘ └──────────┘ └────────────┘ │
58
+ └─────────────────────────────────────────────────────────────┘
59
+ ```
60
+
61
+ ## API Clients
62
+
63
+ ### DataApiClient - Positions, Trades, Leaderboard
64
+
65
+ ```typescript
66
+ // Get wallet positions
67
+ const positions = await sdk.dataApi.getPositions('0x...');
68
+
69
+ // Get recent trades
70
+ const trades = await sdk.dataApi.getTrades('0x...');
71
+
72
+ // Get leaderboard
73
+ const leaderboard = await sdk.dataApi.getLeaderboard();
74
+ ```
75
+
76
+ ### GammaApiClient - Markets, Events
77
+
78
+ ```typescript
79
+ // Search markets
80
+ const markets = await sdk.gammaApi.searchMarkets({ query: 'bitcoin' });
81
+
82
+ // Get trending markets
83
+ const trending = await sdk.gammaApi.getTrendingMarkets(10);
84
+
85
+ // Get events
86
+ const events = await sdk.gammaApi.getEvents({ limit: 20 });
87
+ ```
88
+
89
+ ### ClobApiClient - Orderbook, Trading
90
+
91
+ ```typescript
92
+ // Get orderbook
93
+ const book = await sdk.clobApi.getOrderbook(conditionId);
94
+
95
+ // Get processed orderbook with analytics
96
+ const processed = await sdk.clobApi.getProcessedOrderbook(conditionId);
97
+ console.log(processed.summary.longArbProfit);
98
+ console.log(processed.summary.shortArbProfit);
99
+ ```
100
+
101
+ ## Services
102
+
103
+ ### WalletService - Smart Money Analysis
104
+
105
+ ```typescript
106
+ // Get top traders
107
+ const traders = await sdk.wallets.getTopTraders(10);
108
+
109
+ // Get wallet profile with smart score
110
+ const profile = await sdk.wallets.getWalletProfile('0x...');
111
+ console.log(profile.smartScore); // 0-100
112
+
113
+ // Detect sell activity (for follow-wallet strategy)
114
+ const sellResult = await sdk.wallets.detectSellActivity(
115
+ '0x...',
116
+ conditionId,
117
+ Date.now() - 24 * 60 * 60 * 1000
118
+ );
119
+ if (sellResult.isSelling) {
120
+ console.log(`Sold ${sellResult.percentageSold}%`);
121
+ }
122
+
123
+ // Track group sell ratio
124
+ const groupSell = await sdk.wallets.trackGroupSellRatio(
125
+ ['0x...', '0x...'],
126
+ conditionId,
127
+ peakValue,
128
+ sinceTimestamp
129
+ );
130
+ ```
131
+
132
+ ### MarketService - K-Lines and Signals
133
+
134
+ ```typescript
135
+ // Get K-Line candles
136
+ const klines = await sdk.markets.getKLines(conditionId, '1h', { limit: 100 });
137
+
138
+ // Get dual K-Lines (YES + NO) with spread analysis
139
+ const dual = await sdk.markets.getDualKLines(conditionId, '1h');
140
+ console.log(dual.yes); // YES token candles
141
+ console.log(dual.no); // NO token candles
142
+
143
+ // Historical spread (from trade close prices) - for backtesting
144
+ console.log(dual.spreadAnalysis); // SpreadDataPoint[]
145
+ for (const point of dual.spreadAnalysis) {
146
+ console.log(`${point.timestamp}: priceSum=${point.priceSum}, spread=${point.priceSpread}`);
147
+ if (point.arbOpportunity) {
148
+ console.log(` Historical ${point.arbOpportunity} signal`);
149
+ }
150
+ }
151
+
152
+ // Real-time spread (from orderbook) - for live trading
153
+ if (dual.realtimeSpread) {
154
+ const rt = dual.realtimeSpread;
155
+ console.log(`Ask Sum: ${rt.askSum} (spread: ${rt.askSpread})`);
156
+ console.log(`Bid Sum: ${rt.bidSum} (spread: ${rt.bidSpread})`);
157
+ if (rt.arbOpportunity) {
158
+ console.log(`🎯 ${rt.arbOpportunity} ARB: ${rt.arbProfitPercent.toFixed(2)}% profit`);
159
+ }
160
+ }
161
+
162
+ // Quick real-time spread check (without K-lines)
163
+ const spread = await sdk.markets.getRealtimeSpread(conditionId);
164
+ if (spread.longArbProfit > 0.005) {
165
+ console.log(`Long arb: buy YES@${spread.yesAsk} + NO@${spread.noAsk}`);
166
+ }
167
+
168
+ // Detect market signals
169
+ const signals = await sdk.markets.detectMarketSignals(conditionId);
170
+ for (const signal of signals) {
171
+ console.log(`${signal.type}: ${signal.severity}`);
172
+ }
173
+
174
+ // Detect arbitrage
175
+ const arb = await sdk.markets.detectArbitrage(conditionId);
176
+ ```
177
+
178
+ #### Understanding Polymarket Orderbook & Arbitrage
179
+
180
+ ⚠️ **重要:Polymarket 订单簿的镜像特性**
181
+
182
+ Polymarket 的订单簿有一个关键特性容易被忽略:
183
+
184
+ ```
185
+ 买 YES @ P = 卖 NO @ (1-P)
186
+ ```
187
+
188
+ 这意味着**同一订单会在两个订单簿中出现**。例如,一个 "Sell NO @ 0.50" 订单
189
+ 会同时作为 "Buy YES @ 0.50" 出现在 YES 订单簿中。
190
+
191
+ **常见误解:**
192
+ ```typescript
193
+ // ❌ 错误: 简单相加会重复计算镜像订单
194
+ const askSum = YES.ask + NO.ask; // ≈ 1.998-1.999,而非 ≈ 1.0
195
+ const bidSum = YES.bid + NO.bid; // ≈ 0.001-0.002,而非 ≈ 1.0
196
+ ```
197
+
198
+ **正确做法:使用有效价格 (Effective Prices)**
199
+ ```typescript
200
+ import { getEffectivePrices, checkArbitrage } from '@prediction-router/poly-sdk';
201
+
202
+ // 计算考虑镜像后的最优价格
203
+ const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
204
+
205
+ // effective.effectiveBuyYes = min(YES.ask, 1 - NO.bid)
206
+ // effective.effectiveBuyNo = min(NO.ask, 1 - YES.bid)
207
+ // effective.effectiveSellYes = max(YES.bid, 1 - NO.ask)
208
+ // effective.effectiveSellNo = max(NO.bid, 1 - YES.ask)
209
+
210
+ // 使用有效价格检测套利
211
+ const arb = checkArbitrage(yesAsk, noAsk, yesBid, noBid);
212
+ if (arb) {
213
+ console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
214
+ console.log(arb.description);
215
+ }
216
+ ```
217
+
218
+ 详细文档见: [docs/01-polymarket-orderbook-arbitrage.md](docs/01-polymarket-orderbook-arbitrage.md)
219
+
220
+ #### Spread Analysis - Two Approaches
221
+
222
+ 我们提供两种 Spread 分析方式,核心区别如下:
223
+
224
+ ```
225
+ ┌─────────────────────────────────────────────────────────────────────────┐
226
+ │ spreadAnalysis (历史分析) │ realtimeSpread (实时分析) │
227
+ ├─────────────────────────────────────────────────────────────────────────┤
228
+ │ 数据源: 成交记录的收盘价 │ 数据源: 订单簿的最优 bid/ask │
229
+ │ YES_close + NO_close │ 使用有效价格 (考虑镜像订单) │
230
+ ├─────────────────────────────────────────────────────────────────────────┤
231
+ │ ✅ 可构建历史曲线 │ ❌ 无法构建历史曲线* │
232
+ │ ✅ Polymarket 保留成交历史 │ ❌ Polymarket 不保留盘口历史 │
233
+ │ ✅ 适合回测、模式识别 │ ✅ 适合实盘交易、套利执行 │
234
+ │ ⚠️ 套利信号仅供参考 │ ✅ 套利利润计算准确 │
235
+ └─────────────────────────────────────────────────────────────────────────┘
236
+
237
+ * 如需构建实时 Spread 的历史曲线,必须自行存储盘口快照数据
238
+ 参考: apps/api/src/services/spread-sampler.ts
239
+ ```
240
+
241
+ **核心区别:**
242
+
243
+ 1. **成交价 vs 盘口价**
244
+ - 成交价 (close): 过去某时刻实际成交的价格
245
+ - 盘口价 (bid/ask): 当前市场上的最优挂单价格
246
+ - 例: YES 最后成交 0.52,但当前 bid=0.50, ask=0.54
247
+
248
+ 2. **为什么套利计算需要有效价格?**
249
+ - 同一订单在 YES 和 NO 订单簿中都有镜像
250
+ - 简单的 `YES.ask + NO.ask` 会重复计算
251
+ - 必须用 `min(YES.ask, 1-NO.bid)` 等公式消除重复
252
+
253
+ 3. **为什么历史分析只能用成交价?**
254
+ - Polymarket CLOB API 不保存历史盘口数据
255
+ - 只有成交记录 (trades) 有历史
256
+ - 除非你自己运行 spread-sampler 持续采样盘口
257
+
258
+ ```typescript
259
+ // SpreadDataPoint (历史分析 - 可构建曲线)
260
+ interface SpreadDataPoint {
261
+ timestamp: number;
262
+ yesPrice: number; // YES 收盘价 (来自成交记录)
263
+ noPrice: number; // NO 收盘价
264
+ priceSum: number; // YES + NO
265
+ priceSpread: number; // priceSum - 1 (偏离均衡程度)
266
+ arbOpportunity: 'LONG' | 'SHORT' | ''; // 参考信号
267
+ }
268
+
269
+ // ProcessedOrderbook.summary (实时分析 - 使用有效价格)
270
+ interface OrderbookSummary {
271
+ // 有效价格 (考虑镜像订单)
272
+ effectivePrices: {
273
+ effectiveBuyYes: number; // min(YES.ask, 1 - NO.bid)
274
+ effectiveBuyNo: number; // min(NO.ask, 1 - YES.bid)
275
+ effectiveSellYes: number; // max(YES.bid, 1 - NO.ask)
276
+ effectiveSellNo: number; // max(NO.bid, 1 - YES.ask)
277
+ };
278
+ // 套利成本/收入
279
+ effectiveLongCost: number; // effectiveBuyYes + effectiveBuyNo
280
+ effectiveShortRevenue: number; // effectiveSellYes + effectiveSellNo
281
+ // 套利利润
282
+ longArbProfit: number; // 1 - effectiveLongCost (> 0 可套利)
283
+ shortArbProfit: number; // effectiveShortRevenue - 1 (> 0 可套利)
284
+ yesSpread: number; // YES.ask - YES.bid (市场效率指标)
285
+ }
286
+ ```
287
+
288
+ ### TradingClient - Order Execution
289
+
290
+ ```typescript
291
+ import { TradingClient, RateLimiter } from '@prediction-router/poly-sdk';
292
+
293
+ const rateLimiter = new RateLimiter();
294
+ const tradingClient = new TradingClient(rateLimiter, {
295
+ privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
296
+ });
297
+
298
+ await tradingClient.initialize();
299
+ console.log(`Wallet: ${tradingClient.getAddress()}`);
300
+
301
+ // GTC Limit Order (stays until filled or cancelled)
302
+ const order = await tradingClient.createOrder({
303
+ tokenId: yesTokenId,
304
+ side: 'BUY',
305
+ price: 0.45,
306
+ size: 10,
307
+ orderType: 'GTC',
308
+ });
309
+
310
+ // GTD Limit Order (expires at timestamp)
311
+ const gtdOrder = await tradingClient.createOrder({
312
+ tokenId: yesTokenId,
313
+ side: 'BUY',
314
+ price: 0.45,
315
+ size: 10,
316
+ orderType: 'GTD',
317
+ expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour
318
+ });
319
+
320
+ // FOK Market Order (fill entirely or cancel)
321
+ const marketOrder = await tradingClient.createMarketOrder({
322
+ tokenId: yesTokenId,
323
+ side: 'BUY',
324
+ amount: 10, // $10 USDC
325
+ orderType: 'FOK',
326
+ });
327
+
328
+ // FAK Market Order (partial fill ok)
329
+ const fakOrder = await tradingClient.createMarketOrder({
330
+ tokenId: yesTokenId,
331
+ side: 'SELL',
332
+ amount: 10, // 10 shares
333
+ orderType: 'FAK',
334
+ });
335
+
336
+ // Order management
337
+ const openOrders = await tradingClient.getOpenOrders();
338
+ await tradingClient.cancelOrder(orderId);
339
+ await tradingClient.cancelAllOrders();
340
+
341
+ // Get trade history
342
+ const trades = await tradingClient.getTrades();
343
+ ```
344
+
345
+ ### Rewards - Market Making Incentives
346
+
347
+ ```typescript
348
+ // Check if your orders are earning rewards
349
+ const isScoring = await tradingClient.isOrderScoring(orderId);
350
+
351
+ // Get markets with active reward programs
352
+ const rewards = await tradingClient.getCurrentRewards();
353
+ for (const reward of rewards) {
354
+ console.log(`${reward.question}`);
355
+ console.log(` Max Spread: ${reward.rewardsMaxSpread}`);
356
+ console.log(` Min Size: ${reward.rewardsMinSize}`);
357
+ }
358
+
359
+ // Get your daily earnings
360
+ const earnings = await tradingClient.getTotalEarningsForDay('2024-12-07');
361
+ console.log(`Total earned: $${earnings.totalEarnings}`);
362
+
363
+ // Check balance and allowance
364
+ const balance = await tradingClient.getBalanceAllowance('COLLATERAL');
365
+ console.log(`USDC Balance: ${balance.balance}`);
366
+ ```
367
+
368
+ ### RealtimeService - WebSocket Subscriptions
369
+
370
+ ⚠️ **重要:Orderbook 自动排序**
371
+
372
+ Polymarket CLOB API 返回的 orderbook 顺序与标准预期相反:
373
+ - **bids**: 升序排列 (最低价在前 = 最差价)
374
+ - **asks**: 降序排列 (最高价在前 = 最差价)
375
+
376
+ 我们的 SDK **自动规范化** orderbook 数据:
377
+ - **bids**: 降序排列 (最高价在前 = 最佳买价)
378
+ - **asks**: 升序排列 (最低价在前 = 最佳卖价)
379
+
380
+ 这意味着你可以安全地使用 `bids[0]` 和 `asks[0]` 获取最优价格:
381
+
382
+ ```typescript
383
+ const book = await sdk.clobApi.getOrderbook(conditionId);
384
+ const bestBid = book.bids[0]?.price; // ✅ 最高买价 (最佳 bid)
385
+ const bestAsk = book.asks[0]?.price; // ✅ 最低卖价 (最佳 ask)
386
+
387
+ // WebSocket 更新同样自动排序
388
+ wsManager.on('bookUpdate', (update) => {
389
+ const bestBid = update.bids[0]?.price; // ✅ 已排序
390
+ const bestAsk = update.asks[0]?.price; // ✅ 已排序
391
+ });
392
+ ```
393
+
394
+ ```typescript
395
+ import { WebSocketManager, RealtimeService } from '@prediction-router/poly-sdk';
396
+
397
+ const wsManager = new WebSocketManager();
398
+ const realtime = new RealtimeService(wsManager);
399
+
400
+ // Subscribe to market updates
401
+ const subscription = await realtime.subscribeMarket(yesTokenId, noTokenId, {
402
+ onPriceUpdate: (update) => {
403
+ console.log(`${update.assetId}: ${update.price}`);
404
+ },
405
+ onBookUpdate: (update) => {
406
+ console.log(`Best bid: ${update.bids[0]?.price}`);
407
+ },
408
+ onLastTrade: (trade) => {
409
+ console.log(`Trade: ${trade.side} ${trade.size} @ ${trade.price}`);
410
+ },
411
+ onPairUpdate: (update) => {
412
+ console.log(`YES + NO = ${update.spread}`);
413
+ if (update.spread < 0.99) console.log('ARB opportunity!');
414
+ },
415
+ });
416
+
417
+ // Get cached prices
418
+ const price = realtime.getPrice(yesTokenId);
419
+
420
+ // Cleanup
421
+ await subscription.unsubscribe();
422
+ ```
423
+
424
+ ### CTFClient - On-Chain Token Operations
425
+
426
+ The CTF (Conditional Token Framework) client enables on-chain operations for Polymarket's conditional tokens. This is essential for:
427
+ - **Arbitrage**: Merge tokens when buying YES + NO < $1
428
+ - **Market Making**: Split USDC to create inventory
429
+ - **Redemption**: Claim winnings after market resolution
430
+
431
+ ```typescript
432
+ import { CTFClient, CTF_CONTRACT, USDC_CONTRACT } from '@prediction-router/poly-sdk';
433
+
434
+ const ctf = new CTFClient({
435
+ privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
436
+ rpcUrl: 'https://polygon-rpc.com', // optional
437
+ });
438
+
439
+ console.log(`Wallet: ${ctf.getAddress()}`);
440
+ console.log(`USDC Balance: ${await ctf.getUsdcBalance()}`);
441
+ ```
442
+
443
+ #### Split: USDC → YES + NO Tokens
444
+
445
+ ```typescript
446
+ // Split 100 USDC into 100 YES + 100 NO tokens
447
+ const splitResult = await ctf.split(conditionId, '100');
448
+ console.log(`TX: ${splitResult.txHash}`);
449
+ console.log(`Created ${splitResult.yesTokens} YES + ${splitResult.noTokens} NO`);
450
+ ```
451
+
452
+ #### Merge: YES + NO → USDC
453
+
454
+ ```typescript
455
+ // Merge 100 YES + 100 NO → 100 USDC (for arbitrage)
456
+ const mergeResult = await ctf.merge(conditionId, '100');
457
+ console.log(`TX: ${mergeResult.txHash}`);
458
+ console.log(`Received ${mergeResult.usdcReceived} USDC`);
459
+ ```
460
+
461
+ #### Redeem: Winning Tokens → USDC
462
+
463
+ ⚠️ **重要:两种 Redeem 方法**
464
+
465
+ Polymarket 使用自定义的 token ID,与标准 CTF position ID 计算方式不同:
466
+
467
+ | 方法 | 适用场景 | Token ID 来源 |
468
+ |------|----------|---------------|
469
+ | `redeemByTokenIds()` | **Polymarket CLOB 市场** ✅ | CLOB API 返回的 tokenId |
470
+ | `redeem()` | 标准 Gnosis CTF 市场 | `keccak256(collectionId, conditionId, indexSet)` |
471
+
472
+ ```typescript
473
+ // ✅ 推荐:Polymarket 市场使用 redeemByTokenIds
474
+ const tokenIds = {
475
+ yesTokenId: '25064375110792967023484002819116042931016336431092144471807003884255851454283',
476
+ noTokenId: '98190367690492181203391990709979106077460946443309150166954079213761598385827',
477
+ };
478
+ const result = await ctf.redeemByTokenIds(conditionId, tokenIds);
479
+ console.log(`Redeemed ${result.tokensRedeemed} ${result.outcome} tokens`);
480
+ console.log(`Received ${result.usdcReceived} USDC`);
481
+
482
+ // ❌ 不要用于 Polymarket:redeem() 使用计算的 position ID
483
+ // const result = await ctf.redeem(conditionId); // 可能找不到余额
484
+ ```
485
+
486
+ **为什么 Polymarket token ID 不同?**
487
+ - Polymarket 在 CTF 之上包装了一层 ERC-1155 tokens
488
+ - CLOB API 返回的 `tokenId` (如 `"25064375..."`) 与标准 CTF 计算的 position ID 不同
489
+ - 必须使用 CLOB API 的 token ID 才能正确查询余额和 redeem
490
+
491
+ #### Position Queries
492
+
493
+ ```typescript
494
+ // Get token balances
495
+ const balances = await ctf.getPositionBalance(conditionId);
496
+ console.log(`YES: ${balances.yesBalance}, NO: ${balances.noBalance}`);
497
+
498
+ // Check if market is resolved
499
+ const resolution = await ctf.getMarketResolution(conditionId);
500
+ if (resolution.isResolved) {
501
+ console.log(`Winner: ${resolution.winningOutcome}`);
502
+ }
503
+
504
+ // Gas estimation
505
+ const splitGas = await ctf.estimateSplitGas(conditionId, '100');
506
+ const mergeGas = await ctf.estimateMergeGas(conditionId, '100');
507
+ ```
508
+
509
+ #### Arbitrage Flow
510
+
511
+ ⚠️ **注意:必须使用有效价格计算套利,不能简单相加 ask/bid**
512
+
513
+ 由于 Polymarket 的镜像订单特性(见上文),正确的套利计算方式如下:
514
+
515
+ ```
516
+ ┌─────────────────────────────────────────────────────────────┐
517
+ │ LONG ARB (effectiveLongCost < $1): │
518
+ │ 有效买入成本: │
519
+ │ effectiveBuyYes = min(YES.ask, 1 - NO.bid) │
520
+ │ effectiveBuyNo = min(NO.ask, 1 - YES.bid) │
521
+ │ 操作: │
522
+ │ 1. 用有效价格买入 YES + NO │
523
+ │ 2. CTF Merge → $1 USDC │
524
+ │ 3. Profit = 1 - effectiveLongCost │
525
+ ├─────────────────────────────────────────────────────────────┤
526
+ │ SHORT ARB (effectiveShortRevenue > $1): │
527
+ │ 有效卖出收入: │
528
+ │ effectiveSellYes = max(YES.bid, 1 - NO.ask) │
529
+ │ effectiveSellNo = max(NO.bid, 1 - YES.ask) │
530
+ │ 操作: │
531
+ │ 1. CTF Split $1 → 1 YES + 1 NO │
532
+ │ 2. 用有效价格卖出 YES + NO │
533
+ │ 3. Profit = effectiveShortRevenue - 1 │
534
+ └─────────────────────────────────────────────────────────────┘
535
+ ```
536
+
537
+ ```typescript
538
+ import { checkArbitrage, getEffectivePrices } from '@prediction-router/poly-sdk';
539
+
540
+ // checkArbitrage 内部使用有效价格计算
541
+ const arb = checkArbitrage(yesAsk, noAsk, yesBid, noBid);
542
+ if (arb?.type === 'long') {
543
+ console.log(arb.description); // "Buy YES @ 0.48 + NO @ 0.50, Merge for $1"
544
+ // Buy both tokens at effective prices, then merge
545
+ await tradingClient.createMarketOrder({ tokenId: yesTokenId, side: 'BUY', amount: 100 });
546
+ await tradingClient.createMarketOrder({ tokenId: noTokenId, side: 'BUY', amount: 100 });
547
+ await ctf.merge(conditionId, '100');
548
+ }
549
+ ```
550
+
551
+ ### ArbitrageService - Automated Arbitrage
552
+
553
+ The ArbitrageService combines TradingClient and CTFClient for automated arbitrage detection and execution.
554
+
555
+ **内部使用有效价格计算**,自动处理 Polymarket 的镜像订单特性。
556
+
557
+ 详细的套利计算原理见: [docs/01-polymarket-orderbook-arbitrage.md](docs/01-polymarket-orderbook-arbitrage.md)
558
+
559
+ ```typescript
560
+ import { ArbitrageService, TradingClient, CTFClient, RateLimiter } from '@prediction-router/poly-sdk';
561
+
562
+ const rateLimiter = new RateLimiter();
563
+ const tradingClient = new TradingClient(rateLimiter, { privateKey: '...' });
564
+ const ctfClient = new CTFClient({ privateKey: '...' });
565
+ const sdk = new PolymarketSDK();
566
+
567
+ const arbService = new ArbitrageService(tradingClient, ctfClient, sdk.clobApi, {
568
+ minProfitThreshold: 0.005, // 0.5% minimum (based on effective prices)
569
+ maxGasCost: 0.10, // $0.10 max gas
570
+ dryRun: true, // Simulation mode
571
+ });
572
+
573
+ // Detect opportunity (uses effective prices internally)
574
+ const opportunity = await arbService.detectOpportunity(conditionId);
575
+ if (opportunity) {
576
+ console.log(`${opportunity.type} arb: ${opportunity.profitPercent.toFixed(2)}%`);
577
+ console.log(`Effective cost: ${opportunity.effectiveCost}`);
578
+ }
579
+
580
+ // Scan multiple markets
581
+ const opportunities = await arbService.scanMarkets(conditionIds);
582
+
583
+ // Execute (or simulate)
584
+ const result = await arbService.execute({
585
+ conditionId,
586
+ amount: 100, // $100 USDC
587
+ });
588
+ console.log(`Profit: $${result.netProfit.toFixed(4)}`);
589
+ ```
590
+
591
+ ## Price Utilities
592
+
593
+ ```typescript
594
+ import {
595
+ roundPrice,
596
+ validatePrice,
597
+ calculateBuyAmount,
598
+ getEffectivePrices, // For Polymarket mirror orderbook
599
+ checkArbitrage,
600
+ formatUSDC,
601
+ calculatePnL,
602
+ type TickSize,
603
+ } from '@prediction-router/poly-sdk';
604
+
605
+ // Round price to tick size
606
+ const tickSize: TickSize = '0.01';
607
+ roundPrice(0.523, tickSize, 'floor'); // 0.52
608
+ roundPrice(0.523, tickSize, 'ceil'); // 0.53
609
+
610
+ // Validate price
611
+ const validation = validatePrice(0.525, tickSize);
612
+ if (!validation.valid) {
613
+ console.log(validation.error);
614
+ }
615
+
616
+ // Calculate order cost
617
+ const cost = calculateBuyAmount(0.52, 100); // $52
618
+ console.log(formatUSDC(cost)); // "$52.00"
619
+
620
+ // Get effective prices (considering Polymarket mirror orders)
621
+ const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
622
+ console.log(`Effective buy YES: ${effective.effectiveBuyYes}`); // min(YES.ask, 1 - NO.bid)
623
+ console.log(`Effective buy NO: ${effective.effectiveBuyNo}`); // min(NO.ask, 1 - YES.bid)
624
+
625
+ // Check for arbitrage (uses effective prices internally)
626
+ const arb = checkArbitrage(
627
+ yesAsk, noAsk, // Ask prices
628
+ yesBid, noBid // Bid prices
629
+ );
630
+ if (arb) {
631
+ console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
632
+ console.log(arb.description); // "Buy YES @ 0.48 + NO @ 0.50, Merge for $1"
633
+ }
634
+
635
+ // Calculate PnL
636
+ const pnl = calculatePnL(0.40, 0.55, 100, 'long');
637
+ console.log(`PnL: ${formatUSDC(pnl.pnl)} (${pnl.pnlPercent.toFixed(1)}%)`);
638
+ ```
639
+
640
+ ## K-Line Intervals
641
+
642
+ Supported intervals: `30s`, `1m`, `5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `1d`
643
+
644
+ ```typescript
645
+ import type { KLineInterval } from '@prediction-router/poly-sdk';
646
+
647
+ const interval: KLineInterval = '1h';
648
+ const candles = await sdk.markets.getKLines(conditionId, interval);
649
+ ```
650
+
651
+ ## Types
652
+
653
+ ```typescript
654
+ import type {
655
+ // Core
656
+ UnifiedMarket,
657
+ PriceUpdate,
658
+ BookUpdate,
659
+ ProcessedOrderbook,
660
+ ArbitrageOpportunity,
661
+ EffectivePrices, // Effective prices for Polymarket mirror orderbook
662
+
663
+ // K-Lines & Spread
664
+ KLineInterval,
665
+ KLineCandle,
666
+ DualKLineData,
667
+ SpreadDataPoint, // Historical spread (trade prices)
668
+
669
+ // Wallet
670
+ WalletProfile,
671
+ SellActivityResult,
672
+
673
+ // Trading
674
+ Side,
675
+ OrderType,
676
+ OrderParams,
677
+ MarketOrderParams,
678
+ Order,
679
+ OrderResult,
680
+ TradeInfo,
681
+
682
+ // Rewards
683
+ UserEarning,
684
+ MarketReward,
685
+
686
+ // CTF
687
+ CTFConfig,
688
+ SplitResult,
689
+ MergeResult,
690
+ RedeemResult,
691
+ PositionBalance,
692
+ MarketResolution,
693
+
694
+ // Arbitrage
695
+ ArbitrageConfig,
696
+ ArbitrageOpportunity,
697
+ ArbitrageExecutionParams,
698
+ ArbitrageResult,
699
+ ArbitrageTransaction,
700
+
701
+ // Price Utils
702
+ TickSize,
703
+
704
+ // API types
705
+ Position,
706
+ Trade,
707
+ LeaderboardEntry,
708
+ GammaMarket,
709
+ ClobMarket,
710
+ Orderbook,
711
+ } from '@prediction-router/poly-sdk';
712
+ ```
713
+
714
+ ## Error Handling
715
+
716
+ ```typescript
717
+ import { PolymarketError, ErrorCode, withRetry } from '@prediction-router/poly-sdk';
718
+
719
+ try {
720
+ const market = await sdk.getMarket('invalid-slug');
721
+ } catch (error) {
722
+ if (error instanceof PolymarketError) {
723
+ if (error.code === ErrorCode.MARKET_NOT_FOUND) {
724
+ console.log('Market not found');
725
+ } else if (error.code === ErrorCode.RATE_LIMITED) {
726
+ console.log('Rate limited, retry later');
727
+ }
728
+ }
729
+ }
730
+
731
+ // Auto-retry with exponential backoff
732
+ const result = await withRetry(() => sdk.getMarket(slug), {
733
+ maxRetries: 3,
734
+ baseDelay: 1000,
735
+ });
736
+ ```
737
+
738
+ ## Rate Limiting
739
+
740
+ Built-in rate limiting per API type:
741
+ - Data API: 10 req/sec
742
+ - Gamma API: 10 req/sec
743
+ - CLOB API: 5 req/sec
744
+
745
+ ```typescript
746
+ import { RateLimiter, ApiType } from '@prediction-router/poly-sdk';
747
+
748
+ // Custom rate limiter
749
+ const limiter = new RateLimiter({
750
+ [ApiType.DATA]: { maxConcurrent: 5, minTime: 200 },
751
+ [ApiType.GAMMA]: { maxConcurrent: 5, minTime: 200 },
752
+ [ApiType.CLOB]: { maxConcurrent: 2, minTime: 500 },
753
+ });
754
+ ```
755
+
756
+ ## Caching
757
+
758
+ Built-in TTL-based caching:
759
+
760
+ ```typescript
761
+ // Clear all cache
762
+ sdk.clearCache();
763
+
764
+ // Invalidate specific market
765
+ sdk.invalidateMarketCache(conditionId);
766
+ ```
767
+
768
+ ## Examples
769
+
770
+ | Example | Description | Source |
771
+ |---------|-------------|--------|
772
+ | [Basic Usage](examples/01-basic-usage.ts) | Get markets, orderbooks, detect arbitrage | `pnpm example:basic` |
773
+ | [Smart Money](examples/02-smart-money.ts) | Top traders, wallet profiles, smart scores | `pnpm example:smart-money` |
774
+ | [Market Analysis](examples/03-market-analysis.ts) | Market signals, volume analysis | `pnpm example:market-analysis` |
775
+ | [K-Line Aggregation](examples/04-kline-aggregation.ts) | Build OHLCV candles from trades | `pnpm example:kline` |
776
+ | [Follow Wallet](examples/05-follow-wallet-strategy.ts) | Track smart money positions, detect exits | `pnpm example:follow-wallet` |
777
+ | [Services Demo](examples/06-services-demo.ts) | All SDK services in action | `pnpm example:services` |
778
+ | [Realtime WebSocket](examples/07-realtime-websocket.ts) | Live price feeds, orderbook updates | `pnpm example:realtime` |
779
+ | [Trading Orders](examples/08-trading-orders.ts) | GTC, GTD, FOK, FAK order types | `pnpm example:trading` |
780
+ | [Rewards Tracking](examples/09-rewards-tracking.ts) | Market maker incentives, earnings | `pnpm example:rewards` |
781
+ | [CTF Operations](examples/10-ctf-operations.ts) | Split, merge, redeem tokens | `pnpm example:ctf` |
782
+ | [Arbitrage Service](examples/11-arbitrage-service.ts) | Detect and execute arbitrage | `pnpm example:arbitrage` |
783
+ | [Live Arbitrage Scan](examples/12-live-arbitrage-scan.ts) | Scan real markets for opportunities | `pnpm example:live-arb` |
784
+ | [Trending Arb Monitor](examples/13-trending-arb-monitor.ts) | Real-time trending markets monitor | `pnpm example:trending-arb` |
785
+
786
+ Run any example:
787
+
788
+ ```bash
789
+ pnpm example:basic
790
+ pnpm example:smart-money
791
+ pnpm example:trading
792
+ # etc.
793
+ ```
794
+
795
+ ## Dependencies
796
+
797
+ - `@nevuamarkets/poly-websockets` - WebSocket client
798
+ - `bottleneck` - Rate limiting
799
+ - `ethers` - Blockchain interactions (for CTFClient)
800
+
801
+ ## License
802
+
803
+ Private