@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,841 @@
1
+ /**
2
+ * Bridge Client for Polymarket Cross-Chain Deposits
3
+ *
4
+ * Enables depositing assets from multiple chains (Ethereum, etc.)
5
+ * and having them automatically converted to USDC.e on Polygon for trading.
6
+ *
7
+ * Flow:
8
+ * 1. Request deposit addresses for your Polymarket wallet
9
+ * 2. Send assets to the unique deposit address for each chain/token
10
+ * 3. Assets are automatically bridged and swapped to USDC.e on Polygon
11
+ * 4. USDC.e is credited to your Polymarket account
12
+ *
13
+ * @see https://docs.polymarket.com/developers/misc-endpoints/bridge-deposit
14
+ * @see https://docs.polymarket.com/developers/misc-endpoints/bridge-supported-assets
15
+ */
16
+
17
+ // ===== Types =====
18
+
19
+ /**
20
+ * Supported asset information from the bridge
21
+ */
22
+ export interface BridgeSupportedAsset {
23
+ /** Blockchain chain ID (e.g., 1 for Ethereum) */
24
+ chainId: number;
25
+ /** Human-readable chain name (e.g., "Ethereum") */
26
+ chainName: string;
27
+ /** Token contract address on the source chain */
28
+ tokenAddress: string;
29
+ /** Token symbol (e.g., "USDC", "ETH") */
30
+ tokenSymbol: string;
31
+ /** Token name (e.g., "USD Coin") */
32
+ tokenName: string;
33
+ /** Token decimals (e.g., 6 for USDC) */
34
+ decimals: number;
35
+ /** Minimum deposit amount in token units */
36
+ minDeposit: string;
37
+ /** Minimum deposit amount in USD */
38
+ minDepositUsd: number;
39
+ /** Whether this asset is currently active */
40
+ active: boolean;
41
+ }
42
+
43
+ /**
44
+ * Deposit address for a specific chain/token combination
45
+ */
46
+ export interface DepositAddress {
47
+ /** Blockchain chain ID */
48
+ chainId: number;
49
+ /** Human-readable chain name */
50
+ chainName: string;
51
+ /** Token contract address on source chain */
52
+ tokenAddress: string;
53
+ /** Token symbol */
54
+ tokenSymbol: string;
55
+ /** Unique deposit address to send funds to */
56
+ depositAddress: string;
57
+ /** Minimum deposit amount */
58
+ minDeposit: string;
59
+ }
60
+
61
+ /**
62
+ * Response from creating deposit addresses
63
+ *
64
+ * The Bridge API returns a single universal deposit address structure.
65
+ * - EVM address: Used for all EVM chains (Ethereum, Polygon, Arbitrum, Base, Optimism)
66
+ * - SVM address: Used for Solana
67
+ * - BTC address: Used for Bitcoin
68
+ *
69
+ * @example Response from API:
70
+ * ```json
71
+ * {
72
+ * "address": {
73
+ * "evm": "0x1234...",
74
+ * "svm": "ABC123...",
75
+ * "btc": "bc1q..."
76
+ * }
77
+ * }
78
+ * ```
79
+ */
80
+ export interface CreateDepositResponse {
81
+ /** Universal deposit addresses for different chain types */
82
+ address: {
83
+ /** EVM deposit address (Ethereum, Polygon, Arbitrum, Base, Optimism) */
84
+ evm: string;
85
+ /** Solana deposit address */
86
+ svm: string;
87
+ /** Bitcoin deposit address */
88
+ btc: string;
89
+ };
90
+ }
91
+
92
+ /**
93
+ * Deposit status tracking
94
+ */
95
+ export interface DepositStatus {
96
+ /** Unique deposit ID */
97
+ depositId: string;
98
+ /** Source chain ID */
99
+ sourceChainId: number;
100
+ /** Source transaction hash */
101
+ sourceTxHash: string;
102
+ /** Amount deposited */
103
+ amount: string;
104
+ /** Token symbol */
105
+ tokenSymbol: string;
106
+ /** Status of the deposit */
107
+ status: 'pending' | 'bridging' | 'swapping' | 'completed' | 'failed';
108
+ /** Destination transaction hash (when completed) */
109
+ destinationTxHash?: string;
110
+ /** USDC.e amount received (when completed) */
111
+ usdceReceived?: string;
112
+ /** Error message (if failed) */
113
+ errorMessage?: string;
114
+ /** Timestamp of last update */
115
+ updatedAt: string;
116
+ }
117
+
118
+ /**
119
+ * Bridge configuration
120
+ */
121
+ export interface BridgeConfig {
122
+ /** Base URL for the bridge API (default: https://bridge.polymarket.com) */
123
+ baseUrl?: string;
124
+ /** Request timeout in ms (default: 30000) */
125
+ timeout?: number;
126
+ }
127
+
128
+ // ===== Constants =====
129
+
130
+ const BRIDGE_API_BASE = 'https://bridge.polymarket.com';
131
+
132
+ // Known chain information
133
+ export const SUPPORTED_CHAINS = {
134
+ ETHEREUM: {
135
+ chainId: 1,
136
+ name: 'Ethereum',
137
+ rpcUrl: 'https://eth.llamarpc.com',
138
+ },
139
+ POLYGON: {
140
+ chainId: 137,
141
+ name: 'Polygon',
142
+ rpcUrl: 'https://polygon-rpc.com',
143
+ },
144
+ } as const;
145
+
146
+ // Known token addresses
147
+ export const BRIDGE_TOKENS = {
148
+ // Ethereum
149
+ ETH_USDC: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
150
+ ETH_WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
151
+ ETH_DAI: '0x6B175474E89094C44Da98b954EeDeaC495271d0F',
152
+
153
+ // Polygon (destination)
154
+ POLYGON_USDC_E: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174',
155
+ POLYGON_NATIVE_USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
156
+ } as const;
157
+
158
+ // ===== Bridge Client =====
159
+
160
+ /**
161
+ * Client for interacting with Polymarket's cross-chain bridge
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * const bridge = new BridgeClient();
166
+ *
167
+ * // Get supported assets
168
+ * const assets = await bridge.getSupportedAssets();
169
+ * console.log(`Supported: ${assets.map(a => a.tokenSymbol).join(', ')}`);
170
+ *
171
+ * // Create deposit addresses for your wallet
172
+ * const deposit = await bridge.createDepositAddresses('0xYourAddress');
173
+ * const ethUsdc = deposit.depositAddresses.find(
174
+ * d => d.chainName === 'Ethereum' && d.tokenSymbol === 'USDC'
175
+ * );
176
+ * console.log(`Send USDC on Ethereum to: ${ethUsdc.depositAddress}`);
177
+ * ```
178
+ */
179
+ export class BridgeClient {
180
+ private baseUrl: string;
181
+ private timeout: number;
182
+
183
+ constructor(config: BridgeConfig = {}) {
184
+ this.baseUrl = config.baseUrl || BRIDGE_API_BASE;
185
+ this.timeout = config.timeout || 30000;
186
+ }
187
+
188
+ /**
189
+ * Get all supported assets for bridge deposits
190
+ *
191
+ * @returns Array of supported assets with their chain/token details
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * const assets = await bridge.getSupportedAssets();
196
+ * for (const asset of assets) {
197
+ * console.log(`${asset.chainName} ${asset.tokenSymbol}: min $${asset.minDepositUsd}`);
198
+ * }
199
+ * ```
200
+ */
201
+ async getSupportedAssets(): Promise<BridgeSupportedAsset[]> {
202
+ const response = await this.fetch('/supported-assets') as {
203
+ supportedAssets: Array<{
204
+ chainId: string;
205
+ chainName: string;
206
+ token: {
207
+ name: string;
208
+ symbol: string;
209
+ address: string;
210
+ decimals: number;
211
+ };
212
+ minCheckoutUsd: number;
213
+ }>;
214
+ };
215
+
216
+ // Normalize the API response to match our interface
217
+ return response.supportedAssets.map((asset) => ({
218
+ chainId: parseInt(asset.chainId, 10),
219
+ chainName: asset.chainName,
220
+ tokenSymbol: asset.token.symbol,
221
+ tokenName: asset.token.name,
222
+ tokenAddress: asset.token.address,
223
+ decimals: asset.token.decimals,
224
+ minDeposit: asset.minCheckoutUsd.toString(),
225
+ minDepositUsd: asset.minCheckoutUsd,
226
+ active: true,
227
+ }));
228
+ }
229
+
230
+ /**
231
+ * Get unique deposit addresses for a Polymarket wallet
232
+ *
233
+ * The Bridge API returns a universal deposit address structure:
234
+ * - A single EVM address works for ALL EVM chains (Ethereum, Polygon, Arbitrum, Base, Optimism)
235
+ * - A Solana address for SVM deposits
236
+ * - A Bitcoin address for BTC deposits
237
+ *
238
+ * Funds sent to these addresses are automatically bridged to Polygon
239
+ * and converted to USDC.e for your Polymarket account.
240
+ *
241
+ * @param walletAddress - Your Polymarket wallet address (EOA address)
242
+ * @returns Universal deposit addresses for EVM, Solana, and Bitcoin
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * const result = await bridge.createDepositAddresses('0xYourPolymarketWallet');
247
+ *
248
+ * // The EVM address works for Ethereum, Polygon, Arbitrum, Base, Optimism
249
+ * console.log(`EVM deposit address: ${result.address.evm}`);
250
+ *
251
+ * // For Solana deposits
252
+ * console.log(`Solana deposit address: ${result.address.svm}`);
253
+ *
254
+ * // For Bitcoin deposits
255
+ * console.log(`Bitcoin deposit address: ${result.address.btc}`);
256
+ * ```
257
+ */
258
+ async createDepositAddresses(walletAddress: string): Promise<CreateDepositResponse> {
259
+ const response = await this.fetch('/deposit', {
260
+ method: 'POST',
261
+ body: JSON.stringify({ address: walletAddress }),
262
+ });
263
+
264
+ return response as CreateDepositResponse;
265
+ }
266
+
267
+ /**
268
+ * Get the EVM deposit address for a wallet
269
+ *
270
+ * This address works for ALL supported EVM chains:
271
+ * - Ethereum (chainId: 1)
272
+ * - Polygon (chainId: 137)
273
+ * - Arbitrum (chainId: 42161)
274
+ * - Base (chainId: 8453)
275
+ * - Optimism (chainId: 10)
276
+ *
277
+ * @param walletAddress - Your Polymarket wallet address
278
+ * @returns The universal EVM deposit address
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * const evmAddr = await bridge.getEvmDepositAddress('0xYourWallet');
283
+ * // Send Native USDC on Polygon to this address
284
+ * // Or send USDC on Ethereum to this address
285
+ * console.log(`Deposit to: ${evmAddr}`);
286
+ * ```
287
+ */
288
+ async getEvmDepositAddress(walletAddress: string): Promise<string> {
289
+ const result = await this.createDepositAddresses(walletAddress);
290
+ return result.address.evm;
291
+ }
292
+
293
+ /**
294
+ * Get the Solana deposit address for a wallet
295
+ *
296
+ * @param walletAddress - Your Polymarket wallet address
297
+ * @returns The Solana deposit address
298
+ */
299
+ async getSolanaDepositAddress(walletAddress: string): Promise<string> {
300
+ const result = await this.createDepositAddresses(walletAddress);
301
+ return result.address.svm;
302
+ }
303
+
304
+ /**
305
+ * Get the Bitcoin deposit address for a wallet
306
+ *
307
+ * @param walletAddress - Your Polymarket wallet address
308
+ * @returns The Bitcoin deposit address
309
+ */
310
+ async getBtcDepositAddress(walletAddress: string): Promise<string> {
311
+ const result = await this.createDepositAddresses(walletAddress);
312
+ return result.address.btc;
313
+ }
314
+
315
+ /**
316
+ * @deprecated Use getEvmDepositAddress(), getSolanaDepositAddress(), or getBtcDepositAddress() instead.
317
+ *
318
+ * The Bridge API returns universal addresses by chain type (EVM/SVM/BTC),
319
+ * not by specific chain/token combinations.
320
+ *
321
+ * For EVM chains (Ethereum, Polygon, Arbitrum, Base, Optimism), use getEvmDepositAddress()
322
+ */
323
+ async getDepositAddress(
324
+ address: string,
325
+ _chainId: number,
326
+ _tokenSymbol: string
327
+ ): Promise<DepositAddress | null> {
328
+ // Return a compatibility shim - the EVM address works for all EVM chains
329
+ const result = await this.createDepositAddresses(address);
330
+ return {
331
+ chainId: _chainId,
332
+ chainName: 'Universal EVM',
333
+ tokenAddress: '',
334
+ tokenSymbol: _tokenSymbol,
335
+ depositAddress: result.address.evm,
336
+ minDeposit: '2', // Default minimum
337
+ };
338
+ }
339
+
340
+ /**
341
+ * Check if a chain/token combination is supported
342
+ *
343
+ * @param chainId - The chain ID to check
344
+ * @param tokenSymbol - The token symbol to check
345
+ * @returns True if supported, false otherwise
346
+ */
347
+ async isSupported(chainId: number, tokenSymbol: string): Promise<boolean> {
348
+ const assets = await this.getSupportedAssets();
349
+ return assets.some(
350
+ (a) => a.chainId === chainId && a.tokenSymbol.toUpperCase() === tokenSymbol.toUpperCase()
351
+ );
352
+ }
353
+
354
+ /**
355
+ * Get minimum deposit amount for a chain/token
356
+ *
357
+ * @param chainId - The chain ID
358
+ * @param tokenSymbol - The token symbol
359
+ * @returns Minimum deposit info or null if not supported
360
+ */
361
+ async getMinDeposit(
362
+ chainId: number,
363
+ tokenSymbol: string
364
+ ): Promise<{ amount: string; usd: number } | null> {
365
+ const assets = await this.getSupportedAssets();
366
+ const asset = assets.find(
367
+ (a) => a.chainId === chainId && a.tokenSymbol.toUpperCase() === tokenSymbol.toUpperCase()
368
+ );
369
+
370
+ if (!asset) return null;
371
+
372
+ return {
373
+ amount: asset.minDeposit,
374
+ usd: asset.minDepositUsd,
375
+ };
376
+ }
377
+
378
+ /**
379
+ * Format deposit instructions for a user
380
+ *
381
+ * @param walletAddress - The Polymarket wallet address
382
+ * @returns Formatted instructions string
383
+ */
384
+ async getDepositInstructions(walletAddress: string): Promise<string> {
385
+ const result = await this.createDepositAddresses(walletAddress);
386
+ const assets = await this.getSupportedAssets();
387
+
388
+ const lines: string[] = [
389
+ '═══════════════════════════════════════════════════════════',
390
+ ' POLYMARKET DEPOSIT INSTRUCTIONS',
391
+ '═══════════════════════════════════════════════════════════',
392
+ '',
393
+ `Wallet: ${walletAddress}`,
394
+ '',
395
+ 'Send assets to these addresses to deposit to your Polymarket account:',
396
+ '(Assets will be automatically converted to USDC.e on Polygon)',
397
+ '',
398
+ ];
399
+
400
+ // EVM Deposit Address (works for all EVM chains)
401
+ lines.push('── EVM CHAINS ──');
402
+ lines.push('(Ethereum, Polygon, Arbitrum, Base, Optimism)');
403
+ lines.push('');
404
+ lines.push(` Universal EVM Address: ${result.address.evm}`);
405
+ lines.push('');
406
+
407
+ // Group assets by chain for display
408
+ const evmChainIds = [1, 137, 42161, 8453, 10];
409
+ const evmAssets = assets.filter((a) => evmChainIds.includes(a.chainId));
410
+
411
+ // Group by chain
412
+ const byChain = new Map<number, BridgeSupportedAsset[]>();
413
+ for (const asset of evmAssets) {
414
+ const existing = byChain.get(asset.chainId) || [];
415
+ existing.push(asset);
416
+ byChain.set(asset.chainId, existing);
417
+ }
418
+
419
+ for (const [chainId, chainAssets] of byChain) {
420
+ const chainName = chainAssets[0]?.chainName || `Chain ${chainId}`;
421
+ lines.push(` ${chainName} (${chainId}):`);
422
+ for (const asset of chainAssets) {
423
+ lines.push(` - ${asset.tokenSymbol}: min $${asset.minDepositUsd}`);
424
+ }
425
+ lines.push('');
426
+ }
427
+
428
+ // Solana Deposit Address
429
+ lines.push('── SOLANA ──');
430
+ lines.push(` Address: ${result.address.svm}`);
431
+ const solAssets = assets.filter((a) => a.chainName?.toLowerCase().includes('solana'));
432
+ for (const asset of solAssets) {
433
+ lines.push(` - ${asset.tokenSymbol}: min $${asset.minDepositUsd}`);
434
+ }
435
+ lines.push('');
436
+
437
+ // Bitcoin Deposit Address
438
+ lines.push('── BITCOIN ──');
439
+ lines.push(` Address: ${result.address.btc}`);
440
+ const btcAssets = assets.filter((a) => a.chainName?.toLowerCase().includes('bitcoin'));
441
+ for (const asset of btcAssets) {
442
+ lines.push(` - ${asset.tokenSymbol}: min $${asset.minDepositUsd}`);
443
+ }
444
+ lines.push('');
445
+
446
+ lines.push('═══════════════════════════════════════════════════════════');
447
+ lines.push('');
448
+ lines.push('IMPORTANT:');
449
+ lines.push(' - Always send more than the minimum amount');
450
+ lines.push(' - Deposits may take 1-30 minutes to process');
451
+ lines.push(' - Check Polymarket balance after deposit completes');
452
+ lines.push(' - Bridge fee is approximately 0.16%');
453
+ lines.push('');
454
+
455
+ return lines.join('\n');
456
+ }
457
+
458
+ // ===== Private Methods =====
459
+
460
+ private async fetch(path: string, options: RequestInit = {}): Promise<unknown> {
461
+ const url = `${this.baseUrl}${path}`;
462
+
463
+ const controller = new AbortController();
464
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
465
+
466
+ try {
467
+ const response = await fetch(url, {
468
+ ...options,
469
+ headers: {
470
+ 'Content-Type': 'application/json',
471
+ ...options.headers,
472
+ },
473
+ signal: controller.signal,
474
+ });
475
+
476
+ if (!response.ok) {
477
+ const errorText = await response.text();
478
+ throw new Error(`Bridge API error (${response.status}): ${errorText}`);
479
+ }
480
+
481
+ return await response.json();
482
+ } finally {
483
+ clearTimeout(timeoutId);
484
+ }
485
+ }
486
+ }
487
+
488
+ // ===== Deposit Execution =====
489
+
490
+ import { ethers } from 'ethers';
491
+
492
+ // ERC20 ABI for deposits
493
+ const ERC20_DEPOSIT_ABI = [
494
+ 'function balanceOf(address owner) view returns (uint256)',
495
+ 'function transfer(address to, uint256 amount) returns (bool)',
496
+ ];
497
+
498
+ export interface DepositResult {
499
+ success: boolean;
500
+ txHash?: string;
501
+ amount: string;
502
+ depositAddress: string;
503
+ error?: string;
504
+ }
505
+
506
+ export interface DepositOptions {
507
+ /** Chain ID for the deposit (default: 137 for Polygon) */
508
+ chainId?: number;
509
+ /** Token to deposit: 'NATIVE_USDC' or 'USDC_E' (default: 'NATIVE_USDC') */
510
+ token?: 'NATIVE_USDC' | 'USDC_E';
511
+ /** Gas price multiplier (default: 1.2) */
512
+ gasPriceMultiplier?: number;
513
+ }
514
+
515
+ /**
516
+ * Deposit USDC to Polymarket via Bridge
517
+ *
518
+ * This function:
519
+ * 1. Gets the deposit address for your wallet
520
+ * 2. Transfers USDC to that address
521
+ * 3. The bridge automatically converts it to USDC.e for your Polymarket account
522
+ *
523
+ * @param signer - Ethers wallet/signer to send from
524
+ * @param amount - Amount in USDC (e.g., 10.5 for $10.50)
525
+ * @param options - Deposit options
526
+ * @returns Deposit result with transaction hash
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * const bridge = new BridgeClient();
531
+ * const result = await bridge.depositUsdc(signer, 100);
532
+ * console.log(`Deposited $100: ${result.txHash}`);
533
+ * ```
534
+ */
535
+ export async function depositUsdc(
536
+ signer: ethers.Wallet,
537
+ amount: number,
538
+ options: DepositOptions = {}
539
+ ): Promise<DepositResult> {
540
+ const { token = 'NATIVE_USDC', gasPriceMultiplier = 1.2 } = options;
541
+
542
+ // Validate minimum deposit
543
+ if (amount < 2) {
544
+ return {
545
+ success: false,
546
+ amount: amount.toString(),
547
+ depositAddress: '',
548
+ error: 'Minimum deposit is $2',
549
+ };
550
+ }
551
+
552
+ // Get token address
553
+ const tokenAddress =
554
+ token === 'NATIVE_USDC' ? BRIDGE_TOKENS.POLYGON_NATIVE_USDC : BRIDGE_TOKENS.POLYGON_USDC_E;
555
+
556
+ try {
557
+ // Get deposit address
558
+ const bridge = new BridgeClient();
559
+ const depositAddr = await bridge.getEvmDepositAddress(signer.address);
560
+
561
+ // Create token contract
562
+ const tokenContract = new ethers.Contract(tokenAddress, ERC20_DEPOSIT_ABI, signer);
563
+
564
+ // Check balance
565
+ const balance = await tokenContract.balanceOf(signer.address);
566
+ const amountWei = ethers.utils.parseUnits(amount.toString(), 6);
567
+
568
+ if (balance.lt(amountWei)) {
569
+ const balanceFormatted = ethers.utils.formatUnits(balance, 6);
570
+ return {
571
+ success: false,
572
+ amount: amount.toString(),
573
+ depositAddress: depositAddr,
574
+ error: `Insufficient balance. Have: ${balanceFormatted}, Need: ${amount}`,
575
+ };
576
+ }
577
+
578
+ // Get gas price with buffer
579
+ const feeData = await signer.provider!.getFeeData();
580
+ const gasPrice = feeData.gasPrice
581
+ ? feeData.gasPrice.mul(Math.floor(gasPriceMultiplier * 100)).div(100)
582
+ : undefined;
583
+
584
+ // Execute transfer
585
+ const tx = await tokenContract.transfer(depositAddr, amountWei, {
586
+ gasPrice,
587
+ });
588
+
589
+ const receipt = await tx.wait();
590
+
591
+ if (receipt.status !== 1) {
592
+ return {
593
+ success: false,
594
+ txHash: tx.hash,
595
+ amount: amount.toString(),
596
+ depositAddress: depositAddr,
597
+ error: 'Transaction failed',
598
+ };
599
+ }
600
+
601
+ return {
602
+ success: true,
603
+ txHash: tx.hash,
604
+ amount: amount.toString(),
605
+ depositAddress: depositAddr,
606
+ };
607
+ } catch (err) {
608
+ return {
609
+ success: false,
610
+ amount: amount.toString(),
611
+ depositAddress: '',
612
+ error: err instanceof Error ? err.message : 'Unknown error',
613
+ };
614
+ }
615
+ }
616
+
617
+ // ===== Swap and Deposit =====
618
+
619
+ import { SwapService, POLYGON_TOKENS, TOKEN_DECIMALS } from '../services/swap-service.js';
620
+
621
+ export interface SwapAndDepositOptions {
622
+ /** Slippage tolerance for swap (default: 0.5%) */
623
+ slippage?: number;
624
+ /** Gas price multiplier (default: 1.2) */
625
+ gasPriceMultiplier?: number;
626
+ }
627
+
628
+ export interface SwapAndDepositResult {
629
+ success: boolean;
630
+ /** Swap transaction hash (if swap was needed) */
631
+ swapTxHash?: string;
632
+ /** Deposit transaction hash */
633
+ depositTxHash?: string;
634
+ /** Input token */
635
+ tokenIn: string;
636
+ /** Amount of input token */
637
+ amountIn: string;
638
+ /** Amount of USDC after swap */
639
+ usdcAmount: string;
640
+ /** Deposit address */
641
+ depositAddress: string;
642
+ /** Error message if failed */
643
+ error?: string;
644
+ }
645
+
646
+ /**
647
+ * Swap any supported Polygon token to USDC and deposit to Polymarket
648
+ *
649
+ * Supported tokens: MATIC, WMATIC, USDC, USDC_E, USDT, DAI, WETH
650
+ *
651
+ * Flow:
652
+ * 1. If token is not USDC, swap to USDC using QuickSwap
653
+ * 2. Deposit USDC to the bridge deposit address
654
+ *
655
+ * @param signer - Ethers wallet/signer
656
+ * @param token - Token symbol to deposit (e.g., 'MATIC', 'WETH', 'USDT')
657
+ * @param amount - Amount to deposit in token units
658
+ * @param options - Swap and deposit options
659
+ * @returns Result with transaction hashes
660
+ *
661
+ * @example
662
+ * ```typescript
663
+ * // Deposit 10 MATIC
664
+ * const result = await swapAndDeposit(signer, 'MATIC', '10');
665
+ *
666
+ * // Deposit 100 USDT
667
+ * const result = await swapAndDeposit(signer, 'USDT', '100');
668
+ *
669
+ * // Deposit 0.1 WETH
670
+ * const result = await swapAndDeposit(signer, 'WETH', '0.1');
671
+ * ```
672
+ */
673
+ export async function swapAndDeposit(
674
+ signer: ethers.Wallet,
675
+ token: string,
676
+ amount: string,
677
+ options: SwapAndDepositOptions = {}
678
+ ): Promise<SwapAndDepositResult> {
679
+ const { slippage = 0.5, gasPriceMultiplier = 1.2 } = options;
680
+
681
+ const upperToken = token.toUpperCase();
682
+
683
+ try {
684
+ const swapService = new SwapService(signer);
685
+ const bridge = new BridgeClient();
686
+
687
+ // Get deposit address
688
+ const depositAddr = await bridge.getEvmDepositAddress(signer.address);
689
+
690
+ // If already USDC, skip swap
691
+ if (upperToken === 'USDC' || upperToken === 'NATIVE_USDC') {
692
+ const result = await depositUsdc(signer, parseFloat(amount), {
693
+ token: 'NATIVE_USDC',
694
+ gasPriceMultiplier,
695
+ });
696
+
697
+ return {
698
+ success: result.success,
699
+ depositTxHash: result.txHash,
700
+ tokenIn: upperToken,
701
+ amountIn: amount,
702
+ usdcAmount: amount,
703
+ depositAddress: depositAddr,
704
+ error: result.error,
705
+ };
706
+ }
707
+
708
+ if (upperToken === 'USDC_E') {
709
+ const result = await depositUsdc(signer, parseFloat(amount), {
710
+ token: 'USDC_E',
711
+ gasPriceMultiplier,
712
+ });
713
+
714
+ return {
715
+ success: result.success,
716
+ depositTxHash: result.txHash,
717
+ tokenIn: upperToken,
718
+ amountIn: amount,
719
+ usdcAmount: amount,
720
+ depositAddress: depositAddr,
721
+ error: result.error,
722
+ };
723
+ }
724
+
725
+ // Check balance
726
+ const balance = await swapService.getBalance(token);
727
+ if (parseFloat(balance) < parseFloat(amount)) {
728
+ return {
729
+ success: false,
730
+ tokenIn: upperToken,
731
+ amountIn: amount,
732
+ usdcAmount: '0',
733
+ depositAddress: depositAddr,
734
+ error: `Insufficient ${upperToken} balance. Have: ${balance}, Need: ${amount}`,
735
+ };
736
+ }
737
+
738
+ // Swap to USDC
739
+ const swapResult = await swapService.swapToUsdc(token, amount, {
740
+ usdcType: 'NATIVE_USDC',
741
+ slippage,
742
+ });
743
+
744
+ if (!swapResult.success) {
745
+ return {
746
+ success: false,
747
+ tokenIn: upperToken,
748
+ amountIn: amount,
749
+ usdcAmount: '0',
750
+ depositAddress: depositAddr,
751
+ error: `Swap failed: ${swapResult.transactionHash}`,
752
+ };
753
+ }
754
+
755
+ // Get USDC balance after swap
756
+ const usdcBalance = await swapService.getBalance('USDC');
757
+
758
+ // Deposit USDC
759
+ const depositResult = await depositUsdc(signer, parseFloat(usdcBalance), {
760
+ token: 'NATIVE_USDC',
761
+ gasPriceMultiplier,
762
+ });
763
+
764
+ return {
765
+ success: depositResult.success,
766
+ swapTxHash: swapResult.transactionHash,
767
+ depositTxHash: depositResult.txHash,
768
+ tokenIn: upperToken,
769
+ amountIn: amount,
770
+ usdcAmount: usdcBalance,
771
+ depositAddress: depositAddr,
772
+ error: depositResult.error,
773
+ };
774
+ } catch (err) {
775
+ return {
776
+ success: false,
777
+ tokenIn: upperToken,
778
+ amountIn: amount,
779
+ usdcAmount: '0',
780
+ depositAddress: '',
781
+ error: err instanceof Error ? err.message : 'Unknown error',
782
+ };
783
+ }
784
+ }
785
+
786
+ /**
787
+ * Get list of supported tokens for swap and deposit
788
+ */
789
+ export function getSupportedDepositTokens(): string[] {
790
+ return Object.keys(POLYGON_TOKENS);
791
+ }
792
+
793
+ // ===== Utility Functions =====
794
+
795
+ /**
796
+ * Calculate the expected USDC.e output after bridge fees
797
+ *
798
+ * Note: This is an estimate. Actual output depends on bridge/swap fees.
799
+ *
800
+ * @param amount - Input amount in source token
801
+ * @param tokenSymbol - Source token symbol
802
+ * @returns Estimated USDC.e output
803
+ */
804
+ export function estimateBridgeOutput(amount: number, tokenSymbol: string): number {
805
+ // Typical bridge fees: ~0.5-1%
806
+ // Swap fees: ~0.3%
807
+ const totalFeePercent = 0.01; // 1% estimate
808
+
809
+ // For stablecoins, 1:1 minus fees
810
+ if (['USDC', 'USDT', 'DAI', 'BUSD'].includes(tokenSymbol.toUpperCase())) {
811
+ return amount * (1 - totalFeePercent);
812
+ }
813
+
814
+ // For ETH and other tokens, would need price oracle
815
+ // This is just a placeholder
816
+ return amount * (1 - totalFeePercent);
817
+ }
818
+
819
+ /**
820
+ * Get explorer URL for a deposit transaction
821
+ *
822
+ * @param chainId - The chain ID
823
+ * @param txHash - The transaction hash
824
+ * @returns Block explorer URL
825
+ */
826
+ export function getExplorerUrl(chainId: number, txHash: string): string {
827
+ switch (chainId) {
828
+ case 1:
829
+ return `https://etherscan.io/tx/${txHash}`;
830
+ case 137:
831
+ return `https://polygonscan.com/tx/${txHash}`;
832
+ case 10:
833
+ return `https://optimistic.etherscan.io/tx/${txHash}`;
834
+ case 42161:
835
+ return `https://arbiscan.io/tx/${txHash}`;
836
+ case 8453:
837
+ return `https://basescan.org/tx/${txHash}`;
838
+ default:
839
+ return `https://blockscan.com/tx/${txHash}`;
840
+ }
841
+ }