@catalyst-team/poly-sdk 0.1.0 → 0.2.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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +538 -0
  3. package/README.md +357 -78
  4. package/docs/00-design.md +1 -1
  5. package/docs/02-API.md +21 -21
  6. package/docs/arb/test-plan.md +387 -0
  7. package/docs/arb/test-results.md +336 -0
  8. package/docs/arbitrage.md +754 -0
  9. package/docs/reports/smart-money-analysis-2025-12-23-cn.md +840 -0
  10. package/examples/13-arbitrage-service.ts +211 -0
  11. package/examples/README.md +1 -1
  12. package/package.json +19 -19
  13. package/scripts/arb/faze-bo3-arb.ts +385 -0
  14. package/scripts/arb/settle-position.ts +190 -0
  15. package/scripts/arb/token-rebalancer.ts +420 -0
  16. package/scripts/arb-tests/01-unit-tests.ts +495 -0
  17. package/scripts/arb-tests/02-integration-tests.ts +412 -0
  18. package/scripts/arb-tests/03-e2e-tests.ts +503 -0
  19. package/scripts/arb-tests/README.md +109 -0
  20. package/scripts/verify/verify-all-apis.ts +1 -1
  21. package/src/clients/clob-api.ts +1 -1
  22. package/src/clients/gamma-api.ts +1 -1
  23. package/src/core/cache-adapter-bridge.ts +1 -1
  24. package/src/core/types.ts +3 -3
  25. package/src/core/unified-cache.ts +1 -1
  26. package/src/index.ts +25 -19
  27. package/src/services/arbitrage-service.ts +1807 -0
  28. package/.env +0 -0
  29. package/dist/__tests__/clob-api.test.d.ts +0 -5
  30. package/dist/__tests__/clob-api.test.d.ts.map +0 -1
  31. package/dist/__tests__/clob-api.test.js +0 -240
  32. package/dist/__tests__/clob-api.test.js.map +0 -1
  33. package/dist/__tests__/integration/bridge-client.integration.test.d.ts +0 -11
  34. package/dist/__tests__/integration/bridge-client.integration.test.d.ts.map +0 -1
  35. package/dist/__tests__/integration/bridge-client.integration.test.js +0 -260
  36. package/dist/__tests__/integration/bridge-client.integration.test.js.map +0 -1
  37. package/dist/__tests__/integration/clob-api.integration.test.d.ts +0 -13
  38. package/dist/__tests__/integration/clob-api.integration.test.d.ts.map +0 -1
  39. package/dist/__tests__/integration/clob-api.integration.test.js +0 -170
  40. package/dist/__tests__/integration/clob-api.integration.test.js.map +0 -1
  41. package/dist/__tests__/integration/ctf-client.integration.test.d.ts +0 -17
  42. package/dist/__tests__/integration/ctf-client.integration.test.d.ts.map +0 -1
  43. package/dist/__tests__/integration/ctf-client.integration.test.js +0 -234
  44. package/dist/__tests__/integration/ctf-client.integration.test.js.map +0 -1
  45. package/dist/__tests__/integration/data-api.integration.test.d.ts +0 -9
  46. package/dist/__tests__/integration/data-api.integration.test.d.ts.map +0 -1
  47. package/dist/__tests__/integration/data-api.integration.test.js +0 -161
  48. package/dist/__tests__/integration/data-api.integration.test.js.map +0 -1
  49. package/dist/__tests__/integration/gamma-api.integration.test.d.ts +0 -9
  50. package/dist/__tests__/integration/gamma-api.integration.test.d.ts.map +0 -1
  51. package/dist/__tests__/integration/gamma-api.integration.test.js +0 -170
  52. package/dist/__tests__/integration/gamma-api.integration.test.js.map +0 -1
  53. package/dist/__tests__/test-utils.d.ts +0 -92
  54. package/dist/__tests__/test-utils.d.ts.map +0 -1
  55. package/dist/__tests__/test-utils.js +0 -143
  56. package/dist/__tests__/test-utils.js.map +0 -1
  57. package/dist/clients/bridge-client.d.ts +0 -388
  58. package/dist/clients/bridge-client.d.ts.map +0 -1
  59. package/dist/clients/bridge-client.js +0 -587
  60. package/dist/clients/bridge-client.js.map +0 -1
  61. package/dist/clients/clob-api.d.ts +0 -318
  62. package/dist/clients/clob-api.d.ts.map +0 -1
  63. package/dist/clients/clob-api.js +0 -388
  64. package/dist/clients/clob-api.js.map +0 -1
  65. package/dist/clients/ctf-client.d.ts +0 -473
  66. package/dist/clients/ctf-client.d.ts.map +0 -1
  67. package/dist/clients/ctf-client.js +0 -915
  68. package/dist/clients/ctf-client.js.map +0 -1
  69. package/dist/clients/data-api.d.ts +0 -134
  70. package/dist/clients/data-api.d.ts.map +0 -1
  71. package/dist/clients/data-api.js +0 -265
  72. package/dist/clients/data-api.js.map +0 -1
  73. package/dist/clients/gamma-api.d.ts +0 -401
  74. package/dist/clients/gamma-api.d.ts.map +0 -1
  75. package/dist/clients/gamma-api.js +0 -352
  76. package/dist/clients/gamma-api.js.map +0 -1
  77. package/dist/clients/trading-client.d.ts +0 -252
  78. package/dist/clients/trading-client.d.ts.map +0 -1
  79. package/dist/clients/trading-client.js +0 -543
  80. package/dist/clients/trading-client.js.map +0 -1
  81. package/dist/clients/websocket-manager.d.ts +0 -100
  82. package/dist/clients/websocket-manager.d.ts.map +0 -1
  83. package/dist/clients/websocket-manager.js +0 -193
  84. package/dist/clients/websocket-manager.js.map +0 -1
  85. package/dist/core/cache-adapter-bridge.d.ts +0 -36
  86. package/dist/core/cache-adapter-bridge.d.ts.map +0 -1
  87. package/dist/core/cache-adapter-bridge.js +0 -81
  88. package/dist/core/cache-adapter-bridge.js.map +0 -1
  89. package/dist/core/cache.d.ts +0 -40
  90. package/dist/core/cache.d.ts.map +0 -1
  91. package/dist/core/cache.js +0 -71
  92. package/dist/core/cache.js.map +0 -1
  93. package/dist/core/errors.d.ts +0 -38
  94. package/dist/core/errors.d.ts.map +0 -1
  95. package/dist/core/errors.js +0 -84
  96. package/dist/core/errors.js.map +0 -1
  97. package/dist/core/rate-limiter.d.ts +0 -31
  98. package/dist/core/rate-limiter.d.ts.map +0 -1
  99. package/dist/core/rate-limiter.js +0 -70
  100. package/dist/core/rate-limiter.js.map +0 -1
  101. package/dist/core/types.d.ts +0 -314
  102. package/dist/core/types.d.ts.map +0 -1
  103. package/dist/core/types.js +0 -19
  104. package/dist/core/types.js.map +0 -1
  105. package/dist/core/unified-cache.d.ts +0 -63
  106. package/dist/core/unified-cache.d.ts.map +0 -1
  107. package/dist/core/unified-cache.js +0 -114
  108. package/dist/core/unified-cache.js.map +0 -1
  109. package/dist/index.d.ts +0 -94
  110. package/dist/index.d.ts.map +0 -1
  111. package/dist/index.js +0 -258
  112. package/dist/index.js.map +0 -1
  113. package/dist/mcp/errors.d.ts +0 -33
  114. package/dist/mcp/errors.d.ts.map +0 -1
  115. package/dist/mcp/errors.js +0 -86
  116. package/dist/mcp/errors.js.map +0 -1
  117. package/dist/mcp/index.d.ts +0 -62
  118. package/dist/mcp/index.d.ts.map +0 -1
  119. package/dist/mcp/index.js +0 -173
  120. package/dist/mcp/index.js.map +0 -1
  121. package/dist/mcp/server.d.ts +0 -17
  122. package/dist/mcp/server.d.ts.map +0 -1
  123. package/dist/mcp/server.js +0 -155
  124. package/dist/mcp/server.js.map +0 -1
  125. package/dist/mcp/tools/guide.d.ts +0 -12
  126. package/dist/mcp/tools/guide.d.ts.map +0 -1
  127. package/dist/mcp/tools/guide.js +0 -801
  128. package/dist/mcp/tools/guide.js.map +0 -1
  129. package/dist/mcp/tools/index.d.ts +0 -11
  130. package/dist/mcp/tools/index.d.ts.map +0 -1
  131. package/dist/mcp/tools/index.js +0 -27
  132. package/dist/mcp/tools/index.js.map +0 -1
  133. package/dist/mcp/tools/market.d.ts +0 -11
  134. package/dist/mcp/tools/market.d.ts.map +0 -1
  135. package/dist/mcp/tools/market.js +0 -314
  136. package/dist/mcp/tools/market.js.map +0 -1
  137. package/dist/mcp/tools/order.d.ts +0 -10
  138. package/dist/mcp/tools/order.d.ts.map +0 -1
  139. package/dist/mcp/tools/order.js +0 -258
  140. package/dist/mcp/tools/order.js.map +0 -1
  141. package/dist/mcp/tools/trade.d.ts +0 -38
  142. package/dist/mcp/tools/trade.d.ts.map +0 -1
  143. package/dist/mcp/tools/trade.js +0 -314
  144. package/dist/mcp/tools/trade.js.map +0 -1
  145. package/dist/mcp/tools/trader.d.ts +0 -11
  146. package/dist/mcp/tools/trader.d.ts.map +0 -1
  147. package/dist/mcp/tools/trader.js +0 -277
  148. package/dist/mcp/tools/trader.js.map +0 -1
  149. package/dist/mcp/tools/wallet.d.ts +0 -274
  150. package/dist/mcp/tools/wallet.d.ts.map +0 -1
  151. package/dist/mcp/tools/wallet.js +0 -579
  152. package/dist/mcp/tools/wallet.js.map +0 -1
  153. package/dist/mcp/types.d.ts +0 -413
  154. package/dist/mcp/types.d.ts.map +0 -1
  155. package/dist/mcp/types.js +0 -5
  156. package/dist/mcp/types.js.map +0 -1
  157. package/dist/services/authorization-service.d.ts +0 -97
  158. package/dist/services/authorization-service.d.ts.map +0 -1
  159. package/dist/services/authorization-service.js +0 -279
  160. package/dist/services/authorization-service.js.map +0 -1
  161. package/dist/services/market-service.d.ts +0 -108
  162. package/dist/services/market-service.d.ts.map +0 -1
  163. package/dist/services/market-service.js +0 -458
  164. package/dist/services/market-service.js.map +0 -1
  165. package/dist/services/realtime-service.d.ts +0 -82
  166. package/dist/services/realtime-service.d.ts.map +0 -1
  167. package/dist/services/realtime-service.js +0 -150
  168. package/dist/services/realtime-service.js.map +0 -1
  169. package/dist/services/swap-service.d.ts +0 -217
  170. package/dist/services/swap-service.d.ts.map +0 -1
  171. package/dist/services/swap-service.js +0 -695
  172. package/dist/services/swap-service.js.map +0 -1
  173. package/dist/services/wallet-service.d.ts +0 -94
  174. package/dist/services/wallet-service.d.ts.map +0 -1
  175. package/dist/services/wallet-service.js +0 -173
  176. package/dist/services/wallet-service.js.map +0 -1
  177. package/dist/utils/price-utils.d.ts +0 -153
  178. package/dist/utils/price-utils.d.ts.map +0 -1
  179. package/dist/utils/price-utils.js +0 -236
  180. package/dist/utils/price-utils.js.map +0 -1
  181. package/docs/01-mcp.md +0 -2041
  182. package/docs/e2e/01-trader-tools.md +0 -159
  183. package/docs/e2e/02-market-tools.md +0 -180
  184. package/docs/e2e/03-order-tools.md +0 -166
  185. package/docs/e2e/04-wallet-tools.md +0 -224
  186. package/docs/e2e/05-trading-tools.md +0 -327
  187. package/docs/e2e/06-integration-scenarios.md +0 -481
  188. package/docs/e2e/coordinator.md +0 -376
  189. package/scripts/truth.md +0 -440
  190. package/src/mcp/README.md +0 -380
  191. package/src/mcp/errors.ts +0 -124
  192. package/src/mcp/index.ts +0 -309
  193. package/src/mcp/server.ts +0 -183
  194. package/src/mcp/tools/guide.ts +0 -821
  195. package/src/mcp/tools/index.ts +0 -73
  196. package/src/mcp/tools/market.ts +0 -363
  197. package/src/mcp/tools/order.ts +0 -326
  198. package/src/mcp/tools/trade.ts +0 -417
  199. package/src/mcp/tools/trader.ts +0 -322
  200. package/src/mcp/tools/wallet.ts +0 -683
  201. package/src/mcp/types.ts +0 -472
