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