@catalyst-team/poly-sdk 0.2.0 → 0.3.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 (242) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +548 -813
  3. package/README.zh-CN.md +805 -0
  4. package/dist/__tests__/clob-api.test.d.ts +5 -0
  5. package/dist/__tests__/clob-api.test.d.ts.map +1 -0
  6. package/dist/__tests__/clob-api.test.js +240 -0
  7. package/dist/__tests__/clob-api.test.js.map +1 -0
  8. package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts +12 -0
  9. package/dist/__tests__/integration/arbitrage-service.integration.test.d.ts.map +1 -0
  10. package/dist/__tests__/integration/arbitrage-service.integration.test.js +267 -0
  11. package/dist/__tests__/integration/arbitrage-service.integration.test.js.map +1 -0
  12. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
  13. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
  14. package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
  15. package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
  16. package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
  17. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
  18. package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
  19. package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
  20. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
  21. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
  22. package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
  23. package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
  24. package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
  25. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
  26. package/dist/__tests__/integration/data-api.integration.test.js +164 -0
  27. package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
  28. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
  29. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
  30. package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
  31. package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
  32. package/dist/__tests__/integration/market-service.integration.test.d.ts +10 -0
  33. package/dist/__tests__/integration/market-service.integration.test.d.ts.map +1 -0
  34. package/dist/__tests__/integration/market-service.integration.test.js +173 -0
  35. package/dist/__tests__/integration/market-service.integration.test.js.map +1 -0
  36. package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts +10 -0
  37. package/dist/__tests__/integration/realtime-service-v2.integration.test.d.ts.map +1 -0
  38. package/dist/__tests__/integration/realtime-service-v2.integration.test.js +307 -0
  39. package/dist/__tests__/integration/realtime-service-v2.integration.test.js.map +1 -0
  40. package/dist/__tests__/integration/trading-service.integration.test.d.ts +10 -0
  41. package/dist/__tests__/integration/trading-service.integration.test.d.ts.map +1 -0
  42. package/dist/__tests__/integration/trading-service.integration.test.js +58 -0
  43. package/dist/__tests__/integration/trading-service.integration.test.js.map +1 -0
  44. package/dist/__tests__/test-utils.d.ts +92 -0
  45. package/dist/__tests__/test-utils.d.ts.map +1 -0
  46. package/dist/__tests__/test-utils.js +143 -0
  47. package/dist/__tests__/test-utils.js.map +1 -0
  48. package/dist/clients/bridge-client.d.ts +388 -0
  49. package/dist/clients/bridge-client.d.ts.map +1 -0
  50. package/dist/clients/bridge-client.js +587 -0
  51. package/dist/clients/bridge-client.js.map +1 -0
  52. package/dist/clients/clob-api.d.ts +391 -0
  53. package/dist/clients/clob-api.d.ts.map +1 -0
  54. package/dist/clients/clob-api.js +448 -0
  55. package/dist/clients/clob-api.js.map +1 -0
  56. package/dist/clients/ctf-client.d.ts +473 -0
  57. package/dist/clients/ctf-client.d.ts.map +1 -0
  58. package/dist/clients/ctf-client.js +915 -0
  59. package/dist/clients/ctf-client.js.map +1 -0
  60. package/dist/clients/data-api.d.ts +439 -0
  61. package/dist/clients/data-api.d.ts.map +1 -0
  62. package/dist/clients/data-api.js +592 -0
  63. package/dist/clients/data-api.js.map +1 -0
  64. package/dist/clients/gamma-api.d.ts +401 -0
  65. package/dist/clients/gamma-api.d.ts.map +1 -0
  66. package/dist/clients/gamma-api.js +352 -0
  67. package/dist/clients/gamma-api.js.map +1 -0
  68. package/dist/clients/subgraph.d.ts +196 -0
  69. package/dist/clients/subgraph.d.ts.map +1 -0
  70. package/dist/clients/subgraph.js +332 -0
  71. package/dist/clients/subgraph.js.map +1 -0
  72. package/dist/clients/trading-client.d.ts +252 -0
  73. package/dist/clients/trading-client.d.ts.map +1 -0
  74. package/dist/clients/trading-client.js +543 -0
  75. package/dist/clients/trading-client.js.map +1 -0
  76. package/dist/clients/websocket-manager.d.ts +103 -0
  77. package/dist/clients/websocket-manager.d.ts.map +1 -0
  78. package/dist/clients/websocket-manager.js +200 -0
  79. package/dist/clients/websocket-manager.js.map +1 -0
  80. package/dist/core/cache-adapter-bridge.d.ts +36 -0
  81. package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
  82. package/dist/core/cache-adapter-bridge.js +81 -0
  83. package/dist/core/cache-adapter-bridge.js.map +1 -0
  84. package/dist/core/cache.d.ts +41 -0
  85. package/dist/core/cache.d.ts.map +1 -0
  86. package/dist/core/cache.js +72 -0
  87. package/dist/core/cache.js.map +1 -0
  88. package/dist/core/errors.d.ts +39 -0
  89. package/dist/core/errors.d.ts.map +1 -0
  90. package/dist/core/errors.js +86 -0
  91. package/dist/core/errors.js.map +1 -0
  92. package/dist/core/rate-limiter.d.ts +32 -0
  93. package/dist/core/rate-limiter.d.ts.map +1 -0
  94. package/dist/core/rate-limiter.js +75 -0
  95. package/dist/core/rate-limiter.js.map +1 -0
  96. package/dist/core/types.d.ts +402 -0
  97. package/dist/core/types.d.ts.map +1 -0
  98. package/dist/core/types.js +19 -0
  99. package/dist/core/types.js.map +1 -0
  100. package/dist/core/types.test.d.ts +7 -0
  101. package/dist/core/types.test.d.ts.map +1 -0
  102. package/dist/core/types.test.js +122 -0
  103. package/dist/core/types.test.js.map +1 -0
  104. package/dist/core/unified-cache.d.ts +63 -0
  105. package/dist/core/unified-cache.d.ts.map +1 -0
  106. package/dist/core/unified-cache.js +114 -0
  107. package/dist/core/unified-cache.js.map +1 -0
  108. package/dist/index.d.ts +151 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +248 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/services/arbitrage-service.d.ts +409 -0
  113. package/dist/services/arbitrage-service.d.ts.map +1 -0
  114. package/dist/services/arbitrage-service.js +1440 -0
  115. package/dist/services/arbitrage-service.js.map +1 -0
  116. package/dist/services/authorization-service.d.ts +97 -0
  117. package/dist/services/authorization-service.d.ts.map +1 -0
  118. package/dist/services/authorization-service.js +279 -0
  119. package/dist/services/authorization-service.js.map +1 -0
  120. package/dist/services/market-service.d.ts +208 -0
  121. package/dist/services/market-service.d.ts.map +1 -0
  122. package/dist/services/market-service.js +774 -0
  123. package/dist/services/market-service.js.map +1 -0
  124. package/dist/services/onchain-service.d.ts +309 -0
  125. package/dist/services/onchain-service.d.ts.map +1 -0
  126. package/dist/services/onchain-service.js +417 -0
  127. package/dist/services/onchain-service.js.map +1 -0
  128. package/dist/services/realtime-service-v2.d.ts +361 -0
  129. package/dist/services/realtime-service-v2.d.ts.map +1 -0
  130. package/dist/services/realtime-service-v2.js +840 -0
  131. package/dist/services/realtime-service-v2.js.map +1 -0
  132. package/dist/services/realtime-service.d.ts +82 -0
  133. package/dist/services/realtime-service.d.ts.map +1 -0
  134. package/dist/services/realtime-service.js +182 -0
  135. package/dist/services/realtime-service.js.map +1 -0
  136. package/dist/services/smart-money-service.d.ts +196 -0
  137. package/dist/services/smart-money-service.d.ts.map +1 -0
  138. package/dist/services/smart-money-service.js +358 -0
  139. package/dist/services/smart-money-service.js.map +1 -0
  140. package/dist/services/swap-service.d.ts +217 -0
  141. package/dist/services/swap-service.d.ts.map +1 -0
  142. package/dist/services/swap-service.js +695 -0
  143. package/dist/services/swap-service.js.map +1 -0
  144. package/dist/services/trading-service.d.ts +156 -0
  145. package/dist/services/trading-service.d.ts.map +1 -0
  146. package/dist/services/trading-service.js +356 -0
  147. package/dist/services/trading-service.js.map +1 -0
  148. package/dist/services/wallet-service.d.ts +275 -0
  149. package/dist/services/wallet-service.d.ts.map +1 -0
  150. package/dist/services/wallet-service.js +630 -0
  151. package/dist/services/wallet-service.js.map +1 -0
  152. package/dist/utils/price-utils.d.ts +153 -0
  153. package/dist/utils/price-utils.d.ts.map +1 -0
  154. package/dist/utils/price-utils.js +236 -0
  155. package/dist/utils/price-utils.js.map +1 -0
  156. package/dist/utils/price-utils.test.d.ts +5 -0
  157. package/dist/utils/price-utils.test.d.ts.map +1 -0
  158. package/dist/utils/price-utils.test.js +192 -0
  159. package/dist/utils/price-utils.test.js.map +1 -0
  160. package/package.json +10 -4
  161. package/README.en.md +0 -538
  162. package/docs/00-design.md +0 -760
  163. package/docs/02-API.md +0 -1148
  164. package/docs/arb/test-plan.md +0 -387
  165. package/docs/arb/test-results.md +0 -336
  166. package/docs/arbitrage.md +0 -754
  167. package/docs/reports/smart-money-analysis-2025-12-23-cn.md +0 -840
  168. package/examples/01-basic-usage.ts +0 -68
  169. package/examples/02-smart-money.ts +0 -95
  170. package/examples/03-market-analysis.ts +0 -108
  171. package/examples/04-kline-aggregation.ts +0 -158
  172. package/examples/05-follow-wallet-strategy.ts +0 -156
  173. package/examples/06-services-demo.ts +0 -124
  174. package/examples/07-realtime-websocket.ts +0 -117
  175. package/examples/08-trading-orders.ts +0 -278
  176. package/examples/09-rewards-tracking.ts +0 -187
  177. package/examples/10-ctf-operations.ts +0 -336
  178. package/examples/11-live-arbitrage-scan.ts +0 -221
  179. package/examples/12-trending-arb-monitor.ts +0 -406
  180. package/examples/13-arbitrage-service.ts +0 -211
  181. package/examples/README.md +0 -179
  182. package/scripts/README.md +0 -163
  183. package/scripts/approvals/approve-erc1155.ts +0 -129
  184. package/scripts/approvals/approve-neg-risk-erc1155.ts +0 -149
  185. package/scripts/approvals/approve-neg-risk.ts +0 -102
  186. package/scripts/approvals/check-all-allowances.ts +0 -150
  187. package/scripts/approvals/check-allowance.ts +0 -129
  188. package/scripts/approvals/check-ctf-approval.ts +0 -158
  189. package/scripts/arb/faze-bo3-arb.ts +0 -385
  190. package/scripts/arb/settle-position.ts +0 -190
  191. package/scripts/arb/token-rebalancer.ts +0 -420
  192. package/scripts/arb-tests/01-unit-tests.ts +0 -495
  193. package/scripts/arb-tests/02-integration-tests.ts +0 -412
  194. package/scripts/arb-tests/03-e2e-tests.ts +0 -503
  195. package/scripts/arb-tests/README.md +0 -109
  196. package/scripts/datas/001-report.md +0 -486
  197. package/scripts/datas/clone-modal-screenshot.png +0 -0
  198. package/scripts/deposit/deposit-native-usdc.ts +0 -179
  199. package/scripts/deposit/deposit-usdc.ts +0 -155
  200. package/scripts/deposit/swap-usdc-to-usdce.ts +0 -375
  201. package/scripts/research/research-markets.ts +0 -166
  202. package/scripts/trading/check-orders.ts +0 -50
  203. package/scripts/trading/sell-nvidia-positions.ts +0 -206
  204. package/scripts/trading/test-order.ts +0 -172
  205. package/scripts/verify/test-approve-trading.ts +0 -98
  206. package/scripts/verify/test-provider-fix.ts +0 -43
  207. package/scripts/verify/test-search-mcp.ts +0 -113
  208. package/scripts/verify/verify-all-apis.ts +0 -160
  209. package/scripts/wallet/check-wallet-balances.ts +0 -75
  210. package/scripts/wallet/test-wallet-operations.ts +0 -191
  211. package/scripts/wallet/verify-wallet-tools.ts +0 -124
  212. package/src/__tests__/clob-api.test.ts +0 -301
  213. package/src/__tests__/integration/bridge-client.integration.test.ts +0 -314
  214. package/src/__tests__/integration/clob-api.integration.test.ts +0 -218
  215. package/src/__tests__/integration/ctf-client.integration.test.ts +0 -331
  216. package/src/__tests__/integration/data-api.integration.test.ts +0 -194
  217. package/src/__tests__/integration/gamma-api.integration.test.ts +0 -206
  218. package/src/__tests__/test-utils.ts +0 -170
  219. package/src/clients/bridge-client.ts +0 -841
  220. package/src/clients/clob-api.ts +0 -629
  221. package/src/clients/ctf-client.ts +0 -1216
  222. package/src/clients/data-api.ts +0 -469
  223. package/src/clients/gamma-api.ts +0 -597
  224. package/src/clients/trading-client.ts +0 -749
  225. package/src/clients/websocket-manager.ts +0 -267
  226. package/src/core/cache-adapter-bridge.ts +0 -94
  227. package/src/core/cache.ts +0 -85
  228. package/src/core/errors.ts +0 -117
  229. package/src/core/rate-limiter.ts +0 -74
  230. package/src/core/types.ts +0 -360
  231. package/src/core/unified-cache.ts +0 -153
  232. package/src/index.ts +0 -461
  233. package/src/services/arbitrage-service.ts +0 -1807
  234. package/src/services/authorization-service.ts +0 -357
  235. package/src/services/market-service.ts +0 -544
  236. package/src/services/realtime-service.ts +0 -196
  237. package/src/services/swap-service.ts +0 -896
  238. package/src/services/wallet-service.ts +0 -259
  239. package/src/utils/price-utils.ts +0 -307
  240. package/tsconfig.json +0 -8
  241. package/vitest.config.ts +0 -19
  242. package/vitest.integration.config.ts +0 -18
