@catalyst-team/poly-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/.env +0 -0
  2. package/README.md +803 -0
  3. package/dist/__tests__/clob-api.test.d.ts +5 -0
  4. package/dist/__tests__/clob-api.test.d.ts.map +1 -0
  5. package/dist/__tests__/clob-api.test.js +240 -0
  6. package/dist/__tests__/clob-api.test.js.map +1 -0
  7. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +11 -0
  8. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +1 -0
  9. package/dist/__tests__/integration/bridge-client.integration.test.js +260 -0
  10. package/dist/__tests__/integration/bridge-client.integration.test.js.map +1 -0
  11. package/dist/__tests__/integration/clob-api.integration.test.d.ts +13 -0
  12. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +1 -0
  13. package/dist/__tests__/integration/clob-api.integration.test.js +170 -0
  14. package/dist/__tests__/integration/clob-api.integration.test.js.map +1 -0
  15. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +17 -0
  16. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +1 -0
  17. package/dist/__tests__/integration/ctf-client.integration.test.js +234 -0
  18. package/dist/__tests__/integration/ctf-client.integration.test.js.map +1 -0
  19. package/dist/__tests__/integration/data-api.integration.test.d.ts +9 -0
  20. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +1 -0
  21. package/dist/__tests__/integration/data-api.integration.test.js +161 -0
  22. package/dist/__tests__/integration/data-api.integration.test.js.map +1 -0
  23. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +9 -0
  24. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +1 -0
  25. package/dist/__tests__/integration/gamma-api.integration.test.js +170 -0
  26. package/dist/__tests__/integration/gamma-api.integration.test.js.map +1 -0
  27. package/dist/__tests__/test-utils.d.ts +92 -0
  28. package/dist/__tests__/test-utils.d.ts.map +1 -0
  29. package/dist/__tests__/test-utils.js +143 -0
  30. package/dist/__tests__/test-utils.js.map +1 -0
  31. package/dist/clients/bridge-client.d.ts +388 -0
  32. package/dist/clients/bridge-client.d.ts.map +1 -0
  33. package/dist/clients/bridge-client.js +587 -0
  34. package/dist/clients/bridge-client.js.map +1 -0
  35. package/dist/clients/clob-api.d.ts +318 -0
  36. package/dist/clients/clob-api.d.ts.map +1 -0
  37. package/dist/clients/clob-api.js +388 -0
  38. package/dist/clients/clob-api.js.map +1 -0
  39. package/dist/clients/ctf-client.d.ts +473 -0
  40. package/dist/clients/ctf-client.d.ts.map +1 -0
  41. package/dist/clients/ctf-client.js +915 -0
  42. package/dist/clients/ctf-client.js.map +1 -0
  43. package/dist/clients/data-api.d.ts +134 -0
  44. package/dist/clients/data-api.d.ts.map +1 -0
  45. package/dist/clients/data-api.js +265 -0
  46. package/dist/clients/data-api.js.map +1 -0
  47. package/dist/clients/gamma-api.d.ts +401 -0
  48. package/dist/clients/gamma-api.d.ts.map +1 -0
  49. package/dist/clients/gamma-api.js +352 -0
  50. package/dist/clients/gamma-api.js.map +1 -0
  51. package/dist/clients/trading-client.d.ts +252 -0
  52. package/dist/clients/trading-client.d.ts.map +1 -0
  53. package/dist/clients/trading-client.js +543 -0
  54. package/dist/clients/trading-client.js.map +1 -0
  55. package/dist/clients/websocket-manager.d.ts +100 -0
  56. package/dist/clients/websocket-manager.d.ts.map +1 -0
  57. package/dist/clients/websocket-manager.js +193 -0
  58. package/dist/clients/websocket-manager.js.map +1 -0
  59. package/dist/core/cache-adapter-bridge.d.ts +36 -0
  60. package/dist/core/cache-adapter-bridge.d.ts.map +1 -0
  61. package/dist/core/cache-adapter-bridge.js +81 -0
  62. package/dist/core/cache-adapter-bridge.js.map +1 -0
  63. package/dist/core/cache.d.ts +40 -0
  64. package/dist/core/cache.d.ts.map +1 -0
  65. package/dist/core/cache.js +71 -0
  66. package/dist/core/cache.js.map +1 -0
  67. package/dist/core/errors.d.ts +38 -0
  68. package/dist/core/errors.d.ts.map +1 -0
  69. package/dist/core/errors.js +84 -0
  70. package/dist/core/errors.js.map +1 -0
  71. package/dist/core/rate-limiter.d.ts +31 -0
  72. package/dist/core/rate-limiter.d.ts.map +1 -0
  73. package/dist/core/rate-limiter.js +70 -0
  74. package/dist/core/rate-limiter.js.map +1 -0
  75. package/dist/core/types.d.ts +314 -0
  76. package/dist/core/types.d.ts.map +1 -0
  77. package/dist/core/types.js +19 -0
  78. package/dist/core/types.js.map +1 -0
  79. package/dist/core/unified-cache.d.ts +63 -0
  80. package/dist/core/unified-cache.d.ts.map +1 -0
  81. package/dist/core/unified-cache.js +114 -0
  82. package/dist/core/unified-cache.js.map +1 -0
  83. package/dist/index.d.ts +94 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +258 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/mcp/errors.d.ts +33 -0
  88. package/dist/mcp/errors.d.ts.map +1 -0
  89. package/dist/mcp/errors.js +86 -0
  90. package/dist/mcp/errors.js.map +1 -0
  91. package/dist/mcp/index.d.ts +62 -0
  92. package/dist/mcp/index.d.ts.map +1 -0
  93. package/dist/mcp/index.js +173 -0
  94. package/dist/mcp/index.js.map +1 -0
  95. package/dist/mcp/server.d.ts +17 -0
  96. package/dist/mcp/server.d.ts.map +1 -0
  97. package/dist/mcp/server.js +155 -0
  98. package/dist/mcp/server.js.map +1 -0
  99. package/dist/mcp/tools/guide.d.ts +12 -0
  100. package/dist/mcp/tools/guide.d.ts.map +1 -0
  101. package/dist/mcp/tools/guide.js +801 -0
  102. package/dist/mcp/tools/guide.js.map +1 -0
  103. package/dist/mcp/tools/index.d.ts +11 -0
  104. package/dist/mcp/tools/index.d.ts.map +1 -0
  105. package/dist/mcp/tools/index.js +27 -0
  106. package/dist/mcp/tools/index.js.map +1 -0
  107. package/dist/mcp/tools/market.d.ts +11 -0
  108. package/dist/mcp/tools/market.d.ts.map +1 -0
  109. package/dist/mcp/tools/market.js +314 -0
  110. package/dist/mcp/tools/market.js.map +1 -0
  111. package/dist/mcp/tools/order.d.ts +10 -0
  112. package/dist/mcp/tools/order.d.ts.map +1 -0
  113. package/dist/mcp/tools/order.js +258 -0
  114. package/dist/mcp/tools/order.js.map +1 -0
  115. package/dist/mcp/tools/trade.d.ts +38 -0
  116. package/dist/mcp/tools/trade.d.ts.map +1 -0
  117. package/dist/mcp/tools/trade.js +314 -0
  118. package/dist/mcp/tools/trade.js.map +1 -0
  119. package/dist/mcp/tools/trader.d.ts +11 -0
  120. package/dist/mcp/tools/trader.d.ts.map +1 -0
  121. package/dist/mcp/tools/trader.js +277 -0
  122. package/dist/mcp/tools/trader.js.map +1 -0
  123. package/dist/mcp/tools/wallet.d.ts +274 -0
  124. package/dist/mcp/tools/wallet.d.ts.map +1 -0
  125. package/dist/mcp/tools/wallet.js +579 -0
  126. package/dist/mcp/tools/wallet.js.map +1 -0
  127. package/dist/mcp/types.d.ts +413 -0
  128. package/dist/mcp/types.d.ts.map +1 -0
  129. package/dist/mcp/types.js +5 -0
  130. package/dist/mcp/types.js.map +1 -0
  131. package/dist/services/authorization-service.d.ts +97 -0
  132. package/dist/services/authorization-service.d.ts.map +1 -0
  133. package/dist/services/authorization-service.js +279 -0
  134. package/dist/services/authorization-service.js.map +1 -0
  135. package/dist/services/market-service.d.ts +108 -0
  136. package/dist/services/market-service.d.ts.map +1 -0
  137. package/dist/services/market-service.js +458 -0
  138. package/dist/services/market-service.js.map +1 -0
  139. package/dist/services/realtime-service.d.ts +82 -0
  140. package/dist/services/realtime-service.d.ts.map +1 -0
  141. package/dist/services/realtime-service.js +150 -0
  142. package/dist/services/realtime-service.js.map +1 -0
  143. package/dist/services/swap-service.d.ts +217 -0
  144. package/dist/services/swap-service.d.ts.map +1 -0
  145. package/dist/services/swap-service.js +695 -0
  146. package/dist/services/swap-service.js.map +1 -0
  147. package/dist/services/wallet-service.d.ts +94 -0
  148. package/dist/services/wallet-service.d.ts.map +1 -0
  149. package/dist/services/wallet-service.js +173 -0
  150. package/dist/services/wallet-service.js.map +1 -0
  151. package/dist/utils/price-utils.d.ts +153 -0
  152. package/dist/utils/price-utils.d.ts.map +1 -0
  153. package/dist/utils/price-utils.js +236 -0
  154. package/dist/utils/price-utils.js.map +1 -0
  155. package/docs/00-design.md +760 -0
  156. package/docs/01-mcp.md +2041 -0
  157. package/docs/02-API.md +1148 -0
  158. package/docs/e2e/01-trader-tools.md +159 -0
  159. package/docs/e2e/02-market-tools.md +180 -0
  160. package/docs/e2e/03-order-tools.md +166 -0
  161. package/docs/e2e/04-wallet-tools.md +224 -0
  162. package/docs/e2e/05-trading-tools.md +327 -0
  163. package/docs/e2e/06-integration-scenarios.md +481 -0
  164. package/docs/e2e/coordinator.md +376 -0
  165. package/examples/01-basic-usage.ts +68 -0
  166. package/examples/02-smart-money.ts +95 -0
  167. package/examples/03-market-analysis.ts +108 -0
  168. package/examples/04-kline-aggregation.ts +158 -0
  169. package/examples/05-follow-wallet-strategy.ts +156 -0
  170. package/examples/06-services-demo.ts +124 -0
  171. package/examples/07-realtime-websocket.ts +117 -0
  172. package/examples/08-trading-orders.ts +278 -0
  173. package/examples/09-rewards-tracking.ts +187 -0
  174. package/examples/10-ctf-operations.ts +336 -0
  175. package/examples/11-live-arbitrage-scan.ts +221 -0
  176. package/examples/12-trending-arb-monitor.ts +406 -0
  177. package/examples/README.md +179 -0
  178. package/package.json +62 -0
  179. package/scripts/README.md +163 -0
  180. package/scripts/approvals/approve-erc1155.ts +129 -0
  181. package/scripts/approvals/approve-neg-risk-erc1155.ts +149 -0
  182. package/scripts/approvals/approve-neg-risk.ts +102 -0
  183. package/scripts/approvals/check-all-allowances.ts +150 -0
  184. package/scripts/approvals/check-allowance.ts +129 -0
  185. package/scripts/approvals/check-ctf-approval.ts +158 -0
  186. package/scripts/datas/001-report.md +486 -0
  187. package/scripts/datas/clone-modal-screenshot.png +0 -0
  188. package/scripts/deposit/deposit-native-usdc.ts +179 -0
  189. package/scripts/deposit/deposit-usdc.ts +155 -0
  190. package/scripts/deposit/swap-usdc-to-usdce.ts +375 -0
  191. package/scripts/research/research-markets.ts +166 -0
  192. package/scripts/trading/check-orders.ts +50 -0
  193. package/scripts/trading/sell-nvidia-positions.ts +206 -0
  194. package/scripts/trading/test-order.ts +172 -0
  195. package/scripts/truth.md +440 -0
  196. package/scripts/verify/test-approve-trading.ts +98 -0
  197. package/scripts/verify/test-provider-fix.ts +43 -0
  198. package/scripts/verify/test-search-mcp.ts +113 -0
  199. package/scripts/verify/verify-all-apis.ts +160 -0
  200. package/scripts/wallet/check-wallet-balances.ts +75 -0
  201. package/scripts/wallet/test-wallet-operations.ts +191 -0
  202. package/scripts/wallet/verify-wallet-tools.ts +124 -0
  203. package/src/__tests__/clob-api.test.ts +301 -0
  204. package/src/__tests__/integration/bridge-client.integration.test.ts +314 -0
  205. package/src/__tests__/integration/clob-api.integration.test.ts +218 -0
  206. package/src/__tests__/integration/ctf-client.integration.test.ts +331 -0
  207. package/src/__tests__/integration/data-api.integration.test.ts +194 -0
  208. package/src/__tests__/integration/gamma-api.integration.test.ts +206 -0
  209. package/src/__tests__/test-utils.ts +170 -0
  210. package/src/clients/bridge-client.ts +841 -0
  211. package/src/clients/clob-api.ts +629 -0
  212. package/src/clients/ctf-client.ts +1216 -0
  213. package/src/clients/data-api.ts +469 -0
  214. package/src/clients/gamma-api.ts +597 -0
  215. package/src/clients/trading-client.ts +749 -0
  216. package/src/clients/websocket-manager.ts +267 -0
  217. package/src/core/cache-adapter-bridge.ts +94 -0
  218. package/src/core/cache.ts +85 -0
  219. package/src/core/errors.ts +117 -0
  220. package/src/core/rate-limiter.ts +74 -0
  221. package/src/core/types.ts +360 -0
  222. package/src/core/unified-cache.ts +153 -0
  223. package/src/index.ts +455 -0
  224. package/src/mcp/README.md +380 -0
  225. package/src/mcp/errors.ts +124 -0
  226. package/src/mcp/index.ts +309 -0
  227. package/src/mcp/server.ts +183 -0
  228. package/src/mcp/tools/guide.ts +821 -0
  229. package/src/mcp/tools/index.ts +73 -0
  230. package/src/mcp/tools/market.ts +363 -0
  231. package/src/mcp/tools/order.ts +326 -0
  232. package/src/mcp/tools/trade.ts +417 -0
  233. package/src/mcp/tools/trader.ts +322 -0
  234. package/src/mcp/tools/wallet.ts +683 -0
  235. package/src/mcp/types.ts +472 -0
  236. package/src/services/authorization-service.ts +357 -0
  237. package/src/services/market-service.ts +544 -0
  238. package/src/services/realtime-service.ts +196 -0
  239. package/src/services/swap-service.ts +896 -0
  240. package/src/services/wallet-service.ts +259 -0
  241. package/src/utils/price-utils.ts +307 -0
  242. package/tsconfig.json +8 -0
  243. package/vitest.config.ts +19 -0
  244. package/vitest.integration.config.ts +18 -0
