@continuumdao/ctm-mpc-defi 0.2.0 → 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 (100) hide show
  1. package/README.md +20 -78
  2. package/dist/agent/catalog.cjs +511 -4
  3. package/dist/agent/catalog.cjs.map +1 -1
  4. package/dist/agent/catalog.d.ts +140 -20
  5. package/dist/agent/catalog.js +501 -6
  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 -226
  16. package/dist/chains/evm/index.cjs.map +1 -1
  17. package/dist/chains/evm/index.d.ts +14 -26
  18. package/dist/chains/evm/index.js +21 -211
  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 -1868
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.ts +7 -11
  31. package/dist/index.js +227 -1839
  32. package/dist/index.js.map +1 -1
  33. package/dist/protocols/evm/aave-v4/index.cjs +385 -662
  34. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  35. package/dist/protocols/evm/aave-v4/index.d.ts +1 -2
  36. package/dist/protocols/evm/aave-v4/index.js +385 -662
  37. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  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 +290 -402
  44. package/dist/protocols/evm/ethena/index.cjs.map +1 -1
  45. package/dist/protocols/evm/ethena/index.d.ts +1 -2
  46. package/dist/protocols/evm/ethena/index.js +291 -403
  47. package/dist/protocols/evm/ethena/index.js.map +1 -1
  48. package/dist/protocols/evm/euler-v2/index.cjs +485 -1163
  49. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  50. package/dist/protocols/evm/euler-v2/index.d.ts +1 -2
  51. package/dist/protocols/evm/euler-v2/index.js +486 -1164
  52. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  53. package/dist/protocols/evm/lido/index.cjs +241 -236
  54. package/dist/protocols/evm/lido/index.cjs.map +1 -1
  55. package/dist/protocols/evm/lido/index.d.ts +1 -2
  56. package/dist/protocols/evm/lido/index.js +242 -237
  57. package/dist/protocols/evm/lido/index.js.map +1 -1
  58. package/dist/protocols/evm/maple/index.cjs +310 -398
  59. package/dist/protocols/evm/maple/index.cjs.map +1 -1
  60. package/dist/protocols/evm/maple/index.d.ts +1 -2
  61. package/dist/protocols/evm/maple/index.js +311 -399
  62. package/dist/protocols/evm/maple/index.js.map +1 -1
  63. package/dist/protocols/evm/sky/index.cjs +238 -233
  64. package/dist/protocols/evm/sky/index.cjs.map +1 -1
  65. package/dist/protocols/evm/sky/index.d.ts +1 -2
  66. package/dist/protocols/evm/sky/index.js +236 -231
  67. package/dist/protocols/evm/sky/index.js.map +1 -1
  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 +7 -6
  77. package/dist/agent/catalog.d.cts +0 -939
  78. package/dist/chains/evm/index.d.cts +0 -64
  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 -16
  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/aave-v4/index.d.cts +0 -500
  89. package/dist/protocols/evm/curve-dao/index.d.cts +0 -147
  90. package/dist/protocols/evm/ethena/index.d.cts +0 -161
  91. package/dist/protocols/evm/euler-v2/index.d.cts +0 -317
  92. package/dist/protocols/evm/lido/index.d.cts +0 -120
  93. package/dist/protocols/evm/maple/index.d.cts +0 -109
  94. package/dist/protocols/evm/sky/index.d.cts +0 -218
  95. package/dist/protocols/evm/uniswap-v4/index.d.cts +0 -324
  96. package/dist/registry-BwZoE668.d.cts +0 -8
  97. package/dist/txParams-BC7ogvdR.d.cts +0 -19
  98. package/dist/txParams-BC7ogvdR.d.ts +0 -19
  99. package/dist/types-B8idm_gu.d.cts +0 -34
  100. package/dist/types-Ce2qNHai.d.ts +0 -57
@@ -3,7 +3,11 @@
3
3
  var viem = require('viem');
4
4
  var zodToJsonSchema = require('zod-to-json-schema');
5
5
  var zod = require('zod');
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ var url = require('url');
6
9
 
10
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
7
11
  // src/core/registry.ts
8
12
  var modules = [];