package/README.md CHANGED
@@ -1,318 +1,283 @@
1
1
  # @catalyst-team/poly-sdk
2
2
 
3
- Unified SDK for Polymarket APIs - Data API, Gamma API, CLOB API, and WebSocket real-time updates.
3
+ [![npm version](https://img.shields.io/npm/v/@catalyst-team/poly-sdk.svg)](https://www.npmjs.com/package/@catalyst-team/poly-sdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
5
 
5
- **Builder**: [@hhhx402](https://x.com/hhhx402)
6
- **Project**: [Catalyst.fun](https://x.com/catalystdotfun)
6
+ **Unified TypeScript SDK for Polymarket** - Trading, market data, smart money analysis, and on-chain operations.
7
7
 
8
- ## Installation
8
+ **Builder**: [@hhhx402](https://x.com/hhhx402) | **Project**: [Catalyst.fun](https://x.com/catalystdotfun)
9
9
 
10
- ```bash
11
- pnpm add @catalyst-team/poly-sdk
12
- ```
10
+ [中文文档](README.zh-CN.md)
13
11
 
14
- ## Quick Start
12
+ ---
15
13
 
16
- ```typescript
17
- import { PolymarketSDK } from '@catalyst-team/poly-sdk';
14
+ ## Table of Contents
18
15
 
19
- const sdk = new PolymarketSDK();
16
+ - [Overview](#overview)
17
+ - [Installation](#installation)
18
+ - [Architecture](#architecture)
19
+ - [Quick Start](#quick-start)
20
+ - [Services Guide](#services-guide)
21
+ - [PolymarketSDK (Entry Point)](#polymarketsdk-entry-point)
22
+ - [TradingService](#tradingservice)
23
+ - [MarketService](#marketservice)
24
+ - [OnchainService](#onchainservice)
25
+ - [RealtimeServiceV2](#realtimeservicev2)
26
+ - [WalletService](#walletservice)
27
+ - [SmartMoneyService](#smartmoneyservice)
28
+ - [ArbitrageService](#arbitrageservice)
29
+ - [Low-Level Clients](#low-level-clients)
30
+ - [Breaking Changes (v0.3.0)](#breaking-changes-v030)
31
+ - [Examples](#examples)
32
+ - [API Reference](#api-reference)
33
+ - [License](#license)
20
34
 
21
- // Get market by slug or condition ID
22
- const market = await sdk.getMarket('will-trump-win-2024');
23
- console.log(market.tokens.yes.price); // 0.65
35
+ ---
24
36
 
25
- // Get processed orderbook with analytics
26
- const orderbook = await sdk.getOrderbook(market.conditionId);
27
- console.log(orderbook.summary.longArbProfit); // Arbitrage opportunity
37
+ ## Overview
28
38
 
29
- // Detect arbitrage
30
- const arb = await sdk.detectArbitrage(market.conditionId);
31
- if (arb) {
32
- console.log(`${arb.type} arb: ${arb.profit * 100}% profit`);
33
- }
34
- ```
39
+ `@catalyst-team/poly-sdk` is a comprehensive TypeScript SDK that provides:
35
40
 
36
- ## Architecture
41
+ - **Trading** - Place limit/market orders (GTC, GTD, FOK, FAK)
42
+ - **Market Data** - Real-time prices, orderbooks, K-lines, historical trades
43
+ - **Smart Money Analysis** - Track top traders, calculate smart scores, follow wallet strategies
44
+ - **On-chain Operations** - CTF (split/merge/redeem), approvals, DEX swaps
45
+ - **Arbitrage Detection** - Real-time arbitrage scanning and execution
46
+ - **WebSocket Streaming** - Live price feeds and orderbook updates
37
47
 
38
- ```
39
- ┌──────────────────────────────────────────────────────────────────────────────┐
40
- │ PolymarketSDK │
41
- ├──────────────────────────────────────────────────────────────────────────────┤
42
- │ Layer 3: Services │
43
- │ ┌─────────────┐ ┌─────────────┐ ┌───────────────┐ ┌─────────────────────────┐│
44
- │ │WalletService│ │MarketService│ │RealtimeService│ │ AuthorizationService ││
45
- │ │ - profiles │ │ - K-Lines │ │- subscriptions│ │ - ERC20 approvals ││
46
- │ │ - sell det. │ │ - signals │ │- price cache │ │ - ERC1155 approvals ││
47
- │ └─────────────┘ └─────────────┘ └───────────────┘ └─────────────────────────┘│
48
- │ ┌─────────────────────────────────────────────────────────────────────────┐ │
49
- │ │ ArbitrageService: Real-time arbitrage detection, rebalancer, settlement │ │
50
- │ └─────────────────────────────────────────────────────────────────────────┘ │
51
- │ ┌─────────────────────────────────────────────────────────────────────────┐ │
52
- │ │ SwapService: DEX swaps on Polygon (QuickSwap V3, USDC/USDC.e conversion)│ │
53
- │ └─────────────────────────────────────────────────────────────────────────┘ │
54
- ├──────────────────────────────────────────────────────────────────────────────┤
55
- │ Layer 2: API Clients │
56
- │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌────────────────────┐ │
57
- │ │ DataAPI │ │ GammaAPI │ │ CLOB API │ │ WebSocket │ │ BridgeClient │ │
58
- │ │positions │ │ markets │ │ orderbook│ │ real-time │ │ cross-chain │ │
59
- │ │ trades │ │ events │ │ trading │ │ prices │ │ deposits │ │
60
- │ └──────────┘ └──────────┘ └──────────┘ └───────────┘ └────────────────────┘ │
61
- │ ┌──────────────────────────────────────┐ ┌────────────────────────────────┐ │
62
- │ │ TradingClient: Order execution │ │ CTFClient: On-chain operations │ │
63
- │ │ GTC/GTD/FOK/FAK, rewards, balances │ │ Split / Merge / Redeem tokens │ │
64
- │ └──────────────────────────────────────┘ └────────────────────────────────┘ │
65
- ├──────────────────────────────────────────────────────────────────────────────┤
66
- │ Layer 1: Infrastructure │
67
- │ ┌────────────┐ ┌─────────┐ ┌──────────┐ ┌────────────┐ ┌──────────────┐ │
68
- │ │RateLimiter │ │ Cache │ │ Errors │ │ Types │ │ Price Utils │ │
69
- │ │per-API │ │TTL-based│ │ retry │ │ unified │ │ arb detect │ │
70
- │ └────────────┘ └─────────┘ └──────────┘ └────────────┘ └──────────────┘ │
71
- └──────────────────────────────────────────────────────────────────────────────┘
72
- ```
48
+ ### Key Features
73
49
 
74
- ## API Clients
50
+ | Feature | Description |
51
+ |---------|-------------|
52
+ | **Unified API** | Single SDK for all Polymarket APIs |
53
+ | **Type Safety** | Full TypeScript support with comprehensive types |
54
+ | **Rate Limiting** | Built-in rate limiting per API endpoint |
55
+ | **Caching** | TTL-based caching with pluggable adapters |
56
+ | **Error Handling** | Structured errors with auto-retry |
75
57
 
76
- ### DataApiClient - Positions, Trades, Leaderboard
58
+ ---
77
59
 
78
- ```typescript
79
- // Get wallet positions
80
- const positions = await sdk.dataApi.getPositions('0x...');
60
+ ## Installation
81
61
 
82
- // Get recent trades
83
- const trades = await sdk.dataApi.getTrades('0x...');
62
+ ```bash
63
+ pnpm add @catalyst-team/poly-sdk
84
64
 
85
- // Get leaderboard
86
- const leaderboard = await sdk.dataApi.getLeaderboard();
65
+ # or
66
+ npm install @catalyst-team/poly-sdk
67
+
68
+ # or
69
+ yarn add @catalyst-team/poly-sdk
87
70
  ```
88
71
 
89
- ### GammaApiClient - Markets, Events
72
+ ---
90
73
 
91
- ```typescript
92
- // Search markets
93
- const markets = await sdk.gammaApi.searchMarkets({ query: 'bitcoin' });
74
+ ## Architecture
94
75
 
95
- // Get trending markets
96
- const trending = await sdk.gammaApi.getTrendingMarkets(10);
76
+ The SDK is organized into three layers:
97
77
 
98
- // Get events
99
- const events = await sdk.gammaApi.getEvents({ limit: 20 });
100
78
  ```
79
+ poly-sdk Architecture
80
+ ================================================================================
101
81
 
102
- ### ClobApiClient - Orderbook, Trading
103
-
104
- ```typescript
105
- // Get orderbook
106
- const book = await sdk.clobApi.getOrderbook(conditionId);
107
-
108
- // Get processed orderbook with analytics
109
- const processed = await sdk.clobApi.getProcessedOrderbook(conditionId);
110
- console.log(processed.summary.longArbProfit);
111
- console.log(processed.summary.shortArbProfit);
82
+ ┌──────────────────────────────────────────────────────────────────────────────┐
83
+ │ PolymarketSDK │
84
+ │ (Entry Point) │
85
+ ├──────────────────────────────────────────────────────────────────────────────┤
86
+ │ │
87
+ │ Layer 3: High-Level Services (Recommended) │
88
+ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
89
+ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
90
+ │ │ TradingService │ │ MarketService │ │ OnchainService │ │
91
+ │ │ ────────────── │ │ ────────────── │ │ ────────────── │ │
92
+ │ │ • Limit orders │ │ • K-lines │ │ • Split/Merge │ │
93
+ │ │ • Market orders│ │ • Orderbook │ │ • Redeem │ │
94
+ │ │ • Order mgmt │ │ • Price history│ │ • Approvals │ │
95
+ │ │ • Rewards │ │ • Arbitrage │ │ • Swaps │ │
96
+ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
97
+ │ │
98
+ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
99
+ │ │RealtimeServiceV2│ │ WalletService │ │SmartMoneyService│ │
100
+ │ │ ────────────── │ │ ────────────── │ │ ────────────── │ │
101
+ │ │ • WebSocket │ │ • Profiles │ │ • Top traders │ │
102
+ │ │ • Price feeds │ │ • Smart scores │ │ • Copy trading │ │
103
+ │ │ • Book updates │ │ • Sell detect │ │ • Signal detect │ │
104
+ │ │ • User events │ │ • PnL calc │ │ • Leaderboard │ │
105
+ │ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
106
+ │ │
107
+ │ ┌─────────────────────────────────────────────────────────────────────────┐ │
108
+ │ │ ArbitrageService │ │
109
+ │ │ ───────────────────────────────────────────────────────────────────── │ │
110
+ │ │ • Market scanning • Auto execution • Rebalancer • Smart clearing │ │
111
+ │ └─────────────────────────────────────────────────────────────────────────┘ │
112
+ │ │
113
+ ├──────────────────────────────────────────────────────────────────────────────┤
114
+ │ │
115
+ │ Layer 2: Low-Level Clients (Advanced Users / Raw API Access) │
116
+ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
117
+ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
118
+ │ │GammaApiClnt│ │DataApiClnt │ │SubgraphClnt│ │ CTFClient │ │BridgeClient│ │
119
+ │ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │
120
+ │ │ • Markets │ │ • Positions│ │ • On-chain │ │ • Split │ │ • Cross- │ │
121
+ │ │ • Events │ │ • Trades │ │ • PnL │ │ • Merge │ │ chain │ │
122
+ │ │ • Search │ │ • Activity │ │ • OI │ │ • Redeem │ │ • Deposits │ │
123
+ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
124
+ │ │
125
+ │ Uses Official Polymarket Clients: │
126
+ │ • @polymarket/clob-client - Trading, orderbook, market data │
127
+ │ • @polymarket/real-time-data-client - WebSocket real-time updates │
128
+ │ │
129
+ ├──────────────────────────────────────────────────────────────────────────────┤
130
+ │ │
131
+ │ Layer 1: Core Infrastructure │
132
+ │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
133
+ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
134
+ │ │RateLimiter │ │ Cache │ │ Errors │ │ Types │ │Price Utils │ │
135
+ │ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │ ────────── │ │
136
+ │ │ • Per-API │ │ • TTL-based│ │ • Retry │ │ • Unified │ │ • Arb calc │ │
137
+ │ │ • Bottleneck│ │ • Pluggable│ │ • Codes │ │ • K-lines │ │ • Rounding │ │
138
+ │ └────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
139
+ │ │
140
+ └──────────────────────────────────────────────────────────────────────────────┘
112
141
  ```
113
142
 
114
- ## Services
143
+ ### Service Responsibilities
115
144
 
116
- ### WalletService - Smart Money Analysis
145
+ | Service | Responsibility |
146
+ |---------|---------------|
147
+ | **PolymarketSDK** | Entry point, integrates all services |
148
+ | **TradingService** | Order management (place/cancel/query) |
149
+ | **MarketService** | Market data (orderbook/K-lines/search) |
150
+ | **OnchainService** | On-chain ops (split/merge/redeem/approve/swap) |
151
+ | **RealtimeServiceV2** | WebSocket real-time data |
152
+ | **WalletService** | Wallet/trader analysis |
153
+ | **SmartMoneyService** | Smart money tracking |
154
+ | **ArbitrageService** | Arbitrage detection & execution |
117
155
 
118
- ```typescript
119
- // Get top traders
120
- const traders = await sdk.wallets.getTopTraders(10);
121
-
122
- // Get wallet profile with smart score
123
- const profile = await sdk.wallets.getWalletProfile('0x...');
124
- console.log(profile.smartScore); // 0-100
156
+ ---
125
157
 
126
- // Detect sell activity (for follow-wallet strategy)
127
- const sellResult = await sdk.wallets.detectSellActivity(
128
- '0x...',
129
- conditionId,
130
- Date.now() - 24 * 60 * 60 * 1000
131
- );
132
- if (sellResult.isSelling) {
133
- console.log(`Sold ${sellResult.percentageSold}%`);
134
- }
135
-
136
- // Track group sell ratio
137
- const groupSell = await sdk.wallets.trackGroupSellRatio(
138
- ['0x...', '0x...'],
139
- conditionId,
140
- peakValue,
141
- sinceTimestamp
142
- );
143
- ```
158
+ ## Quick Start
144
159
 
145
- ### MarketService - K-Lines and Signals
160
+ ### Basic Usage (Read-Only)
146
161
 
147
162
  ```typescript
148
- // Get K-Line candles
149
- const klines = await sdk.markets.getKLines(conditionId, '1h', { limit: 100 });
150
-
151
- // Get dual K-Lines (YES + NO) with spread analysis
152
- const dual = await sdk.markets.getDualKLines(conditionId, '1h');
153
- console.log(dual.yes); // YES token candles
154
- console.log(dual.no); // NO token candles
163
+ import { PolymarketSDK } from '@catalyst-team/poly-sdk';
155
164
 
156
- // Historical spread (from trade close prices) - for backtesting
157
- console.log(dual.spreadAnalysis); // SpreadDataPoint[]
158
- for (const point of dual.spreadAnalysis) {
159
- console.log(`${point.timestamp}: priceSum=${point.priceSum}, spread=${point.priceSpread}`);
160
- if (point.arbOpportunity) {
161
- console.log(` Historical ${point.arbOpportunity} signal`);
162
- }
163
- }
165
+ // No authentication needed for read operations
166
+ const sdk = new PolymarketSDK();
164
167
 
165
- // Real-time spread (from orderbook) - for live trading
166
- if (dual.realtimeSpread) {
167
- const rt = dual.realtimeSpread;
168
- console.log(`Ask Sum: ${rt.askSum} (spread: ${rt.askSpread})`);
169
- console.log(`Bid Sum: ${rt.bidSum} (spread: ${rt.bidSpread})`);
170
- if (rt.arbOpportunity) {
171
- console.log(`🎯 ${rt.arbOpportunity} ARB: ${rt.arbProfitPercent.toFixed(2)}% profit`);
172
- }
173
- }
168
+ // Get market by slug or condition ID
169
+ const market = await sdk.getMarket('will-trump-win-2024');
170
+ console.log(`${market.question}`);
171
+ console.log(`YES: ${market.tokens.find(t => t.outcome === 'Yes')?.price}`);
172
+ console.log(`NO: ${market.tokens.find(t => t.outcome === 'No')?.price}`);
174
173
 
175
- // Quick real-time spread check (without K-lines)
176
- const spread = await sdk.markets.getRealtimeSpread(conditionId);
177
- if (spread.longArbProfit > 0.005) {
178
- console.log(`Long arb: buy YES@${spread.yesAsk} + NO@${spread.noAsk}`);
179
- }
174
+ // Get processed orderbook with analytics
175
+ const orderbook = await sdk.getOrderbook(market.conditionId);
176
+ console.log(`Long Arb Profit: ${orderbook.summary.longArbProfit}`);
177
+ console.log(`Short Arb Profit: ${orderbook.summary.shortArbProfit}`);
180
178
 
181
- // Detect market signals
182
- const signals = await sdk.markets.detectMarketSignals(conditionId);
183
- for (const signal of signals) {
184
- console.log(`${signal.type}: ${signal.severity}`);
179
+ // Detect arbitrage opportunities
180
+ const arb = await sdk.detectArbitrage(market.conditionId);
181
+ if (arb) {
182
+ console.log(`${arb.type.toUpperCase()} ARB: ${(arb.profit * 100).toFixed(2)}% profit`);
183
+ console.log(arb.action);
185
184
  }
186
-
187
- // Detect arbitrage
188
- const arb = await sdk.markets.detectArbitrage(conditionId);
189
185
  ```
190
186
 
191
- #### Understanding Polymarket Orderbook & Arbitrage
187
+ ### With Authentication (Trading)
192
188
 
193
- ⚠️ **重要:Polymarket 订单簿的镜像特性**
189
+ ```typescript
190
+ import { PolymarketSDK } from '@catalyst-team/poly-sdk';
194
191
 
195
- Polymarket 的订单簿有一个关键特性容易被忽略:
192
+ // Recommended: Use static factory method (one line to get started)
193
+ const sdk = await PolymarketSDK.create({
194
+ privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
195
+ });
196
+ // Ready to trade - SDK is initialized and WebSocket connected
196
197
 
197
- ```
198
- YES @ P = NO @ (1-P)
199
- ```
198
+ // Place a limit order
199
+ const order = await sdk.tradingService.createLimitOrder({
200
+ tokenId: yesTokenId,
201
+ side: 'BUY',
202
+ price: 0.45,
203
+ size: 10,
204
+ orderType: 'GTC',
205
+ });
206
+ console.log(`Order placed: ${order.id}`);
200
207
 
201
- 这意味着**同一订单会在两个订单簿中出现**。例如,一个 "Sell NO @ 0.50" 订单
202
- 会同时作为 "Buy YES @ 0.50" 出现在 YES 订单簿中。
208
+ // Get open orders
209
+ const openOrders = await sdk.tradingService.getOpenOrders();
210
+ console.log(`Open orders: ${openOrders.length}`);
203
211
 
204
- **常见误解:**
205
- ```typescript
206
- // ❌ 错误: 简单相加会重复计算镜像订单
207
- const askSum = YES.ask + NO.ask; // ≈ 1.998-1.999,而非 ≈ 1.0
208
- const bidSum = YES.bid + NO.bid; // ≈ 0.001-0.002,而非 ≈ 1.0
212
+ // Clean up when done
213
+ sdk.stop();
209
214
  ```
210
215
 
211
- **正确做法:使用有效价格 (Effective Prices)**
212
- ```typescript
213
- import { getEffectivePrices, checkArbitrage } from '@catalyst-team/poly-sdk';
216
+ ---
214
217
 
215
- // 计算考虑镜像后的最优价格
216
- const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
218
+ ## Services Guide
217
219
 
218
- // effective.effectiveBuyYes = min(YES.ask, 1 - NO.bid)
219
- // effective.effectiveBuyNo = min(NO.ask, 1 - YES.bid)
220
- // effective.effectiveSellYes = max(YES.bid, 1 - NO.ask)
221
- // effective.effectiveSellNo = max(NO.bid, 1 - YES.ask)
220
+ ### PolymarketSDK (Entry Point)
222
221
 
223
- // 使用有效价格检测套利
224
- const arb = checkArbitrage(yesAsk, noAsk, yesBid, noBid);
225
- if (arb) {
226
- console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
227
- console.log(arb.description);
228
- }
229
- ```
222
+ The main SDK class that integrates all services.
230
223
 
231
- 详细文档见: [docs/01-polymarket-orderbook-arbitrage.md](docs/01-polymarket-orderbook-arbitrage.md)
224
+ ```typescript
225
+ import { PolymarketSDK } from '@catalyst-team/poly-sdk';
232
226
 
233
- #### Spread Analysis - Two Approaches
227
+ // ===== Method 1: Static Factory (Recommended) =====
228
+ // One line: new + initialize + connect + waitForConnection
229
+ const sdk = await PolymarketSDK.create({
230
+ privateKey: '0x...', // Optional: for trading
231
+ chainId: 137, // Optional: Polygon mainnet (default)
232
+ });
234
233
 
235
- 我们提供两种 Spread 分析方式,核心区别如下:
234
+ // ===== Method 2: Using start() =====
235
+ // const sdk = new PolymarketSDK({ privateKey: '0x...' });
236
+ // await sdk.start(); // initialize + connect + waitForConnection
236
237
 
237
- ```
238
- ┌─────────────────────────────────────────────────────────────────────────┐
239
- │ spreadAnalysis (历史分析) │ realtimeSpread (实时分析) │
240
- ├─────────────────────────────────────────────────────────────────────────┤
241
- │ 数据源: 成交记录的收盘价 │ 数据源: 订单簿的最优 bid/ask │
242
- │ YES_close + NO_close │ 使用有效价格 (考虑镜像订单) │
243
- ├─────────────────────────────────────────────────────────────────────────┤
244
- │ ✅ 可构建历史曲线 │ ❌ 无法构建历史曲线* │
245
- │ ✅ Polymarket 保留成交历史 │ ❌ Polymarket 不保留盘口历史 │
246
- │ ✅ 适合回测、模式识别 │ ✅ 适合实盘交易、套利执行 │
247
- │ ⚠️ 套利信号仅供参考 │ ✅ 套利利润计算准确 │
248
- └─────────────────────────────────────────────────────────────────────────┘
249
-
250
- * 如需构建实时 Spread 的历史曲线,必须自行存储盘口快照数据
251
- 参考: apps/api/src/services/spread-sampler.ts
252
- ```
238
+ // ===== Method 3: Manual Step-by-Step (Full Control) =====
239
+ // const sdk = new PolymarketSDK({ privateKey: '0x...' });
240
+ // await sdk.initialize(); // Initialize trading service
241
+ // sdk.connect(); // Connect WebSocket
242
+ // await sdk.waitForConnection(); // Wait for connection
253
243
 
254
- **核心区别:**
244
+ // Access services
245
+ sdk.tradingService // Trading operations
246
+ sdk.markets // Market data
247
+ sdk.wallets // Wallet analysis
248
+ sdk.realtime // WebSocket real-time data
249
+ sdk.smartMoney // Smart money tracking & copy trading
250
+ sdk.dataApi // Direct Data API access
251
+ sdk.gammaApi // Direct Gamma API access
252
+ sdk.subgraph // On-chain data via Goldsky
255
253
 
256
- 1. **成交价 vs 盘口价**
257
- - 成交价 (close): 过去某时刻实际成交的价格
258
- - 盘口价 (bid/ask): 当前市场上的最优挂单价格
259
- - 例: YES 最后成交 0.52,但当前 bid=0.50, ask=0.54
254
+ // Convenience methods
255
+ await sdk.getMarket(identifier); // Get unified market
256
+ await sdk.getOrderbook(conditionId); // Get processed orderbook
257
+ await sdk.detectArbitrage(conditionId); // Detect arb opportunity
260
258
 
261
- 2. **为什么套利计算需要有效价格?**
262
- - 同一订单在 YES 和 NO 订单簿中都有镜像
263
- - 简单的 `YES.ask + NO.ask` 会重复计算
264
- - 必须用 `min(YES.ask, 1-NO.bid)` 等公式消除重复
259
+ // Clean up
260
+ sdk.stop(); // Disconnect all services
261
+ ```
265
262
 
266
- 3. **为什么历史分析只能用成交价?**
267
- - Polymarket CLOB API 不保存历史盘口数据
268
- - 只有成交记录 (trades) 有历史
269
- - 除非你自己运行 spread-sampler 持续采样盘口
263
+ ---
270
264
 
271
- ```typescript
272
- // SpreadDataPoint (历史分析 - 可构建曲线)
273
- interface SpreadDataPoint {
274
- timestamp: number;
275
- yesPrice: number; // YES 收盘价 (来自成交记录)
276
- noPrice: number; // NO 收盘价
277
- priceSum: number; // YES + NO
278
- priceSpread: number; // priceSum - 1 (偏离均衡程度)
279
- arbOpportunity: 'LONG' | 'SHORT' | ''; // 参考信号
280
- }
281
-
282
- // ProcessedOrderbook.summary (实时分析 - 使用有效价格)
283
- interface OrderbookSummary {
284
- // 有效价格 (考虑镜像订单)
285
- effectivePrices: {
286
- effectiveBuyYes: number; // min(YES.ask, 1 - NO.bid)
287
- effectiveBuyNo: number; // min(NO.ask, 1 - YES.bid)
288
- effectiveSellYes: number; // max(YES.bid, 1 - NO.ask)
289
- effectiveSellNo: number; // max(NO.bid, 1 - YES.ask)
290
- };
291
- // 套利成本/收入
292
- effectiveLongCost: number; // effectiveBuyYes + effectiveBuyNo
293
- effectiveShortRevenue: number; // effectiveSellYes + effectiveSellNo
294
- // 套利利润
295
- longArbProfit: number; // 1 - effectiveLongCost (> 0 可套利)
296
- shortArbProfit: number; // effectiveShortRevenue - 1 (> 0 可套利)
297
- yesSpread: number; // YES.ask - YES.bid (市场效率指标)
298
- }
299
- ```
265
+ ### TradingService
300
266
 
301
- ### TradingClient - Order Execution
267
+ Order management using `@polymarket/clob-client`.
302
268
 
303
269
  ```typescript
304
- import { TradingClient, RateLimiter } from '@catalyst-team/poly-sdk';
270
+ import { TradingService } from '@catalyst-team/poly-sdk';
305
271
 
306
- const rateLimiter = new RateLimiter();
307
- const tradingClient = new TradingClient(rateLimiter, {
272
+ const trading = new TradingService(rateLimiter, cache, {
308
273
  privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
309
274
  });
275
+ await trading.initialize();
310
276
 
311
- await tradingClient.initialize();
312
- console.log(`Wallet: ${tradingClient.getAddress()}`);
277
+ // ===== Limit Orders =====
313
278
 
314
- // GTC Limit Order (stays until filled or cancelled)
315
- const order = await tradingClient.createOrder({
279
+ // GTC: Good Till Cancelled
280
+ const gtcOrder = await trading.createLimitOrder({
316
281
  tokenId: yesTokenId,
317
282
  side: 'BUY',
318
283
  price: 0.45,
@@ -320,8 +285,8 @@ const order = await tradingClient.createOrder({
320
285
  orderType: 'GTC',
321
286
  });
322
287
 
323
- // GTD Limit Order (expires at timestamp)
324
- const gtdOrder = await tradingClient.createOrder({
288
+ // GTD: Good Till Date (expires at timestamp)
289
+ const gtdOrder = await trading.createLimitOrder({
325
290
  tokenId: yesTokenId,
326
291
  side: 'BUY',
327
292
  price: 0.45,
@@ -330,406 +295,297 @@ const gtdOrder = await tradingClient.createOrder({
330
295
  expiration: Math.floor(Date.now() / 1000) + 3600, // 1 hour
331
296
  });
332
297
 
333
- // FOK Market Order (fill entirely or cancel)
334
- const marketOrder = await tradingClient.createMarketOrder({
298
+ // ===== Market Orders =====
299
+
300
+ // FOK: Fill Or Kill (fill entirely or cancel)
301
+ const fokOrder = await trading.createMarketOrder({
335
302
  tokenId: yesTokenId,
336
303
  side: 'BUY',
337
304
  amount: 10, // $10 USDC
338
305
  orderType: 'FOK',
339
306
  });
340
307
 
341
- // FAK Market Order (partial fill ok)
342
- const fakOrder = await tradingClient.createMarketOrder({
308
+ // FAK: Fill And Kill (partial fill ok)
309
+ const fakOrder = await trading.createMarketOrder({
343
310
  tokenId: yesTokenId,
344
311
  side: 'SELL',
345
312
  amount: 10, // 10 shares
346
313
  orderType: 'FAK',
347
314
  });
348
315
 
349
- // Order management
350
- const openOrders = await tradingClient.getOpenOrders();
351
- await tradingClient.cancelOrder(orderId);
352
- await tradingClient.cancelAllOrders();
316
+ // ===== Order Management =====
317
+ const openOrders = await trading.getOpenOrders();
318
+ await trading.cancelOrder(orderId);
319
+ await trading.cancelAllOrders();
353
320
 
354
- // Get trade history
355
- const trades = await tradingClient.getTrades();
321
+ // ===== Rewards (Market Making Incentives) =====
322
+ const isScoring = await trading.isOrderScoring(orderId);
323
+ const rewards = await trading.getCurrentRewards();
324
+ const earnings = await trading.getEarnings('2024-12-07');
356
325
  ```
357
326
 
358
- ### Rewards - Market Making Incentives
327
+ ---
359
328
 
360
- ```typescript
361
- // Check if your orders are earning rewards
362
- const isScoring = await tradingClient.isOrderScoring(orderId);
363
-
364
- // Get markets with active reward programs
365
- const rewards = await tradingClient.getCurrentRewards();
366
- for (const reward of rewards) {
367
- console.log(`${reward.question}`);
368
- console.log(` Max Spread: ${reward.rewardsMaxSpread}`);
369
- console.log(` Min Size: ${reward.rewardsMinSize}`);
370
- }
329
+ ### MarketService
371
330
 
372
- // Get your daily earnings
373
- const earnings = await tradingClient.getTotalEarningsForDay('2024-12-07');
374
- console.log(`Total earned: $${earnings.totalEarnings}`);
331
+ Market data, K-lines, orderbook analysis.
375
332
 
376
- // Check balance and allowance
377
- const balance = await tradingClient.getBalanceAllowance('COLLATERAL');
378
- console.log(`USDC Balance: ${balance.balance}`);
379
- ```
333
+ ```typescript
334
+ import { MarketService } from '@catalyst-team/poly-sdk';
380
335
 
381
- ### RealtimeService - WebSocket Subscriptions
336
+ // Get unified market
337
+ const market = await sdk.markets.getMarket('btc-100k-2024');
382
338
 
383
- ⚠️ **重要:Orderbook 自动排序**
339
+ // Get K-Lines
340
+ const klines = await sdk.markets.getKLines(conditionId, '1h', { limit: 100 });
384
341
 
385
- Polymarket CLOB API 返回的 orderbook 顺序与标准预期相反:
386
- - **bids**: 升序排列 (最低价在前 = 最差价)
387
- - **asks**: 降序排列 (最高价在前 = 最差价)
342
+ // Get dual K-Lines (YES + NO) with spread analysis
343
+ const dual = await sdk.markets.getDualKLines(conditionId, '1h');
344
+ console.log(dual.yes); // YES token candles
345
+ console.log(dual.no); // NO token candles
346
+ console.log(dual.spreadAnalysis); // Historical spread (trade prices)
347
+ console.log(dual.realtimeSpread); // Real-time spread (orderbook)
388
348
 
389
- 我们的 SDK **自动规范化** orderbook 数据:
390
- - **bids**: 降序排列 (最高价在前 = 最佳买价)
391
- - **asks**: 升序排列 (最低价在前 = 最佳卖价)
349
+ // Get processed orderbook
350
+ const orderbook = await sdk.markets.getProcessedOrderbook(conditionId);
392
351
 
393
- 这意味着你可以安全地使用 `bids[0]` `asks[0]` 获取最优价格:
352
+ // Quick real-time spread check
353
+ const spread = await sdk.markets.getRealtimeSpread(conditionId);
354
+ if (spread.longArbProfit > 0.005) {
355
+ console.log(`Long arb: buy YES@${spread.yesAsk} + NO@${spread.noAsk}`);
356
+ }
394
357
 
395
- ```typescript
396
- const book = await sdk.clobApi.getOrderbook(conditionId);
397
- const bestBid = book.bids[0]?.price; // ✅ 最高买价 (最佳 bid)
398
- const bestAsk = book.asks[0]?.price; // ✅ 最低卖价 (最佳 ask)
399
-
400
- // WebSocket 更新同样自动排序
401
- wsManager.on('bookUpdate', (update) => {
402
- const bestBid = update.bids[0]?.price; // ✅ 已排序
403
- const bestAsk = update.asks[0]?.price; // ✅ 已排序
404
- });
358
+ // Detect market signals
359
+ const signals = await sdk.markets.detectMarketSignals(conditionId);
405
360
  ```
406
361
 
407
- ```typescript
408
- import { WebSocketManager, RealtimeService } from '@catalyst-team/poly-sdk';
362
+ #### Understanding Polymarket Orderbook
409
363
 
410
- const wsManager = new WebSocketManager();
411
- const realtime = new RealtimeService(wsManager);
364
+ **Important**: Polymarket orderbooks have a mirror property:
412
365
 
413
- // Subscribe to market updates
414
- const subscription = await realtime.subscribeMarket(yesTokenId, noTokenId, {
415
- onPriceUpdate: (update) => {
416
- console.log(`${update.assetId}: ${update.price}`);
417
- },
418
- onBookUpdate: (update) => {
419
- console.log(`Best bid: ${update.bids[0]?.price}`);
420
- },
421
- onLastTrade: (trade) => {
422
- console.log(`Trade: ${trade.side} ${trade.size} @ ${trade.price}`);
423
- },
424
- onPairUpdate: (update) => {
425
- console.log(`YES + NO = ${update.spread}`);
426
- if (update.spread < 0.99) console.log('ARB opportunity!');
427
- },
428
- });
366
+ ```
367
+ Buy YES @ P = Sell NO @ (1-P)
368
+ ```
429
369
 
430
- // Get cached prices
431
- const price = realtime.getPrice(yesTokenId);
370
+ This means the **same order appears in both orderbooks**. Simple addition causes double-counting:
432
371
 
433
- // Cleanup
434
- await subscription.unsubscribe();
435
- ```
372
+ ```typescript
373
+ // WRONG: Double counts mirror orders
374
+ const askSum = YES.ask + NO.ask; // ~1.998, not ~1.0
436
375
 
437
- ### CTFClient - On-Chain Token Operations (Split/Merge/Redeem)
376
+ // CORRECT: Use effective prices
377
+ import { getEffectivePrices, checkArbitrage } from '@catalyst-team/poly-sdk';
438
378
 
439
- The CTF (Conditional Token Framework) client enables on-chain operations for Polymarket's conditional tokens.
379
+ const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
380
+ // effective.effectiveBuyYes = min(YES.ask, 1 - NO.bid)
381
+ // effective.effectiveBuyNo = min(NO.ask, 1 - YES.bid)
440
382
 
441
- ```
442
- ┌─────────────────────────────────────────────────────────────────────────────┐
443
- CTF 核心操作快速参考 │
444
- ├─────────────────────────────────────────────────────────────────────────────┤
445
- │ 操作 │ 功能 │ 典型场景 │
446
- ├──────────────┼────────────────────────┼──────────────────────────────────────┤
447
- │ Split │ USDC → YES + NO │ 市场做市:创建代币库存 │
448
- │ Merge │ YES + NO → USDC │ 套利:买入双边后合并获利 │
449
- │ Redeem │ 胜出代币 → USDC │ 结算:市场结束后兑换获胜代币 │
450
- └─────────────────────────────────────────────────────────────────────────────┘
383
+ const arb = checkArbitrage(yesAsk, noAsk, yesBid, noBid);
384
+ if (arb) {
385
+ console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
386
+ }
451
387
  ```
452
388
 
453
- **核心用途:**
454
- - **Arbitrage (套利)**: 当 YES + NO 买入成本 < $1 时,Merge 获利
455
- - **Market Making (做市)**: Split USDC 创建代币库存进行双边报价
456
- - **Redemption (结算)**: 市场结束后 Redeem 胜出代币获取 USDC
389
+ ---
390
+
391
+ ### OnchainService
392
+
393
+ Unified interface for all on-chain operations: CTF + Approvals + Swaps.
457
394
 
458
395
  ```typescript
459
- import { CTFClient, CTF_CONTRACT, USDC_CONTRACT } from '@catalyst-team/poly-sdk';
396
+ import { OnchainService } from '@catalyst-team/poly-sdk';
460
397
 
461
- const ctf = new CTFClient({
398
+ const onchain = new OnchainService({
462
399
  privateKey: process.env.POLYMARKET_PRIVATE_KEY!,
463
400
  rpcUrl: 'https://polygon-rpc.com', // optional
464
401
  });
465
402
 
466
- console.log(`Wallet: ${ctf.getAddress()}`);
467
- console.log(`USDC Balance: ${await ctf.getUsdcBalance()}`);
468
- ```
469
-
470
- #### Split: USDC → YES + NO Tokens
471
-
472
- ```typescript
473
- // Split 100 USDC into 100 YES + 100 NO tokens
474
- const splitResult = await ctf.split(conditionId, '100');
475
- console.log(`TX: ${splitResult.txHash}`);
476
- console.log(`Created ${splitResult.yesTokens} YES + ${splitResult.noTokens} NO`);
477
- ```
403
+ // Check if ready for CTF trading
404
+ const status = await onchain.checkReadyForCTF('100');
405
+ if (!status.ready) {
406
+ console.log('Issues:', status.issues);
407
+ await onchain.approveAll();
408
+ }
478
409
 
479
- #### Merge: YES + NO → USDC
410
+ // ===== CTF Operations =====
480
411
 
481
- ⚠️ **重要:两种 Merge 方法**
412
+ // Split: USDC -> YES + NO tokens
413
+ const splitResult = await onchain.split(conditionId, '100');
482
414
 
483
- | 方法 | 适用场景 | 推荐 |
484
- |------|----------|------|
485
- | `mergeByTokenIds()` | **Polymarket CLOB 市场** | ✅ 推荐 |
486
- | `merge()` | 标准 Gnosis CTF 市场 | ❌ Polymarket 慎用 |
415
+ // Merge: YES + NO -> USDC (for arbitrage)
416
+ const mergeResult = await onchain.mergeByTokenIds(conditionId, tokenIds, '100');
487
417
 
488
- ```typescript
489
- // 推荐:Polymarket 市场使用 mergeByTokenIds
490
- const tokenIds = {
491
- yesTokenId: market.tokens[0].tokenId, // 从 CLOB API 获取
492
- noTokenId: market.tokens[1].tokenId,
493
- };
494
- const mergeResult = await ctf.mergeByTokenIds(conditionId, tokenIds, '100');
495
- console.log(`TX: ${mergeResult.txHash}`);
496
- console.log(`Received ${mergeResult.usdcReceived} USDC`);
497
-
498
- // ⚠️ 标准 CTF 方法(可能无法正确检查 Polymarket 余额)
499
- // const mergeResult = await ctf.merge(conditionId, '100');
500
- ```
418
+ // Redeem: Winning tokens -> USDC (after resolution)
419
+ const redeemResult = await onchain.redeemByTokenIds(conditionId, tokenIds);
501
420
 
502
- #### Redeem: Winning Tokens USDC
421
+ // ===== DEX Swaps (QuickSwap V3) =====
503
422
 
504
- ⚠️ **重要:两种 Redeem 方法**
423
+ // Swap MATIC to USDC.e (required for CTF)
424
+ await onchain.swap('MATIC', 'USDC_E', '50');
505
425
 
506
- Polymarket 使用自定义的 token ID,与标准 CTF position ID 计算方式不同:
426
+ // Get balances
427
+ const balances = await onchain.getBalances();
428
+ console.log(`USDC.e: ${balances.usdcE}`);
429
+ ```
507
430
 
508
- | 方法 | 适用场景 | Token ID 来源 |
509
- |------|----------|---------------|
510
- | `redeemByTokenIds()` | **Polymarket CLOB 市场** ✅ | CLOB API 返回的 tokenId |
511
- | `redeem()` | 标准 Gnosis CTF 市场 | `keccak256(collectionId, conditionId, indexSet)` |
431
+ **Note**: Polymarket CTF requires **USDC.e** (0x2791...), not native USDC.
512
432
 
513
- ```typescript
514
- // ✅ 推荐:Polymarket 市场使用 redeemByTokenIds
515
- const tokenIds = {
516
- yesTokenId: '25064375110792967023484002819116042931016336431092144471807003884255851454283',
517
- noTokenId: '98190367690492181203391990709979106077460946443309150166954079213761598385827',
518
- };
519
- const result = await ctf.redeemByTokenIds(conditionId, tokenIds);
520
- console.log(`Redeemed ${result.tokensRedeemed} ${result.outcome} tokens`);
521
- console.log(`Received ${result.usdcReceived} USDC`);
522
-
523
- // ❌ 不要用于 Polymarket:redeem() 使用计算的 position ID
524
- // const result = await ctf.redeem(conditionId); // 可能找不到余额
525
- ```
433
+ ---
526
434
 
527
- **为什么 Polymarket token ID 不同?**
528
- - Polymarket 在 CTF 之上包装了一层 ERC-1155 tokens
529
- - CLOB API 返回的 `tokenId` (如 `"25064375..."`) 与标准 CTF 计算的 position ID 不同
530
- - 必须使用 CLOB API 的 token ID 才能正确查询余额和 redeem
435
+ ### RealtimeServiceV2
531
436
 
532
- #### Position Queries
437
+ WebSocket real-time data using `@polymarket/real-time-data-client`.
533
438
 
534
439
  ```typescript
535
- // Get token balances
536
- const balances = await ctf.getPositionBalance(conditionId);
537
- console.log(`YES: ${balances.yesBalance}, NO: ${balances.noBalance}`);
538
-
539
- // Check if market is resolved
540
- const resolution = await ctf.getMarketResolution(conditionId);
541
- if (resolution.isResolved) {
542
- console.log(`Winner: ${resolution.winningOutcome}`);
543
- }
440
+ import { RealtimeServiceV2 } from '@catalyst-team/poly-sdk';
544
441
 
545
- // Gas estimation
546
- const splitGas = await ctf.estimateSplitGas(conditionId, '100');
547
- const mergeGas = await ctf.estimateMergeGas(conditionId, '100');
548
- ```
442
+ const realtime = new RealtimeServiceV2({
443
+ autoReconnect: true,
444
+ pingInterval: 5000,
445
+ });
549
446
 
550
- #### Arbitrage Flow
447
+ // Connect and subscribe
448
+ realtime.connect();
449
+ realtime.subscribeMarket([yesTokenId, noTokenId]);
551
450
 
552
- ⚠️ **注意:必须使用有效价格计算套利,不能简单相加 ask/bid**
451
+ // Event-based API
452
+ realtime.on('priceUpdate', (update) => {
453
+ console.log(`${update.assetId}: ${update.price}`);
454
+ console.log(`Midpoint: ${update.midpoint}, Spread: ${update.spread}`);
455
+ });
553
456
 
554
- 由于 Polymarket 的镜像订单特性(见上文),正确的套利计算方式如下:
457
+ realtime.on('bookUpdate', (update) => {
458
+ // Orderbook is auto-normalized:
459
+ // bids: descending (best first), asks: ascending (best first)
460
+ console.log(`Best bid: ${update.bids[0]?.price}`);
461
+ console.log(`Best ask: ${update.asks[0]?.price}`);
462
+ });
555
463
 
556
- ```
557
- ┌─────────────────────────────────────────────────────────────┐
558
- │ LONG ARB (effectiveLongCost < $1): │
559
- │ 有效买入成本: │
560
- │ effectiveBuyYes = min(YES.ask, 1 - NO.bid) │
561
- │ effectiveBuyNo = min(NO.ask, 1 - YES.bid) │
562
- │ 操作: │
563
- │ 1. 用有效价格买入 YES + NO │
564
- │ 2. CTF Merge → $1 USDC │
565
- │ 3. Profit = 1 - effectiveLongCost │
566
- ├─────────────────────────────────────────────────────────────┤
567
- │ SHORT ARB (effectiveShortRevenue > $1): │
568
- │ 有效卖出收入: │
569
- │ effectiveSellYes = max(YES.bid, 1 - NO.ask) │
570
- │ effectiveSellNo = max(NO.bid, 1 - YES.ask) │
571
- │ 操作: │
572
- │ 1. CTF Split $1 → 1 YES + 1 NO │
573
- │ 2. 用有效价格卖出 YES + NO │
574
- │ 3. Profit = effectiveShortRevenue - 1 │
575
- └─────────────────────────────────────────────────────────────┘
576
- ```
464
+ realtime.on('lastTrade', (trade) => {
465
+ console.log(`Trade: ${trade.side} ${trade.size} @ ${trade.price}`);
466
+ });
577
467
 
578
- ```typescript
579
- import { checkArbitrage, getEffectivePrices } from '@catalyst-team/poly-sdk';
468
+ // Get cached prices
469
+ const price = realtime.getPrice(yesTokenId);
470
+ const book = realtime.getBook(yesTokenId);
580
471
 
581
- // checkArbitrage 内部使用有效价格计算
582
- const arb = checkArbitrage(yesAsk, noAsk, yesBid, noBid);
583
- if (arb?.type === 'long') {
584
- console.log(arb.description); // "Buy YES @ 0.48 + NO @ 0.50, Merge for $1"
585
- // Buy both tokens at effective prices, then merge
586
- await tradingClient.createMarketOrder({ tokenId: yesTokenId, side: 'BUY', amount: 100 });
587
- await tradingClient.createMarketOrder({ tokenId: noTokenId, side: 'BUY', amount: 100 });
588
- await ctf.merge(conditionId, '100');
589
- }
472
+ // Cleanup
473
+ realtime.disconnect();
590
474
  ```
591
475
 
592
- ### BridgeClient - Cross-Chain Deposits
476
+ ---
593
477
 
594
- Bridge assets from multiple chains (Ethereum, Solana, Bitcoin) to Polygon USDC.e for Polymarket trading.
478
+ ### WalletService
595
479
 
596
- ```
597
- ┌─────────────────────────────────────────────────────────────────────────────┐
598
- │ 跨链充值流程 │
599
- ├─────────────────────────────────────────────────────────────────────────────┤
600
- │ 1. 获取充值地址 → 2. 发送资产到地址 → 3. 自动桥接 → 4. USDC.e 到账 │
601
- └─────────────────────────────────────────────────────────────────────────────┘
602
- ```
480
+ Wallet analysis and smart money scoring.
603
481
 
604
482
  ```typescript
605
- import {
606
- BridgeClient,
607
- SUPPORTED_CHAINS,
608
- depositUsdc,
609
- swapAndDeposit,
610
- } from '@catalyst-team/poly-sdk';
483
+ // Get top traders
484
+ const traders = await sdk.wallets.getTopTraders(10);
611
485
 
612
- // Get deposit addresses for your wallet
613
- const bridge = new BridgeClient();
614
- const addresses = await bridge.createDepositAddresses(walletAddress);
615
- console.log(`EVM chains: ${addresses.address.evm}`);
616
- console.log(`Solana: ${addresses.address.svm}`);
617
- console.log(`Bitcoin: ${addresses.address.btc}`);
618
-
619
- // Get supported assets
620
- const assets = await bridge.getSupportedAssets();
621
- for (const asset of assets) {
622
- console.log(`${asset.chainName} ${asset.tokenSymbol}: min ${asset.minDepositUsd} USD`);
623
- }
486
+ // Get wallet profile with smart score
487
+ const profile = await sdk.wallets.getWalletProfile('0x...');
488
+ console.log(`Smart Score: ${profile.smartScore}/100`);
489
+ console.log(`Win Rate: ${profile.winRate}%`);
490
+ console.log(`Total PnL: $${profile.totalPnL}`);
624
491
 
625
- // Direct USDC deposit from Ethereum
626
- const depositResult = await depositUsdc(signer, '100', walletAddress);
627
- console.log(`Deposited: ${depositResult.txHash}`);
492
+ // Detect sell activity (for follow-wallet strategy)
493
+ const sellResult = await sdk.wallets.detectSellActivity(
494
+ '0x...',
495
+ conditionId,
496
+ Date.now() - 24 * 60 * 60 * 1000 // since 24h ago
497
+ );
498
+ if (sellResult.isSelling) {
499
+ console.log(`Sold ${sellResult.percentageSold}%`);
500
+ }
628
501
 
629
- // Swap ETH to USDC and deposit
630
- const swapResult = await swapAndDeposit(signer, {
631
- tokenIn: 'ETH',
632
- amountIn: '0.1',
633
- targetAddress: walletAddress,
634
- });
635
- console.log(`Swapped & deposited: ${swapResult.usdcAmount}`);
502
+ // Track group sell ratio
503
+ const groupSell = await sdk.wallets.trackGroupSellRatio(
504
+ ['0x...', '0x...'],
505
+ conditionId,
506
+ peakValue,
507
+ sinceTimestamp
508
+ );
636
509
  ```
637
510
 
638
- ### SwapService - DEX Swaps on Polygon
639
-
640
- Swap tokens on Polygon using QuickSwap V3. Essential for converting tokens to USDC.e for CTF operations.
511
+ ---
641
512
 
642
- ⚠️ **USDC vs USDC.e for Polymarket CTF**
513
+ ### SmartMoneyService
643
514
 
644
- | Token | Address | Polymarket CTF |
645
- |-------|---------|----------------|
646
- | USDC.e | `0x2791...` | ✅ **Required** |
647
- | USDC (Native) | `0x3c49...` | ❌ Not accepted |
515
+ Smart money detection and **real-time auto copy trading**.
648
516
 
649
517
  ```typescript
650
- import { SwapService, POLYGON_TOKENS } from '@catalyst-team/poly-sdk';
518
+ import { PolymarketSDK } from '@catalyst-team/poly-sdk';
651
519
 
652
- const swapService = new SwapService(signer);
520
+ // One line to get started (recommended)
521
+ const sdk = await PolymarketSDK.create({ privateKey: '0x...' });
522
+ // SDK is initialized and WebSocket connected
653
523
 
654
- // Check balances
655
- const balances = await swapService.getBalances();
656
- for (const b of balances) {
657
- console.log(`${b.symbol}: ${b.balance}`);
658
- }
524
+ // Get smart money wallets
525
+ const wallets = await sdk.smartMoney.getSmartMoneyList(50);
659
526
 
660
- // Swap native USDC to USDC.e for CTF operations
661
- const swapResult = await swapService.swap('USDC', 'USDC_E', '100');
662
- console.log(`Swapped: ${swapResult.amountOut} USDC.e`);
527
+ // Check if address is smart money
528
+ const isSmartMoney = await sdk.smartMoney.isSmartMoney('0x...');
663
529
 
664
- // Swap MATIC to USDC.e
665
- const maticSwap = await swapService.swap('MATIC', 'USDC_E', '50');
530
+ // Subscribe to smart money trades
531
+ const sub = sdk.smartMoney.subscribeSmartMoneyTrades(
532
+ (trade) => {
533
+ console.log(`${trade.traderName} ${trade.side} ${trade.outcome} @ $${trade.price}`);
534
+ },
535
+ { filterAddresses: ['0x...'], minSize: 10 }
536
+ );
666
537
 
667
- // Get quote before swapping
668
- const quote = await swapService.getQuote('WETH', 'USDC_E', '0.1');
669
- console.log(`Expected output: ${quote.estimatedAmountOut} USDC.e`);
538
+ // ===== Auto Copy Trading =====
539
+ // Real-time copy trading - when smart money trades, copy immediately
670
540
 
671
- // Transfer USDC.e (for CTF operations)
672
- await swapService.transferUsdcE(recipientAddress, '100');
673
- ```
541
+ const subscription = await sdk.smartMoney.startAutoCopyTrading({
542
+ // Target selection
543
+ topN: 50, // Follow top 50 traders from leaderboard
544
+ // targetAddresses: ['0x...'], // Or specify addresses directly
674
545
 
675
- ### AuthorizationService - Trading Approvals
546
+ // Order settings
547
+ sizeScale: 0.1, // Copy 10% of their trade size
548
+ maxSizePerTrade: 10, // Max $10 per trade
549
+ maxSlippage: 0.03, // 3% slippage tolerance
550
+ orderType: 'FOK', // FOK or FAK
676
551
 
677
- Manage ERC20 and ERC1155 approvals required for trading on Polymarket.
678
-
679
- ```typescript
680
- import { AuthorizationService } from '@catalyst-team/poly-sdk';
552
+ // Filters
553
+ minTradeSize: 5, // Only copy trades > $5
554
+ sideFilter: 'BUY', // Only copy BUY trades (optional)
681
555
 
682
- const authService = new AuthorizationService(signer);
556
+ // Testing
557
+ dryRun: true, // Set false for real trades
683
558
 
684
- // Check all allowances
685
- const status = await authService.checkAllowances();
686
- console.log(`Wallet: ${status.wallet}`);
687
- console.log(`USDC Balance: ${status.usdcBalance}`);
688
- console.log(`Trading Ready: ${status.tradingReady}`);
559
+ // Callbacks
560
+ onTrade: (trade, result) => {
561
+ console.log(`Copied ${trade.traderName}: ${result.success ? '✅' : '❌'}`);
562
+ },
563
+ onError: (error) => console.error(error),
564
+ });
689
565
 
690
- if (!status.tradingReady) {
691
- console.log('Issues:', status.issues);
566
+ console.log(`Tracking ${subscription.targetAddresses.length} wallets`);
692
567
 
693
- // Set up all required approvals
694
- const result = await authService.approveAll();
695
- console.log(result.summary);
696
- }
568
+ // Get stats
569
+ const stats = subscription.getStats();
570
+ console.log(`Detected: ${stats.tradesDetected}, Executed: ${stats.tradesExecuted}`);
697
571
 
698
- // Check individual allowances
699
- for (const allowance of status.erc20Allowances) {
700
- console.log(`${allowance.contract}: ${allowance.approved ? '✅' : '❌'}`);
701
- }
572
+ // Stop
573
+ subscription.stop();
574
+ sdk.stop();
702
575
  ```
703
576
 
704
- ### ArbitrageService - 套利服务
577
+ > **Note**: Polymarket minimum order size is **$1**. Orders below $1 will be automatically skipped.
705
578
 
706
- 实时套利检测与执行,支持市场扫描、自动再平衡、智能清仓。
579
+ 📁 **Full examples**: See [scripts/smart-money/](scripts/smart-money/) for complete working scripts:
580
+ - `04-auto-copy-trading.ts` - Full-featured auto copy trading
581
+ - `05-auto-copy-simple.ts` - Simplified SDK usage
582
+ - `06-real-copy-test.ts` - Real trading test
707
583
 
708
- ```
709
- ┌─────────────────────────────────────────────────────────────────────────────┐
710
- │ 核心功能 │
711
- ├─────────────────────────────────────────────────────────────────────────────┤
712
- │ • scanMarkets() - 扫描市场找套利机会 │
713
- │ • start(market) - 启动实时监控 + 自动执行 │
714
- │ • clearPositions() - 智能清仓 (活跃市场卖出, 已结算市场 redeem) │
715
- ├─────────────────────────────────────────────────────────────────────────────┤
716
- │ 自动再平衡 (Rebalancer) │
717
- ├─────────────────────────────────────────────────────────────────────────────┤
718
- │ 套利需要 USDC + YES/NO Token,Rebalancer 自动维持资金比例: │
719
- │ • USDC 比例 < 20% → 自动 Merge (YES+NO → USDC) │
720
- │ • USDC 比例 > 80% → 自动 Split (USDC → YES+NO) │
721
- │ • 冷却机制:两次操作间隔 ≥ 30s,检测间隔 10s │
722
- ├─────────────────────────────────────────────────────────────────────────────┤
723
- │ 执行安全 (Partial Fill Protection) │
724
- ├─────────────────────────────────────────────────────────────────────────────┤
725
- │ 套利需要同时买入 YES 和 NO,但订单可能部分成交: │
726
- │ • sizeSafetyFactor=0.8 → 只使用 80% 的盘口深度,降低滑点风险 │
727
- │ • autoFixImbalance=true → 如果只成交一侧,自动卖出多余的 token │
728
- │ • imbalanceThreshold=5 → YES-NO 差额超过 $5 时触发修复 │
729
- └─────────────────────────────────────────────────────────────────────────────┘
730
- ```
584
+ ---
585
+
586
+ ### ArbitrageService
731
587
 
732
- #### 完整工作流
588
+ Real-time arbitrage detection, execution, and position management.
733
589
 
734
590
  ```typescript
735
591
  import { ArbitrageService } from '@catalyst-team/poly-sdk';
@@ -739,20 +595,17 @@ const arbService = new ArbitrageService({
739
595
  profitThreshold: 0.005, // 0.5% minimum profit
740
596
  minTradeSize: 5, // $5 minimum
741
597
  maxTradeSize: 100, // $100 maximum
742
- autoExecute: true, // Automatically execute opportunities
743
-
744
- // Rebalancer config
745
- enableRebalancer: true, // Auto-rebalance position
746
- minUsdcRatio: 0.2, // Min 20% USDC (Split if below)
747
- maxUsdcRatio: 0.8, // Max 80% USDC (Merge if above)
748
- targetUsdcRatio: 0.5, // Target 50% when rebalancing
749
- imbalanceThreshold: 5, // Max YES-NO difference before fix
750
- rebalanceInterval: 10000, // Check every 10s
751
- rebalanceCooldown: 30000, // Min 30s between actions
752
-
753
- // Execution safety (prevents YES ≠ NO from partial fills)
598
+ autoExecute: true, // Auto-execute opportunities
599
+
600
+ // Rebalancer: auto-maintain USDC/token ratio
601
+ enableRebalancer: true,
602
+ minUsdcRatio: 0.2, // Min 20% USDC
603
+ maxUsdcRatio: 0.8, // Max 80% USDC
604
+ targetUsdcRatio: 0.5, // Target when rebalancing
605
+
606
+ // Execution safety
754
607
  sizeSafetyFactor: 0.8, // Use 80% of orderbook depth
755
- autoFixImbalance: true, // Auto-sell excess if one side fails
608
+ autoFixImbalance: true, // Auto-fix partial fills
756
609
  });
757
610
 
758
611
  // Listen for events
@@ -762,321 +615,203 @@ arbService.on('opportunity', (opp) => {
762
615
 
763
616
  arbService.on('execution', (result) => {
764
617
  if (result.success) {
765
- console.log(`✅ Executed: $${result.profit.toFixed(2)} profit`);
618
+ console.log(`Executed: $${result.profit.toFixed(2)} profit`);
766
619
  }
767
620
  });
768
621
 
769
- arbService.on('rebalance', (result) => {
770
- console.log(`🔄 Rebalance: ${result.action.type} ${result.action.amount}`);
771
- });
622
+ // ===== Workflow =====
772
623
 
773
- // ========== Step 1: 扫描市场 ==========
624
+ // 1. Scan markets for opportunities
774
625
  const results = await arbService.scanMarkets({ minVolume24h: 5000 }, 0.005);
775
- console.log(`Found ${results.filter(r => r.arbType !== 'none').length} opportunities`);
776
626
 
777
- // 或者一键扫描+启动最佳市场
627
+ // 2. Start monitoring best market
778
628
  const best = await arbService.findAndStart(0.005);
779
- if (!best) {
780
- console.log('No arbitrage opportunities found');
781
- process.exit(0);
782
- }
783
- console.log(`🎯 Started: ${best.market.name} (+${best.profitPercent.toFixed(2)}%)`);
629
+ console.log(`Started: ${best.market.name} (+${best.profitPercent.toFixed(2)}%)`);
784
630
 
785
- // ========== Step 2: 运行套利 ==========
786
- // 服务现在自动监控并执行套利...
787
- // 运行一段时间后:
788
- await new Promise(resolve => setTimeout(resolve, 60 * 60 * 1000)); // 1 hour
631
+ // 3. Run for a while...
632
+ await new Promise(r => setTimeout(r, 60 * 60 * 1000)); // 1 hour
789
633
 
790
- // ========== Step 3: 停止并清算 ==========
634
+ // 4. Stop and clear positions
791
635
  await arbService.stop();
792
- console.log('Stats:', arbService.getStats());
793
-
794
- // 智能清仓: 活跃市场 merge+sell, 已结算市场 redeem
795
636
  const clearResult = await arbService.clearPositions(best.market, true);
796
- console.log(`✅ Recovered: $${clearResult.totalUsdcRecovered.toFixed(2)}`);
637
+ console.log(`Recovered: $${clearResult.totalUsdcRecovered.toFixed(2)}`);
797
638
  ```
798
639
 
799
- #### 手动选择市场
640
+ ---
800
641
 
801
- ```typescript
802
- // 如果不用 scanMarkets,可以手动构建 market config
803
- const market = {
804
- name: 'Will BTC reach $100k?',
805
- conditionId: '0x...',
806
- yesTokenId: '12345...',
807
- noTokenId: '67890...',
808
- outcomes: ['Yes', 'No'] as [string, string],
809
- };
810
-
811
- await arbService.start(market);
812
- ```
642
+ ## Low-Level Clients
813
643
 
814
- #### 批量清仓
644
+ For advanced users who need direct API access:
815
645
 
816
646
  ```typescript
817
- // 多个市场一起清仓
818
- const markets = [market1, market2, market3];
819
- const results = await arbService.clearAllPositions(markets, true);
820
- const total = results.reduce((sum, r) => sum + r.totalUsdcRecovered, 0);
821
- console.log(`Total recovered: $${total.toFixed(2)}`);
647
+ import {
648
+ DataApiClient, // Positions, trades, leaderboard
649
+ GammaApiClient, // Markets, events, search
650
+ SubgraphClient, // On-chain data via Goldsky
651
+ CTFClient, // CTF contract operations
652
+ BridgeClient, // Cross-chain deposits
653
+ SwapService, // DEX swaps on Polygon
654
+ } from '@catalyst-team/poly-sdk';
655
+
656
+ // Data API
657
+ const positions = await sdk.dataApi.getPositions('0x...');
658
+ const trades = await sdk.dataApi.getTrades('0x...');
659
+ const leaderboard = await sdk.dataApi.getLeaderboard();
660
+
661
+ // Gamma API
662
+ const markets = await sdk.gammaApi.searchMarkets({ query: 'bitcoin' });
663
+ const trending = await sdk.gammaApi.getTrendingMarkets(10);
664
+ const events = await sdk.gammaApi.getEvents({ limit: 20 });
665
+
666
+ // Subgraph (on-chain data)
667
+ const userPositions = await sdk.subgraph.getUserPositions(address);
668
+ const isResolved = await sdk.subgraph.isConditionResolved(conditionId);
669
+ const globalOI = await sdk.subgraph.getGlobalOpenInterest();
822
670
  ```
823
671
 
824
- #### 仅监控模式
672
+ ---
825
673
 
674
+ ## Breaking Changes (v0.3.0)
675
+
676
+ ### `UnifiedMarket.tokens` is now an Array
677
+
678
+ **Before (v0.2.x)**:
826
679
  ```typescript
827
- // No private key = monitoring only, no execution
828
- const arbService = new ArbitrageService({
829
- profitThreshold: 0.003,
830
- enableLogging: true,
831
- });
680
+ // Object with yes/no properties
681
+ const yesPrice = market.tokens.yes.price;
682
+ const noPrice = market.tokens.no.price;
683
+ ```
832
684
 
833
- arbService.on('opportunity', (opp) => {
834
- // Log opportunities for analysis without executing
835
- console.log(`Found ${opp.type} arb: ${opp.profitPercent.toFixed(2)}%`);
836
- console.log(` ${opp.description}`);
837
- });
685
+ **After (v0.3.0)**:
686
+ ```typescript
687
+ // Array of MarketToken objects
688
+ const yesToken = market.tokens.find(t => t.outcome === 'Yes');
689
+ const noToken = market.tokens.find(t => t.outcome === 'No');
838
690
 
839
- await arbService.start(market);
691
+ const yesPrice = yesToken?.price;
692
+ const noPrice = noToken?.price;
840
693
  ```
841
694
 
842
- ## Price Utilities
695
+ ### Migration Guide
843
696
 
844
697
  ```typescript
845
- import {
846
- roundPrice,
847
- validatePrice,
848
- calculateBuyAmount,
849
- getEffectivePrices, // For Polymarket mirror orderbook
850
- checkArbitrage,
851
- formatUSDC,
852
- calculatePnL,
853
- type TickSize,
854
- } from '@catalyst-team/poly-sdk';
698
+ // Helper function for migration
699
+ function getTokenPrice(market: UnifiedMarket, outcome: 'Yes' | 'No'): number {
700
+ return market.tokens.find(t => t.outcome === outcome)?.price ?? 0;
701
+ }
855
702
 
856
- // Round price to tick size
857
- const tickSize: TickSize = '0.01';
858
- roundPrice(0.523, tickSize, 'floor'); // 0.52
859
- roundPrice(0.523, tickSize, 'ceil'); // 0.53
703
+ // Usage
704
+ const yesPrice = getTokenPrice(market, 'Yes');
705
+ const noPrice = getTokenPrice(market, 'No');
706
+ ```
860
707
 
861
- // Validate price
862
- const validation = validatePrice(0.525, tickSize);
863
- if (!validation.valid) {
864
- console.log(validation.error);
865
- }
708
+ **Why the change?** The array format better supports multi-outcome markets and is more consistent with the Polymarket API response format.
866
709
 
867
- // Calculate order cost
868
- const cost = calculateBuyAmount(0.52, 100); // $52
869
- console.log(formatUSDC(cost)); // "$52.00"
710
+ ---
870
711
 
871
- // Get effective prices (considering Polymarket mirror orders)
872
- const effective = getEffectivePrices(yesAsk, yesBid, noAsk, noBid);
873
- console.log(`Effective buy YES: ${effective.effectiveBuyYes}`); // min(YES.ask, 1 - NO.bid)
874
- console.log(`Effective buy NO: ${effective.effectiveBuyNo}`); // min(NO.ask, 1 - YES.bid)
712
+ ## Examples
875
713
 
876
- // Check for arbitrage (uses effective prices internally)
877
- const arb = checkArbitrage(
878
- yesAsk, noAsk, // Ask prices
879
- yesBid, noBid // Bid prices
880
- );
881
- if (arb) {
882
- console.log(`${arb.type} arb: ${(arb.profit * 100).toFixed(2)}% profit`);
883
- console.log(arb.description); // "Buy YES @ 0.48 + NO @ 0.50, Merge for $1"
884
- }
714
+ Run examples with:
885
715
 
886
- // Calculate PnL
887
- const pnl = calculatePnL(0.40, 0.55, 100, 'long');
888
- console.log(`PnL: ${formatUSDC(pnl.pnl)} (${pnl.pnlPercent.toFixed(1)}%)`);
716
+ ```bash
717
+ pnpm example:basic # Basic usage
718
+ pnpm example:smart-money # Smart money analysis
719
+ pnpm example:trading # Trading orders
720
+ pnpm example:realtime # WebSocket feeds
721
+ pnpm example:arb-service # Arbitrage service
889
722
  ```
890
723
 
891
- ## K-Line Intervals
724
+ | Example | Description |
725
+ |---------|-------------|
726
+ | [01-basic-usage.ts](examples/01-basic-usage.ts) | Get markets, orderbooks, detect arbitrage |
727
+ | [02-smart-money.ts](examples/02-smart-money.ts) | Top traders, wallet profiles, smart scores |
728
+ | [03-market-analysis.ts](examples/03-market-analysis.ts) | Market signals, volume analysis |
729
+ | [04-kline-aggregation.ts](examples/04-kline-aggregation.ts) | Build OHLCV candles from trades |
730
+ | [05-follow-wallet-strategy.ts](examples/05-follow-wallet-strategy.ts) | Track smart money, detect exits |
731
+ | [06-services-demo.ts](examples/06-services-demo.ts) | All SDK services in action |
732
+ | [07-realtime-websocket.ts](examples/07-realtime-websocket.ts) | Live price feeds, orderbook updates |
733
+ | [08-trading-orders.ts](examples/08-trading-orders.ts) | GTC, GTD, FOK, FAK order types |
734
+ | [09-rewards-tracking.ts](examples/09-rewards-tracking.ts) | Market maker incentives, earnings |
735
+ | [10-ctf-operations.ts](examples/10-ctf-operations.ts) | Split, merge, redeem tokens |
736
+ | [11-live-arbitrage-scan.ts](examples/11-live-arbitrage-scan.ts) | Scan markets for opportunities |
737
+ | [12-trending-arb-monitor.ts](examples/12-trending-arb-monitor.ts) | Real-time trending monitor |
738
+ | [13-arbitrage-service.ts](examples/13-arbitrage-service.ts) | Full arbitrage workflow |
892
739
 
893
- Supported intervals: `30s`, `1m`, `5m`, `15m`, `30m`, `1h`, `4h`, `12h`, `1d`
740
+ ---
894
741
 
895
- ```typescript
896
- import type { KLineInterval } from '@catalyst-team/poly-sdk';
742
+ ## API Reference
897
743
 
898
- const interval: KLineInterval = '1h';
899
- const candles = await sdk.markets.getKLines(conditionId, interval);
900
- ```
744
+ For detailed API documentation, see:
745
+
746
+ - [docs/00-design.md](docs/00-design.md) - Architecture design
747
+ - [docs/02-API.md](docs/02-API.md) - Complete API reference
748
+ - [docs/01-polymarket-orderbook-arbitrage.md](docs/01-polymarket-orderbook-arbitrage.md) - Orderbook mirror & arbitrage
901
749
 
902
- ## Types
750
+ ### Type Exports
903
751
 
904
752
  ```typescript
905
753
  import type {
906
- // Core
754
+ // Core types
907
755
  UnifiedMarket,
908
- PriceUpdate,
909
- BookUpdate,
756
+ MarketToken,
910
757
  ProcessedOrderbook,
911
758
  ArbitrageOpportunity,
912
- EffectivePrices, // Effective prices for Polymarket mirror orderbook
759
+ EffectivePrices,
913
760
 
914
- // K-Lines & Spread
761
+ // Trading
762
+ Side,
763
+ OrderType,
764
+ Order,
765
+ OrderResult,
766
+ LimitOrderParams,
767
+ MarketOrderParams,
768
+
769
+ // K-Lines
915
770
  KLineInterval,
916
771
  KLineCandle,
917
772
  DualKLineData,
918
- SpreadDataPoint, // Historical spread (trade prices)
773
+ SpreadDataPoint,
774
+
775
+ // WebSocket
776
+ PriceUpdate,
777
+ BookUpdate,
778
+ OrderbookSnapshot,
919
779
 
920
780
  // Wallet
921
781
  WalletProfile,
922
782
  SellActivityResult,
923
783
 
924
- // Trading
925
- Side,
926
- OrderType,
927
- OrderParams,
928
- MarketOrderParams,
929
- Order,
930
- OrderResult,
931
- TradeInfo,
932
-
933
- // Rewards
934
- UserEarning,
935
- MarketReward,
784
+ // Smart Money
785
+ SmartMoneyWallet,
786
+ SmartMoneyTrade,
787
+ AutoCopyTradingOptions,
788
+ AutoCopyTradingStats,
789
+ AutoCopyTradingSubscription,
936
790
 
937
791
  // CTF
938
- CTFConfig,
939
792
  SplitResult,
940
793
  MergeResult,
941
794
  RedeemResult,
942
- PositionBalance,
943
- MarketResolution,
944
- TokenIds,
945
-
946
- // Bridge
947
- BridgeSupportedAsset,
948
- DepositAddress,
949
- DepositStatus,
950
- DepositResult,
951
- SwapAndDepositResult,
952
-
953
- // Swap
954
- SupportedToken,
955
- SwapQuote,
956
- SwapResult,
957
- TokenBalance,
958
-
959
- // Authorization
960
- AllowanceInfo,
961
- AllowancesResult,
962
- ApprovalTxResult,
963
-
964
- // ArbitrageService
795
+
796
+ // Arbitrage
965
797
  ArbitrageMarketConfig,
966
798
  ArbitrageServiceConfig,
967
- ArbitrageServiceOpportunity,
968
- ArbitrageExecutionResult,
969
- OrderbookState,
970
- BalanceState,
971
- RebalanceAction,
972
- RebalanceResult,
973
- SettleResult,
974
- // ArbitrageService - Scanning
975
- ScanCriteria,
976
799
  ScanResult,
977
- // ArbitrageService - Smart clearing
978
800
  ClearPositionResult,
979
- ClearAction,
980
-
981
- // Price Utils
982
- TickSize,
983
-
984
- // API types
985
- Position,
986
- Trade,
987
- LeaderboardEntry,
988
- GammaMarket,
989
- ClobMarket,
990
- Orderbook,
991
801
  } from '@catalyst-team/poly-sdk';
992
802
  ```
993
803
 
994
- ## Error Handling
995
-
996
- ```typescript
997
- import { PolymarketError, ErrorCode, withRetry } from '@catalyst-team/poly-sdk';
998
-
999
- try {
1000
- const market = await sdk.getMarket('invalid-slug');
1001
- } catch (error) {
1002
- if (error instanceof PolymarketError) {
1003
- if (error.code === ErrorCode.MARKET_NOT_FOUND) {
1004
- console.log('Market not found');
1005
- } else if (error.code === ErrorCode.RATE_LIMITED) {
1006
- console.log('Rate limited, retry later');
1007
- }
1008
- }
1009
- }
1010
-
1011
- // Auto-retry with exponential backoff
1012
- const result = await withRetry(() => sdk.getMarket(slug), {
1013
- maxRetries: 3,
1014
- baseDelay: 1000,
1015
- });
1016
- ```
1017
-
1018
- ## Rate Limiting
1019
-
1020
- Built-in rate limiting per API type:
1021
- - Data API: 10 req/sec
1022
- - Gamma API: 10 req/sec
1023
- - CLOB API: 5 req/sec
1024
-
1025
- ```typescript
1026
- import { RateLimiter, ApiType } from '@catalyst-team/poly-sdk';
1027
-
1028
- // Custom rate limiter
1029
- const limiter = new RateLimiter({
1030
- [ApiType.DATA]: { maxConcurrent: 5, minTime: 200 },
1031
- [ApiType.GAMMA]: { maxConcurrent: 5, minTime: 200 },
1032
- [ApiType.CLOB]: { maxConcurrent: 2, minTime: 500 },
1033
- });
1034
- ```
1035
-
1036
- ## Caching
1037
-
1038
- Built-in TTL-based caching:
1039
-
1040
- ```typescript
1041
- // Clear all cache
1042
- sdk.clearCache();
1043
-
1044
- // Invalidate specific market
1045
- sdk.invalidateMarketCache(conditionId);
1046
- ```
1047
-
1048
- ## Examples
1049
-
1050
- | Example | Description | Source |
1051
- |---------|-------------|--------|
1052
- | [Basic Usage](examples/01-basic-usage.ts) | Get markets, orderbooks, detect arbitrage | `pnpm example:basic` |
1053
- | [Smart Money](examples/02-smart-money.ts) | Top traders, wallet profiles, smart scores | `pnpm example:smart-money` |
1054
- | [Market Analysis](examples/03-market-analysis.ts) | Market signals, volume analysis | `pnpm example:market-analysis` |
1055
- | [K-Line Aggregation](examples/04-kline-aggregation.ts) | Build OHLCV candles from trades | `pnpm example:kline` |
1056
- | [Follow Wallet](examples/05-follow-wallet-strategy.ts) | Track smart money positions, detect exits | `pnpm example:follow-wallet` |
1057
- | [Services Demo](examples/06-services-demo.ts) | All SDK services in action | `pnpm example:services` |
1058
- | [Realtime WebSocket](examples/07-realtime-websocket.ts) | Live price feeds, orderbook updates | `pnpm example:realtime` |
1059
- | [Trading Orders](examples/08-trading-orders.ts) | GTC, GTD, FOK, FAK order types | `pnpm example:trading` |
1060
- | [Rewards Tracking](examples/09-rewards-tracking.ts) | Market maker incentives, earnings | `pnpm example:rewards` |
1061
- | [CTF Operations](examples/10-ctf-operations.ts) | Split, merge, redeem tokens | `pnpm example:ctf` |
1062
- | [Live Arbitrage Scan](examples/11-live-arbitrage-scan.ts) | Scan real markets for opportunities | `pnpm example:live-arb` |
1063
- | [Trending Arb Monitor](examples/12-trending-arb-monitor.ts) | Real-time trending markets monitor | `pnpm example:trending-arb` |
1064
-
1065
- Run any example:
1066
-
1067
- ```bash
1068
- pnpm example:basic
1069
- pnpm example:smart-money
1070
- pnpm example:trading
1071
- # etc.
1072
- ```
804
+ ---
1073
805
 
1074
806
  ## Dependencies
1075
807
 
1076
- - `@nevuamarkets/poly-websockets` - WebSocket client
808
+ - `@polymarket/clob-client` - Official CLOB trading client
809
+ - `@polymarket/real-time-data-client` - Official WebSocket client
810
+ - `ethers@5` - Blockchain interactions
1077
811
  - `bottleneck` - Rate limiting
1078
- - `ethers` - Blockchain interactions (for CTFClient)
812
+
813
+ ---
1079
814
 
1080
815
  ## License
1081
816
 
1082
- Private
817
+ MIT