@@ -1,683 +0,0 @@
1
- /**
2
- * Wallet Tools - MCP tools for deposits, swaps, and authorization management
3
- *
4
- * These tools use SDK services:
5
- * - BridgeClient for deposit addresses and supported assets
6
- * - SwapService for DEX swaps on Polygon (QuickSwap V3)
7
- * - AuthorizationService for allowance checks and approvals
8
- * - depositUsdc() for executing USDC deposits
9
- * - swapAndDeposit() for swapping any token to USDC and depositing
10
- */
11
-
12
- import { ethers } from 'ethers';
13
- import type { PolymarketSDK } from '../../index.js';
14
- import {
15
- BridgeClient,
16
- AuthorizationService,
17
- depositUsdc,
18
- swapAndDeposit,
19
- SwapService,
20
- getSupportedDepositTokens,
21
- } from '../../index.js';
22
- import type { ToolDefinition } from '../types.js';
23
- import { wrapError, McpToolError, ErrorCode } from '../errors.js';
24
-
25
- // Tool definitions
26
- export const walletToolDefinitions: ToolDefinition[] = [
27
- {
28
- name: 'get_supported_deposit_assets',
29
- description: 'Get all supported assets and chains for deposits to Polymarket',
30
- inputSchema: {
31
- type: 'object',
32
- properties: {
33
- chainId: {
34
- type: 'number',
35
- description: 'Filter by chain ID (optional)',
36
- },
37
- },
38
- },
39
- },
40
- {
41
- name: 'get_deposit_addresses',
42
- description: 'Get deposit addresses (EVM, Solana, Bitcoin) for the configured wallet',
43
- inputSchema: {
44
- type: 'object',
45
- properties: {},
46
- },
47
- },
48
- {
49
- name: 'deposit_usdc',
50
- description: 'Deposit USDC to Polymarket. Transfers USDC from your wallet to Polymarket via the Bridge.',
51
- inputSchema: {
52
- type: 'object',
53
- properties: {
54
- amount: {
55
- type: 'number',
56
- description: 'Amount to deposit in USDC (minimum $2)',
57
- },
58
- token: {
59
- type: 'string',
60
- enum: ['NATIVE_USDC', 'USDC_E'],
61
- description: 'Which USDC token to deposit (default: NATIVE_USDC)',
62
- },
63
- },
64
- required: ['amount'],
65
- },
66
- },
67
- {
68
- name: 'check_allowances',
69
- description: 'Check all ERC20 and ERC1155 allowances required for trading',
70
- inputSchema: {
71
- type: 'object',
72
- properties: {},
73
- },
74
- },
75
- {
76
- name: 'approve_trading',
77
- description: 'Set up all required ERC20 and ERC1155 approvals for trading on Polymarket',
78
- inputSchema: {
79
- type: 'object',
80
- properties: {},
81
- },
82
- },
83
- {
84
- name: 'swap',
85
- description: 'Swap between tokens on Polygon using QuickSwap V3. Supports MATIC, WETH, USDC, USDC.e, USDT, DAI.',
86
- inputSchema: {
87
- type: 'object',
88
- properties: {
89
- tokenIn: {
90
- type: 'string',
91
- description: 'Token to swap from (e.g., MATIC, WETH, USDT, DAI, USDC, USDC_E)',
92
- },
93
- tokenOut: {
94
- type: 'string',
95
- description: 'Token to swap to (e.g., USDC, USDC_E, WETH)',
96
- },
97
- amount: {
98
- type: 'string',
99
- description: 'Amount to swap in token units',
100
- },
101
- slippage: {
102
- type: 'number',
103
- description: 'Slippage tolerance in percent (default: 0.5)',
104
- },
105
- },
106
- required: ['tokenIn', 'tokenOut', 'amount'],
107
- },
108
- },
109
- {
110
- name: 'swap_and_deposit',
111
- description: 'Swap any supported Polygon token to USDC and deposit to Polymarket. Supports MATIC, WETH, USDT, DAI, USDC, USDC.e.',
112
- inputSchema: {
113
- type: 'object',
114
- properties: {
115
- token: {
116
- type: 'string',
117
- description: 'Token to deposit (e.g., MATIC, WETH, USDT, DAI, USDC)',
118
- },
119
- amount: {
120
- type: 'string',
121
- description: 'Amount to deposit in token units',
122
- },
123
- slippage: {
124
- type: 'number',
125
- description: 'Slippage tolerance for swap in percent (default: 0.5)',
126
- },
127
- },
128
- required: ['token', 'amount'],
129
- },
130
- },
131
- {
132
- name: 'get_token_balances',
133
- description: 'Get balances for all supported tokens on Polygon for the configured wallet (requires private key)',
134
- inputSchema: {
135
- type: 'object',
136
- properties: {},
137
- },
138
- },
139
- {
140
- name: 'get_wallet_balances',
141
- description: 'Get Polygon token balances for any wallet address (MATIC, USDC, USDC.e, USDT, DAI, WETH). No private key required.',
142
- inputSchema: {
143
- type: 'object',
144
- properties: {
145
- address: {
146
- type: 'string',
147
- description: 'Wallet address to check (0x...)',
148
- },
149
- },
150
- required: ['address'],
151
- },
152
- },
153
- {
154
- name: 'get_swap_quote',
155
- description: 'Get a swap quote to check if a route is available and estimate output amount. No private key required. Uses QuickSwap V3 Quoter contract.',
156
- inputSchema: {
157
- type: 'object',
158
- properties: {
159
- tokenIn: {
160
- type: 'string',
161
- description: 'Token to swap from (e.g., MATIC, WETH, USDT, DAI, USDC, USDC_E)',
162
- },
163
- tokenOut: {
164
- type: 'string',
165
- description: 'Token to swap to (e.g., USDC, USDC_E, WETH)',
166
- },
167
- amount: {
168
- type: 'string',
169
- description: 'Amount to swap in token units',
170
- },
171
- },
172
- required: ['tokenIn', 'tokenOut', 'amount'],
173
- },
174
- },
175
- {
176
- name: 'get_available_pools',
177
- description: 'Get all available liquidity pools on QuickSwap V3. Shows which token pairs can be swapped directly.',
178
- inputSchema: {
179
- type: 'object',
180
- properties: {},
181
- },
182
- },
183
- ];
184
-
185
- // Input/Output types
186
- interface GetSupportedAssetsInput {
187
- chainId?: number;
188
- }
189
-
190
- interface DepositUsdcInput {
191
- amount: number;
192
- token?: 'NATIVE_USDC' | 'USDC_E';
193
- }
194
-
195
- // Default Polygon RPC for wallet operations
196
- const POLYGON_RPC = 'https://polygon-rpc.com';
197
-
198
- /**
199
- * Helper to get signer from SDK
200
- * Ensures the signer is connected to a Polygon provider
201
- */
202
- function getSignerFromSdk(sdk: PolymarketSDK): ethers.Wallet {
203
- const sdkAny = sdk as unknown as {
204
- clobApi: {
205
- signer?: ethers.Wallet;
206
- };
207
- };
208
-
209
- const signer = sdkAny.clobApi?.signer;
210
- if (!signer) {
211
- throw new McpToolError(
212
- ErrorCode.AUTH_REQUIRED,
213
- 'Wallet not configured. Set POLY_PRIVATE_KEY to use wallet features.'
214
- );
215
- }
216
-
217
- // Ensure signer is connected to a provider
218
- if (!signer.provider) {
219
- const provider = new ethers.providers.JsonRpcProvider(POLYGON_RPC);
220
- return signer.connect(provider);
221
- }
222
-
223
- return signer;
224
- }
225
-
226
- /**
227
- * Get supported deposit assets
228
- */
229
- export async function handleGetSupportedAssets(
230
- _sdk: PolymarketSDK,
231
- input: GetSupportedAssetsInput
232
- ) {
233
- try {
234
- const bridge = new BridgeClient();
235
- const assets = await bridge.getSupportedAssets();
236
-
237
- // Filter by chainId if provided
238
- const filtered = input.chainId
239
- ? assets.filter((a) => a.chainId === input.chainId)
240
- : assets;
241
-
242
- // Get unique chains
243
- const chainSet = new Set<string>();
244
- for (const asset of filtered) {
245
- chainSet.add(asset.chainName);
246
- }
247
-
248
- return {
249
- assets: filtered.map((a) => ({
250
- chainId: a.chainId,
251
- chainName: a.chainName,
252
- tokenSymbol: a.tokenSymbol,
253
- tokenName: a.tokenName,
254
- tokenAddress: a.tokenAddress,
255
- decimals: a.decimals,
256
- minDeposit: a.minDeposit,
257
- minDepositUsd: a.minDepositUsd,
258
- })),
259
- summary: {
260
- totalChains: chainSet.size,
261
- totalAssets: filtered.length,
262
- chains: Array.from(chainSet),
263
- },
264
- };
265
- } catch (err) {
266
- throw wrapError(err);
267
- }
268
- }
269
-
270
- /**
271
- * Get deposit addresses for the wallet
272
- */
273
- export async function handleGetDepositAddresses(sdk: PolymarketSDK) {
274
- const signer = getSignerFromSdk(sdk);
275
- const walletAddress = signer.address;
276
-
277
- try {
278
- const bridge = new BridgeClient();
279
- const result = await bridge.createDepositAddresses(walletAddress);
280
-
281
- const evmChains = ['Ethereum', 'Polygon', 'Arbitrum', 'Base', 'Optimism'];
282
-
283
- return {
284
- wallet: walletAddress,
285
- addresses: {
286
- evm: result.address.evm,
287
- solana: result.address.svm,
288
- bitcoin: result.address.btc,
289
- },
290
- evmChains,
291
- instructions: `Send assets to these addresses to deposit to your Polymarket account.
292
-
293
- EVM Chains (Ethereum, Polygon, Arbitrum, Base, Optimism):
294
- ${result.address.evm}
295
-
296
- Solana:
297
- ${result.address.svm}
298
-
299
- Bitcoin:
300
- ${result.address.btc}
301
-
302
- Assets will be automatically converted to USDC.e on Polygon.`,
303
- };
304
- } catch (err) {
305
- throw wrapError(err);
306
- }
307
- }
308
-
309
- /**
310
- * Deposit USDC to Polymarket
311
- */
312
- export async function handleDepositUsdc(
313
- sdk: PolymarketSDK,
314
- input: DepositUsdcInput
315
- ) {
316
- const signer = getSignerFromSdk(sdk);
317
-
318
- try {
319
- const result = await depositUsdc(signer, input.amount, {
320
- token: input.token || 'NATIVE_USDC',
321
- });
322
-
323
- if (!result.success) {
324
- return {
325
- success: false,
326
- error: result.error,
327
- wallet: signer.address,
328
- amount: input.amount,
329
- };
330
- }
331
-
332
- return {
333
- success: true,
334
- wallet: signer.address,
335
- amount: result.amount,
336
- txHash: result.txHash,
337
- depositAddress: result.depositAddress,
338
- message: `Successfully deposited $${result.amount} USDC. The bridge will automatically convert it to USDC.e on Polygon (typically 1-5 minutes).`,
339
- explorerUrl: `https://polygonscan.com/tx/${result.txHash}`,
340
- };
341
- } catch (err) {
342
- throw wrapError(err);
343
- }
344
- }
345
-
346
- /**
347
- * Check all allowances required for trading
348
- */
349
- export async function handleCheckAllowances(sdk: PolymarketSDK) {
350
- const signer = getSignerFromSdk(sdk);
351
-
352
- try {
353
- const authService = new AuthorizationService(signer);
354
- const result = await authService.checkAllowances();
355
-
356
- return {
357
- wallet: result.wallet,
358
- erc20: {
359
- usdc: {
360
- balance: result.usdcBalance,
361
- allowances: result.erc20Allowances,
362
- },
363
- },
364
- erc1155: {
365
- conditionalTokens: {
366
- approvals: result.erc1155Approvals,
367
- },
368
- },
369
- tradingReady: result.tradingReady,
370
- issues: result.issues,
371
- };
372
- } catch (err) {
373
- throw wrapError(err);
374
- }
375
- }
376
-
377
- /**
378
- * Set up all required approvals for trading
379
- */
380
- export async function handleApproveTrading(sdk: PolymarketSDK) {
381
- const signer = getSignerFromSdk(sdk);
382
-
383
- try {
384
- const authService = new AuthorizationService(signer);
385
- const result = await authService.approveAll();
386
-
387
- return {
388
- wallet: result.wallet,
389
- erc20Approvals: result.erc20Approvals,
390
- erc1155Approvals: result.erc1155Approvals,
391
- allApproved: result.allApproved,
392
- summary: result.summary,
393
- };
394
- } catch (err) {
395
- throw wrapError(err);
396
- }
397
- }
398
-
399
- // Input types for new tools
400
- interface SwapInput {
401
- tokenIn: string;
402
- tokenOut: string;
403
- amount: string;
404
- slippage?: number;
405
- }
406
-
407
- interface SwapAndDepositInput {
408
- token: string;
409
- amount: string;
410
- slippage?: number;
411
- }
412
-
413
- /**
414
- * Swap between tokens on Polygon using QuickSwap V3
415
- */
416
- export async function handleSwap(sdk: PolymarketSDK, input: SwapInput) {
417
- const signer = getSignerFromSdk(sdk);
418
-
419
- try {
420
- const swapService = new SwapService(signer);
421
-
422
- // Check balance first
423
- const balance = await swapService.getBalance(input.tokenIn);
424
- if (parseFloat(balance) < parseFloat(input.amount)) {
425
- return {
426
- success: false,
427
- error: `Insufficient ${input.tokenIn} balance. Have: ${balance}, Need: ${input.amount}`,
428
- wallet: signer.address,
429
- };
430
- }
431
-
432
- // Execute swap
433
- const result = await swapService.swap(input.tokenIn, input.tokenOut, input.amount, {
434
- slippage: input.slippage || 0.5,
435
- });
436
-
437
- if (!result.success) {
438
- return {
439
- success: false,
440
- error: 'Swap failed',
441
- wallet: signer.address,
442
- txHash: result.transactionHash,
443
- };
444
- }
445
-
446
- return {
447
- success: true,
448
- wallet: signer.address,
449
- tokenIn: result.tokenIn,
450
- tokenOut: result.tokenOut,
451
- amountIn: result.amountIn,
452
- amountOut: result.amountOut,
453
- txHash: result.transactionHash,
454
- gasUsed: result.gasUsed,
455
- explorerUrl: `https://polygonscan.com/tx/${result.transactionHash}`,
456
- };
457
- } catch (err) {
458
- throw wrapError(err);
459
- }
460
- }
461
-
462
- /**
463
- * Swap any token to USDC and deposit to Polymarket
464
- */
465
- export async function handleSwapAndDeposit(sdk: PolymarketSDK, input: SwapAndDepositInput) {
466
- const signer = getSignerFromSdk(sdk);
467
-
468
- try {
469
- const result = await swapAndDeposit(signer, input.token, input.amount, {
470
- slippage: input.slippage || 0.5,
471
- });
472
-
473
- if (!result.success) {
474
- return {
475
- success: false,
476
- error: result.error,
477
- wallet: signer.address,
478
- token: input.token,
479
- amount: input.amount,
480
- };
481
- }
482
-
483
- return {
484
- success: true,
485
- wallet: signer.address,
486
- tokenIn: result.tokenIn,
487
- amountIn: result.amountIn,
488
- usdcAmount: result.usdcAmount,
489
- swapTxHash: result.swapTxHash || null,
490
- depositTxHash: result.depositTxHash,
491
- depositAddress: result.depositAddress,
492
- message: result.swapTxHash
493
- ? `Swapped ${result.amountIn} ${result.tokenIn} to ${result.usdcAmount} USDC, then deposited to Polymarket.`
494
- : `Deposited ${result.usdcAmount} USDC to Polymarket.`,
495
- explorerUrl: result.depositTxHash
496
- ? `https://polygonscan.com/tx/${result.depositTxHash}`
497
- : undefined,
498
- };
499
- } catch (err) {
500
- throw wrapError(err);
501
- }
502
- }
503
-
504
- /**
505
- * Get balances for all supported tokens (requires configured wallet)
506
- */
507
- export async function handleGetTokenBalances(sdk: PolymarketSDK) {
508
- const signer = getSignerFromSdk(sdk);
509
-
510
- try {
511
- const swapService = new SwapService(signer);
512
- const balances = await swapService.getBalances();
513
-
514
- // Filter out zero balances
515
- const nonZeroBalances = balances.filter((b) => parseFloat(b.balance) > 0);
516
-
517
- return {
518
- wallet: signer.address,
519
- balances: balances.map((b) => ({
520
- token: b.token,
521
- symbol: b.symbol,
522
- balance: b.balance,
523
- decimals: b.decimals,
524
- })),
525
- nonZeroBalances: nonZeroBalances.map((b) => ({
526
- token: b.token,
527
- balance: b.balance,
528
- })),
529
- supportedTokens: getSupportedDepositTokens(),
530
- };
531
- } catch (err) {
532
- throw wrapError(err);
533
- }
534
- }
535
-
536
- /**
537
- * Get balances for any wallet address (no private key required)
538
- */
539
- export async function handleGetWalletBalances(
540
- _sdk: PolymarketSDK,
541
- input: { address: string }
542
- ) {
543
- try {
544
- // Validate address
545
- if (!input.address || !input.address.startsWith('0x') || input.address.length !== 42) {
546
- throw new McpToolError(
547
- ErrorCode.INVALID_INPUT,
548
- 'Invalid wallet address. Must be a valid Ethereum address (0x...)'
549
- );
550
- }
551
-
552
- const balances = await SwapService.getWalletBalances(input.address);
553
-
554
- // Filter out zero balances
555
- const nonZeroBalances = balances.filter((b) => parseFloat(b.balance) > 0);
556
-
557
- // Calculate total USD value (simplified, assumes stablecoins = $1)
558
- let totalUsdValue = 0;
559
- for (const b of nonZeroBalances) {
560
- const amount = parseFloat(b.balance);
561
- if (['USDC', 'USDC_E', 'USDT', 'DAI'].includes(b.token)) {
562
- totalUsdValue += amount;
563
- }
564
- // For MATIC/WETH, would need price oracle for accurate value
565
- }
566
-
567
- return {
568
- address: input.address,
569
- balances: balances.map((b) => ({
570
- token: b.token,
571
- symbol: b.symbol,
572
- balance: b.balance,
573
- decimals: b.decimals,
574
- })),
575
- nonZeroBalances: nonZeroBalances.map((b) => ({
576
- token: b.token,
577
- balance: b.balance,
578
- })),
579
- summary: {
580
- totalTokens: nonZeroBalances.length,
581
- stablecoinValue: totalUsdValue.toFixed(2),
582
- },
583
- supportedTokens: getSupportedDepositTokens(),
584
- };
585
- } catch (err) {
586
- throw wrapError(err);
587
- }
588
- }
589
-
590
- // Input types for quote tools
591
- interface GetSwapQuoteInput {
592
- tokenIn: string;
593
- tokenOut: string;
594
- amount: string;
595
- }
596
-
597
- /**
598
- * Get a swap quote (check route availability and estimate output)
599
- * No private key required - uses read-only provider
600
- */
601
- export async function handleGetSwapQuote(
602
- _sdk: PolymarketSDK,
603
- input: GetSwapQuoteInput
604
- ) {
605
- try {
606
- // Validate inputs
607
- if (!input.tokenIn || !input.tokenOut || !input.amount) {
608
- throw new McpToolError(
609
- ErrorCode.INVALID_INPUT,
610
- 'tokenIn, tokenOut, and amount are all required'
611
- );
612
- }
613
-
614
- // Create a read-only SwapService with a dummy wallet
615
- // The getQuote method only uses the provider, not the signer
616
- const provider = new ethers.providers.JsonRpcProvider(POLYGON_RPC);
617
- const dummyWallet = ethers.Wallet.createRandom().connect(provider);
618
- const swapService = new SwapService(dummyWallet);
619
-
620
- const quote = await swapService.getQuote(input.tokenIn, input.tokenOut, input.amount);
621
-
622
- if (quote.possible) {
623
- return {
624
- possible: true,
625
- tokenIn: quote.tokenIn,
626
- tokenOut: quote.tokenOut,
627
- amountIn: quote.amountIn,
628
- amountOut: quote.amountOut,
629
- route: quote.route,
630
- routeDescription: quote.route.length === 2
631
- ? `Direct swap: ${quote.route.join(' → ')}`
632
- : `Multi-hop: ${quote.route.join(' → ')}`,
633
- message: `Can swap ${quote.amountIn} ${quote.tokenIn} for ~${quote.amountOut} ${quote.tokenOut}`,
634
- };
635
- } else {
636
- return {
637
- possible: false,
638
- tokenIn: quote.tokenIn,
639
- tokenOut: quote.tokenOut,
640
- amountIn: quote.amountIn,
641
- amountOut: null,
642
- route: quote.route,
643
- poolExists: quote.poolExists,
644
- reason: quote.reason,
645
- suggestion: quote.tokenOut === 'USDC_E'
646
- ? 'For USDC.e, use: MATIC → USDC via swap, then USDC → USDC.e via deposit_usdc (Bridge)'
647
- : 'Try swapping through USDC as an intermediate token',
648
- };
649
- }
650
- } catch (err) {
651
- throw wrapError(err);
652
- }
653
- }
654
-
655
- /**
656
- * Get all available liquidity pools on QuickSwap V3
657
- */
658
- export async function handleGetAvailablePools(_sdk: PolymarketSDK) {
659
- try {
660
- // Create a read-only SwapService
661
- const provider = new ethers.providers.JsonRpcProvider(POLYGON_RPC);
662
- const dummyWallet = ethers.Wallet.createRandom().connect(provider);
663
- const swapService = new SwapService(dummyWallet);
664
-
665
- const pools = await swapService.getAvailablePools();
666
-
667
- return {
668
- pools: pools.map((p) => ({
669
- pair: `${p.tokenA}/${p.tokenB}`,
670
- tokenA: p.tokenA,
671
- tokenB: p.tokenB,
672
- poolAddress: p.poolAddress,
673
- })),
674
- totalPools: pools.length,
675
- supportedTokens: swapService.getSupportedTokens().filter(
676
- (t) => t !== 'NATIVE_USDC' && t !== 'WMATIC' // Exclude aliases
677
- ),
678
- note: 'These are direct swap pairs. For pairs not listed, multi-hop routing through USDC or WMATIC may be available. Use get_swap_quote to check.',
679
- };
680
- } catch (err) {
681
- throw wrapError(err);
682
- }
683
- }