package/docs/02-API.md ADDED
@@ -0,0 +1,1148 @@
1
+ # @prediction-router/poly-sdk API Reference
2
+
3
+ Complete API documentation for the Polymarket SDK.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Quick Start](#quick-start)
9
+ - [Core Clients](#core-clients)
10
+ - [PolymarketSDK](#polymarketsdk)
11
+ - [ClobApiClient](#clobapiclient)
12
+ - [GammaApiClient](#gammaapiclient)
13
+ - [DataApiClient](#dataapiclient)
14
+ - [TradingClient](#tradingclient)
15
+ - [BridgeClient](#bridgeclient)
16
+ - [CTFClient](#ctfclient)
17
+ - [WebSocketManager](#websocketmanager)
18
+ - [Services](#services)
19
+ - [MarketService](#marketservice)
20
+ - [ArbitrageService](#arbitrageservice)
21
+ - [RealtimeService](#realtimeservice)
22
+ - [WalletService](#walletservice)
23
+ - [Utility Functions](#utility-functions)
24
+ - [Types](#types)
25
+ - [Error Handling](#error-handling)
26
+
27
+ ---
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pnpm add @prediction-router/poly-sdk
33
+ ```
34
+
35
+ ## Quick Start
36
+
37
+ ```typescript
38
+ import { PolymarketSDK } from '@prediction-router/poly-sdk';
39
+
40
+ const sdk = new PolymarketSDK();
41
+
42
+ // Get trending markets
43
+ const markets = await sdk.gammaApi.getTrendingMarkets(10);
44
+
45
+ // Get orderbook for a specific market
46
+ const orderbook = await sdk.clobApi.getProcessedOrderbook(markets[0].conditionId);
47
+
48
+ console.log('Long arb profit:', orderbook.summary.longArbProfit);
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Core Clients
54
+
55
+ ### PolymarketSDK
56
+
57
+ The main SDK class that provides access to all API clients.
58
+
59
+ ```typescript
60
+ import { PolymarketSDK } from '@prediction-router/poly-sdk';
61
+
62
+ const sdk = new PolymarketSDK(config?: PolymarketSDKConfig);
63
+ ```
64
+
65
+ #### Constructor Parameters
66
+
67
+ | Parameter | Type | Description |
68
+ |-----------|------|-------------|
69
+ | `config.chainId` | `number` | Polygon chain ID (137 = mainnet, 80002 = Amoy testnet) |
70
+ | `config.privateKey` | `string` | Private key for trading operations |
71
+ | `config.apiCredentials` | `ApiCredentials` | Pre-generated API credentials |
72
+
73
+ #### Properties
74
+
75
+ | Property | Type | Description |
76
+ |----------|------|-------------|
77
+ | `gammaApi` | `GammaApiClient` | Market discovery and metadata |
78
+ | `clobApi` | `ClobApiClient` | Orderbook and market data |
79
+ | `dataApi` | `DataApiClient` | Positions, trades, leaderboard |
80
+
81
+ ---
82
+
83
+ ### ClobApiClient
84
+
85
+ Central Limit Order Book (CLOB) API client for orderbook and market data.
86
+
87
+ ```typescript
88
+ import { ClobApiClient, RateLimiter, Cache } from '@prediction-router/poly-sdk';
89
+
90
+ const client = new ClobApiClient(
91
+ rateLimiter: RateLimiter,
92
+ cache: Cache,
93
+ config?: {
94
+ chainId?: number;
95
+ signer?: unknown;
96
+ creds?: ApiCredentials;
97
+ }
98
+ );
99
+ ```
100
+
101
+ #### Methods
102
+
103
+ ##### `getMarket(conditionId: string): Promise<ClobMarket>`
104
+
105
+ Get market information by condition ID.
106
+
107
+ ```typescript
108
+ const market = await client.getMarket('0x82ace55...');
109
+ console.log(market.question); // "Will BTC reach $100k?"
110
+ console.log(market.tokens[0].tokenId); // YES token ID
111
+ console.log(market.tokens[1].tokenId); // NO token ID
112
+ ```
113
+
114
+ **Parameters:**
115
+ - `conditionId` - The unique condition identifier for the market
116
+
117
+ **Returns:** `ClobMarket` object with market details and tokens
118
+
119
+ ---
120
+
121
+ ##### `getOrderbook(tokenId: string): Promise<Orderbook>`
122
+
123
+ Get raw orderbook for a specific token.
124
+
125
+ ```typescript
126
+ const orderbook = await client.getOrderbook('21742633...');
127
+
128
+ console.log('Best bid:', orderbook.bids[0]?.price); // e.g., 0.55
129
+ console.log('Best ask:', orderbook.asks[0]?.price); // e.g., 0.57
130
+ console.log('Spread:', orderbook.asks[0]?.price - orderbook.bids[0]?.price);
131
+ ```
132
+
133
+ **Parameters:**
134
+ - `tokenId` - The ERC-1155 token ID (YES or NO token)
135
+
136
+ **Returns:** `Orderbook` with sorted bids and asks
137
+
138
+ ---
139
+
140
+ ##### `getProcessedOrderbook(conditionId: string): Promise<ProcessedOrderbook>`
141
+
142
+ Get processed orderbook with complete market analysis and arbitrage calculations.
143
+
144
+ ```typescript
145
+ const processed = await client.getProcessedOrderbook('0x82ace55...');
146
+
147
+ // Check for arbitrage
148
+ if (processed.summary.longArbProfit > 0.003) {
149
+ console.log('Long arb opportunity!');
150
+ console.log('Buy YES @', processed.summary.effectivePrices.effectiveBuyYes);
151
+ console.log('Buy NO @', processed.summary.effectivePrices.effectiveBuyNo);
152
+ console.log('Profit:', processed.summary.longArbProfit * 100, '%');
153
+ }
154
+ ```
155
+
156
+ **Parameters:**
157
+ - `conditionId` - The unique condition identifier for the market
158
+
159
+ **Returns:** `ProcessedOrderbook` with both YES/NO books and analytics
160
+
161
+ **Important Notes:**
162
+
163
+ Polymarket orderbooks have a mirroring property:
164
+ - Buying YES @ P = Selling NO @ (1-P)
165
+ - The same order appears in both books
166
+
167
+ Correct arbitrage calculation uses "effective prices":
168
+ - `effectiveBuyYes = min(YES.ask, 1 - NO.bid)`
169
+ - `effectiveBuyNo = min(NO.ask, 1 - YES.bid)`
170
+
171
+ ---
172
+
173
+ ### GammaApiClient
174
+
175
+ Market discovery and metadata API client.
176
+
177
+ ```typescript
178
+ import { GammaApiClient, RateLimiter, Cache } from '@prediction-router/poly-sdk';
179
+
180
+ const client = new GammaApiClient(rateLimiter: RateLimiter, cache: Cache);
181
+ ```
182
+
183
+ #### Methods
184
+
185
+ ##### `getMarkets(params?: MarketSearchParams): Promise<GammaMarket[]>`
186
+
187
+ Get markets with optional filters and sorting.
188
+
189
+ ```typescript
190
+ // Get active markets sorted by 24h volume
191
+ const markets = await client.getMarkets({
192
+ active: true,
193
+ closed: false,
194
+ order: 'volume24hr',
195
+ ascending: false,
196
+ limit: 50,
197
+ });
198
+
199
+ // Search by slug
200
+ const market = await client.getMarkets({
201
+ slug: 'will-btc-reach-100k',
202
+ limit: 1,
203
+ });
204
+ ```
205
+
206
+ **MarketSearchParams:**
207
+
208
+ | Parameter | Type | Description |
209
+ |-----------|------|-------------|
210
+ | `slug` | `string` | Filter by market slug |
211
+ | `conditionId` | `string` | Filter by condition ID |
212
+ | `active` | `boolean` | Filter by active status |
213
+ | `closed` | `boolean` | Filter by closed status |
214
+ | `limit` | `number` | Maximum results (default: 100) |
215
+ | `offset` | `number` | Pagination offset |
216
+ | `order` | `string` | Sort field: `volume24hr`, `liquidity`, `endDate` |
217
+ | `ascending` | `boolean` | Sort direction |
218
+
219
+ ---
220
+
221
+ ##### `getTrendingMarkets(limit?: number): Promise<GammaMarket[]>`
222
+
223
+ Get trending markets sorted by 24-hour volume.
224
+
225
+ ```typescript
226
+ const trending = await client.getTrendingMarkets(10);
227
+
228
+ for (const market of trending) {
229
+ console.log(`${market.question}`);
230
+ console.log(` 24h Volume: $${market.volume24hr?.toLocaleString()}`);
231
+ console.log(` YES Price: ${(market.outcomePrices[0] * 100).toFixed(1)}%`);
232
+ }
233
+ ```
234
+
235
+ ---
236
+
237
+ ##### `getEvents(params?): Promise<GammaEvent[]>`
238
+
239
+ Get events (market groupings) with optional filters.
240
+
241
+ ```typescript
242
+ const events = await client.getEvents({ active: true, limit: 20 });
243
+ ```
244
+
245
+ ---
246
+
247
+ ### DataApiClient
248
+
249
+ User data, positions, and leaderboard API client.
250
+
251
+ ```typescript
252
+ import { DataApiClient, RateLimiter, Cache } from '@prediction-router/poly-sdk';
253
+
254
+ const client = new DataApiClient(rateLimiter: RateLimiter, cache: Cache);
255
+ ```
256
+
257
+ #### Methods
258
+
259
+ ##### `getPositions(address: string): Promise<Position[]>`
260
+
261
+ Get positions for a wallet address.
262
+
263
+ ```typescript
264
+ const positions = await client.getPositions('0x1234...');
265
+ for (const pos of positions) {
266
+ console.log(`${pos.title}: ${pos.size} shares @ ${pos.avgPrice}`);
267
+ console.log(` PnL: $${pos.cashPnl?.toFixed(2)}`);
268
+ }
269
+ ```
270
+
271
+ ---
272
+
273
+ ##### `getActivity(address: string, params?): Promise<Activity[]>`
274
+
275
+ Get trading activity for a wallet.
276
+
277
+ ```typescript
278
+ const activity = await client.getActivity('0x1234...', { limit: 50 });
279
+ ```
280
+
281
+ ---
282
+
283
+ ##### `getTrades(params?): Promise<Trade[]>`
284
+
285
+ Get recent trades, optionally filtered by market.
286
+
287
+ ```typescript
288
+ const trades = await client.getTrades({ market: '0x82ace55...', limit: 100 });
289
+ ```
290
+
291
+ ---
292
+
293
+ ##### `getLeaderboard(params?): Promise<LeaderboardPage>`
294
+
295
+ Get leaderboard rankings.
296
+
297
+ ```typescript
298
+ const leaderboard = await client.getLeaderboard({ limit: 50, offset: 0 });
299
+ for (const entry of leaderboard.entries) {
300
+ console.log(`#${entry.rank} ${entry.address}: $${entry.pnl.toFixed(2)}`);
301
+ }
302
+ ```
303
+
304
+ ---
305
+
306
+ ### TradingClient
307
+
308
+ Trading operations client (requires authentication).
309
+
310
+ ```typescript
311
+ import { TradingClient, RateLimiter } from '@prediction-router/poly-sdk';
312
+
313
+ const client = new TradingClient(rateLimiter: RateLimiter, {
314
+ privateKey: '0x...',
315
+ chainId: 137, // Polygon mainnet
316
+ });
317
+
318
+ await client.initialize();
319
+ ```
320
+
321
+ #### Methods
322
+
323
+ ##### `createOrder(params: OrderParams): Promise<OrderResult>`
324
+
325
+ Create and post a limit order.
326
+
327
+ ```typescript
328
+ const result = await client.createOrder({
329
+ tokenId: '21742633...',
330
+ side: 'BUY',
331
+ price: 0.55,
332
+ size: 100,
333
+ orderType: 'GTC', // Good-til-cancelled
334
+ });
335
+
336
+ if (result.success) {
337
+ console.log('Order placed:', result.orderId);
338
+ }
339
+ ```
340
+
341
+ **OrderParams:**
342
+
343
+ | Parameter | Type | Description |
344
+ |-----------|------|-------------|
345
+ | `tokenId` | `string` | Token ID to trade |
346
+ | `side` | `'BUY' \| 'SELL'` | Order side |
347
+ | `price` | `number` | Price (0.001 - 0.999) |
348
+ | `size` | `number` | Size in shares |
349
+ | `orderType` | `'GTC' \| 'GTD'` | Order type (default: GTC) |
350
+ | `expiration` | `number` | Expiration for GTD orders (unix seconds) |
351
+
352
+ ---
353
+
354
+ ##### `createMarketOrder(params: MarketOrderParams): Promise<OrderResult>`
355
+
356
+ Create and post a market order.
357
+
358
+ ```typescript
359
+ const result = await client.createMarketOrder({
360
+ tokenId: '21742633...',
361
+ side: 'BUY',
362
+ amount: 50, // $50 USDC
363
+ orderType: 'FOK', // Fill-or-kill
364
+ });
365
+ ```
366
+
367
+ ---
368
+
369
+ ##### `cancelOrder(orderId: string): Promise<OrderResult>`
370
+
371
+ Cancel an open order.
372
+
373
+ ```typescript
374
+ await client.cancelOrder('0xabc123...');
375
+ ```
376
+
377
+ ---
378
+
379
+ ##### `getOpenOrders(marketId?: string): Promise<Order[]>`
380
+
381
+ Get all open orders.
382
+
383
+ ```typescript
384
+ const orders = await client.getOpenOrders();
385
+ console.log(`${orders.length} open orders`);
386
+ ```
387
+
388
+ ---
389
+
390
+ ##### `getBalanceAllowance(assetType, tokenId?): Promise<{ balance, allowance }>`
391
+
392
+ Check balance and allowance.
393
+
394
+ ```typescript
395
+ const { balance, allowance } = await client.getBalanceAllowance('COLLATERAL');
396
+ console.log(`USDC Balance: ${balance}`);
397
+ ```
398
+
399
+ ---
400
+
401
+ ### BridgeClient
402
+
403
+ Cross-chain deposit client for funding your Polymarket account.
404
+
405
+ ```typescript
406
+ import { BridgeClient } from '@prediction-router/poly-sdk';
407
+
408
+ const bridge = new BridgeClient();
409
+ ```
410
+
411
+ #### Key Concept: Universal Deposit Addresses
412
+
413
+ The Polymarket Bridge API returns **universal deposit addresses** by chain type:
414
+
415
+ - **EVM Address**: A single address works for ALL EVM chains (Ethereum, Polygon, Arbitrum, Base, Optimism)
416
+ - **Solana Address**: For Solana deposits
417
+ - **Bitcoin Address**: For Bitcoin deposits
418
+
419
+ This means you don't need a different address for each chain - the same EVM address accepts deposits from Ethereum, Polygon, Arbitrum, Base, and Optimism.
420
+
421
+ #### Supported Chains
422
+
423
+ | Chain | Chain ID | Min Deposit | Address Type |
424
+ |-------|----------|-------------|--------------|
425
+ | Ethereum | 1 | $10 | EVM |
426
+ | Polygon | 137 | $2 | EVM |
427
+ | Arbitrum | 42161 | $2 | EVM |
428
+ | Optimism | 10 | $2 | EVM |
429
+ | Base | 8453 | $2 | EVM |
430
+ | Solana | - | $5-10 | SVM |
431
+ | Bitcoin | - | $10+ | BTC |
432
+
433
+ #### Supported Tokens (Polygon)
434
+
435
+ | Token | Address | Description |
436
+ |-------|---------|-------------|
437
+ | Native USDC | `0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359` | Circle's native USDC |
438
+ | USDC.e | `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174` | Bridged USDC (PoS) |
439
+ | USDT | `0xc2132D05D31c914a87C6611C10748AEb04B58e8F` | Tether USD |
440
+ | DAI | `0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063` | Dai Stablecoin |
441
+ | WETH | `0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619` | Wrapped Ether |
442
+ | POL | Native | Polygon native token |
443
+
444
+ #### Methods
445
+
446
+ ##### `getSupportedAssets(): Promise<BridgeSupportedAsset[]>`
447
+
448
+ Get all supported chains and tokens.
449
+
450
+ ```typescript
451
+ const assets = await bridge.getSupportedAssets();
452
+
453
+ // Filter for Polygon assets
454
+ const polygonAssets = assets.filter(a => a.chainId === 137);
455
+ for (const asset of polygonAssets) {
456
+ console.log(`${asset.tokenSymbol}: min $${asset.minDepositUsd}`);
457
+ }
458
+ ```
459
+
460
+ ---
461
+
462
+ ##### `createDepositAddresses(walletAddress: string): Promise<CreateDepositResponse>`
463
+
464
+ Get universal deposit addresses for your wallet.
465
+
466
+ **API Response Format:**
467
+ ```json
468
+ {
469
+ "address": {
470
+ "evm": "0x1234...", // Works for ALL EVM chains
471
+ "svm": "ABC123...", // Solana address
472
+ "btc": "bc1q..." // Bitcoin address
473
+ }
474
+ }
475
+ ```
476
+
477
+ ```typescript
478
+ const result = await bridge.createDepositAddresses('0xYourWallet');
479
+
480
+ console.log('EVM deposit address:', result.address.evm); // All EVM chains
481
+ console.log('Solana deposit address:', result.address.svm); // Solana
482
+ console.log('Bitcoin deposit address:', result.address.btc); // Bitcoin
483
+ ```
484
+
485
+ ---
486
+
487
+ ##### `getEvmDepositAddress(walletAddress: string): Promise<string>`
488
+
489
+ Get the universal EVM deposit address. **Recommended method.**
490
+
491
+ ```typescript
492
+ const evmAddr = await bridge.getEvmDepositAddress('0xYourWallet');
493
+
494
+ // This address works for:
495
+ // - Ethereum USDC, ETH
496
+ // - Polygon Native USDC, USDC.e, MATIC
497
+ // - Arbitrum USDC, ETH
498
+ // - Base USDC, ETH
499
+ // - Optimism USDC, ETH
500
+ console.log(`Send to: ${evmAddr}`);
501
+ ```
502
+
503
+ ---
504
+
505
+ ##### `getSolanaDepositAddress(walletAddress: string): Promise<string>`
506
+
507
+ Get the Solana deposit address.
508
+
509
+ ```typescript
510
+ const solAddr = await bridge.getSolanaDepositAddress('0xYourWallet');
511
+ console.log(`Send SOL or USDC to: ${solAddr}`);
512
+ ```
513
+
514
+ ---
515
+
516
+ ##### `getBtcDepositAddress(walletAddress: string): Promise<string>`
517
+
518
+ Get the Bitcoin deposit address.
519
+
520
+ ```typescript
521
+ const btcAddr = await bridge.getBtcDepositAddress('0xYourWallet');
522
+ console.log(`Send BTC to: ${btcAddr}`);
523
+ ```
524
+
525
+ ---
526
+
527
+ ##### `getDepositAddress(address, chainId, tokenSymbol): Promise<DepositAddress | null>` _(deprecated)_
528
+
529
+ > **Deprecated**: Use `getEvmDepositAddress()`, `getSolanaDepositAddress()`, or `getBtcDepositAddress()` instead.
530
+
531
+ ---
532
+
533
+ ##### `isSupported(chainId, tokenSymbol): Promise<boolean>`
534
+
535
+ Check if a chain/token combination is supported.
536
+
537
+ ```typescript
538
+ const supported = await bridge.isSupported(137, 'USDC');
539
+ console.log(`Polygon USDC supported: ${supported}`);
540
+ ```
541
+
542
+ ---
543
+
544
+ ##### `getMinDeposit(chainId, tokenSymbol): Promise<{ amount, usd } | null>`
545
+
546
+ Get minimum deposit amount.
547
+
548
+ ```typescript
549
+ const min = await bridge.getMinDeposit(137, 'USDC');
550
+ if (min) {
551
+ console.log(`Min deposit: ${min.amount} (~$${min.usd})`);
552
+ }
553
+ ```
554
+
555
+ ---
556
+
557
+ #### Deposit Flow Example
558
+
559
+ ```typescript
560
+ import { providers, Wallet, Contract, utils } from 'ethers';
561
+ import { BridgeClient, BRIDGE_TOKENS } from '@prediction-router/poly-sdk';
562
+
563
+ // 1. Setup
564
+ const provider = new providers.JsonRpcProvider('https://polygon-rpc.com');
565
+ const wallet = new Wallet(PRIVATE_KEY, provider);
566
+ const bridge = new BridgeClient();
567
+
568
+ // 2. Get EVM deposit address (works for all EVM chains)
569
+ const depositAddress = await bridge.getEvmDepositAddress(wallet.address);
570
+ console.log(`Deposit to: ${depositAddress}`);
571
+
572
+ // 3. Send Native USDC to the deposit address
573
+ const nativeUsdc = new Contract(
574
+ BRIDGE_TOKENS.POLYGON_NATIVE_USDC,
575
+ ['function transfer(address to, uint256 amount) returns (bool)'],
576
+ wallet
577
+ );
578
+
579
+ const amount = utils.parseUnits('5.0', 6); // 5 USDC
580
+ const tx = await nativeUsdc.transfer(depositAddress, amount);
581
+ await tx.wait();
582
+
583
+ console.log('Deposit sent! Bridge will convert to USDC.e in 1-5 minutes.');
584
+ console.log('Bridge fee: ~0.16%');
585
+ ```
586
+
587
+ ---
588
+
589
+ ### CTFClient
590
+
591
+ CTF (Conditional Token Framework) client for on-chain token operations.
592
+
593
+ ```typescript
594
+ import { CTFClient } from '@prediction-router/poly-sdk';
595
+
596
+ const ctf = new CTFClient({
597
+ privateKey: '0x...',
598
+ rpcUrl: 'https://polygon-rpc.com',
599
+ chainId: 137,
600
+ });
601
+ ```
602
+
603
+ #### Core Concepts
604
+
605
+ **Token IDs**: Each market has two token IDs (YES and NO). There are two ways to identify tokens:
606
+ 1. **CLOB Token IDs**: From the CLOB API, used for trading
607
+ 2. **Calculated Position IDs**: From `calculatePositionId()`, derived from conditionId
608
+
609
+ **Important**: Always use CLOB Token IDs for balance queries. The calculated position IDs may differ.
610
+
611
+ #### Constants
612
+
613
+ ```typescript
614
+ import {
615
+ CTF_CONTRACT, // 0x4D97DCd97eC945f40cF65F87097ACe5EA0476045
616
+ USDC_CONTRACT, // 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 (USDC.e)
617
+ NEG_RISK_CTF_EXCHANGE, // 0xC5d563A36AE78145C45a50134d48A1215220f80a
618
+ NEG_RISK_ADAPTER, // 0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296
619
+ USDC_DECIMALS, // 6
620
+ } from '@prediction-router/poly-sdk';
621
+ ```
622
+
623
+ #### Methods
624
+
625
+ ##### `split(conditionId: string, amount: number): Promise<SplitResult>`
626
+
627
+ Split USDC.e into YES + NO tokens.
628
+
629
+ ```typescript
630
+ // Split 10 USDC.e into 10 YES + 10 NO
631
+ const result = await ctf.split('0xabc123...', 10);
632
+
633
+ console.log(`TX: ${result.txHash}`);
634
+ console.log(`Status: ${result.status}`);
635
+ ```
636
+
637
+ ---
638
+
639
+ ##### `merge(conditionId: string, amount: number): Promise<MergeResult>`
640
+
641
+ Merge YES + NO tokens back into USDC.e.
642
+
643
+ ```typescript
644
+ // Merge 10 YES + 10 NO into 10 USDC.e
645
+ const result = await ctf.merge('0xabc123...', 10);
646
+
647
+ console.log(`TX: ${result.txHash}`);
648
+ console.log(`USDC received: ${result.usdcReceived}`);
649
+ ```
650
+
651
+ ---
652
+
653
+ ##### `getPositionBalanceByTokenIds(conditionId: string, tokenIds: TokenIds): Promise<PositionBalance>`
654
+
655
+ Get token balances using CLOB token IDs. **Recommended method.**
656
+
657
+ ```typescript
658
+ import type { TokenIds } from '@prediction-router/poly-sdk';
659
+
660
+ // Get token IDs from CLOB API
661
+ const market = await clobApi.getMarket('0xabc123...');
662
+ const yesToken = market.tokens.find(t => t.outcome === 'Yes');
663
+ const noToken = market.tokens.find(t => t.outcome === 'No');
664
+
665
+ const tokenIds: TokenIds = {
666
+ yesTokenId: yesToken.tokenId,
667
+ noTokenId: noToken.tokenId,
668
+ };
669
+
670
+ const balance = await ctf.getPositionBalanceByTokenIds('0xabc123...', tokenIds);
671
+ console.log(`YES: ${balance.yesBalance}, NO: ${balance.noBalance}`);
672
+ ```
673
+
674
+ ---
675
+
676
+ ##### `canMergeWithTokenIds(conditionId: string, tokenIds: TokenIds, amount: number): Promise<boolean>`
677
+
678
+ Check if merge is possible with given token balances.
679
+
680
+ ```typescript
681
+ const canMerge = await ctf.canMergeWithTokenIds('0xabc123...', tokenIds, 5);
682
+ if (canMerge) {
683
+ await ctf.merge('0xabc123...', 5);
684
+ }
685
+ ```
686
+
687
+ ---
688
+
689
+ ##### `getPositionBalance(conditionId: string): Promise<PositionBalance>` _(deprecated)_
690
+
691
+ > **Deprecated**: Use `getPositionBalanceByTokenIds()` instead. This method uses calculated position IDs which may not match CLOB token IDs.
692
+
693
+ ---
694
+
695
+ ##### `redeem(conditionId: string, outcome?: 'YES' | 'NO'): Promise<RedeemResult>`
696
+
697
+ Redeem winning tokens after market resolution. **For standard CTF markets only.**
698
+
699
+ ⚠️ **WARNING**: This method uses calculated position IDs. For Polymarket CLOB markets, use `redeemByTokenIds()` instead.
700
+
701
+ ```typescript
702
+ // ❌ Don't use for Polymarket - may fail to find balance
703
+ const result = await ctf.redeem(conditionId);
704
+ ```
705
+
706
+ **When to use `redeem()`:**
707
+ - Standard Gnosis CTF markets (non-Polymarket)
708
+ - Markets where position IDs are calculated from conditionId
709
+ - Direct CTF contract interactions without CLOB
710
+
711
+ ---
712
+
713
+ ##### `redeemByTokenIds(conditionId: string, tokenIds: TokenIds, outcome?: 'YES' | 'NO'): Promise<RedeemResult>`
714
+
715
+ Redeem winning tokens using Polymarket token IDs. **Recommended for Polymarket.**
716
+
717
+ ```typescript
718
+ // ✅ Use this for Polymarket CLOB markets
719
+ const tokenIds: TokenIds = {
720
+ yesTokenId: '25064375110792967023484002819116042931016336431092144471807003884255851454283',
721
+ noTokenId: '98190367690492181203391990709979106077460946443309150166954079213761598385827',
722
+ };
723
+
724
+ const result = await ctf.redeemByTokenIds(conditionId, tokenIds);
725
+ console.log(`Redeemed ${result.tokensRedeemed} ${result.outcome} tokens`);
726
+ console.log(`Received ${result.usdcReceived} USDC`);
727
+ ```
728
+
729
+ **Parameters:**
730
+ - `conditionId` - The market condition ID
731
+ - `tokenIds` - Polymarket token IDs from CLOB API
732
+ - `outcome` - Optional: 'YES' or 'NO'. Auto-detects winning outcome if not provided.
733
+
734
+ **Returns:** `RedeemResult` with transaction details
735
+
736
+ **Why use this method?**
737
+ - Polymarket wraps CTF positions into ERC-1155 tokens with custom IDs
738
+ - The token IDs from CLOB API differ from calculated position IDs
739
+ - This method queries balances using the correct Polymarket token IDs
740
+
741
+ ---
742
+
743
+ ##### `getMarketResolution(conditionId: string): Promise<MarketResolution>`
744
+
745
+ Check if a market is resolved and get the winning outcome.
746
+
747
+ ```typescript
748
+ const resolution = await ctf.getMarketResolution(conditionId);
749
+ if (resolution.isResolved) {
750
+ console.log(`Winner: ${resolution.winningOutcome}`); // 'YES' or 'NO'
751
+ }
752
+ ```
753
+
754
+ ---
755
+
756
+ ##### `getUsdcBalance(): Promise<string>`
757
+
758
+ Get USDC.e balance.
759
+
760
+ ```typescript
761
+ const balance = await ctf.getUsdcBalance();
762
+ console.log(`USDC.e: ${balance}`);
763
+ ```
764
+
765
+ ---
766
+
767
+ #### Types
768
+
769
+ ```typescript
770
+ interface TokenIds {
771
+ yesTokenId: string;
772
+ noTokenId: string;
773
+ }
774
+
775
+ interface PositionBalance {
776
+ conditionId: string;
777
+ yesBalance: string;
778
+ noBalance: string;
779
+ yesPositionId: string;
780
+ noPositionId: string;
781
+ }
782
+
783
+ interface SplitResult {
784
+ txHash: string;
785
+ status: 'success' | 'failed';
786
+ gasUsed: string;
787
+ yesTokenId: string;
788
+ noTokenId: string;
789
+ amountSplit: string;
790
+ }
791
+
792
+ interface MergeResult {
793
+ txHash: string;
794
+ status: 'success' | 'failed';
795
+ gasUsed: string;
796
+ usdcReceived: string;
797
+ }
798
+
799
+ interface RedeemResult {
800
+ success: boolean;
801
+ txHash: string;
802
+ outcome: 'YES' | 'NO';
803
+ tokensRedeemed: string;
804
+ usdcReceived: string;
805
+ gasUsed: string;
806
+ }
807
+
808
+ interface MarketResolution {
809
+ conditionId: string;
810
+ isResolved: boolean;
811
+ winningOutcome?: 'YES' | 'NO';
812
+ payoutNumerators?: number[];
813
+ }
814
+ ```
815
+
816
+ ---
817
+
818
+ #### CTF Arbitrage Example
819
+
820
+ ```typescript
821
+ import { CTFClient, ClobApiClient, TokenIds } from '@prediction-router/poly-sdk';
822
+
823
+ const ctf = new CTFClient({ privateKey, rpcUrl, chainId: 137 });
824
+ const clobApi = new ClobApiClient(rateLimiter, cache);
825
+
826
+ // 1. Get market and token IDs
827
+ const market = await clobApi.getMarket(conditionId);
828
+ const tokenIds: TokenIds = {
829
+ yesTokenId: market.tokens.find(t => t.outcome === 'Yes').tokenId,
830
+ noTokenId: market.tokens.find(t => t.outcome === 'No').tokenId,
831
+ };
832
+
833
+ // 2. Get processed orderbook
834
+ const ob = await clobApi.getProcessedOrderbook(conditionId);
835
+
836
+ // 3. Check for long arbitrage (buy YES + NO, merge for profit)
837
+ if (ob.summary.longArbProfit > 0.005) {
838
+ // Buy YES and NO tokens via CLOB
839
+ // Then merge
840
+ const balance = await ctf.getPositionBalanceByTokenIds(conditionId, tokenIds);
841
+ const minBalance = Math.min(
842
+ parseFloat(balance.yesBalance),
843
+ parseFloat(balance.noBalance)
844
+ );
845
+
846
+ if (minBalance > 0) {
847
+ const result = await ctf.merge(conditionId, minBalance);
848
+ console.log(`Merged ${minBalance}, received ${result.usdcReceived} USDC`);
849
+ }
850
+ }
851
+
852
+ // 4. Check for short arbitrage (split, sell YES + NO for profit)
853
+ if (ob.summary.shortArbProfit > 0.005) {
854
+ // Split USDC into tokens
855
+ await ctf.split(conditionId, 10);
856
+ // Sell tokens via CLOB
857
+ }
858
+ ```
859
+
860
+ ---
861
+
862
+ ### WebSocketManager
863
+
864
+ Real-time market data via WebSocket.
865
+
866
+ ```typescript
867
+ import { WebSocketManager } from '@prediction-router/poly-sdk';
868
+
869
+ const ws = new WebSocketManager({ enableLogging: true });
870
+ ```
871
+
872
+ #### Methods
873
+
874
+ ##### `subscribe(assetIds: string[]): Promise<void>`
875
+
876
+ Subscribe to market updates.
877
+
878
+ ```typescript
879
+ ws.on('bookUpdate', (update) => {
880
+ console.log(`Book update for ${update.assetId}`);
881
+ console.log(` Best bid: ${update.bids[0]?.price}`);
882
+ });
883
+
884
+ ws.on('priceUpdate', (update) => {
885
+ console.log(`Price: ${update.price}`);
886
+ });
887
+
888
+ await ws.subscribe(['21742633...', '79707176...']);
889
+ ```
890
+
891
+ ---
892
+
893
+ ##### `unsubscribe(assetIds: string[]): Promise<void>`
894
+
895
+ Unsubscribe from specific assets.
896
+
897
+ ---
898
+
899
+ ##### `unsubscribeAll(): Promise<void>`
900
+
901
+ Unsubscribe from all assets and cleanup.
902
+
903
+ ---
904
+
905
+ ## Services
906
+
907
+ ### MarketService
908
+
909
+ High-level market analysis service.
910
+
911
+ ```typescript
912
+ import { MarketService } from '@prediction-router/poly-sdk';
913
+
914
+ const service = new MarketService(clobApi, gammaApi);
915
+
916
+ // Get market with full analysis
917
+ const analysis = await service.getMarketWithAnalysis('0x82ace55...');
918
+ ```
919
+
920
+ ---
921
+
922
+ ### ArbitrageService
923
+
924
+ Arbitrage opportunity detection.
925
+
926
+ ```typescript
927
+ import { ArbitrageService } from '@prediction-router/poly-sdk';
928
+
929
+ const service = new ArbitrageService(clobApi, gammaApi);
930
+
931
+ // Scan for opportunities
932
+ const opportunities = await service.scanForOpportunities({
933
+ minProfit: 0.003, // 0.3% minimum
934
+ maxMarkets: 50,
935
+ });
936
+
937
+ for (const opp of opportunities) {
938
+ console.log(`${opp.type} arb: ${(opp.profit * 100).toFixed(2)}%`);
939
+ }
940
+ ```
941
+
942
+ ---
943
+
944
+ ### RealtimeService
945
+
946
+ High-level WebSocket subscription management.
947
+
948
+ ```typescript
949
+ import { RealtimeService, WebSocketManager } from '@prediction-router/poly-sdk';
950
+
951
+ const ws = new WebSocketManager();
952
+ const realtime = new RealtimeService(ws);
953
+
954
+ // Subscribe to a market pair
955
+ const sub = await realtime.subscribeMarket(yesTokenId, noTokenId, {
956
+ onPairUpdate: (update) => {
957
+ console.log(`YES: ${update.yes.price}, NO: ${update.no.price}`);
958
+ console.log(`Spread: ${update.spread}`);
959
+ },
960
+ });
961
+
962
+ // Later: unsubscribe
963
+ await sub.unsubscribe();
964
+ ```
965
+
966
+ ---
967
+
968
+ ## Utility Functions
969
+
970
+ ### `getEffectivePrices(yesAsk, yesBid, noAsk, noBid)`
971
+
972
+ Calculate effective prices accounting for orderbook mirroring.
973
+
974
+ ```typescript
975
+ import { getEffectivePrices } from '@prediction-router/poly-sdk';
976
+
977
+ const effective = getEffectivePrices(0.57, 0.55, 0.45, 0.43);
978
+ console.log('Effective buy YES:', effective.effectiveBuyYes);
979
+ console.log('Effective buy NO:', effective.effectiveBuyNo);
980
+ ```
981
+
982
+ ---
983
+
984
+ ### `checkArbitrage(yesAsk, yesBid, noAsk, noBid)`
985
+
986
+ Check for arbitrage opportunities.
987
+
988
+ ```typescript
989
+ import { checkArbitrage } from '@prediction-router/poly-sdk';
990
+
991
+ const arb = checkArbitrage(0.57, 0.55, 0.45, 0.43);
992
+ if (arb.hasOpportunity) {
993
+ console.log(`${arb.type} opportunity: ${arb.profit * 100}%`);
994
+ }
995
+ ```
996
+
997
+ ---
998
+
999
+ ## Types
1000
+
1001
+ ### ClobMarket
1002
+
1003
+ ```typescript
1004
+ interface ClobMarket {
1005
+ conditionId: string; // Unique market identifier
1006
+ question: string; // Market question
1007
+ description?: string; // Resolution criteria
1008
+ marketSlug: string; // URL-friendly slug
1009
+ tokens: ClobToken[]; // YES and NO tokens
1010
+ acceptingOrders: boolean; // Can accept orders
1011
+ endDateIso: string; // ISO end date
1012
+ active: boolean; // Is active
1013
+ closed: boolean; // Is resolved
1014
+ }
1015
+ ```
1016
+
1017
+ ### ClobToken
1018
+
1019
+ ```typescript
1020
+ interface ClobToken {
1021
+ tokenId: string; // ERC-1155 token ID
1022
+ outcome: string; // "Yes" or "No"
1023
+ price: number; // Current price (0-1)
1024
+ }
1025
+ ```
1026
+
1027
+ ### Orderbook
1028
+
1029
+ ```typescript
1030
+ interface Orderbook {
1031
+ bids: OrderbookLevel[]; // Sorted descending by price
1032
+ asks: OrderbookLevel[]; // Sorted ascending by price
1033
+ timestamp: number; // Fetch timestamp (ms)
1034
+ }
1035
+
1036
+ interface OrderbookLevel {
1037
+ price: number; // Price (0.001-0.999)
1038
+ size: number; // Size in shares
1039
+ }
1040
+ ```
1041
+
1042
+ ### ProcessedOrderbook
1043
+
1044
+ ```typescript
1045
+ interface ProcessedOrderbook {
1046
+ yes: {
1047
+ bid: number;
1048
+ ask: number;
1049
+ bidSize: number;
1050
+ askSize: number;
1051
+ bidDepth: number;
1052
+ askDepth: number;
1053
+ spread: number;
1054
+ };
1055
+ no: {
1056
+ bid: number;
1057
+ ask: number;
1058
+ bidSize: number;
1059
+ askSize: number;
1060
+ bidDepth: number;
1061
+ askDepth: number;
1062
+ spread: number;
1063
+ };
1064
+ summary: {
1065
+ askSum: number;
1066
+ bidSum: number;
1067
+ effectivePrices: {
1068
+ effectiveBuyYes: number;
1069
+ effectiveBuyNo: number;
1070
+ effectiveSellYes: number;
1071
+ effectiveSellNo: number;
1072
+ };
1073
+ effectiveLongCost: number;
1074
+ effectiveShortRevenue: number;
1075
+ longArbProfit: number; // > 0 = opportunity
1076
+ shortArbProfit: number; // > 0 = opportunity
1077
+ totalBidDepth: number;
1078
+ totalAskDepth: number;
1079
+ imbalanceRatio: number;
1080
+ yesSpread: number;
1081
+ };
1082
+ }
1083
+ ```
1084
+
1085
+ ### Position
1086
+
1087
+ ```typescript
1088
+ interface Position {
1089
+ asset: string; // Token ID
1090
+ conditionId: string; // Market ID
1091
+ outcome: string; // "Yes" or "No"
1092
+ outcomeIndex: number; // 0 = Yes, 1 = No
1093
+ size: number; // Shares held
1094
+ avgPrice: number; // Average entry price
1095
+ curPrice?: number; // Current price
1096
+ cashPnl?: number; // Unrealized PnL in USDC
1097
+ percentPnl?: number; // Unrealized PnL %
1098
+ realizedPnl?: number; // Realized PnL
1099
+ title: string; // Market title
1100
+ }
1101
+ ```
1102
+
1103
+ ---
1104
+
1105
+ ## Error Handling
1106
+
1107
+ The SDK uses `PolymarketError` for all errors.
1108
+
1109
+ ```typescript
1110
+ import { PolymarketError, ErrorCode } from '@prediction-router/poly-sdk';
1111
+
1112
+ try {
1113
+ await client.getMarket('invalid-id');
1114
+ } catch (error) {
1115
+ if (error instanceof PolymarketError) {
1116
+ switch (error.code) {
1117
+ case ErrorCode.NOT_FOUND:
1118
+ console.log('Market not found');
1119
+ break;
1120
+ case ErrorCode.RATE_LIMITED:
1121
+ console.log('Rate limited, retry later');
1122
+ break;
1123
+ case ErrorCode.API_ERROR:
1124
+ console.log('API error:', error.message);
1125
+ break;
1126
+ }
1127
+ }
1128
+ }
1129
+ ```
1130
+
1131
+ ### Error Codes
1132
+
1133
+ | Code | Description |
1134
+ |------|-------------|
1135
+ | `NOT_FOUND` | Resource not found (404) |
1136
+ | `RATE_LIMITED` | Rate limit exceeded (429) |
1137
+ | `UNAUTHORIZED` | Authentication required (401) |
1138
+ | `FORBIDDEN` | Access denied (403) |
1139
+ | `INVALID_RESPONSE` | Invalid API response |
1140
+ | `API_ERROR` | General API error |
1141
+ | `ORDER_FAILED` | Order placement failed |
1142
+ | `NETWORK_ERROR` | Network connectivity issue |
1143
+
1144
+ ---
1145
+
1146
+ ## License
1147
+
1148
+ MIT