9
13
  function registerProtocolModule(mod) {
@@ -161,6 +165,96 @@ function isCurveApiChainSupported(chainId) {
161
165
  if (Number.isNaN(n) || n < 0) return false;
162
166
  return CURVE_FULL_NETWORK_CONSTANTS_CHAIN_IDS.has(n);
163
167
  }
168
+ var CURVE_NATIVE_PLACEHOLDER = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
169
+ var ETH_PLACEHOLDER = CURVE_NATIVE_PLACEHOLDER;
170
+ function normalizeAddr(a) {
171
+ return a.toLowerCase();
172
+ }
173
+ function addEdge(adj, a, b) {
174
+ if (a === b) return;
175
+ if (!adj.has(a)) adj.set(a, /* @__PURE__ */ new Set());
176
+ if (!adj.has(b)) adj.set(b, /* @__PURE__ */ new Set());
177
+ adj.get(a).add(b);
178
+ adj.get(b).add(a);
179
+ }
180
+ function buildCurveLiquidityGraphFromApi(curve) {
181
+ const adj = /* @__PURE__ */ new Map();
182
+ for (const id of curve.getPoolList()) {
183
+ try {
184
+ const pool = curve.getPool(id);
185
+ const w = (pool.wrappedCoinAddresses ?? []).map(normalizeAddr);
186
+ const u = (pool.underlyingCoinAddresses ?? []).map(normalizeAddr);
187
+ const all = [.../* @__PURE__ */ new Set([...w, ...u])];
188
+ for (let i = 0; i < all.length; i++) {
189
+ for (let j = i + 1; j < all.length; j++) {
190
+ addEdge(adj, all[i], all[j]);
191
+ }
192
+ }
193
+ } catch {
194
+ }
195
+ }
196
+ return adj;
197
+ }
198
+ function addNativeWethBridge(adj, wrappedNative) {
199
+ if (!wrappedNative) return;
200
+ const w = wrappedNative.toLowerCase();
201
+ const a = ETH_PLACEHOLDER;
202
+ const b = w;
203
+ if (a === b) return;
204
+ if (!adj.has(a)) adj.set(a, /* @__PURE__ */ new Set());
205
+ if (!adj.has(b)) adj.set(b, /* @__PURE__ */ new Set());
206
+ adj.get(a).add(b);
207
+ adj.get(b).add(a);
208
+ }
209
+ function swappableCurveGraphNodeKeys(adj) {
210
+ const out = /* @__PURE__ */ new Set();
211
+ for (const [k, neigh] of adj) {
212
+ if (neigh.size > 0) out.add(k);
213
+ }
214
+ return out;
215
+ }
216
+
217
+ // src/protocols/evm/curve-dao/apiSession.ts
218
+ async function fetchAllCurvePools(curve) {
219
+ const run = (p) => p.catch(() => void 0);
220
+ await Promise.all([
221
+ run(curve.factory.fetchPools()),
222
+ run(curve.crvUSDFactory.fetchPools()),
223
+ run(curve.EYWAFactory.fetchPools()),
224
+ run(curve.cryptoFactory.fetchPools()),
225
+ run(curve.twocryptoFactory.fetchPools()),
226
+ run(curve.tricryptoFactory.fetchPools()),
227
+ run(curve.stableNgFactory.fetchPools())
228
+ ]);
229
+ }
230
+ async function loadFullCurveSessionForRpc(rpcUrl) {
231
+ const url = (rpcUrl ?? "").trim();
232
+ if (!url) return null;
233
+ try {
234
+ const { default: curve } = await import('@curvefi/api');
235
+ await curve.init("JsonRpc", { url }, {});
236
+ const wrapped = curve.getNetworkConstants().NATIVE_COIN?.wrappedAddress;
237
+ if (!curve.hasRouter || !curve.hasRouter()) {
238
+ return {
239
+ curve,
240
+ adj: /* @__PURE__ */ new Map(),
241
+ swappableNodeKeys: /* @__PURE__ */ new Set(),
242
+ wrappedNative: wrapped
243
+ };
244
+ }
245
+ await fetchAllCurvePools(curve);
246
+ const adj = buildCurveLiquidityGraphFromApi(curve);
247
+ addNativeWethBridge(adj, wrapped);
248
+ return {
249
+ curve,
250
+ adj,
251
+ swappableNodeKeys: swappableCurveGraphNodeKeys(adj),
252
+ wrappedNative: wrapped
253
+ };
254
+ } catch {
255
+ return null;
256
+ }
257
+ }
164
258
 
165
259
  // src/protocols/evm/curve-dao/index.ts
166
260
  var CURVE_DAO_PROTOCOL_ID = "curve-dao";
@@ -250,7 +344,14 @@ var MULTISIGN_OUTPUT_DOC = {
250
344
  }
251
345
  };
