@continuumdao/ctm-mpc-defi 0.1.4 → 0.2.1

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 (94) hide show
  1. package/README.md +20 -78
  2. package/dist/agent/catalog.cjs +1388 -144
  3. package/dist/agent/catalog.cjs.map +1 -1
  4. package/dist/agent/catalog.d.ts +881 -17
  5. package/dist/agent/catalog.js +1327 -145
  6. package/dist/agent/catalog.js.map +1 -1
  7. package/dist/agent/skills/aave-v4/SKILL.md +43 -0
  8. package/dist/agent/skills/curve-dao/SKILL.md +12 -0
  9. package/dist/agent/skills/ethena/SKILL.md +10 -0
  10. package/dist/agent/skills/euler-v2/SKILL.md +10 -0
  11. package/dist/agent/skills/lido/SKILL.md +22 -0
  12. package/dist/agent/skills/maple-syrup/SKILL.md +10 -0
  13. package/dist/agent/skills/sky/SKILL.md +10 -0
  14. package/dist/agent/skills/uniswap-v4/SKILL.md +22 -0
  15. package/dist/chains/evm/index.cjs +27 -213
  16. package/dist/chains/evm/index.cjs.map +1 -1
  17. package/dist/chains/evm/index.d.ts +15 -25
  18. package/dist/chains/evm/index.js +21 -199
  19. package/dist/chains/evm/index.js.map +1 -1
  20. package/dist/chains/near/index.d.ts +1 -1
  21. package/dist/chains/solana/index.d.ts +1 -1
  22. package/dist/core/index.cjs +8 -110
  23. package/dist/core/index.cjs.map +1 -1
  24. package/dist/core/index.d.ts +5 -39
  25. package/dist/core/index.js +6 -100
  26. package/dist/core/index.js.map +1 -1
  27. package/dist/{envelope-CcE5Cz_q.d.ts → envelope-CpBUh9eP.d.ts} +1 -1
  28. package/dist/index.cjs +238 -1184
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.ts +7 -10
  31. package/dist/index.js +227 -1156
  32. package/dist/index.js.map +1 -1
  33. package/dist/protocols/evm/aave-v4/index.cjs +1710 -0
  34. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -0
  35. package/dist/protocols/evm/aave-v4/index.d.ts +499 -0
  36. package/dist/protocols/evm/aave-v4/index.js +1666 -0
  37. package/dist/protocols/evm/aave-v4/index.js.map +1 -0
  38. package/dist/protocols/evm/curve-dao/index.cjs +24 -124
  39. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
  40. package/dist/protocols/evm/curve-dao/index.d.ts +3 -4
  41. package/dist/protocols/evm/curve-dao/index.js +15 -115
  42. package/dist/protocols/evm/curve-dao/index.js.map +1 -1
  43. package/dist/protocols/evm/ethena/index.cjs +853 -0
  44. package/dist/protocols/evm/ethena/index.cjs.map +1 -0
  45. package/dist/protocols/evm/ethena/index.d.ts +160 -0
  46. package/dist/protocols/evm/ethena/index.js +831 -0
  47. package/dist/protocols/evm/ethena/index.js.map +1 -0
  48. package/dist/protocols/evm/euler-v2/index.cjs +1585 -0
  49. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -0
  50. package/dist/protocols/evm/euler-v2/index.d.ts +316 -0
  51. package/dist/protocols/evm/euler-v2/index.js +1560 -0
  52. package/dist/protocols/evm/euler-v2/index.js.map +1 -0
  53. package/dist/protocols/evm/lido/index.cjs +839 -0
  54. package/dist/protocols/evm/lido/index.cjs.map +1 -0
  55. package/dist/protocols/evm/lido/index.d.ts +119 -0
  56. package/dist/protocols/evm/lido/index.js +814 -0
  57. package/dist/protocols/evm/lido/index.js.map +1 -0
  58. package/dist/protocols/evm/maple/index.cjs +619 -0
  59. package/dist/protocols/evm/maple/index.cjs.map +1 -0
  60. package/dist/protocols/evm/maple/index.d.ts +108 -0
  61. package/dist/protocols/evm/maple/index.js +605 -0
  62. package/dist/protocols/evm/maple/index.js.map +1 -0
  63. package/dist/protocols/evm/sky/index.cjs +1259 -0
  64. package/dist/protocols/evm/sky/index.cjs.map +1 -0
  65. package/dist/protocols/evm/sky/index.d.ts +217 -0
  66. package/dist/protocols/evm/sky/index.js +1234 -0
  67. package/dist/protocols/evm/sky/index.js.map +1 -0
  68. package/dist/protocols/evm/uniswap-v4/index.cjs +423 -658
  69. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
  70. package/dist/protocols/evm/uniswap-v4/index.d.ts +3 -4
  71. package/dist/protocols/evm/uniswap-v4/index.js +422 -657
  72. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
  73. package/dist/{registry-oMKlO_5z.d.ts → registry-Bv5o37_w.d.ts} +1 -1
  74. package/dist/{types-Ce2qNHai.d.cts → types-BfjWdw1j.d.ts} +3 -1
  75. package/dist/{types-5u863Fd9.d.ts → types-DUeNJLr9.d.ts} +1 -1
  76. package/package.json +43 -8
  77. package/dist/agent/catalog.d.cts +0 -195
  78. package/dist/chains/evm/index.d.cts +0 -62
  79. package/dist/chains/near/index.d.cts +0 -37
  80. package/dist/chains/solana/index.d.cts +0 -40
  81. package/dist/core/index.d.cts +0 -43
  82. package/dist/envelope-DYDPnrHZ.d.cts +0 -35
  83. package/dist/index.d.cts +0 -15
  84. package/dist/keygen-CfNp8yKJ.d.cts +0 -9
  85. package/dist/keygen-DsINazx8.d.ts +0 -9
  86. package/dist/nodeRead-BnmSaMGO.d.cts +0 -8
  87. package/dist/nodeRead-BnmSaMGO.d.ts +0 -8
  88. package/dist/protocols/evm/curve-dao/index.d.cts +0 -147
  89. package/dist/protocols/evm/uniswap-v4/index.d.cts +0 -324
  90. package/dist/registry-BwZoE668.d.cts +0 -8
  91. package/dist/txParams-BC7ogvdR.d.cts +0 -19
  92. package/dist/txParams-BC7ogvdR.d.ts +0 -19
  93. package/dist/types-B8idm_gu.d.cts +0 -34
  94. package/dist/types-Ce2qNHai.d.ts +0 -57
@@ -1,4 +1,9 @@
1
- import 'viem';
1
+ import { getAddress, isAddress } from 'viem';
2
+ import { zodToJsonSchema } from 'zod-to-json-schema';
3
+ import { z } from 'zod';
4
+ import { readFileSync } from 'fs';
5
+ import { join, dirname } from 'path';
6
+ import { fileURLToPath } from 'url';
2
7
 
3
8
  // src/core/registry.ts
4
9
  var modules = [];
@@ -157,6 +162,96 @@ function isCurveApiChainSupported(chainId) {
157
162
  if (Number.isNaN(n) || n < 0) return false;
158
163
  return CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS.has(n);
159
164
  }
165
+ var CURVE_NATIVE_PLACEHOLDER = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
166
+ var ETH_PLACEHOLDER = CURVE_NATIVE_PLACEHOLDER;
167
+ function normalizeAddr(a) {
168
+ return a.toLowerCase();
169
+ }
170
+ function addEdge(adj, a, b) {
171
+ if (a === b) return;
172
+ if (!adj.has(a)) adj.set(a, /* @__PURE__ */ new Set());
173
+ if (!adj.has(b)) adj.set(b, /* @__PURE__ */ new Set());
174
+ adj.get(a).add(b);
175
+ adj.get(b).add(a);
176
+ }
177
+ function buildCurveLiquidityGraphFromApi(curve) {
178
+ const adj = /* @__PURE__ */ new Map();
179
+ for (const id of curve.getPoolList()) {
180
+ try {
181
+ const pool = curve.getPool(id);
182
+ const w = (pool.wrappedCoinAddresses ?? []).map(normalizeAddr);
183
+ const u = (pool.underlyingCoinAddresses ?? []).map(normalizeAddr);
184
+ const all = [.../* @__PURE__ */ new Set([...w, ...u])];
185
+ for (let i = 0; i < all.length; i++) {
186
+ for (let j = i + 1; j < all.length; j++) {
187
+ addEdge(adj, all[i], all[j]);
188
+ }
189
+ }
190
+ } catch {
191
+ }
192
+ }
193
+ return adj;
194
+ }
195
+ function addNativeWethBridge(adj, wrappedNative) {
196
+ if (!wrappedNative) return;
197
+ const w = wrappedNative.toLowerCase();
198
+ const a = ETH_PLACEHOLDER;
199
+ const b = w;
200
+ if (a === b) return;
201
+ if (!adj.has(a)) adj.set(a, /* @__PURE__ */ new Set());
202
+ if (!adj.has(b)) adj.set(b, /* @__PURE__ */ new Set());
203
+ adj.get(a).add(b);
204
+ adj.get(b).add(a);
205
+ }
206
+ function swappableCurveGraphNodeKeys(adj) {
207
+ const out = /* @__PURE__ */ new Set();
208
+ for (const [k, neigh] of adj) {
209
+ if (neigh.size > 0) out.add(k);
210
+ }
211
+ return out;
212
+ }
213
+
214
+ // src/protocols/evm/curve-dao/apiSession.ts
215
+ async function fetchAllCurvePools(curve) {
216
+ const run = (p) => p.catch(() => void 0);
217
+ await Promise.all([
218
+ run(curve.factory.fetchPools()),
219
+ run(curve.crvUSDFactory.fetchPools()),
220
+ run(curve.EYWAFactory.fetchPools()),
221
+ run(curve.cryptoFactory.fetchPools()),
222
+ run(curve.twocryptoFactory.fetchPools()),
223
+ run(curve.tricryptoFactory.fetchPools()),
224
+ run(curve.stableNgFactory.fetchPools())
225
+ ]);
226
+ }
227
+ async function loadFullCurveSessionForRpc(rpcUrl) {
228
+ const url = (rpcUrl ?? "").trim();
229
+ if (!url) return null;
230
+ try {
231
+ const { default: curve } = await import('@curvefi/api');
232
+ await curve.init("JsonRpc", { url }, {});
233
+ const wrapped = curve.getNetworkConstants().NATIVE_COIN?.wrappedAddress;
234
+ if (!curve.hasRouter || !curve.hasRouter()) {
235
+ return {
236
+ curve,
237
+ adj: /* @__PURE__ */ new Map(),
238
+ swappableNodeKeys: /* @__PURE__ */ new Set(),
239
+ wrappedNative: wrapped
240
+ };
241
+ }
242
+ await fetchAllCurvePools(curve);
243
+ const adj = buildCurveLiquidityGraphFromApi(curve);
244
+ addNativeWethBridge(adj, wrapped);
245
+ return {
246
+ curve,
247
+ adj,
248
+ swappableNodeKeys: swappableCurveGraphNodeKeys(adj),
249
+ wrappedNative: wrapped
250
+ };
251
+ } catch {
252
+ return null;
253
+ }
254
+ }
160
255
 
161
256
  // src/protocols/evm/curve-dao/index.ts
162
257
  var CURVE_DAO_PROTOCOL_ID = "curve-dao";
@@ -246,7 +341,14 @@ var MULTISIGN_OUTPUT_DOC = {
246
341
  }
