@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
@@ -0,0 +1,760 @@
1
+ # poly-sdk Design Document
2
+
3
+ > This document describes how poly-sdk inherits and normalizes Polymarket API interfaces.
4
+ > All fields verified against actual API responses on 2024-12-22.
5
+
6
+ ## Overview
7
+
8
+ poly-sdk wraps Polymarket APIs and provides services for wallet operations:
9
+
10
+ ```
11
+ ┌──────────────────────────────────────────────────────────────────────────────────────────┐
12
+ │ poly-sdk │
13
+ ├──────────────────────────────────────────────────────────────────────────────────────────┤
14
+ │ │
15
+ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌────────────────┐ │
16
+ │ │ DataApiClient │ │ GammaApiClient │ │ ClobApiClient │ │ BridgeClient │ │
17
+ │ │ │ │ │ │ │ │ │ │
18
+ │ │ - Positions │ │ - Markets │ │ - Markets │ │ - Deposits │ │
19
+ │ │ - Activity │ │ - Events │ │ - Orderbooks │ │ - Assets │ │
20
+ │ │ - Trades │ │ - Trending │ │ - Tokens │ │ - Swap+Deposit │ │
21
+ │ │ - Leaderboard │ │ │ │ │ │ │ │
22
+ │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ └───────┬────────┘ │
23
+ │ │ │ │ │ │
24
+ ├───────────┼───────────────────┼───────────────────┼──────────────────┼───────────────────┤
25
+ │ │ │ │ │ │
26
+ │ ┌────────┴───────────────────┴───────────────────┴──────────────────┴────────────────┐ │
27
+ │ │ Services Layer │ │
28
+ │ │ ┌──────────────┐ ┌──────────────┐ ┌─────────────────────┐ ┌─────────────────┐ │ │
29
+ │ │ │ WalletService│ │ MarketService│ │ AuthorizationService│ │ SwapService │ │ │
30
+ │ │ │ │ │ │ │ - checkAllowances() │ │ │ │ │
31
+ │ │ │ - Profiles │ │ - Unified │ │ - approveAll() │ │ - swap() │ │ │
32
+ │ │ │ - SmartScore │ │ - Orderbooks │ │ - ERC20/ERC1155 │ │ - getBalances() │ │ │
33
+ │ │ └──────────────┘ └──────────────┘ └─────────────────────┘ └─────────────────┘ │ │
34
+ │ └────────────────────────────────────────────────────────────────────────────────────┘ │
35
+ │ │
36
+ └───────────────────────────────────────────────────────────────────────────────────────────┘
37
+ │ │ │ │
38
+ ▼ ▼ ▼ ▼
39
+ data-api.polymarket.com gamma-api.polymarket.com clob.polymarket.com bridge.polymarket.com
40
+ + QuickSwap V3
41
+ ```
42
+
43
+ ## API Endpoints and SDK Methods
44
+
45
+ ### Data API (data-api.polymarket.com)
46
+
47
+ | Endpoint | SDK Method | Description |
48
+ |----------|------------|-------------|
49
+ | `GET /positions?user={address}` | `dataApi.getPositions(address)` | Wallet positions |
50
+ | `GET /activity?user={address}` | `dataApi.getActivity(address)` | Wallet activity |
51
+ | `GET /trades` | `dataApi.getTrades()` | Recent trades |
52
+ | `GET /v1/leaderboard` | `dataApi.getLeaderboard()` | PnL leaderboard |
53
+
54
+ ### Gamma API (gamma-api.polymarket.com)
55
+
56
+ | Endpoint | SDK Method | Description |
57
+ |----------|------------|-------------|
58
+ | `GET /markets` | `gammaApi.getMarkets(params)` | Market discovery |
59
+ | `GET /events` | `gammaApi.getEvents(params)` | Event groups |
60
+ | `GET /events/{id}` | `gammaApi.getEventById(id)` | Single event |
61
+
62
+ ### CLOB API (clob.polymarket.com)
63
+
64
+ | Endpoint | SDK Method | Description |
65
+ |----------|------------|-------------|
66
+ | `GET /markets/{conditionId}` | `clobApi.getMarket(conditionId)` | Market info |
67
+ | `GET /book?token_id={tokenId}` | `clobApi.getOrderbook(tokenId)` | Order book |
68
+
69
+ ### Bridge API (bridge.polymarket.com)
70
+
71
+ | Endpoint | SDK Method | Description |
72
+ |----------|------------|-------------|
73
+ | `GET /supported-assets` | `bridge.getSupportedAssets()` | Supported deposit assets |
74
+ | `POST /deposit` | `bridge.createDepositAddresses(address)` | Get deposit addresses |
75
+
76
+ **Verified API Response** (2024-12-22):
77
+
78
+ `GET /supported-assets`:
79
+ ```json
80
+ {
81
+ "supportedAssets": [
82
+ {
83
+ "chainId": "1",
84
+ "chainName": "Ethereum",
85
+ "token": {
86
+ "name": "USD Coin",
87
+ "symbol": "USDC",
88
+ "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
89
+ "decimals": 6
90
+ },
91
+ "minCheckoutUsd": 2
92
+ }
93
+ ]
94
+ }
95
+ ```
96
+
97
+ `POST /deposit`:
98
+ ```json
99
+ {
100
+ "address": {
101
+ "evm": "0x95DDa253Bd8B816223...",
102
+ "svm": "gbjjH2LP3ufgue9co25H...",
103
+ "btc": "bc1q6smhd5lma9pulfq9..."
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### Swap Service (QuickSwap V3)
109
+
110
+ The `SwapService` enables token swaps on Polygon using QuickSwap V3 DEX:
111
+
112
+ | Method | Description |
113
+ |--------|-------------|
114
+ | `swap(tokenIn, tokenOut, amount, options?)` | Swap between any supported tokens |
115
+ | `swapToUsdc(token, amount, options?)` | Swap any token to USDC |
116
+ | `getBalances()` | Get balances for all supported tokens (requires signer) |
117
+ | `getBalance(token)` | Get balance for a specific token (requires signer) |
118
+ | `wrapMatic(amount)` | Wrap native MATIC to WMATIC |
119
+ | `unwrapMatic(amount)` | Unwrap WMATIC to native MATIC |
120
+ | `static getWalletBalances(address)` | Get balances for any wallet (no signer required) |
121
+ | `static getWalletBalance(address, token)` | Get specific token balance for any wallet |
122
+
123
+ **Supported Tokens**:
124
+
125
+ | Token | Address | Decimals | CTF Compatible |
126
+ |-------|---------|----------|----------------|
127
+ | MATIC/WMATIC | `0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270` | 18 | - |
128
+ | USDC (Native) | `0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359` | 6 | ❌ No |
129
+ | USDC.e (Bridged) | `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174` | 6 | ✅ **Required** |
130
+ | USDT | `0xc2132D05D31c914a87C6611C10748AEb04B58e8F` | 6 | - |
131
+ | DAI | `0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063` | 18 | - |
132
+ | WETH | `0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619` | 18 | - |
133
+
134
+ **QuickSwap V3 Router**: `0xf5b509bB0909a69B1c207E495f687a596C168E12`
135
+
136
+ ### ⚠️ CRITICAL: USDC.e vs Native USDC for Polymarket CTF
137
+
138
+ Polymarket's Conditional Token Framework (CTF) only accepts **USDC.e** (bridged USDC), NOT native USDC.
139
+
140
+ **Common Mistake**:
141
+ ```
142
+ Your wallet shows 100 USDC in block explorer
143
+ → CTFClient.getUsdcBalance() returns 0
144
+ → CTF operations fail with "Insufficient USDC balance"
145
+ ```
146
+
147
+ **Reason**: You have native USDC, not USDC.e.
148
+
149
+ **Solution**:
150
+
151
+ | Method | Description |
152
+ |--------|-------------|
153
+ | `SwapService.swap('USDC', 'USDC_E', amount)` | Convert native USDC to USDC.e |
154
+ | `SwapService.transferUsdcE(to, amount)` | Transfer USDC.e (for CTF operations) |
155
+ | `SwapService.transferUsdc(to, amount)` | Transfer native USDC (NOT for CTF) |
156
+ | `CTFClient.checkReadyForCTF(amount)` | Check if wallet is ready for CTF |
157
+
158
+ **Example**:
159
+ ```typescript
160
+ // Check if ready for CTF
161
+ const status = await ctf.checkReadyForCTF('100');
162
+ if (!status.ready) {
163
+ console.log(status.suggestion);
164
+ // "You have 50 native USDC but 0 USDC.e. Swap native USDC to USDC.e first."
165
+ }
166
+
167
+ // Convert native USDC to USDC.e
168
+ await swapService.swap('USDC', 'USDC_E', '100');
169
+
170
+ // Fund a session wallet for CTF trading (use USDC.e!)
171
+ await swapService.transferUsdcE(sessionWallet, '100');
172
+ ```
173
+
174
+ ### Swap and Deposit
175
+
176
+ The `swapAndDeposit()` function combines swap and deposit in one operation:
177
+
178
+ ```typescript
179
+ import { swapAndDeposit } from '@prediction-router/poly-sdk';
180
+
181
+ // Swap MATIC to USDC and deposit to Polymarket
182
+ const result = await swapAndDeposit(signer, 'MATIC', '100', {
183
+ slippage: 0.5 // 0.5% slippage tolerance
184
+ });
185
+ ```
186
+
187
+ ### Authorization Service
188
+
189
+ The `AuthorizationService` manages ERC20 and ERC1155 approvals required for trading:
190
+
191
+ | Method | Description |
192
+ |--------|-------------|
193
+ | `checkAllowances()` | Check all ERC20/ERC1155 allowances |
194
+ | `approveAll()` | Set up all required approvals |
195
+ | `approveUsdc(spender, amount)` | Approve USDC for a specific contract |
196
+ | `setErc1155Approval(operator, approved)` | Set ERC1155 approval |
197
+
198
+ **Required Approvals for Trading**:
199
+
200
+ | Type | Contract | Address |
201
+ |------|----------|---------|
202
+ | ERC20 | CTF Exchange | `0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E` |
203
+ | ERC20 | Neg Risk CTF Exchange | `0xC5d563A36AE78145C45a50134d48A1215220f80a` |
204
+ | ERC20 | Neg Risk Adapter | `0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296` |
205
+ | ERC20 | Conditional Tokens | `0x4D97DCd97eC945f40cF65F87097ACe5EA0476045` |
206
+ | ERC1155 | CTF Exchange | `0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E` |
207
+ | ERC1155 | Neg Risk CTF Exchange | `0xC5d563A36AE78145C45a50134d48A1215220f80a` |
208
+ | ERC1155 | Neg Risk Adapter | `0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296` |
209
+
210
+ ---
211
+
212
+ ## Type Definitions and API Inheritance
213
+
214
+ The SDK normalizes raw API responses into typed interfaces. Below is the mapping between API fields and SDK types.
215
+
216
+ ### Position (Data API)
217
+
218
+ **API Endpoint**: `GET /positions?user={address}`
219
+
220
+ **Verified API Response** (2024-12-21):
221
+ ```json
222
+ {
223
+ "proxyWallet": "0xc2e7800b5af46e6093872b177b7a5e7f0563be51",
224
+ "asset": "4765501864982032589494809396214706270671021091620334552669038388080328898101",
225
+ "conditionId": "0x39e493c3cd953e45a632f4f5dde639ccd37f97743203be9c1eb01fbb155a4803",
226
+ "size": 1346825.460224,
227
+ "avgPrice": 0.520337,
228
+ "initialValue": 700803.1194965754,
229
+ "currentValue": 1346825.460224,
230
+ "cashPnl": 646022.3407274245,
231
+ "percentPnl": 92.18314284780823,
232
+ "totalBought": 1346825.460224,
233
+ "realizedPnl": 0,
234
+ "percentRealizedPnl": 92.18314284780824,
235
+ "curPrice": 1,
236
+ "redeemable": true,
237
+ "mergeable": false,
238
+ "title": "Spread: Grizzlies (-12.5)",
239
+ "slug": "nba-was-mem-2025-12-20-spread-home-12pt5",
240
+ "icon": "https://polymarket-upload.s3.us-east-2.amazonaws.com/...",
241
+ "eventId": "104888",
242
+ "eventSlug": "nba-was-mem-2025-12-20",
243
+ "outcome": "Wizards",
244
+ "outcomeIndex": 1,
245
+ "oppositeOutcome": "Grizzlies",
246
+ "oppositeAsset": "13094498429043262538336168554322406952756859431736544943974983877714521454902",
247
+ "endDate": "2025-12-21",
248
+ "negativeRisk": false
249
+ }
250
+ ```
251
+
252
+ **SDK Interface** (`data-api.ts`):
253
+ ```typescript
254
+ export interface Position {
255
+ // Wallet identifier
256
+ proxyWallet?: string;
257
+
258
+ // Core identifiers
259
+ asset: string;
260
+ conditionId: string;
261
+ outcome: string;
262
+ outcomeIndex: number;
263
+
264
+ // Position data
265
+ size: number;
266
+ avgPrice: number;
267
+ curPrice?: number;
268
+ totalBought?: number;
269
+
270
+ // Value calculations
271
+ initialValue?: number;
272
+ currentValue?: number;
273
+ cashPnl?: number;
274
+ percentPnl?: number;
275
+ realizedPnl?: number;
276
+ percentRealizedPnl?: number;
277
+
278
+ // Market metadata
279
+ title: string;
280
+ slug?: string;
281
+ icon?: string;
282
+ eventId?: string;
283
+ eventSlug?: string;
284
+
285
+ // Opposite side info
286
+ oppositeOutcome?: string;
287
+ oppositeAsset?: string;
288
+
289
+ // Status fields
290
+ redeemable?: boolean;
291
+ mergeable?: boolean;
292
+ endDate?: string;
293
+ negativeRisk?: boolean;
294
+ }
295
+ ```
296
+
297
+ ---
298
+
299
+ ### Activity (Data API)
300
+
301
+ **API Endpoint**: `GET /activity?user={address}`
302
+
303
+ **Verified API Response** (2024-12-21):
304
+ ```json
305
+ {
306
+ "type": "TRADE",
307
+ "side": "BUY",
308
+ "size": 100.0,
309
+ "price": 0.55,
310
+ "usdcSize": 55.0,
311
+ "asset": "21742633143463906290569050155826241533067272736897614950488156847949938836455",
312
+ "conditionId": "0x82ace55cdcba920112a2b3548f21e6e117730144db4dd580456aaecf1a2ad751",
313
+ "outcome": "Yes",
314
+ "outcomeIndex": 0,
315
+ "timestamp": 1702555200,
316
+ "transactionHash": "0xabc...",
317
+ "title": "Will BTC reach $100k?",
318
+ "slug": "will-btc-reach-100k",
319
+ "name": "trader123"
320
+ }
321
+ ```
322
+
323
+ **SDK Interface** (`data-api.ts`):
324
+ ```typescript
325
+ export interface Activity {
326
+ // Transaction type
327
+ type: 'TRADE' | 'SPLIT' | 'MERGE' | 'REDEEM' | 'CONVERSION';
328
+ side: 'BUY' | 'SELL';
329
+
330
+ // Trade data
331
+ size: number;
332
+ price: number;
333
+ usdcSize?: number;
334
+
335
+ // Market identifiers
336
+ asset: string;
337
+ conditionId: string;
338
+ outcome: string;
339
+ outcomeIndex?: number;
340
+
341
+ // Transaction info
342
+ timestamp: number;
343
+ transactionHash: string;
344
+
345
+ // Market metadata
346
+ title?: string;
347
+ slug?: string;
348
+
349
+ // Trader info
350
+ name?: string;
351
+ }
352
+ ```
353
+
354
+ ---
355
+
356
+ ### Trade (Data API)
357
+
358
+ **API Endpoint**: `GET /trades`
359
+
360
+ **Verified API Response** (2024-12-21):
361
+ ```json
362
+ {
363
+ "proxyWallet": "0x750e52d38753546eb57395811f2c324d3db01fac",
364
+ "side": "SELL",
365
+ "asset": "3826026842978178641920766976929297863453551585071976524482954212194670371395",
366
+ "conditionId": "0xe48a7cbb6c76a2dc89f39e6e75dbb4806daa11f18b91638976e30088445fcedd",
367
+ "size": 16,
368
+ "price": 0.55,
369
+ "timestamp": 1766319567,
370
+ "title": "Bitcoin Up or Down - December 21, 7:15AM-7:30AM ET",
371
+ "slug": "btc-updown-15m-1766319300",
372
+ "icon": "https://polymarket-upload.s3.us-east-2.amazonaws.com/BTC+fullsize.png",
373
+ "eventSlug": "btc-updown-15m-1766319300",
374
+ "outcome": "Up",
375
+ "outcomeIndex": 0,
376
+ "name": "sadfgas",
377
+ "pseudonym": "Striped-Moai",
378
+ "bio": "",
379
+ "profileImage": "",
380
+ "profileImageOptimized": "",
381
+ "transactionHash": "0x5aa793936a8530a292c58ef8e3ed253056b113b978f6807a6ff9cf40c86a5a7d"
382
+ }
383
+ ```
384
+
385
+ **SDK Interface** (`data-api.ts`):
386
+ ```typescript
387
+ export interface Trade {
388
+ // Identifiers
389
+ id?: string;
390
+ market: string;
391
+ asset: string;
392
+
393
+ // Trade data
394
+ side: 'BUY' | 'SELL';
395
+ price: number;
396
+ size: number;
397
+ outcome: string;
398
+ outcomeIndex: number;
399
+
400
+ // Transaction info
401
+ timestamp: number;
402
+ transactionHash: string;
403
+ proxyWallet?: string;
404
+
405
+ // Market metadata
406
+ title?: string;
407
+ slug?: string;
408
+ icon?: string;
409
+ eventSlug?: string;
410
+
411
+ // Trader info
412
+ name?: string;
413
+ pseudonym?: string;
414
+ bio?: string;
415
+ profileImage?: string;
416
+ profileImageOptimized?: string;
417
+ }
418
+ ```
419
+
420
+ ---
421
+
422
+ ### LeaderboardEntry (Data API)
423
+
424
+ **API Endpoint**: `GET /v1/leaderboard`
425
+
426
+ **Verified API Response** (2024-12-21):
427
+ ```json
428
+ {
429
+ "rank": "1",
430
+ "proxyWallet": "0xc2e7800b5af46e6093872b177b7a5e7f0563be51",
431
+ "userName": "beachboy4",
432
+ "xUsername": "",
433
+ "verifiedBadge": false,
434
+ "vol": 1346825.460224,
435
+ "pnl": 802943.8607537004,
436
+ "profileImage": ""
437
+ }
438
+ ```
439
+
440
+ **Note**: `rank` is returned as string; `positions` and `trades` fields are not returned.
441
+
442
+ **SDK Interface** (`data-api.ts`):
443
+ ```typescript
444
+ export interface LeaderboardEntry {
445
+ address: string; // Normalized from proxyWallet
446
+ rank: number;
447
+ pnl: number;
448
+ volume: number; // Normalized from "vol"
449
+
450
+ // User profile
451
+ userName?: string;
452
+ xUsername?: string;
453
+ verifiedBadge?: boolean;
454
+ profileImage?: string;
455
+
456
+ // Activity counts (optional - API often returns null)
457
+ positions?: number;
458
+ trades?: number;
459
+ }
460
+ ```
461
+
462
+ ---
463
+
464
+ ### ClobMarket (CLOB API)
465
+
466
+ **API Endpoint**: `GET /markets/{conditionId}`
467
+
468
+ **Verified API Response** (2024-12-21):
469
+ ```json
470
+ {
471
+ "enable_order_book": true,
472
+ "active": true,
473
+ "closed": false,
474
+ "archived": false,
475
+ "accepting_orders": true,
476
+ "accepting_order_timestamp": "2025-12-02T13:27:14Z",
477
+ "minimum_order_size": 5,
478
+ "minimum_tick_size": 0.001,
479
+ "condition_id": "0xac9c6628a5398bb2a06f566854270a9fbc7f2badec4329d3b5fdc1407291c35b",
480
+ "question_id": "0x74ace93c6bc3d695886ffe4fd33a749dac5395fb9afd4ca0e6de986010a7b1ab",
481
+ "question": "Will Trump release the Epstein files by December 19?",
482
+ "description": "...",
483
+ "market_slug": "will-trump-release-the-epstein-files-by-december-19-771",
484
+ "end_date_iso": null,
485
+ "game_start_time": null,
486
+ "seconds_delay": 0,
487
+ "fpmm": "",
488
+ "maker_base_fee": 0,
489
+ "taker_base_fee": 0,
490
+ "notifications_enabled": true,
491
+ "neg_risk": false,
492
+ "neg_risk_market_id": "",
493
+ "neg_risk_request_id": "",
494
+ "icon": "https://...",
495
+ "image": "https://...",
496
+ "rewards": {
497
+ "rates": null,
498
+ "min_size": 200,
499
+ "max_spread": 4.5
500
+ },
501
+ "is_50_50_outcome": false,
502
+ "tokens": [
503
+ { "token_id": "97631444...", "outcome": "Yes", "price": 0.9975, "winner": false },
504
+ { "token_id": "34188370...", "outcome": "No", "price": 0.0025, "winner": false }
505
+ ],
506
+ "tags": ["Politics", "Trump", "Epstein"]
507
+ }
508
+ ```
509
+
510
+ **SDK Interface** (`clob-api.ts`):
511
+ ```typescript
512
+ export interface ClobMarket {
513
+ // Core identifiers
514
+ conditionId: string;
515
+ questionId?: string;
516
+ marketSlug: string;
517
+
518
+ // Market content
519
+ question: string;
520
+ description?: string;
521
+ image?: string;
522
+ icon?: string;
523
+
524
+ // Tokens
525
+ tokens: ClobToken[];
526
+ tags?: string[];
527
+
528
+ // Status flags
529
+ active: boolean;
530
+ closed: boolean;
531
+ archived?: boolean;
532
+ acceptingOrders: boolean;
533
+ acceptingOrderTimestamp?: string;
534
+ enableOrderBook?: boolean;
535
+
536
+ // Trading parameters
537
+ minimumOrderSize?: number;
538
+ minimumTickSize?: number;
539
+ makerBaseFee?: number;
540
+ takerBaseFee?: number;
541
+
542
+ // Timing
543
+ endDateIso?: string | null;
544
+ gameStartTime?: string | null;
545
+ secondsDelay?: number;
546
+
547
+ // Neg risk
548
+ negRisk?: boolean;
549
+ negRiskMarketId?: string;
550
+ negRiskRequestId?: string;
551
+
552
+ // Rewards
553
+ rewards?: {
554
+ rates?: unknown;
555
+ minSize?: number;
556
+ maxSpread?: number;
557
+ };
558
+
559
+ // Other
560
+ fpmm?: string;
561
+ notificationsEnabled?: boolean;
562
+ is5050Outcome?: boolean;
563
+ }
564
+
565
+ export interface ClobToken {
566
+ tokenId: string;
567
+ outcome: string;
568
+ price: number;
569
+ winner?: boolean;
570
+ }
571
+ ```
572
+
573
+ ---
574
+
575
+ ### Orderbook (CLOB API)
576
+
577
+ **API Endpoint**: `GET /book?token_id={tokenId}`
578
+
579
+ **Verified API Response** (2024-12-21):
580
+ ```json
581
+ {
582
+ "market": "0xac9c6628a5398bb2a06f566854270a9fbc7f2badec4329d3b5fdc1407291c35b",
583
+ "asset_id": "97631444429136963410558776454705646247419477447963422218240880878426855760467",
584
+ "timestamp": "1766319576845",
585
+ "hash": "8f61a83ce893fc0b5bd5a30bb6e73d77a7ca8816",
586
+ "bids": [
587
+ { "price": "0.997", "size": "451990.61" },
588
+ { "price": "0.996", "size": "1203906.34" }
589
+ ],
590
+ "asks": [
591
+ { "price": "0.998", "size": "1243577.96" },
592
+ { "price": "0.999", "size": "4250974.87" }
593
+ ],
594
+ "min_order_size": "5",
595
+ "tick_size": "0.001",
596
+ "neg_risk": false
597
+ }
598
+ ```
599
+
600
+ **SDK Interface** (`clob-api.ts`):
601
+ ```typescript
602
+ export interface Orderbook {
603
+ bids: OrderbookLevel[];
604
+ asks: OrderbookLevel[];
605
+ timestamp: number;
606
+
607
+ // Additional fields from API
608
+ market?: string;
609
+ assetId?: string;
610
+ hash?: string;
611
+ minOrderSize?: string;
612
+ tickSize?: string;
613
+ negRisk?: boolean;
614
+ }
615
+
616
+ export interface OrderbookLevel {
617
+ price: number;
618
+ size: number;
619
+ }
620
+ ```
621
+
622
+ ---
623
+
624
+ ### GammaMarket (Gamma API)
625
+
626
+ **API Endpoint**: `GET /markets`
627
+
628
+ **Verified Key Fields** (2024-12-21):
629
+ - `outcomes` and `outcomePrices` are JSON-encoded strings (need parsing)
630
+ - Many additional fields: `volumeNum`, `liquidityNum`, `volume24hr`, etc.
631
+
632
+ **SDK Interface** (`gamma-api.ts`):
633
+ ```typescript
634
+ export interface GammaMarket {
635
+ id: string;
636
+ conditionId: string;
637
+ slug: string;
638
+ question: string;
639
+ description?: string;
640
+ outcomes: string[]; // Parsed from JSON string
641
+ outcomePrices: number[]; // Parsed from JSON string
642
+ volume: number;
643
+ volume24hr?: number;
644
+ volume1wk?: number;
645
+ liquidity: number;
646
+ spread?: number;
647
+ oneDayPriceChange?: number;
648
+ oneWeekPriceChange?: number;
649
+ lastTradePrice?: number;
650
+ bestBid?: number;
651
+ bestAsk?: number;
652
+ endDate: Date;
653
+ active: boolean;
654
+ closed: boolean;
655
+ image?: string;
656
+ icon?: string;
657
+ tags?: string[];
658
+ }
659
+ ```
660
+
661
+ ---
662
+
663
+ ## Normalization Patterns
664
+
665
+ ### 1. String to Number Conversion
666
+
667
+ API returns strings for numeric values; SDK converts them:
668
+ ```typescript
669
+ size: Number(p.size),
670
+ price: Number(p.price),
671
+ ```
672
+
673
+ ### 2. Snake Case to Camel Case
674
+
675
+ CLOB API uses snake_case; SDK normalizes to camelCase:
676
+ ```typescript
677
+ conditionId: String(m.condition_id || ''),
678
+ marketSlug: String(m.market_slug || ''),
679
+ minimumOrderSize: Number(m.minimum_order_size),
680
+ ```
681
+
682
+ ### 3. Optional Field Handling
683
+
684
+ Fields that may be undefined or null are handled explicitly:
685
+ ```typescript
686
+ // Check for undefined
687
+ curPrice: p.curPrice !== undefined ? Number(p.curPrice) : undefined,
688
+
689
+ // Check for null (using != null checks both null and undefined)
690
+ positions: e.positions != null ? Number(e.positions) : undefined,
691
+
692
+ // Handle null explicitly
693
+ endDateIso: m.end_date_iso !== undefined
694
+ ? (m.end_date_iso === null ? null : String(m.end_date_iso))
695
+ : undefined,
696
+ ```
697
+
698
+ ### 4. Timestamp Normalization
699
+
700
+ API may return timestamps in seconds or milliseconds:
701
+ ```typescript
702
+ private normalizeTimestamp(ts: unknown): number {
703
+ if (typeof ts === 'number') {
704
+ return ts < 1e12 ? ts * 1000 : ts; // Convert seconds to ms
705
+ }
706
+ // ...
707
+ }
708
+ ```
709
+
710
+ ### 5. Wallet Address Normalization
711
+
712
+ Leaderboard returns `proxyWallet`; SDK normalizes to `address`:
713
+ ```typescript
714
+ address: String(e.proxyWallet || e.address || ''),
715
+ ```
716
+
717
+ ### 6. JSON String Parsing
718
+
719
+ Gamma API returns some arrays as JSON strings:
720
+ ```typescript
721
+ private parseJsonArray<T>(value: unknown, fallback: T[]): T[] {
722
+ if (Array.isArray(value)) return value as T[];
723
+ if (typeof value === 'string') {
724
+ try { return JSON.parse(value); }
725
+ catch { return fallback; }
726
+ }
727
+ return fallback;
728
+ }
729
+ ```
730
+
731
+ ---
732
+
733
+ ## Design Principles
734
+
735
+ 1. **Faithful API Inheritance**: SDK types include all fields returned by the API
736
+ 2. **Optional by Default**: Fields that may be missing are marked optional (`?`)
737
+ 3. **Type Safety**: All values are explicitly typed; numbers are converted from strings
738
+ 4. **Normalized Naming**: Consistent camelCase across all SDK interfaces
739
+ 5. **Null Handling**: Explicit handling of null vs undefined values
740
+ 6. **Verified Fields**: All field mappings verified against actual API responses
741
+
742
+ ---
743
+
744
+ ## Verification Scripts
745
+
746
+ To verify API responses match SDK types:
747
+
748
+ ```bash
749
+ # Run verification script
750
+ cd packages/poly-sdk
751
+ npx tsx scripts/verify-all-apis.ts
752
+
753
+ # Or manually verify with curl
754
+ curl "https://data-api.polymarket.com/positions?user=0x..." | jq '.[0]'
755
+ curl "https://data-api.polymarket.com/v1/leaderboard?limit=1" | jq '.[0]'
756
+ curl "https://data-api.polymarket.com/trades?limit=1" | jq '.[0]'
757
+ curl "https://gamma-api.polymarket.com/markets?active=true&limit=1" | jq '.[0]'
758
+ curl "https://clob.polymarket.com/markets/0x..." | jq
759
+ curl "https://clob.polymarket.com/book?token_id=..." | jq
760
+ ```