@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,155 @@
1
+ /**
2
+ * Deposit USDC.e to Polymarket for Trading
3
+ *
4
+ * Polymarket requires USDC to be deposited into their trading contracts
5
+ * before you can place orders.
6
+ *
7
+ * Usage:
8
+ * POLY_PRIVKEY=0x... npx tsx scripts/deposit-usdc.ts [amount]
9
+ *
10
+ * Examples:
11
+ * POLY_PRIVKEY=0x... npx tsx scripts/deposit-usdc.ts 100 # Deposit 100 USDC
12
+ * POLY_PRIVKEY=0x... npx tsx scripts/deposit-usdc.ts # Check balance only
13
+ */
14
+
15
+ import { ethers } from 'ethers';
16
+
17
+ const PRIVATE_KEY = process.env.POLY_PRIVKEY || '';
18
+
19
+ // Contract addresses on Polygon
20
+ const USDC_E_ADDRESS = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174';
21
+ const CTF_EXCHANGE = '0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E';
22
+ const NEG_RISK_CTF_EXCHANGE = '0xC5d563A36AE78145C45a50134d48A1215220f80a';
23
+ const NEG_RISK_ADAPTER = '0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296';
24
+
25
+ // ABIs
26
+ const ERC20_ABI = [
27
+ 'function balanceOf(address owner) view returns (uint256)',
28
+ 'function allowance(address owner, address spender) view returns (uint256)',
29
+ 'function approve(address spender, uint256 amount) returns (bool)',
30
+ 'function transfer(address to, uint256 amount) returns (bool)',
31
+ 'function decimals() view returns (uint8)',
32
+ ];
33
+
34
+ const EXCHANGE_ABI = [
35
+ 'function getPolyProxyWalletAddress(address _addr) view returns (address)',
36
+ 'function isValidNonce(address usr, uint256 nonce) view returns (bool)',
37
+ ];
38
+
39
+ async function main() {
40
+ if (!PRIVATE_KEY) {
41
+ console.error('Error: Set POLY_PRIVKEY environment variable');
42
+ process.exit(1);
43
+ }
44
+
45
+ const amount = process.argv[2] ? parseFloat(process.argv[2]) : 0;
46
+
47
+ console.log('╔════════════════════════════════════════════════════════════════╗');
48
+ console.log('║ POLYMARKET USDC DEPOSIT ║');
49
+ console.log('╚════════════════════════════════════════════════════════════════╝');
50
+ console.log('');
51
+
52
+ // Connect to Polygon
53
+ const provider = new ethers.providers.JsonRpcProvider('https://polygon-rpc.com');
54
+ const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
55
+ const address = wallet.address;
56
+
57
+ console.log(`Wallet: ${address}`);
58
+ console.log('');
59
+
60
+ // Get USDC contract
61
+ const usdc = new ethers.Contract(USDC_E_ADDRESS, ERC20_ABI, wallet);
62
+ const exchange = new ethers.Contract(CTF_EXCHANGE, EXCHANGE_ABI, provider);
63
+
64
+ // Check balances
65
+ console.log('─── Current Status ───');
66
+
67
+ const walletBalance = await usdc.balanceOf(address);
68
+ const walletBalanceUsdc = parseFloat(ethers.utils.formatUnits(walletBalance, 6));
69
+ console.log(`Wallet USDC.e Balance: ${walletBalanceUsdc.toFixed(6)} USDC`);
70
+
71
+ // Check allowances
72
+ const ctfAllowance = await usdc.allowance(address, CTF_EXCHANGE);
73
+ const negRiskAllowance = await usdc.allowance(address, NEG_RISK_CTF_EXCHANGE);
74
+ const adapterAllowance = await usdc.allowance(address, NEG_RISK_ADAPTER);
75
+
76
+ console.log(`CTF Exchange Allowance: ${ethers.utils.formatUnits(ctfAllowance, 6)} USDC`);
77
+ console.log(`Neg Risk Exchange Allowance: ${ethers.utils.formatUnits(negRiskAllowance, 6)} USDC`);
78
+ console.log(`Neg Risk Adapter Allowance: ${ethers.utils.formatUnits(adapterAllowance, 6)} USDC`);
79
+ console.log('');
80
+
81
+ // Try to get proxy wallet address
82
+ try {
83
+ const proxyWallet = await exchange.getPolyProxyWalletAddress(address);
84
+ console.log(`Proxy Wallet: ${proxyWallet}`);
85
+
86
+ // Check proxy wallet balance
87
+ const proxyBalance = await usdc.balanceOf(proxyWallet);
88
+ const proxyBalanceUsdc = parseFloat(ethers.utils.formatUnits(proxyBalance, 6));
89
+ console.log(`Proxy USDC.e Balance: ${proxyBalanceUsdc.toFixed(6)} USDC`);
90
+ } catch (e) {
91
+ console.log('Proxy Wallet: Not created yet');
92
+ }
93
+ console.log('');
94
+
95
+ if (amount <= 0) {
96
+ console.log('─── Usage ───');
97
+ console.log('To deposit USDC, run with an amount:');
98
+ console.log(' POLY_PRIVKEY=0x... npx tsx scripts/deposit-usdc.ts 100');
99
+ console.log('');
100
+ console.log('Note: Polymarket uses a proxy wallet system. You may need to:');
101
+ console.log('1. Visit polymarket.com and connect your wallet');
102
+ console.log('2. Click "Deposit" to create your proxy wallet');
103
+ console.log('3. The proxy wallet will be funded from your wallet');
104
+ return;
105
+ }
106
+
107
+ // Approve and deposit
108
+ console.log(`─── Depositing ${amount} USDC ───`);
109
+
110
+ if (amount > walletBalanceUsdc) {
111
+ console.error(`Error: Insufficient balance. You have ${walletBalanceUsdc} USDC`);
112
+ process.exit(1);
113
+ }
114
+
115
+ const amountWei = ethers.utils.parseUnits(amount.toString(), 6);
116
+
117
+ // Check if we need to approve
118
+ const MAX_UINT256 = ethers.constants.MaxUint256;
119
+
120
+ if (ctfAllowance.lt(amountWei)) {
121
+ console.log('Approving CTF Exchange...');
122
+ const tx1 = await usdc.approve(CTF_EXCHANGE, MAX_UINT256);
123
+ console.log(` TX: ${tx1.hash}`);
124
+ await tx1.wait();
125
+ console.log(' ✓ Approved');
126
+ }
127
+
128
+ if (negRiskAllowance.lt(amountWei)) {
129
+ console.log('Approving Neg Risk CTF Exchange...');
130
+ const tx2 = await usdc.approve(NEG_RISK_CTF_EXCHANGE, MAX_UINT256);
131
+ console.log(` TX: ${tx2.hash}`);
132
+ await tx2.wait();
133
+ console.log(' ✓ Approved');
134
+ }
135
+
136
+ if (adapterAllowance.lt(amountWei)) {
137
+ console.log('Approving Neg Risk Adapter...');
138
+ const tx3 = await usdc.approve(NEG_RISK_ADAPTER, MAX_UINT256);
139
+ console.log(` TX: ${tx3.hash}`);
140
+ await tx3.wait();
141
+ console.log(' ✓ Approved');
142
+ }
143
+
144
+ console.log('');
145
+ console.log('✅ All approvals complete!');
146
+ console.log('');
147
+ console.log('Note: Polymarket trading balance should now be available.');
148
+ console.log('The USDC remains in your wallet but is authorized for trading.');
149
+ console.log('');
150
+ console.log('If you still see "not enough balance" errors, try:');
151
+ console.log('1. Visit polymarket.com and deposit via their UI');
152
+ console.log('2. This creates a proxy wallet and funds it');
153
+ }
154
+
155
+ main().catch(console.error);
@@ -0,0 +1,375 @@
1
+ /**
2
+ * USDC to USDC.e Conversion Script
3
+ *
4
+ * This script provides two methods to get USDC.e on Polygon for Polymarket trading:
5
+ *
6
+ * 1. SWAP (Polygon): Swap native USDC to USDC.e using QuickSwap V3
7
+ * 2. BRIDGE (Cross-chain): Deposit from Ethereum/other chains via Polymarket Bridge
8
+ *
9
+ * Usage:
10
+ * # Check current balances
11
+ * npx ts-node scripts/swap-usdc-to-usdce.ts
12
+ *
13
+ * # Swap 100 USDC to USDC.e on Polygon
14
+ * npx ts-node scripts/swap-usdc-to-usdce.ts swap 100
15
+ *
16
+ * # Dry run swap (no transaction)
17
+ * npx ts-node scripts/swap-usdc-to-usdce.ts swap 100 --dry-run
18
+ *
19
+ * # Get bridge deposit addresses
20
+ * npx ts-node scripts/swap-usdc-to-usdce.ts bridge
21
+ *
22
+ * # Check supported bridge assets
23
+ * npx ts-node scripts/swap-usdc-to-usdce.ts bridge --assets
24
+ *
25
+ * Contract addresses:
26
+ * - Native USDC (Polygon): 0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359
27
+ * - USDC.e (Polygon): 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174
28
+ * - QuickSwap Router V3: 0xf5b509bB0909a69B1c207E495f687a596C168E12
29
+ */
30
+
31
+ import { ethers, Contract, Wallet } from 'ethers';
32
+ import { BridgeClient, BRIDGE_TOKENS } from '../src/clients/bridge-client.js';
33
+
34
+ // Configuration
35
+ const PRIVATE_KEY = process.env.POLYMARKET_PRIVATE_KEY || '';
36
+ const RPC_URL = process.env.POLYGON_RPC_URL || 'https://polygon-rpc.com';
37
+
38
+ // Token addresses
39
+ const NATIVE_USDC = '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359';
40
+ const USDC_E = '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174';
41
+
42
+ // QuickSwap V3 SwapRouter
43
+ const QUICKSWAP_ROUTER = '0xf5b509bB0909a69B1c207E495f687a596C168E12';
44
+
45
+ // ABIs
46
+ const ERC20_ABI = [
47
+ 'function balanceOf(address) view returns (uint256)',
48
+ 'function decimals() view returns (uint8)',
49
+ 'function symbol() view returns (string)',
50
+ 'function approve(address spender, uint256 amount) returns (bool)',
51
+ 'function allowance(address owner, address spender) view returns (uint256)',
52
+ ];
53
+
54
+ const QUICKSWAP_ROUTER_ABI = [
55
+ 'function exactInputSingle((address tokenIn, address tokenOut, address recipient, uint256 deadline, uint256 amountIn, uint256 amountOutMinimum, uint160 limitSqrtPrice)) external payable returns (uint256 amountOut)',
56
+ ];
57
+
58
+ // ===== Helper Functions =====
59
+
60
+ async function checkBalances(wallet: Wallet) {
61
+ const provider = wallet.provider!;
62
+ const nativeUsdc = new Contract(NATIVE_USDC, ERC20_ABI, wallet);
63
+ const usdce = new Contract(USDC_E, ERC20_ABI, wallet);
64
+
65
+ const [nativeBalance, usdceBalance, maticBalance] = await Promise.all([
66
+ nativeUsdc.balanceOf(wallet.address),
67
+ usdce.balanceOf(wallet.address),
68
+ provider.getBalance(wallet.address),
69
+ ]);
70
+
71
+ return { nativeBalance, usdceBalance, maticBalance };
72
+ }
73
+
74
+ function printBalances(
75
+ nativeBalance: ethers.BigNumber,
76
+ usdceBalance: ethers.BigNumber,
77
+ maticBalance: ethers.BigNumber
78
+ ) {
79
+ console.log('Current Polygon Balances:');
80
+ console.log(` Native USDC: ${ethers.utils.formatUnits(nativeBalance, 6)}`);
81
+ console.log(` USDC.e: ${ethers.utils.formatUnits(usdceBalance, 6)}`);
82
+ console.log(` MATIC: ${ethers.utils.formatEther(maticBalance)}`);
83
+ console.log();
84
+ }
85
+
86
+ // ===== Swap Command =====
87
+
88
+ async function executeSwap(wallet: Wallet, amount?: string, dryRun = false) {
89
+ console.log('╔════════════════════════════════════════════════════════════╗');
90
+ console.log('║ USDC → USDC.e SWAP (QuickSwap V3) ║');
91
+ console.log('╚════════════════════════════════════════════════════════════╝\n');
92
+
93
+ console.log(`Wallet: ${wallet.address}\n`);
94
+
95
+ const { nativeBalance, usdceBalance, maticBalance } = await checkBalances(wallet);
96
+ printBalances(nativeBalance, usdceBalance, maticBalance);
97
+
98
+ if (nativeBalance.eq(0)) {
99
+ console.log('❌ No native USDC to swap. Exiting.');
100
+ return;
101
+ }
102
+
103
+ // Parse amount to swap
104
+ let amountToSwap = nativeBalance;
105
+ if (amount) {
106
+ const requestedAmount = ethers.utils.parseUnits(amount, 6);
107
+ if (requestedAmount.gt(nativeBalance)) {
108
+ console.log(`❌ Requested ${amount} but only have ${ethers.utils.formatUnits(nativeBalance, 6)}`);
109
+ return;
110
+ }
111
+ amountToSwap = requestedAmount;
112
+ }
113
+
114
+ console.log(`Amount to swap: ${ethers.utils.formatUnits(amountToSwap, 6)} USDC\n`);
115
+ if (dryRun) {
116
+ console.log('🔍 DRY RUN MODE - No transactions will be executed\n');
117
+ }
118
+
119
+ // Check and approve if needed
120
+ const nativeUsdc = new Contract(NATIVE_USDC, ERC20_ABI, wallet);
121
+ const router = new Contract(QUICKSWAP_ROUTER, QUICKSWAP_ROUTER_ABI, wallet);
122
+ const currentAllowance = await nativeUsdc.allowance(wallet.address, QUICKSWAP_ROUTER);
123
+
124
+ if (currentAllowance.lt(amountToSwap)) {
125
+ console.log('Step 1: Approving USDC for QuickSwap Router...');
126
+
127
+ if (!dryRun) {
128
+ const approveTx = await nativeUsdc.approve(QUICKSWAP_ROUTER, ethers.constants.MaxUint256);
129
+ console.log(` TX: ${approveTx.hash}`);
130
+ await approveTx.wait();
131
+ console.log(' ✅ Approved\n');
132
+ } else {
133
+ console.log(' [DRY RUN] Would approve USDC\n');
134
+ }
135
+ } else {
136
+ console.log('Step 1: USDC already approved ✅\n');
137
+ }
138
+
139
+ // Execute swap
140
+ console.log('Step 2: Executing swap...');
141
+
142
+ // Calculate minimum output (0.5% slippage)
143
+ const minAmountOut = amountToSwap.mul(995).div(1000);
144
+
145
+ const swapParams = {
146
+ tokenIn: NATIVE_USDC,
147
+ tokenOut: USDC_E,
148
+ recipient: wallet.address,
149
+ deadline: Math.floor(Date.now() / 1000) + 300, // 5 minutes
150
+ amountIn: amountToSwap,
151
+ amountOutMinimum: minAmountOut,
152
+ limitSqrtPrice: 0, // No price limit
153
+ };
154
+
155
+ console.log(' Swap parameters:');
156
+ console.log(` Input: ${ethers.utils.formatUnits(amountToSwap, 6)} USDC`);
157
+ console.log(` Min Output: ${ethers.utils.formatUnits(minAmountOut, 6)} USDC.e`);
158
+ console.log(` Slippage: 0.5%`);
159
+ console.log();
160
+
161
+ if (!dryRun) {
162
+ try {
163
+ const tx = await router.exactInputSingle(swapParams);
164
+ console.log(` TX: ${tx.hash}`);
165
+ console.log(' Waiting for confirmation...');
166
+
167
+ const receipt = await tx.wait();
168
+ console.log(` ✅ Confirmed in block ${receipt.blockNumber}`);
169
+ console.log(` Gas used: ${receipt.gasUsed.toString()}`);
170
+
171
+ // Check new balances
172
+ const { nativeBalance: newNative, usdceBalance: newUsdce } = await checkBalances(wallet);
173
+
174
+ console.log('\nNew Balances:');
175
+ console.log(` Native USDC: ${ethers.utils.formatUnits(newNative, 6)}`);
176
+ console.log(` USDC.e: ${ethers.utils.formatUnits(newUsdce, 6)}`);
177
+
178
+ const received = newUsdce.sub(usdceBalance);
179
+ console.log(`\n✅ Received: ${ethers.utils.formatUnits(received, 6)} USDC.e`);
180
+ } catch (error) {
181
+ console.log(`\n❌ Swap failed: ${(error as Error).message}`);
182
+ printManualSwapInstructions(amountToSwap);
183
+ }
184
+ } else {
185
+ console.log(' [DRY RUN] Would execute swap\n');
186
+ console.log('Run without --dry-run to execute the swap.');
187
+ }
188
+ }
189
+
190
+ function printManualSwapInstructions(amount: ethers.BigNumber) {
191
+ console.log('\n═══════════════════════════════════════════════════════════');
192
+ console.log('ALTERNATIVE: Manual swap on QuickSwap\n');
193
+ console.log('1. Visit: https://quickswap.exchange/#/swap');
194
+ console.log('2. Connect your wallet');
195
+ console.log('3. Swap:');
196
+ console.log(` From: USDC (${NATIVE_USDC})`);
197
+ console.log(` To: USDC.e (${USDC_E})`);
198
+ console.log(` Amount: ${ethers.utils.formatUnits(amount, 6)}`);
199
+ console.log('4. Execute swap');
200
+ console.log('═══════════════════════════════════════════════════════════\n');
201
+ }
202
+
203
+ // ===== Bridge Command =====
204
+
205
+ async function executeBridge(wallet: Wallet, showAssets = false) {
206
+ console.log('╔════════════════════════════════════════════════════════════╗');
207
+ console.log('║ POLYMARKET CROSS-CHAIN BRIDGE ║');
208
+ console.log('╚════════════════════════════════════════════════════════════╝\n');
209
+
210
+ const bridge = new BridgeClient();
211
+
212
+ if (showAssets) {
213
+ console.log('Fetching supported bridge assets...\n');
214
+
215
+ try {
216
+ const assets = await bridge.getSupportedAssets();
217
+
218
+ console.log('Supported Assets for Bridge Deposits:');
219
+ console.log('─────────────────────────────────────────────────────────────\n');
220
+
221
+ // Group by chain
222
+ const byChain = new Map<number, typeof assets>();
223
+ for (const asset of assets) {
224
+ const existing = byChain.get(asset.chainId) || [];
225
+ existing.push(asset);
226
+ byChain.set(asset.chainId, existing);
227
+ }
228
+
229
+ for (const [chainId, chainAssets] of byChain) {
230
+ const chainName = chainAssets[0].chainName;
231
+ console.log(`${chainName} (Chain ID: ${chainId}):`);
232
+
233
+ for (const asset of chainAssets) {
234
+ const status = asset.active ? '✅' : '❌';
235
+ console.log(` ${status} ${asset.tokenSymbol.padEnd(8)} - ${asset.tokenName}`);
236
+ console.log(` Address: ${asset.tokenAddress}`);
237
+ console.log(` Min deposit: ${asset.minDeposit} (~$${asset.minDepositUsd})`);
238
+ }
239
+ console.log();
240
+ }
241
+ } catch (error) {
242
+ console.log(`❌ Failed to fetch assets: ${(error as Error).message}`);
243
+ console.log('\nNote: The bridge API may not be publicly accessible.');
244
+ console.log('Visit https://polymarket.com to deposit through the web interface.\n');
245
+ printKnownTokens();
246
+ }
247
+ return;
248
+ }
249
+
250
+ // Get deposit addresses
251
+ console.log(`Wallet: ${wallet.address}\n`);
252
+ console.log('Fetching deposit addresses...\n');
253
+
254
+ try {
255
+ const instructions = await bridge.getDepositInstructions(wallet.address);
256
+ console.log(instructions);
257
+ } catch (error) {
258
+ console.log(`❌ Failed to get deposit addresses: ${(error as Error).message}`);
259
+ console.log('\nNote: The bridge API may not be publicly accessible.');
260
+ console.log('Visit https://polymarket.com to deposit through the web interface.\n');
261
+ printKnownTokens();
262
+ printManualBridgeInstructions();
263
+ }
264
+ }
265
+
266
+ function printKnownTokens() {
267
+ console.log('Known Token Addresses:');
268
+ console.log('─────────────────────────────────────────────────────────────');
269
+ console.log('Ethereum:');
270
+ console.log(` USDC: ${BRIDGE_TOKENS.ETH_USDC}`);
271
+ console.log(` WETH: ${BRIDGE_TOKENS.ETH_WETH}`);
272
+ console.log(` DAI: ${BRIDGE_TOKENS.ETH_DAI}`);
273
+ console.log('\nPolygon (Destination):');
274
+ console.log(` USDC.e: ${BRIDGE_TOKENS.POLYGON_USDC_E}`);
275
+ console.log(` Native USDC: ${BRIDGE_TOKENS.POLYGON_NATIVE_USDC}`);
276
+ console.log();
277
+ }
278
+
279
+ function printManualBridgeInstructions() {
280
+ console.log('═══════════════════════════════════════════════════════════');
281
+ console.log('MANUAL BRIDGE OPTIONS:\n');
282
+ console.log('Option 1: Polymarket Deposit (Recommended)');
283
+ console.log(' 1. Visit: https://polymarket.com');
284
+ console.log(' 2. Connect wallet → Click "Deposit"');
285
+ console.log(' 3. Select source chain and token');
286
+ console.log(' 4. Follow deposit instructions\n');
287
+ console.log('Option 2: Official Polygon Bridge');
288
+ console.log(' 1. Visit: https://wallet.polygon.technology/polygon/bridge');
289
+ console.log(' 2. Bridge USDC from Ethereum to Polygon');
290
+ console.log(' 3. Use this script to swap to USDC.e\n');
291
+ console.log('Option 3: Third-party Bridges');
292
+ console.log(' - Jumper.exchange');
293
+ console.log(' - Stargate.finance');
294
+ console.log(' - Across.to');
295
+ console.log('═══════════════════════════════════════════════════════════\n');
296
+ }
297
+
298
+ // ===== Main =====
299
+
300
+ async function main() {
301
+ const args = process.argv.slice(2);
302
+ const command = args[0];
303
+
304
+ // Check for private key
305
+ if (!PRIVATE_KEY) {
306
+ console.log('╔════════════════════════════════════════════════════════════╗');
307
+ console.log('║ USDC.e CONVERSION TOOL ║');
308
+ console.log('╚════════════════════════════════════════════════════════════╝\n');
309
+
310
+ console.log('⚠️ No private key configured.\n');
311
+ console.log('Set POLYMARKET_PRIVATE_KEY environment variable to use this tool.\n');
312
+ console.log('Usage:');
313
+ console.log(' # Check balances and swap on Polygon');
314
+ console.log(' npx ts-node scripts/swap-usdc-to-usdce.ts swap [amount] [--dry-run]\n');
315
+ console.log(' # Get bridge deposit addresses');
316
+ console.log(' npx ts-node scripts/swap-usdc-to-usdce.ts bridge\n');
317
+ console.log(' # Check supported bridge assets');
318
+ console.log(' npx ts-node scripts/swap-usdc-to-usdce.ts bridge --assets\n');
319
+ return;
320
+ }
321
+
322
+ const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
323
+ const wallet = new Wallet(PRIVATE_KEY, provider);
324
+
325
+ switch (command) {
326
+ case 'swap': {
327
+ const amount = args.find((a) => !a.startsWith('--') && a !== 'swap');
328
+ const dryRun = args.includes('--dry-run');
329
+ await executeSwap(wallet, amount, dryRun);
330
+ break;
331
+ }
332
+
333
+ case 'bridge': {
334
+ const showAssets = args.includes('--assets');
335
+ await executeBridge(wallet, showAssets);
336
+ break;
337
+ }
338
+
339
+ default: {
340
+ // Default: show balances and usage
341
+ console.log('╔════════════════════════════════════════════════════════════╗');
342
+ console.log('║ USDC.e CONVERSION TOOL ║');
343
+ console.log('╚════════════════════════════════════════════════════════════╝\n');
344
+
345
+ console.log(`Wallet: ${wallet.address}\n`);
346
+
347
+ const { nativeBalance, usdceBalance, maticBalance } = await checkBalances(wallet);
348
+ printBalances(nativeBalance, usdceBalance, maticBalance);
349
+
350
+ console.log('Available Commands:');
351
+ console.log('───────────────────────────────────────────────────────────────');
352
+ console.log('');
353
+ console.log(' swap [amount] [--dry-run]');
354
+ console.log(' Swap native USDC to USDC.e on Polygon using QuickSwap');
355
+ console.log(' Example: npx ts-node scripts/swap-usdc-to-usdce.ts swap 100');
356
+ console.log('');
357
+ console.log(' bridge');
358
+ console.log(' Get deposit addresses for cross-chain deposits');
359
+ console.log(' Example: npx ts-node scripts/swap-usdc-to-usdce.ts bridge');
360
+ console.log('');
361
+ console.log(' bridge --assets');
362
+ console.log(' Show all supported bridge assets and chains');
363
+ console.log(' Example: npx ts-node scripts/swap-usdc-to-usdce.ts bridge --assets');
364
+ console.log('');
365
+ console.log('───────────────────────────────────────────────────────────────');
366
+
367
+ if (nativeBalance.gt(0)) {
368
+ console.log(`\n💡 You have ${ethers.utils.formatUnits(nativeBalance, 6)} native USDC.`);
369
+ console.log(' Run: npx ts-node scripts/swap-usdc-to-usdce.ts swap');
370
+ }
371
+ }
372
+ }
373
+ }
374
+
375
+ main().catch(console.error);