247
342
  };
248
343
  var MANAGEMENT_SIG_DOC = {
249
- description: "Management POST bodies embed NodeMgtKeySig: { nonce, clientSig, nodeKey }. Sign JSON with clientSig cleared; POST with clientSig set to the Ed25519 128-hex or EIP-191 signature. Legacy Nonce/Sig/sig field names are not accepted.",
344
+ description: "Management POST bodies embed NodeMgtKeySig: { nonce, clientSig, nodeKey }. Sign JSON with clientSig cleared via messageToSignManagementBody; POST with withManagementClientSig(body, sig). Do not put signedMessage in the JSON body for standard management routes. Legacy Nonce/Sig/sig field names are not accepted.",
345
+ exceptions: {
346
+ configUpdateImplement: "POST /configUpdateImplement: include nodeKey + plannedYaml + signedMessage (opaque configUpdateImplement|<sha256> line). Sign the opaque line bytes, not the JSON body.",
347
+ postMSQTTKey: "POST /postMSQTTKey: include nodeKey + caCertPem + clientSig. Sign caCertPem PEM bytes directly (use buildPostMqttKeyBody).",
348
+ addManagementKey: "POST /addManagementKey / removeManagementKey (EIP-191): may still use signedMessage equal to the canonical JSON string for dual-mode Ethereum signing.",
349
+ agentLlmConfig: "POST /agentLlmConfig / agentLlmApiKey: sign canonical JSON with action + clientSig cleared; POST body has nonce, clientSig, nodeKey, endpoint fields \u2014 no signedMessage field.",
350
+ multiSignRequest: "POST /multiSignRequest (client key, not management): POST { ...bodyForSign, clientSig, signedMessage: messageToSign }."
351
+ },
250
352
  fields: {
251
353
  nonce: {
252
354
  type: "number",
@@ -264,52 +366,592 @@ var MANAGEMENT_SIG_DOC = {
264
366
  helpers: {
265
367
  managementSigFields: "Base envelope with clientSig cleared.",
266
368
  buildManagementPostBody: "Spread managementSigFields then endpoint fields.",
369
+ buildPostMqttKeyBody: "POST /postMSQTTKey unsigned body (sign PEM directly).",
370
+ buildPostPreferredKeyGenBody: "POST /postPreferredKeyGen unsigned body.",
371
+ buildConfigUpdateImplementPostBody: "POST /configUpdateImplement with opaque signedMessage line.",
372
+ buildSignRequestAgreeUnsignedBody: "POST /signRequestAgree unsigned body with nodeKey.",
267
373
  messageToSignManagementBody: "Canonical JSON string to sign.",
268
374
  withManagementClientSig: "Attach signature to POST body.",
269
375
  fetchNodeKey: "GET /getNodeKey via nodeFetchWithReadAuth.",
270
- fetchManagementNonce: "GET nonce for Ed25519 or Ethereum management key."
376
+ fetchManagementNonce: "GET nonce for Ed25519 or Ethereum management key.",
377
+ fetchPreferredKeyGen: "GET /getPreferredKeyGen for agent default KeyGen."
271
378
  }
272
379
  };
273
-
274
- // src/agent/mcpTools.ts
275
- function paramProperties(params, includeCommon = []) {
276
- const out = {};
277
- for (const k of includeCommon) {
278
- const d = EVM_COMMON_PARAM_DOCS[k];
279
- if (d) out[k] = { type: d.type, description: d.description };
380
+ function zodSchemaToMcpJsonSchema(schema) {
381
+ const raw = zodToJsonSchema(schema, {
382
+ target: "openApi3",
383
+ $refStrategy: "none"
384
+ });
385
+ if (raw.type === "object" || raw.type === "array" || raw.type === "string") {
386
+ const { $schema: _s, ...rest } = raw;
387
+ return rest;
280
388
  }
281
- for (const [k, d] of Object.entries(params)) {
282
- out[k] = { type: d.type, description: d.description };
389
+ const defs = raw.definitions;
390
+ if (defs) {
391
+ const first = Object.values(defs)[0];
392
+ if (first?.type) {
393
+ const { $schema: _s, ...rest } = first;
394
+ return rest;
395
+ }
283
396
  }
284
- return out;
397
+ return raw;
285
398
  }
286
- function requiredKeys(params, includeCommon = []) {
287
- const req = [];
288
- for (const k of includeCommon) {
289
- if (EVM_COMMON_PARAM_DOCS[k]?.required) req.push(k);
290
- }
291
- for (const [k, d] of Object.entries(params)) {
292
- if (d.required) req.push(k);
293
- }
294
- return req;
399
+ var evmAddressSchema = z.string().min(1).describe("EVM address (0x-prefixed, 40 hex nibbles)");
400
+ var keyGenSchema = z.object({
401
+ pubkeyhex: z.string().min(1).describe("MPC secp256k1 public key hex (required for multiSignRequest pubKey)"),
402
+ keylist: z.array(z.string()).optional().describe("Key list on the sign request"),
403
+ ClientKeys: z.record(z.string()).optional().describe("Optional client key map from keyGen")
404
+ }).describe(
405
+ "MPC key slice: { pubkeyhex, keylist?, ClientKeys? }. Used for pubKey/keyList on POST /multiSignRequest."
406
+ );
407
+ var chainDetailSchema = z.object({
408
+ legacy: z.boolean().optional(),
409
+ gasLimit: z.number().optional(),
410
+ gasMultiplier: z.number().optional(),
411
+ gasPrice: z.number().optional(),
412
+ baseFee: z.number().optional(),
413
+ priorityFee: z.number().optional(),
414
+ baseFeeMultiplier: z.number().optional()
415
+ }).passthrough().describe(
416
+ "Optional gas config: { legacy?, gasLimit?, gasMultiplier?, gasPrice?, baseFee?, priorityFee?, baseFeeMultiplier? }."
417
+ );
418
+ var evmMultisignCommonInputSchema = z.object({
419
+ keyGen: keyGenSchema,
420
+ purposeText: z.string().min(1).describe(
421
+ "Human-readable purpose for the sign request. Stored in bodyForSign.purpose (may be appended with an automatic batch suffix)."
422
+ ),
423
+ useCustomGas: z.boolean().describe(
424
+ "When true, apply chain gas settings from chainDetail / customGasChainDetails instead of raw RPC estimates only."
425
+ ),
426
+ chainId: z.number().int().positive().describe("EVM chain id (decimal). Becomes destinationChainID on the sign request."),
427
+ rpcUrl: z.string().min(1).describe("HTTPS JSON-RPC URL for gas estimation, nonce, and allowance reads."),
428
+ executorAddress: evmAddressSchema.describe(
429
+ "MPC wallet address (from keyGen ethereumaddress) \u2014 tx sender for estimates and approvals."
430
+ ),
431
+ chainDetail: chainDetailSchema,
432
+ customGasChainDetails: z.record(z.unknown()).optional().describe("Snapshot written to extraJSON.customGasChainDetails when useCustomGas is true.")
433
+ });
434
+ var multisignOutputSchema = z.object({
435
+ bodyForSign: z.record(z.unknown()).describe(
436
+ "POST body fields without clientSig: keyList, pubKey, msgHash, msgRaw, destinationChainID, purpose, extraJSON, proposalTxParams (batch), messageHashes/messageRawBatch when N>1 txs."
437
+ ),
438
+ messageToSign: z.string().describe("JSON.stringify(bodyForSign) \u2014 exact string to sign before adding clientSig.")
439
+ }).describe(
440
+ "Unsigned mpc-auth multiSignRequest payload. Sign messageToSign and POST { ...bodyForSign, clientSig, signedMessage } to /multiSignRequest."
441
+ );
442
+ var jsonObjectSchema = z.record(z.unknown());
443
+ var uniswapQuoteTradeTypeSchema = z.enum(["EXACT_INPUT", "EXACT_OUTPUT"]);
444
+ var mcpUniswapV4QuoteInputSchema = z.object({
445
+ type: uniswapQuoteTradeTypeSchema.describe("EXACT_INPUT or EXACT_OUTPUT"),
446
+ amount: z.string().min(1).describe("Amount in token-in base units (wei string for ERC-20)"),
447
+ tokenIn: z.string().min(1).describe("Input token; 0x0 for native ETH"),
448
+ tokenOut: z.string().min(1).describe("Output token address"),
449
+ chainId: z.union([z.number().int().positive(), z.string().min(1)]).describe("tokenInChainId / same-chain default"),
450
+ uniswapApiKey: z.string().min(1).describe("Uniswap Trade API x-api-key"),
451
+ swapper: evmAddressSchema.optional().describe("MPC executor; omit if keyGen + managementNodeUrl provided"),
452
+ slippage: z.union([z.number(), z.string()]).optional().describe("Slippage percent; omit for API auto slippage"),
453
+ keyGen: z.string().optional().describe("KeyGen id \u2014 resolves swapper via GET /getKeyGenResultById when swapper omitted"),
454
+ managementNodeUrl: z.string().min(1).optional().describe("MPC node base URL; required with keyGen when swapper is omitted"),
455
+ tokenInChainId: z.union([z.number(), z.string()]).optional(),
456
+ tokenOutChainId: z.union([z.number(), z.string()]).optional(),
457
+ permit2Disabled: z.boolean().optional(),
458
+ baseUrl: z.string().optional(),
459
+ universalRouterVersion: z.string().optional()
460
+ });
461
+ var mcpUniswapV4QuoteOutputSchema = jsonObjectSchema.describe(
462
+ "Full Uniswap POST /quote JSON (includes nested quote object with input/output amounts)."
463
+ );
464
+ var mcpUniswapV4CreateSwapInputSchema = z.object({
465
+ uniswapApiKey: z.string().min(1).describe("Uniswap Trade API key"),
466
+ fullQuoteFromPermit: jsonObjectSchema.describe("Full quote JSON from ctm_uniswap_v4_quote"),
467
+ swapTransactionDeadlineUnix: z.number().int().positive().optional().describe("On-chain deadline unix seconds; default ~30 min from now"),
468
+ useServerProxy: z.boolean().optional().describe("Set false in Node/agents; true only in browser via Next API route"),
469
+ baseUrl: z.string().optional(),
470
+ universalRouterVersion: z.string().optional()
471
+ });
472
+ var mcpUniswapV4CreateSwapOutputSchema = z.object({
473
+ swap: jsonObjectSchema.describe("Universal Router tx: { to, data, value, gasLimit? }"),
474
+ requestId: z.string().optional(),
475
+ gasFee: z.string().optional()
476
+ }).passthrough().describe("{ swap: TransactionRequest, requestId?, gasFee? }");
477
+ var swapTxRequestSchema = jsonObjectSchema.describe("swap field from create_swap response (to, data, value)");
478
+ var mcpUniswapV4BuildSwapMultisignInputSchema = evmMultisignCommonInputSchema.extend({
479
+ tokenIn: evmAddressSchema.describe("Token in; 0x0 for native ETH"),
480
+ swap: swapTxRequestSchema,
481
+ createSwapResponse: z.object({
482
+ swap: swapTxRequestSchema,
483
+ requestId: z.string().optional(),
484
+ gasFee: z.string().optional()
485
+ }).passthrough().describe("Full create_swap response"),
486
+ fullQuoteSnapshot: jsonObjectSchema.describe("Quote JSON used for the swap"),
487
+ swapDeadlineUnix: z.number().describe("Same deadline passed to create_swap"),
488
+ slippagePercent: z.number().optional().describe("Extra approve headroom for EXACT_OUTPUT")
489
+ });
490
+ var mcpCurveDaoBuildSwapMultisignInputSchema = evmMultisignCommonInputSchema.extend({
491
+ tokenIn: evmAddressSchema.describe("ERC-20 sold (native in uses WETH path in UI)"),
492
+ tokenOut: z.string().min(1).describe("Output token or 0xeeee\u2026 native placeholder"),
493
+ amountHuman: z.string().min(1).describe("Human-readable amount of tokenIn"),
494
+ slippagePercent: z.number().gt(0).lt(100).describe("Slippage 0\u2013100 exclusive")
495
+ });
496
+ function mcpMultisignInput(fields) {
497
+ return evmMultisignCommonInputSchema.extend(fields);
295
498
  }
296
- var multisignOutputSchema = {
297
- type: "object",
298
- description: MULTISIGN_OUTPUT_DOC.description,
299
- properties: {
300
- bodyForSign: {
301
- type: "object",
302
- description: MULTISIGN_OUTPUT_DOC.fields.bodyForSign.description
303
- },
304
- messageToSign: {
305
- type: "string",
306
- description: MULTISIGN_OUTPUT_DOC.fields.messageToSign.description
307
- }
308
- },
309
- required: ["bodyForSign", "messageToSign"]
310
- };
311
- var MCP_TOOL_DEFINITIONS = [
312
- {
499
+ var mcpLidoSubmitInputSchema = mcpMultisignInput({
500
+ valueWei: z.string().min(1).describe("ETH to stake (wei decimal string)"),
501
+ referral: evmAddressSchema.optional()
502
+ });
503
+ var mcpLidoRequestWithdrawalsInputSchema = mcpMultisignInput({
504
+ stEthAmountsWei: z.array(z.string()).min(1).describe("stETH amounts per withdrawal request (wei strings)")
505
+ });
506
+ var mcpLidoClaimWithdrawalInputSchema = mcpMultisignInput({
507
+ requestId: z.union([z.string(), z.number()]).describe("Withdrawal queue request id")
508
+ });
509
+ var mcpLidoWrapStEthInputSchema = mcpMultisignInput({
510
+ stEthAmountWei: z.string().min(1)
511
+ });
512
+ var mcpLidoUnwrapWstEthInputSchema = mcpMultisignInput({
513
+ wstEthAmountWei: z.string().min(1)
514
+ });
515
+ var mcpEthenaStakeInputSchema = mcpMultisignInput({
516
+ usdeAmountHuman: z.string().min(1),
517
+ susdeVault: evmAddressSchema.optional()
518
+ });
519
+ var mcpEthenaRedeemInputSchema = mcpMultisignInput({
520
+ susdeSharesHuman: z.string().min(1),
521
+ susdeVault: evmAddressSchema.optional()
522
+ });
523
+ var mcpEthenaCooldownInputSchema = mcpMultisignInput({
524
+ susdeSharesHuman: z.string().min(1),
525
+ susdeVault: evmAddressSchema.optional()
526
+ });
527
+ var mcpEthenaClaimInputSchema = mcpMultisignInput({
528
+ susdeVault: evmAddressSchema.optional()
529
+ });
530
+ var mcpMapleDepositInputSchema = mcpMultisignInput({
531
+ syrupRouter: evmAddressSchema,
532
+ pool: evmAddressSchema,
533
+ asset: evmAddressSchema,
534
+ amountHuman: z.string().min(1),
535
+ authorizeSig: jsonObjectSchema.optional()
536
+ });
537
+ var mcpMapleRequestRedeemInputSchema = mcpMultisignInput({
538
+ pool: evmAddressSchema,
539
+ sharesHuman: z.string().min(1),
540
+ receiver: evmAddressSchema
541
+ });
542
+ var mcpSkyLockstakeStakeInputSchema = mcpMultisignInput({
543
+ skyAmountHuman: z.string().min(1),
544
+ usdsDrawHuman: z.string().optional(),
545
+ farmRef: z.string().optional()
546
+ });
547
+ var mcpSkyLockstakeDrawInputSchema = mcpMultisignInput({
548
+ usdsAmountHuman: z.string().min(1),
549
+ urnIndex: z.number().int().nonnegative()
550
+ });
551
+ var mcpSkyLockstakeWipeInputSchema = mcpMultisignInput({
552
+ usdsAmountHuman: z.string().min(1),
553
+ urnIndex: z.number().int().nonnegative()
554
+ });
555
+ var mcpSkyLockstakeCloseInputSchema = mcpMultisignInput({
556
+ urnIndex: z.number().int().nonnegative()
557
+ });
558
+ var mcpSkyLockstakeGetRewardInputSchema = mcpMultisignInput({
559
+ urnIndex: z.number().int().nonnegative()
560
+ });
561
+ var mcpSkySusdsDepositInputSchema = mcpMultisignInput({
562
+ usdsAmountHuman: z.string().min(1)
563
+ });
564
+ var mcpSkySusdsRedeemInputSchema = mcpMultisignInput({
565
+ sharesHuman: z.string().min(1)
566
+ });
567
+ var mcpAaveV4DepositInputSchema = mcpMultisignInput({
568
+ spoke: evmAddressSchema,
569
+ underlying: evmAddressSchema,
570
+ amountHuman: z.string().min(1),
571
+ marketId: z.string().min(1)
572
+ });
573
+ var mcpAaveV4WithdrawInputSchema = mcpMultisignInput({
574
+ spoke: evmAddressSchema,
575
+ underlying: evmAddressSchema,
576
+ amountHuman: z.string().min(1),
577
+ marketId: z.string().min(1)
578
+ });
579
+ var mcpAaveV4BorrowInputSchema = mcpMultisignInput({
580
+ spoke: evmAddressSchema,
581
+ underlying: evmAddressSchema,
582
+ amountHuman: z.string().min(1),
583
+ marketId: z.string().min(1)
584
+ });
585
+ var mcpAaveV4RepayInputSchema = mcpMultisignInput({
586
+ spoke: evmAddressSchema,
587
+ underlying: evmAddressSchema,
588
+ amountHuman: z.string().min(1),
589
+ marketId: z.string().min(1)
590
+ });
591
+ var mcpEulerV2IsolatedLendInputSchema = mcpMultisignInput({
592
+ vault: evmAddressSchema,
593
+ assetAmountHuman: z.string().min(1)
594
+ });
595
+ var mcpEulerV2IsolatedBorrowInputSchema = mcpMultisignInput({
596
+ vault: evmAddressSchema,
597
+ collateralAsset: evmAddressSchema,
598
+ borrowAsset: evmAddressSchema,
599
+ collateralAmountHuman: z.string().min(1),
600
+ loopBorrowWeis: z.array(z.string()).min(1)
601
+ });
602
+ var mcpEulerV2VaultWithdrawInputSchema = mcpMultisignInput({
603
+ vault: evmAddressSchema,
604
+ sharesHuman: z.string().min(1)
605
+ });
606
+ var mcpEulerV2BorrowRepayInputSchema = mcpMultisignInput({
607
+ vault: evmAddressSchema,
608
+ amountHuman: z.string().min(1)
609
+ });
610
+ var mcpEulerV2CollateralDepositInputSchema = mcpMultisignInput({
611
+ vault: evmAddressSchema,
612
+ collateralAsset: evmAddressSchema,
613
+ amountHuman: z.string().min(1)
614
+ });
615
+ var mcpEulerV2CollateralWithdrawInputSchema = mcpMultisignInput({
616
+ vault: evmAddressSchema,
617
+ collateralAsset: evmAddressSchema,
618
+ amountHuman: z.string().min(1)
619
+ });
620
+
621
+ // src/agent/mcpProtocolTools.ts
622
+ function defineProtocolMcpTool(def) {
623
+ return {
624
+ ...def,
625
+ outputZod: multisignOutputSchema,
626
+ inputSchema: zodSchemaToMcpJsonSchema(def.inputZod),
627
+ outputSchema: zodSchemaToMcpJsonSchema(multisignOutputSchema),
628
+ parseInput: (data) => def.inputZod.parse(data),
629
+ parseOutput: (data) => multisignOutputSchema.parse(data)
630
+ };
631
+ }
632
+ var MCP_PROTOCOL_TOOL_DEFINITIONS = [
633
+ defineProtocolMcpTool({
634
+ name: "ctm_lido_build_submit_multisign",
635
+ actionId: "lido.submit",
636
+ protocolId: "lido",
637
+ chainCategory: "evm",
638
+ description: "Build mpc-auth multiSignRequest for Lido ETH stake (submit).",
639
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
640
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
641
+ handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoSubmit" },
642
+ inputZod: mcpLidoSubmitInputSchema
643
+ }),
644
+ defineProtocolMcpTool({
645
+ name: "ctm_lido_build_request_withdrawals_multisign",
646
+ actionId: "lido.request-withdrawals",
647
+ protocolId: "lido",
648
+ chainCategory: "evm",
649
+ description: "Build batch for Lido withdrawal queue (approve + requestWithdrawals).",
650
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
651
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
652
+ handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoRequestWithdrawals" },
653
+ inputZod: mcpLidoRequestWithdrawalsInputSchema
654
+ }),
655
+ defineProtocolMcpTool({
656
+ name: "ctm_lido_build_claim_withdrawal_multisign",
657
+ actionId: "lido.claim-withdrawal",
658
+ protocolId: "lido",
659
+ chainCategory: "evm",
660
+ description: "Build tx for Lido claimWithdrawal.",
661
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
662
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
663
+ handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoClaimWithdrawal" },
664
+ inputZod: mcpLidoClaimWithdrawalInputSchema
665
+ }),
666
+ defineProtocolMcpTool({
667
+ name: "ctm_lido_build_wrap_steth_multisign",
668
+ actionId: "lido.wrap-steth",
669
+ protocolId: "lido",
670
+ chainCategory: "evm",
671
+ description: "Build batch for wstETH wrap.",
672
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
673
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
674
+ handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoWrapStEth" },
675
+ inputZod: mcpLidoWrapStEthInputSchema
676
+ }),
677
+ defineProtocolMcpTool({
678
+ name: "ctm_lido_build_unwrap_wsteth_multisign",
679
+ actionId: "lido.unwrap-wsteth",
680
+ protocolId: "lido",
681
+ chainCategory: "evm",
682
+ description: "Build tx for wstETH unwrap.",
683
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
684
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
685
+ handler: { importPath: "protocols/evm/lido", exportName: "buildEvmMultisignBodyLidoUnwrapWstEth" },
686
+ inputZod: mcpLidoUnwrapWstEthInputSchema
687
+ }),
688
+ defineProtocolMcpTool({
689
+ name: "ctm_ethena_build_stake_multisign",
690
+ actionId: "ethena.stake-usde",
691
+ protocolId: "ethena",
692
+ chainCategory: "evm",
693
+ description: "Build batch: USDe approve + sUSDe deposit.",
694
+ prerequisites: ["keyGen", "executorAddress", "Ethereum mainnet RPC"],
695
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
696
+ handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaUsdeStakeToSusde" },
697
+ inputZod: mcpEthenaStakeInputSchema
698
+ }),
699
+ defineProtocolMcpTool({
700
+ name: "ctm_ethena_build_redeem_multisign",
701
+ actionId: "ethena.redeem-susde",
702
+ protocolId: "ethena",
703
+ chainCategory: "evm",
704
+ description: "Build sUSDe redeem when cooldown is off.",
705
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
706
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
707
+ handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaSusdeRedeemToUsde" },
708
+ inputZod: mcpEthenaRedeemInputSchema
709
+ }),
710
+ defineProtocolMcpTool({
711
+ name: "ctm_ethena_build_cooldown_multisign",
712
+ actionId: "ethena.cooldown-shares",
713
+ protocolId: "ethena",
714
+ chainCategory: "evm",
715
+ description: "Build sUSDe cooldownShares batch step.",
716
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
717
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
718
+ handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaSusdeCooldownShares" },
719
+ inputZod: mcpEthenaCooldownInputSchema
720
+ }),
721
+ defineProtocolMcpTool({
722
+ name: "ctm_ethena_build_claim_multisign",
723
+ actionId: "ethena.claim-unstake",
724
+ protocolId: "ethena",
725
+ chainCategory: "evm",
726
+ description: "Build unstake claim after cooldown.",
727
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
728
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
729
+ handler: { importPath: "protocols/evm/ethena", exportName: "buildEvmMultisignBodyEthenaUnstakeClaim" },
730
+ inputZod: mcpEthenaClaimInputSchema
731
+ }),
732
+ defineProtocolMcpTool({
733
+ name: "ctm_maple_build_deposit_multisign",
734
+ actionId: "maple-syrup.deposit",
735
+ protocolId: "maple-syrup",
736
+ chainCategory: "evm",
737
+ description: "Build Maple Syrup router deposit batch.",
738
+ prerequisites: ["keyGen", "executorAddress", "router + pool addresses"],
739
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
740
+ handler: { importPath: "protocols/evm/maple", exportName: "buildEvmMultisignBodyMapleSyrupDeposit" },
741
+ inputZod: mcpMapleDepositInputSchema
742
+ }),
743
+ defineProtocolMcpTool({
744
+ name: "ctm_maple_build_request_redeem_multisign",
745
+ actionId: "maple-syrup.request-redeem",
746
+ protocolId: "maple-syrup",
747
+ chainCategory: "evm",
748
+ description: "Build Maple PoolV2 requestRedeem batch.",
749
+ prerequisites: ["keyGen", "executorAddress", "pool address"],
750
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
751
+ handler: { importPath: "protocols/evm/maple", exportName: "buildEvmMultisignBodyMaplePoolRequestRedeem" },
752
+ inputZod: mcpMapleRequestRedeemInputSchema
753
+ }),
754
+ defineProtocolMcpTool({
755
+ name: "ctm_sky_build_lockstake_stake_multisign",
756
+ actionId: "sky.lockstake-stake",
757
+ protocolId: "sky",
758
+ chainCategory: "evm",
759
+ description: "Build Sky Lockstake open/stake batch.",
760
+ prerequisites: ["keyGen", "executorAddress", "Ethereum mainnet RPC"],
761
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
762
+ handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeStakePositionBatch" },
763
+ inputZod: mcpSkyLockstakeStakeInputSchema
764
+ }),
765
+ defineProtocolMcpTool({
766
+ name: "ctm_sky_build_lockstake_draw_multisign",
767
+ actionId: "sky.lockstake-draw",
768
+ protocolId: "sky",
769
+ chainCategory: "evm",
770
+ description: "Build Lockstake draw (borrow USDS).",
771
+ prerequisites: ["keyGen", "executorAddress", "open urn"],
772
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
773
+ handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeDrawBatch" },
774
+ inputZod: mcpSkyLockstakeDrawInputSchema
775
+ }),
776
+ defineProtocolMcpTool({
777
+ name: "ctm_sky_build_lockstake_wipe_multisign",
778
+ actionId: "sky.lockstake-wipe",
779
+ protocolId: "sky",
780
+ chainCategory: "evm",
781
+ description: "Build Lockstake repay/wipe batch.",
782
+ prerequisites: ["keyGen", "executorAddress", "urn index"],
783
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
784
+ handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeWipeBatch" },
785
+ inputZod: mcpSkyLockstakeWipeInputSchema
786
+ }),
787
+ defineProtocolMcpTool({
788
+ name: "ctm_sky_build_lockstake_close_multisign",
789
+ actionId: "sky.lockstake-close",
790
+ protocolId: "sky",
791
+ chainCategory: "evm",
792
+ description: "Build Lockstake close position batch.",
793
+ prerequisites: ["keyGen", "executorAddress", "urn index"],
794
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
795
+ handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeCloseBatch" },
796
+ inputZod: mcpSkyLockstakeCloseInputSchema
797
+ }),
798
+ defineProtocolMcpTool({
799
+ name: "ctm_sky_build_lockstake_get_reward_multisign",
800
+ actionId: "sky.lockstake-get-reward",
801
+ protocolId: "sky",
802
+ chainCategory: "evm",
803
+ description: "Build Lockstake getReward batch.",
804
+ prerequisites: ["keyGen", "executorAddress", "urn index"],
805
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
806
+ handler: { importPath: "protocols/evm/sky", exportName: "buildSkyLockstakeGetRewardBatch" },
807
+ inputZod: mcpSkyLockstakeGetRewardInputSchema
808
+ }),
809
+ defineProtocolMcpTool({
810
+ name: "ctm_sky_build_susds_deposit_multisign",
811
+ actionId: "sky.susds-deposit",
812
+ protocolId: "sky",
813
+ chainCategory: "evm",
814
+ description: "Build USDS \u2192 sUSDS ERC-4626 deposit batch.",
815
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
816
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
817
+ handler: { importPath: "protocols/evm/sky", exportName: "buildSkySusdsDepositFromUsdsBatch" },
818
+ inputZod: mcpSkySusdsDepositInputSchema
819
+ }),
820
+ defineProtocolMcpTool({
821
+ name: "ctm_sky_build_susds_redeem_multisign",
822
+ actionId: "sky.susds-redeem",
823
+ protocolId: "sky",
824
+ chainCategory: "evm",
825
+ description: "Build sUSDS redeem to USDS batch.",
826
+ prerequisites: ["keyGen", "executorAddress", "RPC URL"],
827
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
828
+ handler: { importPath: "protocols/evm/sky", exportName: "buildSkySusdsRedeemToUsdsBatch" },
829
+ inputZod: mcpSkySusdsRedeemInputSchema
830
+ }),
831
+ defineProtocolMcpTool({
832
+ name: "ctm_aave_v4_build_deposit_multisign",
833
+ actionId: "aave-v4.deposit",
834
+ protocolId: "aave-v4",
835
+ chainCategory: "evm",
836
+ description: "Build Aave v4 Spoke supply/deposit batch.",
837
+ prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
838
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
839
+ handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4DepositBatch" },
840
+ inputZod: mcpAaveV4DepositInputSchema
841
+ }),
842
+ defineProtocolMcpTool({
843
+ name: "ctm_aave_v4_build_withdraw_multisign",
844
+ actionId: "aave-v4.withdraw",
845
+ protocolId: "aave-v4",
846
+ chainCategory: "evm",
847
+ description: "Build Aave v4 Spoke withdraw batch.",
848
+ prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
849
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
850
+ handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4SpokeWithdraw" },
851
+ inputZod: mcpAaveV4WithdrawInputSchema
852
+ }),
853
+ defineProtocolMcpTool({
854
+ name: "ctm_aave_v4_build_borrow_multisign",
855
+ actionId: "aave-v4.borrow",
856
+ protocolId: "aave-v4",
857
+ chainCategory: "evm",
858
+ description: "Build Aave v4 Spoke borrow batch.",
859
+ prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
860
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
861
+ handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4SpokeBorrow" },
862
+ inputZod: mcpAaveV4BorrowInputSchema
863
+ }),
864
+ defineProtocolMcpTool({
865
+ name: "ctm_aave_v4_build_repay_multisign",
866
+ actionId: "aave-v4.repay",
867
+ protocolId: "aave-v4",
868
+ chainCategory: "evm",
869
+ description: "Build Aave v4 Spoke repay batch.",
870
+ prerequisites: ["keyGen", "executorAddress", "spoke + underlying"],
871
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
872
+ handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4SpokeRepay" },
873
+ inputZod: mcpAaveV4RepayInputSchema
874
+ }),
875
+ defineProtocolMcpTool({
876
+ name: "ctm_euler_v2_build_isolated_lend_multisign",
877
+ actionId: "euler-v2.isolated-lend",
878
+ protocolId: "euler-v2",
879
+ chainCategory: "evm",
880
+ description: "Build Euler v2 vault deposit/lend batch.",
881
+ prerequisites: ["keyGen", "executorAddress", "vault address"],
882
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
883
+ handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2IsolatedLendDepositBatch" },
884
+ inputZod: mcpEulerV2IsolatedLendInputSchema
885
+ }),
886
+ defineProtocolMcpTool({
887
+ name: "ctm_euler_v2_build_isolated_borrow_multisign",
888
+ actionId: "euler-v2.isolated-borrow",
889
+ protocolId: "euler-v2",
890
+ chainCategory: "evm",
891
+ description: "Build Euler v2 isolated borrow loop batch.",
892
+ prerequisites: ["keyGen", "executorAddress", "vault + collateral"],
893
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
894
+ handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2IsolatedBorrowBatch" },
895
+ inputZod: mcpEulerV2IsolatedBorrowInputSchema
896
+ }),
897
+ defineProtocolMcpTool({
898
+ name: "ctm_euler_v2_build_vault_withdraw_multisign",
899
+ actionId: "euler-v2.vault-withdraw",
900
+ protocolId: "euler-v2",
901
+ chainCategory: "evm",
902
+ description: "Build Euler v2 vault withdraw/redeem batch.",
903
+ prerequisites: ["keyGen", "executorAddress", "vault address"],
904
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
905
+ handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2VaultWithdraw" },
906
+ inputZod: mcpEulerV2VaultWithdrawInputSchema
907
+ }),
908
+ defineProtocolMcpTool({
909
+ name: "ctm_euler_v2_build_borrow_repay_multisign",
910
+ actionId: "euler-v2.borrow-repay",
911
+ protocolId: "euler-v2",
912
+ chainCategory: "evm",
913
+ description: "Build Euler v2 borrow repay batch.",
914
+ prerequisites: ["keyGen", "executorAddress", "vault address"],
915
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
916
+ handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2BorrowRepayBatch" },
917
+ inputZod: mcpEulerV2BorrowRepayInputSchema
918
+ }),
919
+ defineProtocolMcpTool({
920
+ name: "ctm_euler_v2_build_collateral_deposit_multisign",
921
+ actionId: "euler-v2.collateral-deposit",
922
+ protocolId: "euler-v2",
923
+ chainCategory: "evm",
924
+ description: "Build Euler v2 borrow collateral deposit batch.",
925
+ prerequisites: ["keyGen", "executorAddress", "vault + collateral asset"],
926
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
927
+ handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2BorrowCollateralDepositBatch" },
928
+ inputZod: mcpEulerV2CollateralDepositInputSchema
929
+ }),
930
+ defineProtocolMcpTool({
931
+ name: "ctm_euler_v2_build_collateral_withdraw_multisign",
932
+ actionId: "euler-v2.collateral-withdraw",
933
+ protocolId: "euler-v2",
934
+ chainCategory: "evm",
935
+ description: "Build Euler v2 borrow collateral withdraw batch.",
936
+ prerequisites: ["keyGen", "executorAddress", "vault + collateral asset"],
937
+ followUp: ["Sign messageToSign", "POST /multiSignRequest"],
938
+ handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2BorrowCollateralWithdrawBatch" },
939
+ inputZod: mcpEulerV2CollateralWithdrawInputSchema
940
+ })
941
+ ];
942
+
943
+ // src/agent/mcpTools.ts
944
+ function defineMcpTool(def) {
945
+ return {
946
+ ...def,
947
+ inputSchema: zodSchemaToMcpJsonSchema(def.inputZod),
948
+ outputSchema: zodSchemaToMcpJsonSchema(def.outputZod),
949
+ parseInput: (data) => def.inputZod.parse(data),
950
+ parseOutput: (data) => def.outputZod.parse(data)
951
+ };
952
+ }
953
+ var CORE_MCP_TOOL_DEFINITIONS = [
954
+ defineMcpTool({
313
955
  name: "ctm_uniswap_v4_quote",
314
956
  actionId: "uniswap-v4.quote",
315
957
  protocolId: "uniswap-v4",
@@ -318,33 +960,10 @@ var MCP_TOOL_DEFINITIONS = [
318
960
  prerequisites: ["Chain must be supported by Uniswap V4 (Universal Router map)."],
319
961
  followUp: ["ctm_uniswap_v4_create_swap", "ctm_uniswap_v4_build_swap_multisign"],
320
962
  handler: { importPath: "protocols/evm/uniswap-v4", exportName: "uniswapTradeQuote" },
321
- inputSchema: {
322
- type: "object",
323
- properties: paramProperties({
324
- type: { type: "string", required: true, description: "EXACT_INPUT or EXACT_OUTPUT" },
325
- amount: { type: "string", required: true, description: "Amount in token-in base units (wei string for ERC-20)" },
326
- tokenIn: { type: "address", required: true, description: "Input token; 0x0 for native ETH" },
327
- tokenOut: { type: "address", required: true, description: "Output token address" },
328
- chainId: { type: "number", required: true, description: "tokenInChainId / same-chain default" },
329
- uniswapApiKey: { type: "string", required: true, description: "Uniswap Trade API x-api-key" },
330
- swapper: { type: "address", required: false, description: "MPC executor; omit if keyGen + managementNodeUrl provided" },
331
- slippage: { type: "number", required: false, description: "Slippage percent; omit for API auto slippage" }
332
- }),
333
- required: requiredKeys({
334
- type: { type: "string", required: true, description: "" },
335
- amount: { type: "string", required: true, description: "" },
336
- tokenIn: { type: "address", required: true, description: "" },
337
- tokenOut: { type: "address", required: true, description: "" },
338
- chainId: { type: "number", required: true, description: "" },
339
- uniswapApiKey: { type: "string", required: true, description: "" }
340
- })
341
- },
342
- outputSchema: {
343
- type: "object",
344
- description: "Full Uniswap POST /quote JSON (includes nested quote object with input/output amounts)."
345
- }
346
- },
347
- {
963
+ inputZod: mcpUniswapV4QuoteInputSchema,
964
+ outputZod: mcpUniswapV4QuoteOutputSchema
965
+ }),
966
+ defineMcpTool({
348
967
  name: "ctm_uniswap_v4_create_swap",
349
968
  actionId: "uniswap-v4.create-swap",
350
969
  protocolId: "uniswap-v4",
@@ -353,33 +972,10 @@ var MCP_TOOL_DEFINITIONS = [
353
972
  prerequisites: ["ctm_uniswap_v4_quote output (fullQuoteFromPermit)"],
354
973
  followUp: ["ctm_uniswap_v4_build_swap_multisign"],
355
974
  handler: { importPath: "protocols/evm/uniswap-v4", exportName: "uniswapCreateSwap" },
356
- inputSchema: {
357
- type: "object",
358
- properties: paramProperties({
359
- uniswapApiKey: { type: "string", required: true, description: "Uniswap Trade API key" },
360
- fullQuoteFromPermit: { type: "object", required: true, description: "Full quote JSON from ctm_uniswap_v4_quote" },
361
- swapTransactionDeadlineUnix: {
362
- type: "number",
363
- required: false,
364
- description: "On-chain deadline unix seconds; default ~30 min from now"
365
- },
366
- useServerProxy: {
367
- type: "boolean",
368
- required: false,
369
- description: "Set false in Node/agents; true only in browser via Next API route"
370
- }
371
- }),
372
- required: requiredKeys({
373
- uniswapApiKey: { type: "string", required: true, description: "" },
374
- fullQuoteFromPermit: { type: "object", required: true, description: "" }
375
- })
376
- },
377
- outputSchema: {
378
- type: "object",
379
- description: "{ swap: TransactionRequest, requestId?, gasFee? }"
380
- }
381
- },
382
- {
975
+ inputZod: mcpUniswapV4CreateSwapInputSchema,
976
+ outputZod: mcpUniswapV4CreateSwapOutputSchema
977
+ }),
978
+ defineMcpTool({
383
979
  name: "ctm_uniswap_v4_build_swap_multisign",
384
980
  actionId: "uniswap-v4.swap-exact-input",
385
981
  protocolId: "uniswap-v4",
@@ -393,33 +989,10 @@ var MCP_TOOL_DEFINITIONS = [
393
989
  ],
394
990
  followUp: ["Sign messageToSign", "POST /multiSignRequest with clientSig and signedMessage"],
395
991
  handler: { importPath: "protocols/evm/uniswap-v4", exportName: "buildEvmMultisignBodyUniswapV4SkipPermit2Batch" },
396
- inputSchema: {
397
- type: "object",
398
- properties: paramProperties(
399
- {
400
- tokenIn: { type: "address", required: true, description: "Token in; 0x0 for native ETH" },
401
- swap: { type: "object", required: true, description: "swap field from create_swap response" },
402
- createSwapResponse: { type: "object", required: true, description: "Full create_swap response" },
403
- fullQuoteSnapshot: { type: "object", required: true, description: "Quote JSON used for the swap" },
404
- swapDeadlineUnix: { type: "number", required: true, description: "Same deadline passed to create_swap" },
405
- slippagePercent: { type: "number", required: false, description: "Extra approve headroom for EXACT_OUTPUT" }
406
- },
407
- ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail", "customGasChainDetails"]
408
- ),
409
- required: requiredKeys(
410
- {
411
- tokenIn: { type: "address", required: true, description: "" },
412
- swap: { type: "object", required: true, description: "" },
413
- createSwapResponse: { type: "object", required: true, description: "" },
414
- fullQuoteSnapshot: { type: "object", required: true, description: "" },
415
- swapDeadlineUnix: { type: "number", required: true, description: "" }
416
- },
417
- ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail"]
418
- )
419
- },
420
- outputSchema: multisignOutputSchema
421
- },
422
- {
992
+ inputZod: mcpUniswapV4BuildSwapMultisignInputSchema,
993
+ outputZod: multisignOutputSchema
994
+ }),
995
+ defineMcpTool({
423
996
  name: "ctm_curve_dao_build_swap_multisign",
424
997
  actionId: "curve-dao.swap",
425
998
  protocolId: "curve-dao",
@@ -428,36 +1001,45 @@ var MCP_TOOL_DEFINITIONS = [
428
1001
  prerequisites: ["keyGen", "executorAddress", "tokenIn/tokenOut/amountHuman/slippage", "RPC URL"],
429
1002
  followUp: ["Sign messageToSign", "POST /multiSignRequest with clientSig and signedMessage"],
430
1003
  handler: { importPath: "protocols/evm/curve-dao", exportName: "buildEvmMultisignBodyCurveDaoBatch" },
431
- inputSchema: {
432
- type: "object",
433
- properties: paramProperties(
434
- {
435
- tokenIn: { type: "address", required: true, description: "ERC-20 sold (native in uses WETH path in UI)" },
436
- tokenOut: { type: "string", required: true, description: "Output token or 0xeeee\u2026 native placeholder" },
437
- amountHuman: { type: "string", required: true, description: "Human-readable amount of tokenIn" },
438
- slippagePercent: { type: "number", required: true, description: "Slippage 0\u2013100 exclusive" }
439
- },
440
- ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail", "customGasChainDetails"]
441
- ),
442
- required: requiredKeys(
443
- {
444
- tokenIn: { type: "address", required: true, description: "" },
445
- tokenOut: { type: "string", required: true, description: "" },
446
- amountHuman: { type: "string", required: true, description: "" },
447
- slippagePercent: { type: "number", required: true, description: "" }
448
- },
449
- ["keyGen", "purposeText", "useCustomGas", "chainId", "rpcUrl", "executorAddress", "chainDetail"]
450
- )
451
- },
452
- outputSchema: multisignOutputSchema
453
- }
1004
+ inputZod: mcpCurveDaoBuildSwapMultisignInputSchema,
1005
+ outputZod: multisignOutputSchema
1006
+ })
1007
+ ];
1008
+ var MCP_TOOL_DEFINITIONS = [
1009
+ ...CORE_MCP_TOOL_DEFINITIONS,
1010
+ ...MCP_PROTOCOL_TOOL_DEFINITIONS
454
1011
  ];
1012
+ function buildToolSchemaMap(kind) {
1013
+ const out = {};
1014
+ for (const tool of MCP_TOOL_DEFINITIONS) {
1015
+ out[tool.name] = kind === "input" ? tool.inputZod : tool.outputZod;
1016
+ }
1017
+ return out;
1018
+ }
1019
+ var MCP_TOOL_INPUT_SCHEMAS = buildToolSchemaMap("input");
1020
+ var MCP_TOOL_OUTPUT_SCHEMAS = buildToolSchemaMap("output");
455
1021
  function getMcpToolDefinitions() {
456
1022
  return MCP_TOOL_DEFINITIONS;
457
1023
  }
458
1024
  function getMcpToolByName(name) {
459
1025
  return MCP_TOOL_DEFINITIONS.find((t) => t.name === name);
460
1026
  }
1027
+ function getMcpToolInputSchema(name) {
1028
+ const schema = MCP_TOOL_INPUT_SCHEMAS[name];
1029
+ if (!schema) throw new Error(`Unknown MCP tool: ${name}`);
1030
+ return schema;
1031
+ }
1032
+ function getMcpToolOutputSchema(name) {
1033
+ const schema = MCP_TOOL_OUTPUT_SCHEMAS[name];
1034
+ if (!schema) throw new Error(`Unknown MCP tool: ${name}`);
1035
+ return schema;
1036
+ }
1037
+ function parseMcpToolInput(name, data) {
1038
+ return getMcpToolInputSchema(name).parse(data);
1039
+ }
1040
+ function parseMcpToolOutput(name, data) {
1041
+ return getMcpToolOutputSchema(name).parse(data);
1042
+ }
461
1043
  function getAgentCatalogForMcp() {
462
1044
  return {
463
1045
  tools: MCP_TOOL_DEFINITIONS,
@@ -465,6 +1047,9 @@ function getAgentCatalogForMcp() {
465
1047
  commonParams: EVM_COMMON_PARAM_DOCS,
466
1048
  multisignOutput: MULTISIGN_OUTPUT_DOC,
467
1049
  managementSig: MANAGEMENT_SIG_DOC,
1050
+ /** Zod schemas for MCP tool I/O — source of truth for continuum-mcp-server validation. */
1051
+ inputSchemas: MCP_TOOL_INPUT_SCHEMAS,
1052
+ outputSchemas: MCP_TOOL_OUTPUT_SCHEMAS,
468
1053
  workflow: {
469
1054
  evmSwapTypical: [
470
1055
  "1. Quote (protocol-specific API if needed)",
@@ -478,15 +1063,606 @@ function getAgentCatalogForMcp() {
478
1063
  "2. GET /getPublicMgtKeyNonce or /getNodeMgtKeyNonce \u2192 nonce",
479
1064
  "3. buildManagementPostBody(nonce, nodeKey, { \u2026endpoint fields })",
480
1065
  "4. messageToSignManagementBody(body) \u2192 sign \u2192 withManagementClientSig(body, sig)",
481
- "5. POST management route with signed body"
1066
+ "5. POST management route with signed body (no signedMessage field except configUpdateImplement opaque line)"
1067
+ ],
1068
+ agentMultisignTypical: [
1069
+ "1. load_defi_protocol for the target protocol",
1070
+ "2. get_defi_protocol_supported_chains / get_token_registry to pick chainId and tokens",
1071
+ "3. MCP build_* tool with keyGenId + chainId \u2192 { requestId }",
1072
+ "4. Base MCP: wait_for_sign_request_ready \u2192 sign_request_agree \u2192 trigger_sign_result \u2192 broadcast_sign_result"
482
1073
  ]
483
1074
  }
484
1075
  };
485
1076
  }
1077
+ getAddress(
1078
+ "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84"
1079
+ );
1080
+ getAddress(
1081
+ "0x7f39C581F595B853cBbF37C12FfeeA971C5a5bEa"
1082
+ );
1083
+ getAddress("0x889edC2eDab5f40e902b864aD4d7AdE8E412F9B1");
1084
+ var LIDO_ETHEREUM_MAINNET_CHAIN_ID = 1;
1085
+
1086
+ // src/protocols/evm/lido/index.ts
1087
+ var LIDO_PROTOCOL_ID = "lido";
1088
+ var lidoProtocolModule = {
1089
+ id: LIDO_PROTOCOL_ID,
1090
+ chainCategory: "evm",
1091
+ isChainSupported(ctx) {
1092
+ if (ctx.chainCategory !== "evm") return false;
1093
+ return Number(ctx.chainId) === LIDO_ETHEREUM_MAINNET_CHAIN_ID;
1094
+ },
1095
+ isTokenSupported(token) {
1096
+ return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
1097
+ },
1098
+ actions: [
1099
+ { id: "lido.submit", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Stake ETH via Lido submit()", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: { valueWei: { type: "string", required: true, description: "ETH to stake (wei string)" } } },
1100
+ { id: "lido.request-withdrawals", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Queue stETH withdrawal", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1101
+ { id: "lido.claim-withdrawal", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Claim finalized withdrawal", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1102
+ { id: "lido.wrap-steth", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Wrap stETH to wstETH", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1103
+ { id: "lido.unwrap-wsteth", protocolId: LIDO_PROTOCOL_ID, chainCategory: "evm", description: "Unwrap wstETH to stETH", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
1104
+ ]
1105
+ };
1106
+ registerProtocolModule(lidoProtocolModule);
1107
+ var USDE_ETHEREUM_MAINNET = "0x4c9edd5852cd905f086c759e8383e09bff1e68b3";
1108
+ var SUSDE_ETHEREUM_MAINNET = "0x9d39a5de30e57443bff2a8307a4256c8797a3497";
1109
+ var USDE_MOST_L2S = "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34";
1110
+ var USDE_ZKSYNC_ERA = "0x39Fe7a0DACcE31Bd90418e3e659fb0b5f0B3Db0d";
1111
+ var L2_SAME_ADDRESS_CHAIN_IDS = /* @__PURE__ */ new Set([
1112
+ 42161,
1113
+ // Arbitrum One
1114
+ 10,
1115
+ // Optimism
1116
+ 8453,
1117
+ // Base
1118
+ 56,
1119
+ // BNB Chain
1120
+ 59144,
1121
+ // Linea
1122
+ 5e3,
1123
+ // Mantle
1124
+ 81457,
1125
+ // Blast
1126
+ 169,
1127
+ // Manta Pacific
1128
+ 534352,
1129
+ // Scroll
1130
+ 252,
1131
+ // Fraxtal
1132
+ 34443,
1133
+ // Mode
1134
+ 196,
1135
+ // X Layer
1136
+ 1088,
1137
+ // Metis
1138
+ 80084,
1139
+ // Berachain
1140
+ 2222,
1141
+ // Kava
1142
+ 2818,
1143
+ // Morph
1144
+ 1923,
1145
+ // Swell
1146
+ 48900
1147
+ // Zircuit
1148
+ ]);
1149
+ var FALLBACK_NAME_BY_ID = {
1150
+ 1: "Ethereum",
1151
+ 42161: "Arbitrum One",
1152
+ 10: "Optimism",
1153
+ 8453: "Base",
1154
+ 56: "BNB Chain",
1155
+ 59144: "Linea",
1156
+ 5e3: "Mantle",
1157
+ 81457: "Blast",
1158
+ 169: "Manta Pacific",
1159
+ 534352: "Scroll",
1160
+ 252: "Fraxtal",
1161
+ 34443: "Mode",
1162
+ 196: "X Layer",
1163
+ 1088: "Metis",
1164
+ 80084: "Berachain",
1165
+ 2222: "Kava",
1166
+ 2818: "Morph",
1167
+ 1923: "Swell",
1168
+ 48900: "Zircuit",
1169
+ 324: "ZKSync Era"
1170
+ };
1171
+ function usdeTokenAddressOnEvmChain(chainId) {
1172
+ if (chainId === 1) return USDE_ETHEREUM_MAINNET;
1173
+ if (chainId === 324) return USDE_ZKSYNC_ERA;
1174
+ if (L2_SAME_ADDRESS_CHAIN_IDS.has(chainId)) return USDE_MOST_L2S;
1175
+ return null;
1176
+ }
1177
+ function listEthenaUsdeEvmNetworkRows() {
1178
+ const rows = [
1179
+ { chainId: 1, label: FALLBACK_NAME_BY_ID[1], usde: USDE_ETHEREUM_MAINNET }
1180
+ ];
1181
+ const l2 = [...L2_SAME_ADDRESS_CHAIN_IDS].sort((a, b) => a - b);
1182
+ for (const id of l2) {
1183
+ rows.push({
1184
+ chainId: id,
1185
+ label: FALLBACK_NAME_BY_ID[id] ?? `Chain ${id}`,
1186
+ usde: USDE_MOST_L2S
1187
+ });
1188
+ }
1189
+ rows.push({ chainId: 324, label: FALLBACK_NAME_BY_ID[324], usde: USDE_ZKSYNC_ERA });
1190
+ return rows.sort((a, b) => {
1191
+ if (a.chainId === 1) return -1;
1192
+ if (b.chainId === 1) return 1;
1193
+ return a.chainId - b.chainId;
1194
+ });
1195
+ }
1196
+ function isEvmChainInEthenaUsdeList(chainId) {
1197
+ return usdeTokenAddressOnEvmChain(chainId) != null;
1198
+ }
1199
+
1200
+ // src/protocols/evm/ethena/index.ts
1201
+ var ETHENA_PROTOCOL_ID = "ethena";
1202
+ var ethenaProtocolModule = {
1203
+ id: ETHENA_PROTOCOL_ID,
1204
+ chainCategory: "evm",
1205
+ isChainSupported(ctx) {
1206
+ if (ctx.chainCategory !== "evm") return false;
1207
+ const n = typeof ctx.chainId === "number" ? ctx.chainId : Number.parseInt(String(ctx.chainId), 10);
1208
+ return isEvmChainInEthenaUsdeList(n);
1209
+ },
1210
+ isTokenSupported(token) {
1211
+ return token.category === "evm" && token.kind === "erc20";
1212
+ },
1213
+ actions: [
1214
+ { id: "ethena.stake-usde", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Stake USDe \u2192 sUSDe", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: { amountHuman: { type: "string", required: true, description: "USDe amount" } } },
1215
+ { id: "ethena.redeem-susde", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Redeem sUSDe \u2192 USDe (no cooldown)", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1216
+ { id: "ethena.cooldown-shares", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Start sUSDe cooldown", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1217
+ { id: "ethena.claim-unstake", protocolId: ETHENA_PROTOCOL_ID, chainCategory: "evm", description: "Claim after cooldown", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
1218
+ ]
1219
+ };
1220
+ registerProtocolModule(ethenaProtocolModule);
1221
+
1222
+ // src/protocols/evm/maple/constants.ts
1223
+ function isMapleSyrupSupportedChain(chainId) {
1224
+ return chainId === 1 || chainId === 11155111;
1225
+ }
1226
+
1227
+ // src/protocols/evm/maple/index.ts
1228
+ var MAPLE_PROTOCOL_ID = "maple-syrup";
1229
+ var mapleProtocolModule = {
1230
+ id: MAPLE_PROTOCOL_ID,
1231
+ chainCategory: "evm",
1232
+ isChainSupported(ctx) {
1233
+ if (ctx.chainCategory !== "evm") return false;
1234
+ const n = typeof ctx.chainId === "number" ? ctx.chainId : Number.parseInt(String(ctx.chainId), 10);
1235
+ return isMapleSyrupSupportedChain(n);
1236
+ },
1237
+ isTokenSupported(token) {
1238
+ return token.category === "evm" && token.kind === "erc20";
1239
+ },
1240
+ actions: [
1241
+ { id: "maple-syrup.deposit", protocolId: MAPLE_PROTOCOL_ID, chainCategory: "evm", description: "Deposit into Maple Syrup pool", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1242
+ { id: "maple-syrup.request-redeem", protocolId: MAPLE_PROTOCOL_ID, chainCategory: "evm", description: "Request redeem from pool", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
1243
+ ]
1244
+ };
1245
+ registerProtocolModule(mapleProtocolModule);
1246
+
1247
+ // src/protocols/evm/sky/mainnet.ts
1248
+ var SKY_ETHEREUM_MAINNET_CHAIN_ID = 1;
1249
+
1250
+ // src/protocols/evm/sky/index.ts
1251
+ var SKY_PROTOCOL_ID = "sky";
1252
+ var skyProtocolModule = {
1253
+ id: SKY_PROTOCOL_ID,
1254
+ chainCategory: "evm",
1255
+ isChainSupported(ctx) {
1256
+ if (ctx.chainCategory !== "evm") return false;
1257
+ return Number(ctx.chainId) === SKY_ETHEREUM_MAINNET_CHAIN_ID;
1258
+ },
1259
+ isTokenSupported(token) {
1260
+ return token.category === "evm" && token.kind === "erc20";
1261
+ },
1262
+ actions: [
1263
+ { id: "sky.lockstake-stake", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Open Lockstake position", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1264
+ { id: "sky.lockstake-draw", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Borrow USDS from Lockstake", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1265
+ { id: "sky.lockstake-wipe", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Repay Lockstake debt", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1266
+ { id: "sky.lockstake-close", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Close Lockstake position", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1267
+ { id: "sky.susds-deposit", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Deposit USDS into sUSDS vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1268
+ { id: "sky.susds-redeem", protocolId: SKY_PROTOCOL_ID, chainCategory: "evm", description: "Redeem sUSDS to USDS", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
1269
+ ]
1270
+ };
1271
+ registerProtocolModule(skyProtocolModule);
1272
+ var AAVE_V4_GRAPHQL_URL = "https://api.v4.aave.com/graphql";
1273
+ async function aaveV4Gql(query, variables) {
1274
+ const r = await fetch(AAVE_V4_GRAPHQL_URL, {
1275
+ method: "POST",
1276
+ headers: { "content-type": "application/json" },
1277
+ body: JSON.stringify({ query, variables: variables ?? {} })
1278
+ });
1279
+ if (!r.ok) {
1280
+ const t = await r.text().catch(() => "");
1281
+ throw new Error(t ? `Aave V4 API HTTP ${r.status}: ${t.slice(0, 200)}` : `Aave V4 API HTTP ${r.status}`);
1282
+ }
1283
+ const j = await r.json();
1284
+ if (j.errors?.length) {
1285
+ const msg = j.errors.map((e) => e.message ?? "Unknown").join("; ");
1286
+ throw new Error(msg);
1287
+ }
1288
+ if (j.data == null) {
1289
+ throw new Error("Aave V4 API: empty response");
1290
+ }
1291
+ return j.data;
1292
+ }
1293
+ async function fetchAaveV4Chains() {
1294
+ const d = await aaveV4Gql(`
1295
+ query C($c: ChainsRequest!) { chains(request: $c) { chainId name nativeWrappedToken } }
1296
+ `, { c: { query: { filter: "ALL" } } });
1297
+ return d.chains ?? [];
1298
+ }
1299
+ async function loadAaveV4SupportedChainIdsFromV4Api() {
1300
+ const rows = await fetchAaveV4Chains();
1301
+ const s = /* @__PURE__ */ new Set();
1302
+ for (const c of rows) s.add(c.chainId);
1303
+ return s;
1304
+ }
1305
+ var RESERVES_ADDRESS_FRAGMENT = `
1306
+ asset { underlying { address } }
1307
+ `;
1308
+ async function fetchAaveV4NativeWrappedToken(chainId) {
1309
+ const all = await fetchAaveV4Chains();
1310
+ const c = all.find((x) => x.chainId === chainId);
1311
+ const t = (c?.nativeWrappedToken ?? "").trim();
1312
+ if (t && isAddress(t)) return getAddress(t);
1313
+ return null;
1314
+ }
1315
+ async function fetchAaveV4SupportedUnderlyingAddressSet(chainId) {
1316
+ const d = await aaveV4Gql(
1317
+ `
1318
+ query A($r: ReservesRequest!) { reserves(request: $r) { ${RESERVES_ADDRESS_FRAGMENT} } }
1319
+ `,
1320
+ {
1321
+ r: {
1322
+ query: { chainIds: [chainId] },
1323
+ filter: "ALL",
1324
+ orderBy: { supplyApy: "DESC" }
1325
+ }
1326
+ }
1327
+ );
1328
+ const s = /* @__PURE__ */ new Set();
1329
+ for (const r of d.reserves ?? []) {
1330
+ const a = (r.asset?.underlying?.address ?? "").trim();
1331
+ if (a && isAddress(a)) s.add(a.toLowerCase());
1332
+ }
1333
+ return s;
1334
+ }
1335
+ var aaveV4ChainTokenCache = /* @__PURE__ */ new Map();
1336
+ function ensureAaveV4ChainTokenCache(chainId) {
1337
+ const hit = aaveV4ChainTokenCache.get(chainId);
1338
+ if (hit) return hit;
1339
+ const p = (async () => {
1340
+ const [nativeWrapped, supportedUnderlying] = await Promise.all([
1341
+ fetchAaveV4NativeWrappedToken(chainId),
1342
+ fetchAaveV4SupportedUnderlyingAddressSet(chainId)
1343
+ ]);
1344
+ return { supportedUnderlying, nativeWrapped };
1345
+ })();
1346
+ aaveV4ChainTokenCache.set(chainId, p);
1347
+ return p;
1348
+ }
1349
+
1350
+ // src/protocols/evm/aave-v4/index.ts
1351
+ var AAVE_V4_PROTOCOL_ID = "aave-v4";
1352
+ var aaveV4ProtocolModule = {
1353
+ id: AAVE_V4_PROTOCOL_ID,
1354
+ chainCategory: "evm",
1355
+ isChainSupported(ctx) {
1356
+ return ctx.chainCategory === "evm";
1357
+ },
1358
+ isTokenSupported(token) {
1359
+ return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
1360
+ },
1361
+ actions: [
1362
+ { id: "aave-v4.deposit", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Supply to Aave v4 Spoke", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1363
+ { id: "aave-v4.withdraw", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw from Spoke", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1364
+ { id: "aave-v4.borrow", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Borrow from Spoke", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1365
+ { id: "aave-v4.repay", protocolId: AAVE_V4_PROTOCOL_ID, chainCategory: "evm", description: "Repay Spoke debt", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
1366
+ ]
1367
+ };
1368
+ registerProtocolModule(aaveV4ProtocolModule);
1369
+
1370
+ // src/protocols/evm/euler-v2/index.ts
1371
+ var EULER_V2_PROTOCOL_ID = "euler-v2";
1372
+ var eulerV2ProtocolModule = {
1373
+ id: EULER_V2_PROTOCOL_ID,
1374
+ chainCategory: "evm",
1375
+ isChainSupported(ctx) {
1376
+ return ctx.chainCategory === "evm";
1377
+ },
1378
+ isTokenSupported(token) {
1379
+ return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
1380
+ },
1381
+ actions: [
1382
+ { id: "euler-v2.isolated-lend", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Deposit into Euler vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1383
+ { id: "euler-v2.isolated-borrow", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Borrow from Euler vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1384
+ { id: "euler-v2.vault-withdraw", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw from Euler vault", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1385
+ { id: "euler-v2.borrow-repay", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Repay Euler borrow", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1386
+ { id: "euler-v2.collateral-deposit", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Deposit borrow collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} },
1387
+ { id: "euler-v2.collateral-withdraw", protocolId: EULER_V2_PROTOCOL_ID, chainCategory: "evm", description: "Withdraw borrow collateral", commonParams: ["keyGen", "purposeText", "useCustomGas"], params: {} }
1388
+ ]
1389
+ };
1390
+ registerProtocolModule(eulerV2ProtocolModule);
1391
+ var skillsDir = join(dirname(fileURLToPath(import.meta.url)), "skills");
1392
+ var SKILL_PROTOCOL_IDS = [
1393
+ "aave-v4",
1394
+ "lido",
1395
+ "uniswap-v4",
1396
+ "curve-dao",
1397
+ "ethena",
1398
+ "euler-v2",
1399
+ "maple-syrup",
1400
+ "sky"
1401
+ ];
1402
+ function getToolsForProtocol(protocolId) {
1403
+ return MCP_TOOL_DEFINITIONS.filter((t) => t.protocolId === protocolId);
1404
+ }
1405
+ function getProtocolSkill(protocolId) {
1406
+ if (!SKILL_PROTOCOL_IDS.includes(protocolId)) {
1407
+ return void 0;
1408
+ }
1409
+ try {
1410
+ return readFileSync(join(skillsDir, protocolId, "SKILL.md"), "utf8");
1411
+ } catch {
1412
+ return void 0;
1413
+ }
1414
+ }
1415
+ function listProtocolsWithSkills() {
1416
+ return [...SKILL_PROTOCOL_IDS];
1417
+ }
1418
+ function getProtocolDiscoverySummary(protocolId) {
1419
+ const mod = getProtocolModules().find((p) => p.id === protocolId);
1420
+ if (!mod) return void 0;
1421
+ return {
1422
+ protocolId: mod.id,
1423
+ chainCategory: mod.chainCategory,
1424
+ actions: mod.actions.map((a) => ({ id: a.id, description: a.description })),
1425
+ tools: getToolsForProtocol(protocolId).map((t) => ({
1426
+ name: t.name,
1427
+ actionId: t.actionId,
1428
+ description: t.description,
1429
+ prerequisites: t.prerequisites,
1430
+ followUp: t.followUp
1431
+ }))
1432
+ };
1433
+ }
1434
+ var EULER_V2_SUBGRAPH_CHAIN_IDS = [
1435
+ 1,
1436
+ 8453,
1437
+ 42161,
1438
+ 10,
1439
+ 137,
1440
+ 56,
1441
+ 43114,
1442
+ 100,
1443
+ 59144,
1444
+ 146,
1445
+ 1923,
1446
+ 130
1447
+ ];
1448
+ function advisor(protocolId, tokenFilter, impl) {
1449
+ return { protocolId, tokenFilter, ...impl };
1450
+ }
1451
+ var PROTOCOL_SUPPORT_ADVISORS = {
1452
+ "aave-v4": advisor("aave-v4", "api_underlyings", {
1453
+ async supportedChainIds() {
1454
+ const set = await loadAaveV4SupportedChainIdsFromV4Api();
1455
+ return [...set].sort((a, b) => a - b);
1456
+ },
1457
+ async supportedTokens(chainId) {
1458
+ const cache = await ensureAaveV4ChainTokenCache(chainId);
1459
+ const tokens = [...cache.supportedUnderlying].map((address) => ({
1460
+ address,
1461
+ roles: ["underlying"]
1462
+ }));
1463
+ if (cache.nativeWrapped) {
1464
+ tokens.unshift({
1465
+ address: cache.nativeWrapped,
1466
+ symbol: "WETH",
1467
+ roles: ["native_wrapped"]
1468
+ });
1469
+ }
1470
+ return {
1471
+ tokens,
1472
+ nativeWrapped: cache.nativeWrapped ?? void 0,
1473
+ notes: "Native ETH deposits use wrapped native token address from Aave v4 API."
1474
+ };
1475
+ },
1476
+ async isTokenSupported(chainId, address) {
1477
+ const cache = await ensureAaveV4ChainTokenCache(chainId);
1478
+ let normalized;
1479
+ try {
1480
+ normalized = getAddress(address).toLowerCase();
1481
+ } catch {
1482
+ return false;
1483
+ }
1484
+ if (cache.nativeWrapped && getAddress(cache.nativeWrapped).toLowerCase() === normalized) {
1485
+ return true;
1486
+ }
1487
+ return cache.supportedUnderlying.has(normalized);
1488
+ }
1489
+ }),
1490
+ "uniswap-v4": advisor("uniswap-v4", "any_erc20_on_chain", {
1491
+ async supportedChainIds() {
1492
+ const ids = [];
1493
+ for (const id of [
1494
+ 1,
1495
+ 5,
1496
+ 11155111,
1497
+ 137,
1498
+ 80001,
1499
+ 10,
1500
+ 420,
1501
+ 42161,
1502
+ 421613,
1503
+ 42220,
1504
+ 44787,
1505
+ 56,
1506
+ 43114,
1507
+ 84531,
1508
+ 8453,
1509
+ 81457,
1510
+ 7777777,
1511
+ 324,
1512
+ 480,
1513
+ 1301,
1514
+ 130,
1515
+ 10143,
1516
+ 84532,
1517
+ 1868,
1518
+ 143,
1519
+ 59144,
1520
+ 4217,
1521
+ 196
1522
+ ]) {
1523
+ if (isUniswapV4ChainSupported(id)) ids.push(id);
1524
+ }
1525
+ return ids;
1526
+ },
1527
+ async supportedTokens() {
1528
+ return {
1529
+ tokens: [],
1530
+ notes: "Any ERC-20 or native token on a supported chain may be used. Resolve addresses via get_token_registry; tokenOut may be any address."
1531
+ };
1532
+ }
1533
+ }),
1534
+ "curve-dao": advisor("curve-dao", "pool_graph", {
1535
+ async supportedChainIds() {
1536
+ return [1, 10, 56, 100, 137, 146, 196, 250, 252, 324, 999, 1284, 2222, 5e3, 8453, 42161, 42220, 43114, 1313161554];
1537
+ },
1538
+ async supportedTokens(chainId, ctx) {
1539
+ if (!isCurveApiChainSupported(chainId)) {
1540
+ return { tokens: [], notes: "Chain not supported by Curve SDK network constants." };
1541
+ }
1542
+ const rpcUrl = ctx?.rpcUrl?.trim();
1543
+ if (!rpcUrl) {
1544
+ return {
1545
+ tokens: [],
1546
+ notes: "Provide rpcUrl (from get_chain_registry) to load Curve pool graph token list."
1547
+ };
1548
+ }
1549
+ const session = await loadFullCurveSessionForRpc(rpcUrl);
1550
+ if (!session?.swappableNodeKeys?.size) {
1551
+ return { tokens: [], notes: "Curve session returned no swappable tokens for this RPC." };
1552
+ }
1553
+ return {
1554
+ tokens: [...session.swappableNodeKeys].map((key) => {
1555
+ const address = key.startsWith("0x") ? key : key.split(":")[0] ?? key;
1556
+ return { address, roles: ["swappable"] };
1557
+ })
1558
+ };
1559
+ }
1560
+ }),
1561
+ lido: advisor("lido", "mainnet_only", {
1562
+ async supportedChainIds() {
1563
+ return [LIDO_ETHEREUM_MAINNET_CHAIN_ID];
1564
+ },
1565
+ async supportedTokens() {
1566
+ return {
1567
+ tokens: [
1568
+ { address: "0x0000000000000000000000000000000000000000", symbol: "ETH", roles: ["native", "stake"] },
1569
+ { address: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", symbol: "stETH", roles: ["erc20"] },
1570
+ { address: "0x7f39C581F595B853cBbF37C12FfeeA971C5a5bEa", symbol: "wstETH", roles: ["erc20"] }
1571
+ ],
1572
+ notes: "Lido staking and withdrawals are Ethereum mainnet only."
1573
+ };
1574
+ }
1575
+ }),
1576
+ ethena: advisor("ethena", "minting_contract", {
1577
+ async supportedChainIds() {
1578
+ return listEthenaUsdeEvmNetworkRows().map((r) => r.chainId);
1579
+ },
1580
+ async supportedTokens(chainId) {
1581
+ if (chainId === 1) {
1582
+ return {
1583
+ tokens: [
1584
+ { address: USDE_ETHEREUM_MAINNET, symbol: "USDe", roles: ["stake"] },
1585
+ { address: SUSDE_ETHEREUM_MAINNET, symbol: "sUSDe", roles: ["vault"] }
1586
+ ],
1587
+ notes: "Ethena stake/redeem UI actions are mainnet-only; USDe exists on other chains for transfers."
1588
+ };
1589
+ }
1590
+ if (isEvmChainInEthenaUsdeList(chainId)) {
1591
+ const row = listEthenaUsdeEvmNetworkRows().find((r) => r.chainId === chainId);
1592
+ return {
1593
+ tokens: row ? [{ address: row.usde, symbol: "USDe", roles: ["erc20"] }] : [],
1594
+ notes: "USDe on L2; staking MCP tools target mainnet only."
1595
+ };
1596
+ }
1597
+ return { tokens: [] };
1598
+ }
1599
+ }),
1600
+ "euler-v2": advisor("euler-v2", "subgraph_vaults", {
1601
+ async supportedChainIds() {
1602
+ return [...EULER_V2_SUBGRAPH_CHAIN_IDS];
1603
+ },
1604
+ async supportedTokens() {
1605
+ return {
1606
+ tokens: [],
1607
+ notes: "Euler vault/collateral assets vary by chain. Pass vault and asset addresses from Euler app or subgraph."
1608
+ };
1609
+ }
1610
+ }),
1611
+ [MAPLE_PROTOCOL_ID]: advisor(MAPLE_PROTOCOL_ID, "fixed_addresses", {
1612
+ async supportedChainIds() {
1613
+ return [1, 11155111];
1614
+ },
1615
+ async supportedTokens() {
1616
+ return {
1617
+ tokens: [],
1618
+ notes: "Maple Syrup pools are discovered via GraphQL; pass syrupRouter, pool, and asset from Maple UI."
1619
+ };
1620
+ }
1621
+ }),
1622
+ [SKY_PROTOCOL_ID]: advisor(SKY_PROTOCOL_ID, "fixed_addresses", {
1623
+ async supportedChainIds() {
1624
+ return [1];
1625
+ },
1626
+ async supportedTokens() {
1627
+ return {
1628
+ tokens: [],
1629
+ notes: "Sky Lockstake and sUSDS use fixed mainnet contract addresses in protocol builders."
1630
+ };
1631
+ }
1632
+ })
1633
+ };
1634
+ function getProtocolSupportAdvisor(protocolId) {
1635
+ return PROTOCOL_SUPPORT_ADVISORS[protocolId];
1636
+ }
1637
+ function listProtocolSupportAdvisorIds() {
1638
+ return Object.keys(PROTOCOL_SUPPORT_ADVISORS);
1639
+ }
1640
+ var mcpServerCommonInputSchema = z.object({
1641
+ keyGenId: z.string().min(1).describe("KeyGen id from fetch_key_gen_result / node preferred KeyGen"),
1642
+ chainId: z.number().int().positive().describe("EVM chain id; RPC and gas config resolved from chain registry"),
1643
+ purposeText: z.string().min(1).describe("Human-readable purpose for the sign request"),
1644
+ useCustomGas: z.boolean().optional().describe("Apply chain gas settings from registry when true")
1645
+ });
1646
+ function mcpServerMultisignInput(fields) {
1647
+ return mcpServerCommonInputSchema.extend(fields);
1648
+ }
1649
+ var mcpServerSubmitOutputSchema = z.object({
1650
+ requestId: z.string().min(1)
1651
+ }).describe("mpc-auth multiSignRequest id; continue with trigger_sign_result / broadcast_sign_result");
1652
+ var MCP_NON_SUBMIT_TOOL_NAMES = /* @__PURE__ */ new Set([
1653
+ "ctm_uniswap_v4_quote",
1654
+ "ctm_uniswap_v4_create_swap"
1655
+ ]);
486
1656
 
487
1657
  // src/agent/catalog.ts
488
1658
  registerProtocolModule(uniswapV4ProtocolModule);
489
1659
  registerProtocolModule(curveDaoProtocolModule);
1660
+ registerProtocolModule(lidoProtocolModule);
1661
+ registerProtocolModule(ethenaProtocolModule);
1662
+ registerProtocolModule(mapleProtocolModule);
1663
+ registerProtocolModule(skyProtocolModule);
1664
+ registerProtocolModule(aaveV4ProtocolModule);
1665
+ registerProtocolModule(eulerV2ProtocolModule);
490
1666
  function getAgentCatalog() {
491
1667
  return {
492
1668
  protocols: getProtocolModules(),
@@ -497,11 +1673,17 @@ function getAgentCatalog() {
497
1673
  },
498
1674
  uniswapV4: uniswapV4ProtocolModule,
499
1675
  curveDao: curveDaoProtocolModule,
1676
+ lido: lidoProtocolModule,
1677
+ ethena: ethenaProtocolModule,
1678
+ maple: mapleProtocolModule,
1679
+ sky: skyProtocolModule,
1680
+ aaveV4: aaveV4ProtocolModule,
1681
+ eulerV2: eulerV2ProtocolModule,
500
1682
  /** Prefer getAgentCatalogForMcp() or getMcpToolDefinitions() for MCP servers. */
501
1683
  mcp: getAgentCatalogForMcp()
502
1684
  };
503
1685
  }
504
1686
 
505
- export { EVM_COMMON_PARAM_DOCS, MANAGEMENT_SIG_DOC, MCP_TOOL_DEFINITIONS, MULTISIGN_OUTPUT_DOC, getActionsByChainCategory, getAgentCatalog, getAgentCatalogForMcp, getMcpToolByName, getMcpToolDefinitions, getProtocolModules };
1687
+ export { EVM_COMMON_PARAM_DOCS, MANAGEMENT_SIG_DOC, MCP_NON_SUBMIT_TOOL_NAMES, MCP_TOOL_DEFINITIONS, MCP_TOOL_INPUT_SCHEMAS, MCP_TOOL_OUTPUT_SCHEMAS, MULTISIGN_OUTPUT_DOC, PROTOCOL_SUPPORT_ADVISORS, chainDetailSchema, evmAddressSchema, evmMultisignCommonInputSchema, getActionsByChainCategory, getAgentCatalog, getAgentCatalogForMcp, getMcpToolByName, getMcpToolDefinitions, getMcpToolInputSchema, getMcpToolOutputSchema, getProtocolDiscoverySummary, getProtocolModules, getProtocolSkill, getProtocolSupportAdvisor, getToolsForProtocol, jsonObjectSchema, keyGenSchema, listProtocolSupportAdvisorIds, listProtocolsWithSkills, mcpAaveV4BorrowInputSchema, mcpAaveV4DepositInputSchema, mcpAaveV4RepayInputSchema, mcpAaveV4WithdrawInputSchema, mcpCurveDaoBuildSwapMultisignInputSchema, mcpEthenaClaimInputSchema, mcpEthenaCooldownInputSchema, mcpEthenaRedeemInputSchema, mcpEthenaStakeInputSchema, mcpEulerV2BorrowRepayInputSchema, mcpEulerV2CollateralDepositInputSchema, mcpEulerV2CollateralWithdrawInputSchema, mcpEulerV2IsolatedBorrowInputSchema, mcpEulerV2IsolatedLendInputSchema, mcpEulerV2VaultWithdrawInputSchema, mcpLidoClaimWithdrawalInputSchema, mcpLidoRequestWithdrawalsInputSchema, mcpLidoSubmitInputSchema, mcpLidoUnwrapWstEthInputSchema, mcpLidoWrapStEthInputSchema, mcpMapleDepositInputSchema, mcpMapleRequestRedeemInputSchema, mcpMultisignInput, multisignOutputSchema as mcpMultisignOutputSchema, mcpServerCommonInputSchema, mcpServerMultisignInput, mcpServerSubmitOutputSchema, mcpSkyLockstakeCloseInputSchema, mcpSkyLockstakeDrawInputSchema, mcpSkyLockstakeGetRewardInputSchema, mcpSkyLockstakeStakeInputSchema, mcpSkyLockstakeWipeInputSchema, mcpSkySusdsDepositInputSchema, mcpSkySusdsRedeemInputSchema, mcpUniswapV4BuildSwapMultisignInputSchema, mcpUniswapV4CreateSwapInputSchema, mcpUniswapV4CreateSwapOutputSchema, mcpUniswapV4QuoteInputSchema, mcpUniswapV4QuoteOutputSchema, multisignOutputSchema, parseMcpToolInput, parseMcpToolOutput, uniswapQuoteTradeTypeSchema, zodSchemaToMcpJsonSchema };
506
1688
  //# sourceMappingURL=catalog.js.map
507
1689
  //# sourceMappingURL=catalog.js.map