252
346
  var MANAGEMENT_SIG_DOC = {
253
- 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.",
347
+ 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.",
348
+ exceptions: {
349
+ configUpdateImplement: "POST /configUpdateImplement: include nodeKey + plannedYaml + signedMessage (opaque configUpdateImplement|<sha256> line). Sign the opaque line bytes, not the JSON body.",
350
+ postMSQTTKey: "POST /postMSQTTKey: include nodeKey + caCertPem + clientSig. Sign caCertPem PEM bytes directly (use buildPostMqttKeyBody).",
351
+ addManagementKey: "POST /addManagementKey / removeManagementKey (EIP-191): may still use signedMessage equal to the canonical JSON string for dual-mode Ethereum signing.",
352
+ agentLlmConfig: "POST /agentLlmConfig / agentLlmApiKey: sign canonical JSON with action + clientSig cleared; POST body has nonce, clientSig, nodeKey, endpoint fields \u2014 no signedMessage field.",
353
+ multiSignRequest: "POST /multiSignRequest (client key, not management): POST { ...bodyForSign, clientSig, signedMessage: messageToSign }."
354
+ },
254
355
  fields: {
255
356
  nonce: {
256
357
  type: "number",
@@ -268,10 +369,15 @@ var MANAGEMENT_SIG_DOC = {
268
369
  helpers: {
269
370
  managementSigFields: "Base envelope with clientSig cleared.",
270
371
  buildManagementPostBody: "Spread managementSigFields then endpoint fields.",
372
+ buildPostMqttKeyBody: "POST /postMSQTTKey unsigned body (sign PEM directly).",
373
+ buildPostPreferredKeyGenBody: "POST /postPreferredKeyGen unsigned body.",
374
+ buildConfigUpdateImplementPostBody: "POST /configUpdateImplement with opaque signedMessage line.",
375
+ buildSignRequestAgreeUnsignedBody: "POST /signRequestAgree unsigned body with nodeKey.",
271
376
  messageToSignManagementBody: "Canonical JSON string to sign.",
272
377
  withManagementClientSig: "Attach signature to POST body.",
273
378
  fetchNodeKey: "GET /getNodeKey via nodeFetchWithReadAuth.",
274
- fetchManagementNonce: "GET nonce for Ed25519 or Ethereum management key."
379
+ fetchManagementNonce: "GET nonce for Ed25519 or Ethereum management key.",
380
+ fetchPreferredKeyGen: "GET /getPreferredKeyGen for agent default KeyGen."
275
381
  }
276
382
  };
277
383
  function zodSchemaToMcpJsonSchema(schema) {
@@ -799,7 +905,7 @@ var MCP_PROTOCOL_TOOL_DEFINITIONS = [
799
905
  description: "Build Euler v2 vault withdraw/redeem batch.",
800
906
  prerequisites: ["keyGen", "executorAddress", "vault address"],
801
907
  followUp: ["Sign messageToSign", "POST /multiSignRequest"],
802
- handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2VaultWithdrawBatch" },
908
+ handler: { importPath: "protocols/evm/euler-v2", exportName: "buildEvmMultisignBodyEulerV2VaultWithdraw" },
803
909
  inputZod: mcpEulerV2VaultWithdrawInputSchema
804
910
  }),
805
911
  defineProtocolMcpTool({
@@ -960,7 +1066,13 @@ function getAgentCatalogForMcp() {
960
1066
  "2. GET /getPublicMgtKeyNonce or /getNodeMgtKeyNonce \u2192 nonce",
961
1067
  "3. buildManagementPostBody(nonce, nodeKey, { \u2026endpoint fields })",
962
1068
  "4. messageToSignManagementBody(body) \u2192 sign \u2192 withManagementClientSig(body, sig)",
963
- "5. POST management route with signed body"
1069
+ "5. POST management route with signed body (no signedMessage field except configUpdateImplement opaque line)"
1070
+ ],
1071
+ agentMultisignTypical: [
1072
+ "1. load_defi_protocol for the target protocol",
1073
+ "2. get_defi_protocol_supported_chains / get_token_registry to pick chainId and tokens",
1074
+ "3. MCP build_* tool with keyGenId + chainId \u2192 { requestId }",
1075
+ "4. Base MCP: wait_for_sign_request_ready \u2192 sign_request_agree \u2192 trigger_sign_result \u2192 broadcast_sign_result"
964
1076
  ]
965
1077
  }
966
1078
  };
@@ -996,6 +1108,7 @@ var lidoProtocolModule = {
996
1108
  };
997
1109
  registerProtocolModule(lidoProtocolModule);
998
1110
  var USDE_ETHEREUM_MAINNET = "0x4c9edd5852cd905f086c759e8383e09bff1e68b3";
1111
+ var SUSDE_ETHEREUM_MAINNET = "0x9d39a5de30e57443bff2a8307a4256c8797a3497";
999
1112
  var USDE_MOST_L2S = "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34";
1000
1113
  var USDE_ZKSYNC_ERA = "0x39Fe7a0DACcE31Bd90418e3e659fb0b5f0B3Db0d";
1001
1114
  var L2_SAME_ADDRESS_CHAIN_IDS = /* @__PURE__ */ new Set([
@@ -1036,12 +1149,53 @@ var L2_SAME_ADDRESS_CHAIN_IDS = /* @__PURE__ */ new Set([
1036
1149
  48900
1037
1150
  // Zircuit
1038
1151
  ]);
1152
+ var FALLBACK_NAME_BY_ID = {
1153
+ 1: "Ethereum",
1154
+ 42161: "Arbitrum One",
1155
+ 10: "Optimism",
1156
+ 8453: "Base",
1157
+ 56: "BNB Chain",
1158
+ 59144: "Linea",
1159
+ 5e3: "Mantle",
1160
+ 81457: "Blast",
1161
+ 169: "Manta Pacific",
1162
+ 534352: "Scroll",
1163
+ 252: "Fraxtal",
1164
+ 34443: "Mode",
1165
+ 196: "X Layer",
1166
+ 1088: "Metis",
1167
+ 80084: "Berachain",
1168
+ 2222: "Kava",
1169
+ 2818: "Morph",
1170
+ 1923: "Swell",
1171
+ 48900: "Zircuit",
1172
+ 324: "ZKSync Era"
1173
+ };
1039
1174
  function usdeTokenAddressOnEvmChain(chainId) {
1040
1175
  if (chainId === 1) return USDE_ETHEREUM_MAINNET;
1041
1176
  if (chainId === 324) return USDE_ZKSYNC_ERA;
1042
1177
  if (L2_SAME_ADDRESS_CHAIN_IDS.has(chainId)) return USDE_MOST_L2S;
1043
1178
  return null;
1044
1179
  }
1180
+ function listEthenaUsdeEvmNetworkRows() {
1181
+ const rows = [
1182
+ { chainId: 1, label: FALLBACK_NAME_BY_ID[1], usde: USDE_ETHEREUM_MAINNET }
1183
+ ];
1184
+ const l2 = [...L2_SAME_ADDRESS_CHAIN_IDS].sort((a, b) => a - b);
1185
+ for (const id of l2) {
1186
+ rows.push({
1187
+ chainId: id,
1188
+ label: FALLBACK_NAME_BY_ID[id] ?? `Chain ${id}`,
1189
+ usde: USDE_MOST_L2S
1190
+ });
1191
+ }
1192
+ rows.push({ chainId: 324, label: FALLBACK_NAME_BY_ID[324], usde: USDE_ZKSYNC_ERA });
1193
+ return rows.sort((a, b) => {
1194
+ if (a.chainId === 1) return -1;
1195
+ if (b.chainId === 1) return 1;
1196
+ return a.chainId - b.chainId;
1197
+ });
1198
+ }
1045
1199
  function isEvmChainInEthenaUsdeList(chainId) {
1046
1200
  return usdeTokenAddressOnEvmChain(chainId) != null;
1047
1201
  }
@@ -1118,6 +1272,83 @@ var skyProtocolModule = {
1118
1272
  ]
1119
1273
  };
1120
1274
  registerProtocolModule(skyProtocolModule);
1275
+ var AAVE_V4_GRAPHQL_URL = "https://api.v4.aave.com/graphql";
1276
+ async function aaveV4Gql(query, variables) {
1277
+ const r = await fetch(AAVE_V4_GRAPHQL_URL, {
1278
+ method: "POST",
1279
+ headers: { "content-type": "application/json" },
1280
+ body: JSON.stringify({ query, variables: variables ?? {} })
1281
+ });
1282
+ if (!r.ok) {
1283
+ const t = await r.text().catch(() => "");
1284
+ throw new Error(t ? `Aave V4 API HTTP ${r.status}: ${t.slice(0, 200)}` : `Aave V4 API HTTP ${r.status}`);
1285
+ }
1286
+ const j = await r.json();
1287
+ if (j.errors?.length) {
1288
+ const msg = j.errors.map((e) => e.message ?? "Unknown").join("; ");
1289
+ throw new Error(msg);
1290
+ }
1291
+ if (j.data == null) {
1292
+ throw new Error("Aave V4 API: empty response");
1293
+ }
1294
+ return j.data;
1295
+ }
1296
+ async function fetchAaveV4Chains() {
1297
+ const d = await aaveV4Gql(`
1298
+ query C($c: ChainsRequest!) { chains(request: $c) { chainId name nativeWrappedToken } }
1299
+ `, { c: { query: { filter: "ALL" } } });
1300
+ return d.chains ?? [];
1301
+ }
1302
+ async function loadAaveV4SupportedChainIdsFromV4Api() {
1303
+ const rows = await fetchAaveV4Chains();
1304
+ const s = /* @__PURE__ */ new Set();
1305
+ for (const c of rows) s.add(c.chainId);
1306
+ return s;
1307
+ }
1308
+ var RESERVES_ADDRESS_FRAGMENT = `
1309
+ asset { underlying { address } }
1310
+ `;
1311
+ async function fetchAaveV4NativeWrappedToken(chainId) {
1312
+ const all = await fetchAaveV4Chains();
1313
+ const c = all.find((x) => x.chainId === chainId);
1314
+ const t = (c?.nativeWrappedToken ?? "").trim();
1315
+ if (t && viem.isAddress(t)) return viem.getAddress(t);
1316
+ return null;
1317
+ }
1318
+ async function fetchAaveV4SupportedUnderlyingAddressSet(chainId) {
1319
+ const d = await aaveV4Gql(
1320
+ `
1321
+ query A($r: ReservesRequest!) { reserves(request: $r) { ${RESERVES_ADDRESS_FRAGMENT} } }
1322
+ `,
1323
+ {
1324
+ r: {
1325
+ query: { chainIds: [chainId] },
1326
+ filter: "ALL",
1327
+ orderBy: { supplyApy: "DESC" }
1328
+ }
1329
+ }
1330
+ );
1331
+ const s = /* @__PURE__ */ new Set();
1332
+ for (const r of d.reserves ?? []) {
1333
+ const a = (r.asset?.underlying?.address ?? "").trim();
1334
+ if (a && viem.isAddress(a)) s.add(a.toLowerCase());
1335
+ }
1336
+ return s;
1337
+ }
1338
+ var aaveV4ChainTokenCache = /* @__PURE__ */ new Map();
1339
+ function ensureAaveV4ChainTokenCache(chainId) {
1340
+ const hit = aaveV4ChainTokenCache.get(chainId);
1341
+ if (hit) return hit;
1342
+ const p = (async () => {
1343
+ const [nativeWrapped, supportedUnderlying] = await Promise.all([
1344
+ fetchAaveV4NativeWrappedToken(chainId),
1345
+ fetchAaveV4SupportedUnderlyingAddressSet(chainId)
1346
+ ]);
1347
+ return { supportedUnderlying, nativeWrapped };
1348
+ })();
1349
+ aaveV4ChainTokenCache.set(chainId, p);
1350
+ return p;
1351
+ }
1121
1352
 
1122
1353
  // src/protocols/evm/aave-v4/index.ts
1123
1354
  var AAVE_V4_PROTOCOL_ID = "aave-v4";
@@ -1160,6 +1391,271 @@ var eulerV2ProtocolModule = {
1160
1391
  ]
1161
1392
  };
1162
1393
  registerProtocolModule(eulerV2ProtocolModule);
1394
+ var skillsDir = path.join(path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('catalog.cjs', document.baseURI).href)))), "skills");
1395
+ var SKILL_PROTOCOL_IDS = [
1396
+ "aave-v4",
1397
+ "lido",
1398
+ "uniswap-v4",
1399
+ "curve-dao",
1400
+ "ethena",
1401
+ "euler-v2",
1402
+ "maple-syrup",
1403
+ "sky"
1404
+ ];
1405
+ function getToolsForProtocol(protocolId) {
1406
+ return MCP_TOOL_DEFINITIONS.filter((t) => t.protocolId === protocolId);
1407
+ }
1408
+ function getProtocolSkill(protocolId) {
1409
+ if (!SKILL_PROTOCOL_IDS.includes(protocolId)) {
1410
+ return void 0;
1411
+ }
1412
+ try {
1413
+ return fs.readFileSync(path.join(skillsDir, protocolId, "SKILL.md"), "utf8");
1414
+ } catch {
1415
+ return void 0;
1416
+ }
1417
+ }
1418
+ function listProtocolsWithSkills() {
1419
+ return [...SKILL_PROTOCOL_IDS];
1420
+ }
1421
+ function getProtocolDiscoverySummary(protocolId) {
1422
+ const mod = getProtocolModules().find((p) => p.id === protocolId);
1423
+ if (!mod) return void 0;
1424
+ return {
1425
+ protocolId: mod.id,
1426
+ chainCategory: mod.chainCategory,
1427
+ actions: mod.actions.map((a) => ({ id: a.id, description: a.description })),
1428
+ tools: getToolsForProtocol(protocolId).map((t) => ({
1429
+ name: t.name,
1430
+ actionId: t.actionId,
1431
+ description: t.description,
1432
+ prerequisites: t.prerequisites,
1433
+ followUp: t.followUp
1434
+ }))
1435
+ };
1436
+ }
1437
+ var EULER_V2_SUBGRAPH_CHAIN_IDS = [
1438
+ 1,
1439
+ 8453,
1440
+ 42161,
1441
+ 10,
1442
+ 137,
1443
+ 56,
1444
+ 43114,
1445
+ 100,
1446
+ 59144,
1447
+ 146,
1448
+ 1923,
1449
+ 130
1450
+ ];
1451
+ function advisor(protocolId, tokenFilter, impl) {
1452
+ return { protocolId, tokenFilter, ...impl };
1453
+ }
1454
+ var PROTOCOL_SUPPORT_ADVISORS = {
1455
+ "aave-v4": advisor("aave-v4", "api_underlyings", {
1456
+ async supportedChainIds() {
1457
+ const set = await loadAaveV4SupportedChainIdsFromV4Api();
1458
+ return [...set].sort((a, b) => a - b);
1459
+ },
1460
+ async supportedTokens(chainId) {
1461
+ const cache = await ensureAaveV4ChainTokenCache(chainId);
1462
+ const tokens = [...cache.supportedUnderlying].map((address) => ({
1463
+ address,
1464
+ roles: ["underlying"]
1465
+ }));
1466
+ if (cache.nativeWrapped) {
1467
+ tokens.unshift({
1468
+ address: cache.nativeWrapped,
1469
+ symbol: "WETH",
1470
+ roles: ["native_wrapped"]
1471
+ });
1472
+ }
1473
+ return {
1474
+ tokens,
1475
+ nativeWrapped: cache.nativeWrapped ?? void 0,
1476
+ notes: "Native ETH deposits use wrapped native token address from Aave v4 API."
1477
+ };
1478
+ },
1479
+ async isTokenSupported(chainId, address) {
1480
+ const cache = await ensureAaveV4ChainTokenCache(chainId);
1481
+ let normalized;
1482
+ try {
1483
+ normalized = viem.getAddress(address).toLowerCase();
1484
+ } catch {
1485
+ return false;
1486
+ }
1487
+ if (cache.nativeWrapped && viem.getAddress(cache.nativeWrapped).toLowerCase() === normalized) {
1488
+ return true;
1489
+ }
1490
+ return cache.supportedUnderlying.has(normalized);
1491
+ }
1492
+ }),
1493
+ "uniswap-v4": advisor("uniswap-v4", "any_erc20_on_chain", {
1494
+ async supportedChainIds() {
1495
+ const ids = [];
1496
+ for (const id of [
1497
+ 1,
1498
+ 5,
1499
+ 11155111,
1500
+ 137,
1501
+ 80001,
1502
+ 10,
1503
+ 420,
1504
+ 42161,
1505
+ 421613,
1506
+ 42220,
1507
+ 44787,
1508
+ 56,
1509
+ 43114,
1510
+ 84531,
1511
+ 8453,
1512
+ 81457,
1513
+ 7777777,
1514
+ 324,
1515
+ 480,
1516
+ 1301,
1517
+ 130,
1518
+ 10143,
1519
+ 84532,
1520
+ 1868,
1521
+ 143,
1522
+ 59144,
1523
+ 4217,
1524
+ 196
1525
+ ]) {
1526
+ if (isUniswapV4ChainSupported(id)) ids.push(id);
1527
+ }
1528
+ return ids;
1529
+ },
1530
+ async supportedTokens() {
1531
+ return {
1532
+ tokens: [],
1533
+ 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."
1534
+ };
1535
+ }
1536
+ }),
1537
+ "curve-dao": advisor("curve-dao", "pool_graph", {
1538
+ async supportedChainIds() {
1539
+ return [1, 10, 56, 100, 137, 146, 196, 250, 252, 324, 999, 1284, 2222, 5e3, 8453, 42161, 42220, 43114, 1313161554];
1540
+ },
1541
+ async supportedTokens(chainId, ctx) {
1542
+ if (!isCurveApiChainSupported(chainId)) {
1543
+ return { tokens: [], notes: "Chain not supported by Curve SDK network constants." };
1544
+ }
1545
+ const rpcUrl = ctx?.rpcUrl?.trim();
1546
+ if (!rpcUrl) {
1547
+ return {
1548
+ tokens: [],
1549
+ notes: "Provide rpcUrl (from get_chain_registry) to load Curve pool graph token list."
1550
+ };
1551
+ }
1552
+ const session = await loadFullCurveSessionForRpc(rpcUrl);
1553
+ if (!session?.swappableNodeKeys?.size) {
1554
+ return { tokens: [], notes: "Curve session returned no swappable tokens for this RPC." };
1555
+ }
1556
+ return {
1557
+ tokens: [...session.swappableNodeKeys].map((key) => {
1558
+ const address = key.startsWith("0x") ? key : key.split(":")[0] ?? key;
1559
+ return { address, roles: ["swappable"] };
1560
+ })
1561
+ };
1562
+ }
1563
+ }),
1564
+ lido: advisor("lido", "mainnet_only", {
1565
+ async supportedChainIds() {
1566
+ return [LIDO_ETHEREUM_MAINNET_CHAIN_ID];
1567
+ },
1568
+ async supportedTokens() {
1569
+ return {
1570
+ tokens: [
1571
+ { address: "0x0000000000000000000000000000000000000000", symbol: "ETH", roles: ["native", "stake"] },
1572
+ { address: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", symbol: "stETH", roles: ["erc20"] },
1573
+ { address: "0x7f39C581F595B853cBbF37C12FfeeA971C5a5bEa", symbol: "wstETH", roles: ["erc20"] }
1574
+ ],
1575
+ notes: "Lido staking and withdrawals are Ethereum mainnet only."
1576
+ };
1577
+ }
1578
+ }),
1579
+ ethena: advisor("ethena", "minting_contract", {
1580
+ async supportedChainIds() {
1581
+ return listEthenaUsdeEvmNetworkRows().map((r) => r.chainId);
1582
+ },
1583
+ async supportedTokens(chainId) {
1584
+ if (chainId === 1) {
1585
+ return {
1586
+ tokens: [
1587
+ { address: USDE_ETHEREUM_MAINNET, symbol: "USDe", roles: ["stake"] },
1588
+ { address: SUSDE_ETHEREUM_MAINNET, symbol: "sUSDe", roles: ["vault"] }
1589
+ ],
1590
+ notes: "Ethena stake/redeem UI actions are mainnet-only; USDe exists on other chains for transfers."
1591
+ };
1592
+ }
1593
+ if (isEvmChainInEthenaUsdeList(chainId)) {
1594
+ const row = listEthenaUsdeEvmNetworkRows().find((r) => r.chainId === chainId);
1595
+ return {
1596
+ tokens: row ? [{ address: row.usde, symbol: "USDe", roles: ["erc20"] }] : [],
1597
+ notes: "USDe on L2; staking MCP tools target mainnet only."
1598
+ };
1599
+ }
1600
+ return { tokens: [] };
1601
+ }
1602
+ }),
1603
+ "euler-v2": advisor("euler-v2", "subgraph_vaults", {
1604
+ async supportedChainIds() {
1605
+ return [...EULER_V2_SUBGRAPH_CHAIN_IDS];
1606
+ },
1607
+ async supportedTokens() {
1608
+ return {
1609
+ tokens: [],
1610
+ notes: "Euler vault/collateral assets vary by chain. Pass vault and asset addresses from Euler app or subgraph."
1611
+ };
1612
+ }
1613
+ }),
1614
+ [MAPLE_PROTOCOL_ID]: advisor(MAPLE_PROTOCOL_ID, "fixed_addresses", {
1615
+ async supportedChainIds() {
1616
+ return [1, 11155111];
1617
+ },
1618
+ async supportedTokens() {
1619
+ return {
1620
+ tokens: [],
1621
+ notes: "Maple Syrup pools are discovered via GraphQL; pass syrupRouter, pool, and asset from Maple UI."
1622
+ };
1623
+ }
1624
+ }),
1625
+ [SKY_PROTOCOL_ID]: advisor(SKY_PROTOCOL_ID, "fixed_addresses", {
1626
+ async supportedChainIds() {
1627
+ return [1];
1628
+ },
1629
+ async supportedTokens() {
1630
+ return {
1631
+ tokens: [],
1632
+ notes: "Sky Lockstake and sUSDS use fixed mainnet contract addresses in protocol builders."
1633
+ };
1634
+ }
1635
+ })
1636
+ };
1637
+ function getProtocolSupportAdvisor(protocolId) {
1638
+ return PROTOCOL_SUPPORT_ADVISORS[protocolId];
1639
+ }
1640
+ function listProtocolSupportAdvisorIds() {
1641
+ return Object.keys(PROTOCOL_SUPPORT_ADVISORS);
1642
+ }
1643
+ var mcpServerCommonInputSchema = zod.z.object({
1644
+ keyGenId: zod.z.string().min(1).describe("KeyGen id from fetch_key_gen_result / node preferred KeyGen"),
1645
+ chainId: zod.z.number().int().positive().describe("EVM chain id; RPC and gas config resolved from chain registry"),
1646
+ purposeText: zod.z.string().min(1).describe("Human-readable purpose for the sign request"),
1647
+ useCustomGas: zod.z.boolean().optional().describe("Apply chain gas settings from registry when true")
1648
+ });
1649
+ function mcpServerMultisignInput(fields) {
1650
+ return mcpServerCommonInputSchema.extend(fields);
1651
+ }
1652
+ var mcpServerSubmitOutputSchema = zod.z.object({
1653
+ requestId: zod.z.string().min(1)
1654
+ }).describe("mpc-auth multiSignRequest id; continue with trigger_sign_result / broadcast_sign_result");
1655
+ var MCP_NON_SUBMIT_TOOL_NAMES = /* @__PURE__ */ new Set([
1656
+ "ctm_uniswap_v4_quote",
1657
+ "ctm_uniswap_v4_create_swap"
1658
+ ]);
1163
1659
 
1164
1660
  // src/agent/catalog.ts
1165
1661
  registerProtocolModule(uniswapV4ProtocolModule);
@@ -1193,10 +1689,12 @@ function getAgentCatalog() {
1193
1689
 
1194
1690
  exports.EVM_COMMON_PARAM_DOCS = EVM_COMMON_PARAM_DOCS;
1195
1691
  exports.MANAGEMENT_SIG_DOC = MANAGEMENT_SIG_DOC;
1692
+ exports.MCP_NON_SUBMIT_TOOL_NAMES = MCP_NON_SUBMIT_TOOL_NAMES;
1196
1693
  exports.MCP_TOOL_DEFINITIONS = MCP_TOOL_DEFINITIONS;
1197
1694
  exports.MCP_TOOL_INPUT_SCHEMAS = MCP_TOOL_INPUT_SCHEMAS;
1198
1695
  exports.MCP_TOOL_OUTPUT_SCHEMAS = MCP_TOOL_OUTPUT_SCHEMAS;
1199
1696
  exports.MULTISIGN_OUTPUT_DOC = MULTISIGN_OUTPUT_DOC;
1697
+ exports.PROTOCOL_SUPPORT_ADVISORS = PROTOCOL_SUPPORT_ADVISORS;
1200
1698
  exports.chainDetailSchema = chainDetailSchema;
1201
1699
  exports.evmAddressSchema = evmAddressSchema;
1202
1700
  exports.evmMultisignCommonInputSchema = evmMultisignCommonInputSchema;
@@ -1207,9 +1705,15 @@ exports.getMcpToolByName = getMcpToolByName;
1207
1705
  exports.getMcpToolDefinitions = getMcpToolDefinitions;
1208
1706
  exports.getMcpToolInputSchema = getMcpToolInputSchema;
1209
1707
  exports.getMcpToolOutputSchema = getMcpToolOutputSchema;
1708
+ exports.getProtocolDiscoverySummary = getProtocolDiscoverySummary;
1210
1709
  exports.getProtocolModules = getProtocolModules;
1710
+ exports.getProtocolSkill = getProtocolSkill;
1711
+ exports.getProtocolSupportAdvisor = getProtocolSupportAdvisor;
1712
+ exports.getToolsForProtocol = getToolsForProtocol;
1211
1713
  exports.jsonObjectSchema = jsonObjectSchema;
1212
1714
  exports.keyGenSchema = keyGenSchema;
1715
+ exports.listProtocolSupportAdvisorIds = listProtocolSupportAdvisorIds;
1716
+ exports.listProtocolsWithSkills = listProtocolsWithSkills;
1213
1717
  exports.mcpAaveV4BorrowInputSchema = mcpAaveV4BorrowInputSchema;
1214
1718
  exports.mcpAaveV4DepositInputSchema = mcpAaveV4DepositInputSchema;
1215
1719
  exports.mcpAaveV4RepayInputSchema = mcpAaveV4RepayInputSchema;
@@ -1234,6 +1738,9 @@ exports.mcpMapleDepositInputSchema = mcpMapleDepositInputSchema;
1234
1738
  exports.mcpMapleRequestRedeemInputSchema = mcpMapleRequestRedeemInputSchema;
1235
1739
  exports.mcpMultisignInput = mcpMultisignInput;
1236
1740
  exports.mcpMultisignOutputSchema = multisignOutputSchema;
1741
+ exports.mcpServerCommonInputSchema = mcpServerCommonInputSchema;
1742
+ exports.mcpServerMultisignInput = mcpServerMultisignInput;
1743
+ exports.mcpServerSubmitOutputSchema = mcpServerSubmitOutputSchema;
1237
1744
  exports.mcpSkyLockstakeCloseInputSchema = mcpSkyLockstakeCloseInputSchema;
1238
1745
  exports.mcpSkyLockstakeDrawInputSchema = mcpSkyLockstakeDrawInputSchema;
1239
1746
  exports.mcpSkyLockstakeGetRewardInputSchema = mcpSkyLockstakeGetRewardInputSchema;