@continuumdao/ctm-mpc-defi 0.2.56 → 0.2.58

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 (66) hide show
  1. package/dist/agent/catalog.cjs +749 -171
  2. package/dist/agent/catalog.cjs.map +1 -1
  3. package/dist/agent/catalog.d.ts +373 -44
  4. package/dist/agent/catalog.js +738 -173
  5. package/dist/agent/catalog.js.map +1 -1
  6. package/dist/agent/skills/aave-v4/SKILL.md +26 -3
  7. package/dist/agent/skills/aerodrome/SKILL.md +3 -1
  8. package/dist/agent/skills/circle-cctp/SKILL.md +1 -1
  9. package/dist/agent/skills/curve-dao/SKILL.md +2 -2
  10. package/dist/agent/skills/railgun/SKILL.md +39 -0
  11. package/dist/agent/skills/uniswap-v4/SKILL.md +2 -2
  12. package/dist/index.cjs +165 -19
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.js +166 -20
  15. package/dist/index.js.map +1 -1
  16. package/dist/protocols/evm/aave-v4/index.cjs +198 -15
  17. package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
  18. package/dist/protocols/evm/aave-v4/index.d.ts +62 -7
  19. package/dist/protocols/evm/aave-v4/index.js +189 -16
  20. package/dist/protocols/evm/aave-v4/index.js.map +1 -1
  21. package/dist/protocols/evm/aerodrome/index.cjs +152 -63
  22. package/dist/protocols/evm/aerodrome/index.cjs.map +1 -1
  23. package/dist/protocols/evm/aerodrome/index.d.ts +30 -58
  24. package/dist/protocols/evm/aerodrome/index.js +151 -64
  25. package/dist/protocols/evm/aerodrome/index.js.map +1 -1
  26. package/dist/protocols/evm/circle-cctp/index.cjs +5 -3
  27. package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
  28. package/dist/protocols/evm/circle-cctp/index.d.ts +3 -1
  29. package/dist/protocols/evm/circle-cctp/index.js +5 -4
  30. package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
  31. package/dist/protocols/evm/compound-v3/index.cjs +115 -2
  32. package/dist/protocols/evm/compound-v3/index.cjs.map +1 -1
  33. package/dist/protocols/evm/compound-v3/index.js +116 -3
  34. package/dist/protocols/evm/compound-v3/index.js.map +1 -1
  35. package/dist/protocols/evm/continuum-dao/index.cjs +1 -1
  36. package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -1
  37. package/dist/protocols/evm/continuum-dao/index.d.ts +1 -1
  38. package/dist/protocols/evm/continuum-dao/index.js +1 -1
  39. package/dist/protocols/evm/continuum-dao/index.js.map +1 -1
  40. package/dist/protocols/evm/curve-dao/index.cjs +120 -5
  41. package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
  42. package/dist/protocols/evm/curve-dao/index.js +120 -5
  43. package/dist/protocols/evm/curve-dao/index.js.map +1 -1
  44. package/dist/protocols/evm/euler-v2/index.cjs +121 -6
  45. package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
  46. package/dist/protocols/evm/euler-v2/index.js +121 -6
  47. package/dist/protocols/evm/euler-v2/index.js.map +1 -1
  48. package/dist/protocols/evm/morpho/index.cjs +129 -57
  49. package/dist/protocols/evm/morpho/index.cjs.map +1 -1
  50. package/dist/protocols/evm/morpho/index.d.ts +2 -1
  51. package/dist/protocols/evm/morpho/index.js +129 -58
  52. package/dist/protocols/evm/morpho/index.js.map +1 -1
  53. package/dist/protocols/evm/pendle/index.cjs +129 -10
  54. package/dist/protocols/evm/pendle/index.cjs.map +1 -1
  55. package/dist/protocols/evm/pendle/index.js +129 -10
  56. package/dist/protocols/evm/pendle/index.js.map +1 -1
  57. package/dist/protocols/evm/railgun/index.cjs +1261 -0
  58. package/dist/protocols/evm/railgun/index.cjs.map +1 -0
  59. package/dist/protocols/evm/railgun/index.d.ts +294 -0
  60. package/dist/protocols/evm/railgun/index.js +1218 -0
  61. package/dist/protocols/evm/railgun/index.js.map +1 -0
  62. package/dist/protocols/evm/uniswap-v4/index.cjs +164 -17
  63. package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
  64. package/dist/protocols/evm/uniswap-v4/index.js +165 -18
  65. package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
  66. package/package.json +17 -1
@@ -48,6 +48,111 @@ var init_chainIdParse = __esm({
48
48
  "src/chains/evm/chainIdParse.ts"() {
49
49
  }
50
50
  });
51
+ function isCoinbaseB20AssetToken(address) {
52
+ try {
53
+ return viem.getAddress(address).toLowerCase().startsWith(COINBASE_B20_ASSET_PREFIX);
54
+ } catch {
55
+ return false;
56
+ }
57
+ }
58
+ function looksLikeCoinbaseStockSymbol(symbol) {
59
+ return /^[A-Za-z][A-Za-z0-9]{0,8}(?:\.[A-Za-z][A-Za-z0-9]{0,4})?c$/.test((symbol ?? "").trim());
60
+ }
61
+ function indexCatalog(rows) {
62
+ catalogRows = rows;
63
+ catalogAt = Date.now();
64
+ catalogBySymbol.clear();
65
+ catalogByAddress.clear();
66
+ for (const row of rows) {
67
+ catalogBySymbol.set(row.symbol.toLowerCase(), row);
68
+ catalogByAddress.set(row.address.toLowerCase(), row);
69
+ }
70
+ }
71
+ function parseCoinbaseTokenizedStocksPayload(payload) {
72
+ const tokens = Array.isArray(payload) ? payload : payload && typeof payload === "object" && Array.isArray(payload.tokens) ? payload.tokens : [];
73
+ const out = [];
74
+ const seen = /* @__PURE__ */ new Set();
75
+ for (const row of tokens) {
76
+ if (!row || typeof row !== "object") continue;
77
+ const rec = row;
78
+ const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
79
+ const addressRaw = typeof rec.contract_address === "string" ? rec.contract_address.trim() : "";
80
+ if (!looksLikeCoinbaseStockSymbol(symbol) || !isCoinbaseB20AssetToken(addressRaw)) continue;
81
+ const address = viem.getAddress(addressRaw);
82
+ const key = address.toLowerCase();
83
+ if (seen.has(key)) continue;
84
+ seen.add(key);
85
+ const name = typeof rec.name === "string" && rec.name.trim() ? rec.name.trim() : symbol;
86
+ const iconUrl = typeof rec.icon_url === "string" && rec.icon_url.trim() ? rec.icon_url.trim() : void 0;
87
+ const decimals = typeof rec.decimals === "number" && Number.isInteger(rec.decimals) && rec.decimals >= 0 && rec.decimals <= 18 ? rec.decimals : COINBASE_B20_STOCK_DECIMALS;
88
+ out.push({ address, symbol, name, decimals, iconUrl });
89
+ if (out.length >= CATALOG_MAX) break;
90
+ }
91
+ return out;
92
+ }
93
+ async function fetchCoinbaseB20StockCatalog() {
94
+ const merged = [];
95
+ const seen = /* @__PURE__ */ new Set();
96
+ let pageToken = "";
97
+ for (let page = 0; page < 4; page++) {
98
+ const url = new URL(COINBASE_TOKENIZED_STOCKS_API_URL);
99
+ url.searchParams.set("page_size", "500");
100
+ if (pageToken) url.searchParams.set("page_token", pageToken);
101
+ const res = await fetch(url, { cache: "no-store", signal: AbortSignal.timeout(8e3) });
102
+ if (!res.ok) break;
103
+ const json = await res.json();
104
+ for (const row of parseCoinbaseTokenizedStocksPayload(json)) {
105
+ const key = row.address.toLowerCase();
106
+ if (seen.has(key)) continue;
107
+ seen.add(key);
108
+ merged.push(row);
109
+ if (merged.length >= CATALOG_MAX) break;
110
+ }
111
+ pageToken = typeof json.next_page_token === "string" ? json.next_page_token.trim() : "";
112
+ if (!pageToken || merged.length >= CATALOG_MAX) break;
113
+ }
114
+ if (merged.length > 0) indexCatalog(merged);
115
+ return catalogRows ?? [];
116
+ }
117
+ async function ensureCoinbaseB20StockCatalog() {
118
+ if (catalogRows && catalogRows.length > 0 && Date.now() - catalogAt < CATALOG_TTL_MS) return catalogRows;
119
+ if (!catalogInflight) {
120
+ catalogInflight = fetchCoinbaseB20StockCatalog().finally(() => {
121
+ catalogInflight = null;
122
+ });
123
+ }
124
+ try {
125
+ return await catalogInflight;
126
+ } catch {
127
+ return catalogRows ?? [];
128
+ }
129
+ }
130
+ function lookupCoinbaseB20StockToken(token) {
131
+ const key = (token ?? "").trim();
132
+ if (!key) return null;
133
+ const fromCatalog = catalogBySymbol.get(key.toLowerCase());
134
+ if (fromCatalog) return fromCatalog;
135
+ try {
136
+ return catalogByAddress.get(viem.getAddress(key).toLowerCase()) ?? null;
137
+ } catch {
138
+ return null;
139
+ }
140
+ }
141
+ var COINBASE_B20_STOCK_DECIMALS, COINBASE_B20_ASSET_PREFIX, COINBASE_TOKENIZED_STOCKS_API_URL, CATALOG_TTL_MS, CATALOG_MAX, catalogRows, catalogAt, catalogInflight, catalogBySymbol, catalogByAddress;
142
+ var init_coinbaseB20 = __esm({
143
+ "src/protocols/evm/shared/coinbaseB20.ts"() {
144
+ COINBASE_B20_STOCK_DECIMALS = 8;
145
+ COINBASE_B20_ASSET_PREFIX = "0xb200000000000000000000";
146
+ COINBASE_TOKENIZED_STOCKS_API_URL = "https://api.coinbase.com/v1/tokenized-stocks";
147
+ CATALOG_TTL_MS = 15 * 60 * 1e3;
148
+ CATALOG_MAX = 500;
149
+ catalogRows = null;
150
+ catalogAt = 0;
151
+ catalogInflight = null;
152
+ catalogBySymbol = /* @__PURE__ */ new Map();
153
+ catalogByAddress = /* @__PURE__ */ new Map();
154
+ }
155
+ });
51
156
  function defiEvmTransport(rpcUrl, opts) {
52
157
  const url = rpcUrl.trim();
53
158
  return viem.http(url, opts);
@@ -183,7 +288,7 @@ var init_constants = __esm({
183
288
  rewards: viem.zeroAddress,
184
289
  governor: viem.zeroAddress
185
290
  };
186
- CTM_TOKEN_ADDRESS = viem.getAddress("0x2026027054F5beBCEB650aBD62dC623e327658e7");
291
+ CTM_TOKEN_ADDRESS = viem.getAddress("0x7581696b0ED142f6534E5797baaABBb9a1b27086");
187
292
  VOTING_ESCROW_LINEA_ADDRESS = viem.getAddress("0x221EC90B3B083A8501A37bdeb7035CeaedF3C31f");
188
293
  viem.getAddress("0x4ebd7cCBe32a51d1638cFE90E8eD1c4BdF42f729");
189
294
  VOTING_ESCROW_MARKETPLACE_LINEA_ADDRESS = viem.getAddress("0x92557d38beAe4658d3c03A02F349FFB60c3bfFA5");
@@ -520,27 +625,6 @@ var init_midnightApi = __esm({
520
625
  init_midnightConstants();
521
626
  }
522
627
  });
523
- var COINBASE_B20_STOCK_TOKENS, COINBASE_B20_STOCK_DECIMALS;
524
- var init_coinbaseB20 = __esm({
525
- "src/protocols/evm/shared/coinbaseB20.ts"() {
526
- COINBASE_B20_STOCK_TOKENS = [
527
- { symbol: "AAPLc", name: "Apple Inc.", address: "0xb200000000000000000000C2e324d24d7eEcd1fb" },
528
- { symbol: "NVDAc", name: "NVIDIA Corporation", address: "0xb20000000000000000000078ee7ce2fE4908108C" },
529
- { symbol: "METAc", name: "Meta Platforms Inc.", address: "0xb2000000000000000000008bC8786B856E61707C" },
530
- { symbol: "GOOGLc", name: "Alphabet Inc.", address: "0xb2000000000000000000002D0BA3164cc74f58B7" },
531
- { symbol: "AMZNc", name: "Amazon.com Inc.", address: "0xb200000000000000000000d9192b6B456483C2E8" },
532
- { symbol: "TSLAc", name: "Tesla Inc.", address: "0xb2000000000000000000001e800a7f5189430cD0" },
533
- { symbol: "MSFTc", name: "Microsoft Corporation", address: "0xB200000000000000000000Ab99cFa739E253872B" },
534
- { symbol: "COINc", name: "Coinbase Global Inc.", address: "0xb200000000000000000000c85a31389D71F3ecfb" },
535
- { symbol: "MSTRc", name: "Strategy Inc.", address: "0xb2000000000000000000004884b426556b92883d" },
536
- { symbol: "CRCLc", name: "Circle Internet Group Inc.", address: "0xB20000000000000000000019f6E7C675b73C2e4D" },
537
- { symbol: "INTCc", name: "Intel Corporation", address: "0xB2000000000000000000004AFF16039bA04bdFBc" },
538
- { symbol: "SNDKc", name: "Sandisk Corporation", address: "0xb200000000000000000000397293Cb8cda9a10c5" },
539
- { symbol: "SPCXc", name: "Space Exploration Technologies Corp.", address: "0xb2000000000000000000007b9fcbd005511aCBd5" }
540
- ];
541
- COINBASE_B20_STOCK_DECIMALS = 8;
542
- }
543
- });
544
628
  function isAerodromeChainSupported(chainId) {
545
629
  const n = typeof chainId === "number" ? chainId : Number.parseInt(String(chainId), 10);
546
630
  return n === AERODROME_CHAIN_ID;
@@ -944,9 +1028,9 @@ async function loadFullCurveSessionForRpc(rpcUrl) {
944
1028
  if (!url) {
945
1029
  throw new Error("rpcUrl is required.");
946
1030
  }
947
- const cached2 = curveSessionCache.get(url);
948
- if (cached2 && cached2.expiresAt > Date.now()) {
949
- return cached2.session;
1031
+ const cached3 = curveSessionCache.get(url);
1032
+ if (cached3 && cached3.expiresAt > Date.now()) {
1033
+ return cached3.session;
950
1034
  }
951
1035
  try {
952
1036
  const { default: curve } = await import('@curvefi/api');
@@ -1309,7 +1393,108 @@ function parseMultisignBuilderOutput(data) {
1309
1393
  return multisignOutputSchema.parse(data);
1310
1394
  }
1311
1395
 
1396
+ // src/protocols/evm/aave-v4/api.ts
1397
+ init_defiProxy();
1398
+ init_coinbaseB20();
1399
+ var AAVE_V4_GRAPHQL_URL = "https://api.v4.aave.com/graphql";
1400
+ async function aaveV4Gql(query, variables) {
1401
+ const body = { query, variables: variables ?? {} };
1402
+ const j = await postJsonViaOptionalProxy({
1403
+ directUrl: AAVE_V4_GRAPHQL_URL,
1404
+ body,
1405
+ proxyUrl: getAaveGraphqlProxyUrl(),
1406
+ proxyEnvelope: body
1407
+ });
1408
+ if (j.errors?.length) {
1409
+ const msg = j.errors.map((e) => e.message ?? "Unknown").join("; ");
1410
+ throw new Error(msg);
1411
+ }
1412
+ if (j.data == null) {
1413
+ throw new Error("Aave V4 API: empty response");
1414
+ }
1415
+ return j.data;
1416
+ }
1417
+ async function fetchAaveV4Chains() {
1418
+ const d = await aaveV4Gql(`
1419
+ query C($c: ChainsRequest!) { chains(request: $c) { chainId name nativeWrappedToken } }
1420
+ `, { c: { query: { filter: "ALL" } } });
1421
+ return d.chains ?? [];
1422
+ }
1423
+ async function loadAaveV4SupportedChainIdsFromV4Api() {
1424
+ const rows = await fetchAaveV4Chains();
1425
+ const s = /* @__PURE__ */ new Set();
1426
+ for (const c of rows) s.add(c.chainId);
1427
+ return s;
1428
+ }
1429
+ var RESERVES_ADDRESS_FRAGMENT = `
1430
+ asset { underlying { address } }
1431
+ `;
1432
+ async function fetchAaveV4NativeWrappedToken(chainId) {
1433
+ const all = await fetchAaveV4Chains();
1434
+ const c = all.find((x) => x.chainId === chainId);
1435
+ const t = (c?.nativeWrappedToken ?? "").trim();
1436
+ if (t && viem.isAddress(t)) return viem.getAddress(t);
1437
+ return null;
1438
+ }
1439
+ async function fetchAaveV4SupportedUnderlyingAddressSet(chainId) {
1440
+ const d = await aaveV4Gql(
1441
+ `
1442
+ query A($r: ReservesRequest!) { reserves(request: $r) { ${RESERVES_ADDRESS_FRAGMENT} } }
1443
+ `,
1444
+ {
1445
+ r: {
1446
+ query: { chainIds: [chainId] },
1447
+ filter: "ALL",
1448
+ orderBy: { supplyApy: "DESC" }
1449
+ }
1450
+ }
1451
+ );
1452
+ const s = /* @__PURE__ */ new Set();
1453
+ for (const r of d.reserves ?? []) {
1454
+ const a = (r.asset?.underlying?.address ?? "").trim();
1455
+ if (a && viem.isAddress(a)) s.add(a.toLowerCase());
1456
+ }
1457
+ return s;
1458
+ }
1459
+ var aaveV4ChainTokenCache = /* @__PURE__ */ new Map();
1460
+ function ensureAaveV4ChainTokenCache(chainId) {
1461
+ const hit = aaveV4ChainTokenCache.get(chainId);
1462
+ if (hit) return hit;
1463
+ const p = (async () => {
1464
+ const [nativeWrapped, supportedUnderlying] = await Promise.all([
1465
+ fetchAaveV4NativeWrappedToken(chainId),
1466
+ fetchAaveV4SupportedUnderlyingAddressSet(chainId)
1467
+ ]);
1468
+ return { supportedUnderlying, nativeWrapped };
1469
+ })();
1470
+ aaveV4ChainTokenCache.set(chainId, p);
1471
+ return p;
1472
+ }
1473
+ function parseAaveV4UiMarketId(raw) {
1474
+ const t = (raw ?? "").trim().toLowerCase().replace(/\s+/g, " ");
1475
+ if (!t) return void 0;
1476
+ if (t === "core") return "core";
1477
+ if (t === "bluechip" || t === "prime" || t === "institutional") return "bluechip";
1478
+ if (t === "main" || t === "plus" || t === "default") return "main";
1479
+ if (t === "bstocks" || t === "bstock" || t === "b stocks" || t === "stocks" || t === "stock" || t === "equities" || t === "equity" || t === "coinbase stocks" || t === "tokenized stocks" || t === "tokenised stocks") {
1480
+ return "bstocks";
1481
+ }
1482
+ return void 0;
1483
+ }
1484
+ function resolveAaveV4UnderlyingAddress(token) {
1485
+ const raw = (token ?? "").trim();
1486
+ if (!raw) return null;
1487
+ if (viem.isAddress(raw)) return viem.getAddress(raw);
1488
+ return lookupCoinbaseB20StockToken(raw)?.address ?? null;
1489
+ }
1490
+
1312
1491
  // src/agent/schemas/chainPreprocess.ts
1492
+ function rewriteAaveV4AssetField(o, key) {
1493
+ const raw = String(o[key] ?? "").trim();
1494
+ if (!raw || viem.isAddress(raw)) return;
1495
+ const resolved = resolveAaveV4UnderlyingAddress(raw);
1496
+ if (resolved) o[key] = resolved;
1497
+ }
1313
1498
  function preprocessObject(raw) {
1314
1499
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
1315
1500
  return { ...raw };
@@ -1651,6 +1836,12 @@ function preprocessAaveMultisignInput(action) {
1651
1836
  return (raw) => {
1652
1837
  const o = preprocessObject(raw);
1653
1838
  if (!o) return raw;
1839
+ rewriteAaveV4AssetField(o, "underlying");
1840
+ rewriteAaveV4AssetField(o, "collateralUnderlying");
1841
+ if (typeof o.marketId === "string") {
1842
+ const id = parseAaveV4UiMarketId(o.marketId);
1843
+ if (id) o.marketId = id;
1844
+ }
1654
1845
  derivePurposeIfMissing(o, (x) => {
1655
1846
  const amt = String(x.amountHuman ?? "").trim();
1656
1847
  const asset = String(x.underlying ?? "").trim();
@@ -1667,8 +1858,8 @@ var uniswapQuoteTradeTypeSchema = zod.z.enum(["EXACT_INPUT", "EXACT_OUTPUT"]);
1667
1858
  var mcpUniswapV4QuoteInputSchema = zod.z.object({
1668
1859
  type: uniswapQuoteTradeTypeSchema.describe("EXACT_INPUT or EXACT_OUTPUT"),
1669
1860
  amount: zod.z.string().min(1).describe("Amount in token-in base units (wei string for ERC-20)"),
1670
- tokenIn: zod.z.string().min(1).describe("Input token; 0x0 for native ETH"),
1671
- tokenOut: zod.z.string().min(1).describe("Output token address"),
1861
+ tokenIn: zod.z.string().min(1).describe("Input token address or Coinbase stock ticker (AAPLc); 0x0 for native ETH"),
1862
+ tokenOut: zod.z.string().min(1).describe("Output token address or Coinbase stock ticker (AAPLc)"),
1672
1863
  chainId: agentEvmChainIdSchema.describe("tokenInChainId / same-chain default"),
1673
1864
  uniswapApiKey: zod.z.string().min(1).describe("Uniswap Trade API x-api-key"),
1674
1865
  swapper: evmAddressSchema.optional().describe("MPC executor; omit if keyGen + managementNodeUrl provided"),
@@ -1704,7 +1895,9 @@ var mcpUniswapV4BuildSwapMultisignInputSchema = withMultisignKeySourceRefine(
1704
1895
  zod.z.preprocess(
1705
1896
  preprocessUniswapBuildSwapInput,
1706
1897
  evmMultisignCommonInputSchema.extend({
1707
- tokenIn: evmAddressSchema.describe("Token in; 0x0 for native ETH"),
1898
+ tokenIn: evmAddressSchema.describe(
1899
+ "Token in address or Coinbase stock ticker (AAPLc); 0x0 for native ETH"
1900
+ ),
1708
1901
  swap: swapTxRequestSchema,
1709
1902
  createSwapResponse: zod.z.object({
1710
1903
  swap: swapTxRequestSchema,
@@ -1721,8 +1914,8 @@ var mcpUniswapV4LimitOrderQuoteInputSchema = zod.z.object({
1721
1914
  type: uniswapQuoteTradeTypeSchema.describe("EXACT_INPUT or EXACT_OUTPUT"),
1722
1915
  amount: zod.z.string().min(1).describe("Amount in token-in base units (wei string for ERC-20)"),
1723
1916
  limitPrice: zod.z.string().min(1).describe("Limit price string from Trade API (pair exchange rate)"),
1724
- tokenIn: zod.z.string().min(1).describe("Input token; 0x0 for native ETH"),
1725
- tokenOut: zod.z.string().min(1).describe("Output token address"),
1917
+ tokenIn: zod.z.string().min(1).describe("Input token address or Coinbase stock ticker (AAPLc); 0x0 for native ETH"),
1918
+ tokenOut: zod.z.string().min(1).describe("Output token address or Coinbase stock ticker (AAPLc)"),
1726
1919
  chainId: agentEvmChainIdSchema.describe("Must be 1 (Ethereum mainnet) for limit orders"),
1727
1920
  orderDeadline: agentCoercedIntSchema(zod.z.number().int().positive()).describe("Unix seconds when unfilled order expires"),
1728
1921
  uniswapApiKey: zod.z.string().min(1).describe("Uniswap Trade API x-api-key"),
@@ -2069,8 +2262,8 @@ var mcpUniswapV4BuildAllowlistFinalizeMultisignInputSchema = withMultisignKeySou
2069
2262
  var mcpCurveDaoQuoteInputSchema = zod.z.object({
2070
2263
  chainId: agentEvmChainIdSchema.describe("EVM chain id (rpcUrl resolved from get_chain_registry rpcGateway)"),
2071
2264
  rpcUrl: zod.z.string().min(1).optional().describe("JSON-RPC URL; continuum-mcp-server injects from chain registry \u2014 do not pass a public RPC URL"),
2072
- tokenIn: zod.z.string().min(1).describe("Input token address, or 0xeeee\u2026 / 0x0 / eth for native"),
2073
- tokenOut: zod.z.string().min(1).describe("Output token address or 0xeeee\u2026 native placeholder"),
2265
+ tokenIn: zod.z.string().min(1).describe("Input token address, Coinbase stock ticker (AAPLc), or 0xeeee\u2026 / 0x0 / eth for native"),
2266
+ tokenOut: zod.z.string().min(1).describe("Output token address, Coinbase stock ticker (AAPLc), or 0xeeee\u2026 native placeholder"),
2074
2267
  amountHuman: zod.z.string().min(1).describe("Human-readable amount of tokenIn"),
2075
2268
  tokenInDecimals: zod.z.number().int().min(0).max(18).optional().describe("Token-in decimals; omit to read on-chain (native uses 18)")
2076
2269
  });
@@ -2081,8 +2274,10 @@ var mcpCurveDaoBuildSwapMultisignInputSchema = withMultisignKeySourceRefine(
2081
2274
  zod.z.preprocess(
2082
2275
  preprocessCurveBuildSwapInput,
2083
2276
  evmMultisignCommonInputSchema.extend({
2084
- tokenIn: evmAddressSchema.describe("ERC-20 sold (native in uses WETH path in UI)"),
2085
- tokenOut: zod.z.string().min(1).describe("Output token or 0xeeee\u2026 native placeholder"),
2277
+ tokenIn: evmAddressSchema.describe(
2278
+ "ERC-20 sold, or a Coinbase stock ticker (AAPLc). Native in uses the WETH path in the UI."
2279
+ ),
2280
+ tokenOut: zod.z.string().min(1).describe("Output token, Coinbase stock ticker (AAPLc), or 0xeeee\u2026 native placeholder"),
2086
2281
  amountHuman: zod.z.string().min(1).describe("Human-readable amount of tokenIn"),
2087
2282
  slippagePercent: zod.z.number().gt(0).lt(100).describe("Slippage 0\u2013100 exclusive"),
2088
2283
  quoteSnapshot: jsonObjectSchema.optional().describe("Optional quote row from ctm_curve_dao_quote \u2014 aliases tokenIn/tokenOut/amountHuman")
@@ -3033,7 +3228,9 @@ var mcpSkySusdsDepositInputSchema = mcpMultisignInput({
3033
3228
  var mcpSkySusdsRedeemInputSchema = mcpMultisignInput({
3034
3229
  sharesHuman: zod.z.string().min(1)
3035
3230
  });
3036
- var mcpAaveV4MarketIdSchema = zod.z.string().min(1).optional().describe("UI market segment: main (Plus), core, or bluechip (Prime). Default main.");
3231
+ var mcpAaveV4MarketIdSchema = zod.z.string().min(1).optional().describe(
3232
+ "UI market segment: main (Plus), core, bluechip (Prime), or bstocks (Base Coinbase tokenized stocks). Aliases: stocks, equities. Default main."
3233
+ );
3037
3234
  function mcpAaveV4MultisignInput(fields, action) {
3038
3235
  return withMultisignKeySourceRefine(
3039
3236
  zod.z.preprocess(preprocessAaveMultisignInput(action), evmMultisignCommonInputSchema.extend(fields))
@@ -3051,7 +3248,7 @@ var mcpAaveV4DepositInputSchema = mcpAaveV4MultisignInput(
3051
3248
  {
3052
3249
  spoke: evmAddressSchema.optional().describe("Omit \u2014 continuum-mcp-server resolves spoke from Aave v4 API."),
3053
3250
  underlying: evmAddressSchema.describe(
3054
- "Asset to supply. Native ETH: 0x0 or wrapped native with isNativeIn true."
3251
+ "Asset to supply. Address, or a Base bStock ticker (AAPLc). Native ETH: 0x0 or wrapped native with isNativeIn true."
3055
3252
  ),
3056
3253
  amountHuman: zod.z.string().min(1),
3057
3254
  marketId: mcpAaveV4MarketIdSchema,
@@ -3067,7 +3264,7 @@ var mcpAaveV4DepositInputSchema = mcpAaveV4MultisignInput(
3067
3264
  var mcpAaveV4WithdrawInputSchema = mcpAaveV4MultisignInput(
3068
3265
  {
3069
3266
  spoke: evmAddressSchema.optional().describe("Omit \u2014 server resolves from Aave v4 API."),
3070
- underlying: evmAddressSchema.describe("Supplied asset to withdraw."),
3267
+ underlying: evmAddressSchema.describe("Supplied asset to withdraw. Address or bStock ticker (AAPLc)."),
3071
3268
  amountHuman: zod.z.string().min(1),
3072
3269
  marketId: mcpAaveV4MarketIdSchema,
3073
3270
  ...mcpAaveV4HealthPreviewFields
@@ -3077,10 +3274,14 @@ var mcpAaveV4WithdrawInputSchema = mcpAaveV4MultisignInput(
3077
3274
  var mcpAaveV4BorrowInputSchema = mcpAaveV4MultisignInput(
3078
3275
  {
3079
3276
  spoke: evmAddressSchema.optional().describe("Omit \u2014 server resolves from Aave v4 API."),
3080
- underlying: evmAddressSchema.describe("Debt asset to borrow (e.g. USDC), not collateral."),
3277
+ underlying: evmAddressSchema.describe(
3278
+ "Debt asset to borrow (e.g. USDC), not collateral. On bstocks the equities are not borrowable."
3279
+ ),
3081
3280
  amountHuman: zod.z.string().min(1),
3082
3281
  marketId: mcpAaveV4MarketIdSchema,
3083
- collateralUnderlying: evmAddressSchema.optional().describe("Collateral token already supplied; helps pick hub when debt exists on multiple hubs."),
3282
+ collateralUnderlying: evmAddressSchema.optional().describe(
3283
+ "Collateral token already supplied (address or bStock ticker such as AAPLc). Helps pick the hub when debt exists on multiple hubs."
3284
+ ),
3084
3285
  ...mcpAaveV4HealthPreviewFields
3085
3286
  },
3086
3287
  "borrow"
@@ -3088,7 +3289,7 @@ var mcpAaveV4BorrowInputSchema = mcpAaveV4MultisignInput(
3088
3289
  var mcpAaveV4RepayInputSchema = mcpAaveV4MultisignInput(
3089
3290
  {
3090
3291
  spoke: evmAddressSchema.optional().describe("Omit \u2014 server resolves from Aave v4 API."),
3091
- underlying: evmAddressSchema.describe("Debt token to repay."),
3292
+ underlying: evmAddressSchema.describe("Debt token to repay. On bstocks this is USDC."),
3092
3293
  amountHuman: zod.z.string().min(1),
3093
3294
  marketId: mcpAaveV4MarketIdSchema,
3094
3295
  ...mcpAaveV4HealthPreviewFields
@@ -4266,11 +4467,18 @@ var mcpMapleFetchMarketInputSchema = zod.z.object({
4266
4467
  underlying: zod.z.string().trim().min(1).optional().describe("Deposit asset address or ticker (USDC, USDT, USDG).")
4267
4468
  });
4268
4469
  var mcpMapleFetchMarketOutputSchema = mcpMapleFetchMarketsOutputSchema;
4269
- var mcpAaveV4UiMarketIdSchema = zod.z.enum(["main", "core", "bluechip"]).optional().describe("UI market segment: main (Plus), core, or bluechip (Prime). Omit to list all hubs.");
4470
+ var aaveV4UiMarketIdEnum = zod.z.enum(["main", "core", "bluechip", "bstocks"]);
4471
+ function preprocessAaveV4MarketId(value) {
4472
+ if (typeof value !== "string") return value;
4473
+ return parseAaveV4UiMarketId(value) ?? value;
4474
+ }
4475
+ var mcpAaveV4UiMarketIdSchema = zod.z.preprocess(preprocessAaveV4MarketId, aaveV4UiMarketIdEnum.optional()).describe(
4476
+ "UI market segment: main (Plus), core, bluechip (Prime), or bstocks (Base Coinbase tokenized stocks). Aliases: stocks, equities. Omit to list all hubs."
4477
+ );
4270
4478
  var mcpAaveV4MarketSummarySchema = zod.z.object({
4271
4479
  chainId: zod.z.number(),
4272
4480
  hubName: zod.z.string(),
4273
- marketId: zod.z.enum(["main", "core", "bluechip"]),
4481
+ marketId: aaveV4UiMarketIdEnum,
4274
4482
  hubAddress: zod.z.string(),
4275
4483
  symbol: zod.z.string(),
4276
4484
  name: zod.z.string(),
@@ -4290,7 +4498,9 @@ var mcpAaveV4MarketSummarySchema = zod.z.object({
4290
4498
  var mcpAaveV4FetchMarketsInputSchema = zod.z.object({
4291
4499
  chainId: agentEvmChainIdSchema,
4292
4500
  marketId: mcpAaveV4UiMarketIdSchema,
4293
- underlying: zod.z.string().trim().min(1).optional().describe("Optional filter: ERC-20 address or ticker (USDT, USDC). Omit to list all reserves.")
4501
+ underlying: zod.z.string().trim().min(1).optional().describe(
4502
+ 'Optional filter: ERC-20 address or ticker (USDT, USDC, AAPLc). "stock" lists bStock collateral. Omit to list all reserves.'
4503
+ )
4294
4504
  });
4295
4505
  var mcpAaveV4FetchMarketsOutputSchema = zod.z.object({
4296
4506
  chainId: zod.z.number(),
@@ -4299,14 +4509,21 @@ var mcpAaveV4FetchMarketsOutputSchema = zod.z.object({
4299
4509
  });
4300
4510
  var mcpAaveV4FetchMarketInputSchema = zod.z.object({
4301
4511
  chainId: agentEvmChainIdSchema,
4302
- underlying: zod.z.string().trim().min(1).describe("Reserve underlying address or ticker (e.g. USDT). Prefer fetch_markets when listing rates."),
4512
+ underlying: zod.z.string().trim().min(1).describe(
4513
+ "Reserve underlying address or ticker (USDT, AAPLc). Prefer fetch_markets or fetch_stock_markets when listing rates."
4514
+ ),
4303
4515
  marketId: mcpAaveV4UiMarketIdSchema
4304
4516
  });
4305
4517
  var mcpAaveV4FetchMarketOutputSchema = mcpAaveV4FetchMarketsOutputSchema;
4518
+ var mcpAaveV4FetchStockMarketsInputSchema = zod.z.object({
4519
+ chainId: agentEvmChainIdSchema.optional().describe("Defaults to Base 8453 (Coinbase Stocks hub)."),
4520
+ underlying: zod.z.string().trim().min(1).optional().describe("B20 ticker or address (AAPLc), or USDC. Omit to list the whole Coinbase Stocks hub.")
4521
+ });
4522
+ var mcpAaveV4FetchStockMarketsOutputSchema = mcpAaveV4FetchMarketsOutputSchema;
4306
4523
  var mcpEulerV2FetchLendVaultsInputSchema = zod.z.object({
4307
4524
  chainId: agentEvmChainIdSchema,
4308
4525
  underlyingAddress: evmAddressSchema.describe(
4309
- "Underlying asset address from get_defi_protocol_supported_tokens."
4526
+ "Underlying asset address, or a Coinbase stock ticker (AAPLc) from the live catalog."
4310
4527
  ),
4311
4528
  limit: agentCoercedOptionalIntSchema(zod.z.number().int().min(1).max(100)).describe("Max vault rows (default 30).")
4312
4529
  });
@@ -4328,7 +4545,7 @@ var mcpEulerV2FetchLendVaultsOutputSchema = zod.z.object({
4328
4545
  var mcpEulerV2FetchEarnVaultsInputSchema = zod.z.object({
4329
4546
  chainId: agentEvmChainIdSchema,
4330
4547
  underlyingAddress: evmAddressSchema.describe(
4331
- "Underlying asset address from get_defi_protocol_supported_tokens."
4548
+ "Underlying asset address, or a Coinbase stock ticker (AAPLc) from the live catalog."
4332
4549
  ),
4333
4550
  limit: agentCoercedOptionalIntSchema(zod.z.number().int().min(1).max(100)).describe("Max vault rows (default 30).")
4334
4551
  });
@@ -4355,6 +4572,77 @@ var mcpLidoFetchStethAprOutputSchema = zod.z.object({
4355
4572
  source: zod.z.string(),
4356
4573
  notes: zod.z.string()
4357
4574
  });
4575
+ var mcpRailgunFetchPopularAssetsInputSchema = zod.z.object({
4576
+ chainId: agentEvmChainIdSchema,
4577
+ rpcUrl: zod.z.string().min(1).optional().describe("Server-filled from the chain registry. Agents should omit.")
4578
+ }).strict();
4579
+ var mcpRailgunFetchPopularAssetsOutputSchema = zod.z.object({
4580
+ chainId: zod.z.number(),
4581
+ tokens: zod.z.array(zod.z.object({ address: zod.z.string() }).strict()),
4582
+ nativeWrapped: zod.z.string().optional(),
4583
+ notes: zod.z.string()
4584
+ }).strict();
4585
+ var mcpRailgunFetchPrivateBalancesInputSchema = zod.z.object({
4586
+ keyGenId: zod.z.string().min(1).describe("KeyGen request id. The shielded wallet is stored on that KeyGen record."),
4587
+ chainId: agentEvmChainIdSchema,
4588
+ refresh: zod.z.boolean().optional().describe("Scan again and write the KeyGen record. Default reads the stored scan, and scans when none is stored.")
4589
+ }).strict();
4590
+ var mcpRailgunPrivateBalanceSchema = zod.z.object({
4591
+ tokenAddress: zod.z.string(),
4592
+ spendable: zod.z.string(),
4593
+ pending: zod.z.string(),
4594
+ symbol: zod.z.string().optional()
4595
+ }).strict();
4596
+ var mcpRailgunFetchPrivateBalancesOutputSchema = zod.z.object({
4597
+ railgunAddress: zod.z.string(),
4598
+ walletConfigured: zod.z.boolean(),
4599
+ chainId: zod.z.number(),
4600
+ scanned: zod.z.boolean(),
4601
+ scanStatus: zod.z.enum(["scanning", "ready", "empty", "error", "unscanned"]),
4602
+ balances: zod.z.array(mcpRailgunPrivateBalanceSchema),
4603
+ notes: zod.z.string()
4604
+ }).strict();
4605
+ var mcpRailgunEnsureWalletInputSchema = zod.z.object({
4606
+ keyGenId: zod.z.string().min(1),
4607
+ chainId: agentEvmChainIdSchema.optional()
4608
+ }).strict();
4609
+ var mcpRailgunEnsureWalletOutputSchema = zod.z.object({
4610
+ railgunAddress: zod.z.string(),
4611
+ created: zod.z.boolean()
4612
+ }).strict();
4613
+ var mcpRailgunShieldInputSchema = mcpMultisignInput({
4614
+ tokenAddress: evmAddressSchema.describe("ERC-20 contract to shield"),
4615
+ amountWei: zod.z.string().min(1).describe("Amount in wei"),
4616
+ railgunAddress: zod.z.string().min(1).describe("Recipient 0zk address"),
4617
+ shieldSignature: zod.z.string().min(1).optional().describe("personal_sign result from the first shield call. Omit on the first call.")
4618
+ });
4619
+ var mcpRailgunPrivateTransferInputSchema = zod.z.object({
4620
+ keyGenId: zod.z.string().min(1),
4621
+ chainId: agentEvmChainIdSchema,
4622
+ tokenAddress: evmAddressSchema,
4623
+ amountWei: zod.z.string().min(1),
4624
+ recipientAddress: zod.z.string().min(1).describe("Recipient 0zk address"),
4625
+ memoText: zod.z.string().optional()
4626
+ }).strict();
4627
+ var mcpRailgunUnshieldInputSchema = zod.z.object({
4628
+ keyGenId: zod.z.string().min(1),
4629
+ chainId: agentEvmChainIdSchema,
4630
+ tokenAddress: evmAddressSchema,
4631
+ amountWei: zod.z.string().min(1),
4632
+ recipientAddress: evmAddressSchema.optional().describe("Public recipient. Defaults to this KeyGen Ethereum address.")
4633
+ }).strict();
4634
+ var mcpRailgunAgreeSpendInputSchema = zod.z.object({
4635
+ keyGenId: zod.z.string().min(1),
4636
+ spendId: zod.z.string().min(1)
4637
+ }).strict();
4638
+ var mcpRailgunPrivateActionOutputSchema = zod.z.object({
4639
+ status: zod.z.enum(["pending", "submitted", "failed"]),
4640
+ spendId: zod.z.string(),
4641
+ approvals: zod.z.number().int().nonnegative(),
4642
+ quorum: zod.z.number().int().positive(),
4643
+ txHash: zod.z.string().optional(),
4644
+ error: zod.z.string().optional()
4645
+ }).strict();
4358
4646
  var mcpSkyFetchSusdsRateInputSchema = zod.z.object({
4359
4647
  rpcUrl: zod.z.string().min(1).optional().describe("Server-filled from chain registry. Agents should omit.")
4360
4648
  }).strict();
@@ -4423,7 +4711,7 @@ var mcpPendleFetchMerkleRewardsOutputSchema = jsonObjectSchema.describe(
4423
4711
  var mcpPendleQuoteSwapInputSchema = zod.z.object({
4424
4712
  chainId: agentEvmChainIdSchema,
4425
4713
  rpcUrl: zod.z.string().min(1).optional(),
4426
- tokenIn: zod.z.string().min(1).describe("Underlying, PT, or YT (0xeeee / 0x0 = native)."),
4714
+ tokenIn: zod.z.string().min(1).describe("Underlying, PT, YT, or Coinbase stock ticker (AAPLc). 0xeeee / 0x0 = native."),
4427
4715
  tokenOut: zod.z.string().min(1),
4428
4716
  amountHuman: zod.z.string().min(1),
4429
4717
  slippagePercent: zod.z.number().gt(0).lt(100),
@@ -6097,7 +6385,7 @@ var mcpCctpFetchBurnFeesInputSchema = zod.z.object({
6097
6385
  transferAmountHuman: zod.z.string().min(1).optional().describe(
6098
6386
  "Human USDC amount the recipient receives (6 decimals). Required for a maxFee that includes the fast-transfer protocol fee and for totalBurn. Omit only to inspect raw forwarding tiers."
6099
6387
  ),
6100
- feeTier: zod.z.enum(["low", "med", "high"]).optional().describe("Iris forwardFee tier; default med"),
6388
+ feeTier: zod.z.enum(["low", "med", "high"]).optional().describe("Iris forwardFee tier; default high"),
6101
6389
  minFinalityThreshold: agentCoercedOptionalIntSchema(zod.z.number().int().positive()).describe(
6102
6390
  "Iris fee row. 1000 (default) is fast transfer and includes minimumFee bps. 2000 is standard transfer."
6103
6391
  )
@@ -6134,7 +6422,7 @@ var mcpCctpBuildBurnMultisignInputSchema = mcpMultisignInput({
6134
6422
  destChainId: agentEvmChainIdSchema.describe("Destination chain EIP-155 id (mint chain)"),
6135
6423
  transferAmountHuman: zod.z.string().min(1).describe("Human USDC amount recipient receives"),
6136
6424
  mintRecipient: evmAddressSchema.optional().describe("Recipient on destination chain; defaults to MPC executor address"),
6137
- feeTier: zod.z.enum(["low", "med", "high"]).optional(),
6425
+ feeTier: zod.z.enum(["low", "med", "high"]).optional().describe("Iris forwardFee tier; default high"),
6138
6426
  minFinalityThreshold: agentCoercedOptionalIntSchema(zod.z.number().int().positive()),
6139
6427
  feeSnapshot: jsonObjectSchema.optional().describe(
6140
6428
  "Optional output from ctm_cctp_fetch_burn_fees. Build re-quotes Iris. A snapshot maxFee below the live forward+protocol total is ignored; a higher snapshot is kept as a cap."
@@ -6558,7 +6846,7 @@ var MCP_PROTOCOL_TOOL_DEFINITIONS = [
6558
6846
  actionId: "aave-v4.deposit",
6559
6847
  protocolId: "aave-v4",
6560
6848
  chainCategory: "evm",
6561
- description: "Build Aave v4 Spoke supply/deposit batch (wrap native, approve, supply).",
6849
+ description: "Build Aave v4 Spoke supply/deposit batch (wrap native, approve, supply). Base bStocks: marketId bstocks and underlying ticker (AAPLc) or address.",
6562
6850
  prerequisites: ["keyGenId", "chainId", "underlying", "amountHuman", "get_defi_protocol_skill for hubs/spokes"],
6563
6851
  handler: { importPath: "protocols/evm/aave-v4", exportName: "buildEvmMultisignBodyAaveV4DepositBatch" },
6564
6852
  inputZod: mcpAaveV4DepositInputSchema
@@ -6578,7 +6866,7 @@ var MCP_PROTOCOL_TOOL_DEFINITIONS = [
6578
6866
  actionId: "aave-v4.borrow",
6579
6867
  protocolId: "aave-v4",
6580
6868
  chainCategory: "evm",
6581
- description: "Build Aave v4 Spoke borrow; underlying is debt asset; collateral must be supplied first.",
6869
+ description: "Build Aave v4 Spoke borrow; underlying is the debt asset (USDC on bstocks). Equities are collateral-only. collateralUnderlying may be a bStock ticker (AAPLc).",
6582
6870
  prerequisites: [
6583
6871
  "keyGenId",
6584
6872
  "chainId",
@@ -7712,6 +8000,16 @@ var MCP_PROTOCOL_TOOL_DEFINITIONS = [
7712
8000
  prerequisites: ["keyGenId", "chainId 999", "question", "outcome", "amountHuman", "purposeText"],
7713
8001
  handler: { importPath: "protocols/evm/hyperliquidOutcome", exportName: "buildEvmMultisignBodyHyperliquidOutcomeNegate" },
7714
8002
  inputZod: mcpHyperliquidOutcomeNegateInputSchema
8003
+ }),
8004
+ defineProtocolMcpTool({
8005
+ name: "ctm_railgun_build_shield_multisign",
8006
+ actionId: "railgun.shield",
8007
+ protocolId: "railgun",
8008
+ chainCategory: "evm",
8009
+ description: "Shield an ERC-20 into a Railgun 0zk address. The first call omits shieldSignature and returns a personal_sign. Submit it, then call again with shieldSignature to build the approve-and-shield transaction.",
8010
+ prerequisites: ["keyGen", "executorAddress", "RPC URL", "0zk recipient"],
8011
+ handler: { importPath: "protocols/evm/railgun", exportName: "buildEvmMultisignBodyRailgunShield" },
8012
+ inputZod: mcpRailgunShieldInputSchema
7715
8013
  })
7716
8014
  ];
7717
8015
  var catalogQuery = {
@@ -10012,10 +10310,11 @@ var CORE_MCP_TOOL_DEFINITIONS = [
10012
10310
  actionId: "aave-v4.fetch-markets",
10013
10311
  protocolId: "aave-v4",
10014
10312
  chainCategory: "evm",
10015
- description: "List Aave v4 hub reserves on a chain with live supply/borrow APY, liquidity, and collateral factor. Use this (not web search) to compare lending rates or pick an underlying + marketId for build_*_multisign. Optional marketId (main/core/bluechip) or underlying filter.",
10313
+ description: "List Aave v4 hub reserves on a chain with live supply/borrow APY, liquidity, and collateral factor. Use this (not web search) to compare lending rates or pick an underlying + marketId for build_*_multisign. Optional marketId (main/core/bluechip/bstocks) or underlying filter. Base tokenized stocks: marketId bstocks or ctm_aave_v4_fetch_stock_markets. Tickers (AAPLc) OK.",
10016
10314
  prerequisites: ["chainId", "get_defi_protocol_supported_chains"],
10017
10315
  followUp: [
10018
10316
  "ctm_aave_v4_fetch_market",
10317
+ "ctm_aave_v4_fetch_stock_markets",
10019
10318
  "ctm_aave_v4_build_deposit_multisign",
10020
10319
  "ctm_aave_v4_build_borrow_multisign"
10021
10320
  ],
@@ -10028,7 +10327,7 @@ var CORE_MCP_TOOL_DEFINITIONS = [
10028
10327
  actionId: "aave-v4.fetch-market",
10029
10328
  protocolId: "aave-v4",
10030
10329
  chainCategory: "evm",
10031
- description: "One Aave v4 reserve (or the same underlying across hubs) with supply/borrow APY and liquidity. Copy underlying + marketId for deposit/borrow/repay. Do not web-search Aave rates.",
10330
+ description: "One Aave v4 reserve (or the same underlying across hubs) with supply/borrow APY and liquidity. Copy underlying + marketId for deposit/borrow/repay. Tickers OK (USDT, AAPLc). Do not web-search Aave rates.",
10032
10331
  prerequisites: ["chainId", "underlying from ctm_aave_v4_fetch_markets or get_defi_protocol_supported_tokens"],
10033
10332
  followUp: [
10034
10333
  "ctm_aave_v4_build_deposit_multisign",
@@ -10040,6 +10339,23 @@ var CORE_MCP_TOOL_DEFINITIONS = [
10040
10339
  inputZod: mcpAaveV4FetchMarketInputSchema,
10041
10340
  outputZod: mcpAaveV4FetchMarketOutputSchema
10042
10341
  }),
10342
+ defineMcpTool({
10343
+ name: "ctm_aave_v4_fetch_stock_markets",
10344
+ actionId: "aave-v4.fetch-stock-markets",
10345
+ protocolId: "aave-v4",
10346
+ chainCategory: "evm",
10347
+ description: "Coinbase tokenized stocks (bStocks) on the Aave v4 Coinbase Stocks hub, Base chainId 8453 by default. Equities (AAPLc, NVDAc, \u2026) are collateral-only; USDC is the borrow asset. Tickers OK. Same rows as ctm_aave_v4_fetch_markets with marketId bstocks. Chainlink feeds are 24/5. Not for U.S. persons.",
10348
+ prerequisites: ["chainId 8453 or omit"],
10349
+ followUp: [
10350
+ "ctm_aave_v4_build_deposit_multisign",
10351
+ "ctm_aave_v4_build_borrow_multisign",
10352
+ "ctm_aave_v4_build_repay_multisign",
10353
+ "ctm_aave_v4_build_withdraw_multisign"
10354
+ ],
10355
+ handler: { importPath: "protocols/evm/aave-v4", exportName: "aaveV4FetchStockMarketsSummary" },
10356
+ inputZod: mcpAaveV4FetchStockMarketsInputSchema,
10357
+ outputZod: mcpAaveV4FetchStockMarketsOutputSchema
10358
+ }),
10043
10359
  defineMcpTool({
10044
10360
  name: "ctm_aave_v4_fetch_merkl_rewards",
10045
10361
  actionId: "aave-v4.fetch-merkl-rewards",
@@ -10724,6 +11040,78 @@ var CORE_MCP_TOOL_DEFINITIONS = [
10724
11040
  handler: { importPath: "protocols/evm/trueo", exportName: "trueoFetchOrderbookSummary" },
10725
11041
  inputZod: mcpTrueoFetchOrderbookInputSchema,
10726
11042
  outputZod: mcpTrueoFetchOrderbookOutputSchema
11043
+ }),
11044
+ defineMcpTool({
11045
+ name: "ctm_railgun_fetch_popular_assets",
11046
+ actionId: "railgun.fetch-popular-assets",
11047
+ protocolId: "railgun",
11048
+ chainCategory: "evm",
11049
+ description: "Top 5 public ERC-20s on a Railgun chain by recent shield count. This is the asset-row icon list, not the user shielded holdings. rpcUrl is injected.",
11050
+ prerequisites: ["chainId", "get_defi_protocol_supported_chains"],
11051
+ followUp: ["ctm_railgun_build_shield_multisign"],
11052
+ handler: { importPath: "protocols/evm/railgun", exportName: "railgunFetchPopularAssets" },
11053
+ inputZod: mcpRailgunFetchPopularAssetsInputSchema,
11054
+ outputZod: mcpRailgunFetchPopularAssetsOutputSchema
11055
+ }),
11056
+ defineMcpTool({
11057
+ name: "ctm_railgun_ensure_wallet",
11058
+ actionId: "railgun.ensure-wallet",
11059
+ protocolId: "railgun",
11060
+ chainCategory: "evm",
11061
+ description: "Create the Railgun wallet on this KeyGen if it does not exist yet, and return its 0zk address. The spending key is split across the KeyGen nodes. No node receives a key it can spend alone. Does not return a mnemonic. Use this from the node agent and from Telegram before shield, unshield, or private transfer.",
11062
+ prerequisites: ["keyGenId"],
11063
+ followUp: ["ctm_railgun_fetch_private_balances", "ctm_railgun_build_shield_multisign"],
11064
+ handler: { importPath: "protocols/evm/railgun", exportName: "railgunFetchPrivateBalancesSummary" },
11065
+ inputZod: mcpRailgunEnsureWalletInputSchema,
11066
+ outputZod: mcpRailgunEnsureWalletOutputSchema
11067
+ }),
11068
+ defineMcpTool({
11069
+ name: "ctm_railgun_fetch_private_balances",
11070
+ actionId: "railgun.fetch-private-balances",
11071
+ protocolId: "railgun",
11072
+ chainCategory: "evm",
11073
+ description: "Shielded balances stored on the KeyGen record for this chain. Scans on the node when no scan is stored, or when refresh is true, then writes the result back to the KeyGen. Does not return a mnemonic or viewing key. Works from the node agent and from Telegram.",
11074
+ prerequisites: ["keyGenId", "chainId", "ctm_railgun_ensure_wallet"],
11075
+ followUp: ["ctm_railgun_private_transfer", "ctm_railgun_unshield"],
11076
+ handler: { importPath: "protocols/evm/railgun", exportName: "railgunFetchPrivateBalancesSummary" },
11077
+ inputZod: mcpRailgunFetchPrivateBalancesInputSchema,
11078
+ outputZod: mcpRailgunFetchPrivateBalancesOutputSchema
11079
+ }),
11080
+ defineMcpTool({
11081
+ name: "ctm_railgun_private_transfer",
11082
+ actionId: "railgun.private-transfer",
11083
+ protocolId: "railgun",
11084
+ chainCategory: "evm",
11085
+ description: "Start a private Railgun transfer. It stays pending until the KeyGen signing quorum agrees with ctm_railgun_agree_spend. No single node can spend. Do not pass a mnemonic.",
11086
+ prerequisites: ["keyGenId", "chainId", "0zk recipient", "ctm_railgun_ensure_wallet"],
11087
+ followUp: ["ctm_railgun_fetch_private_balances"],
11088
+ handler: { importPath: "protocols/evm/railgun", exportName: "railgunPrivateTransfer" },
11089
+ inputZod: mcpRailgunPrivateTransferInputSchema,
11090
+ outputZod: mcpRailgunPrivateActionOutputSchema
11091
+ }),
11092
+ defineMcpTool({
11093
+ name: "ctm_railgun_unshield",
11094
+ actionId: "railgun.unshield",
11095
+ protocolId: "railgun",
11096
+ chainCategory: "evm",
11097
+ description: "Start an unshield to a public address. It stays pending until the KeyGen signing quorum agrees with ctm_railgun_agree_spend. Recipient defaults to the KeyGen Ethereum address. No single node can spend. Do not pass a mnemonic.",
11098
+ prerequisites: ["keyGenId", "chainId", "ctm_railgun_ensure_wallet"],
11099
+ followUp: ["ctm_railgun_fetch_private_balances"],
11100
+ handler: { importPath: "protocols/evm/railgun", exportName: "railgunUnshield" },
11101
+ inputZod: mcpRailgunUnshieldInputSchema,
11102
+ outputZod: mcpRailgunPrivateActionOutputSchema
11103
+ }),
11104
+ defineMcpTool({
11105
+ name: "ctm_railgun_agree_spend",
11106
+ actionId: "railgun.agree-spend",
11107
+ protocolId: "railgun",
11108
+ chainCategory: "evm",
11109
+ description: "Agree this node\u2019s Railgun spending share for a pending spendId. Read the pending spend on the KeyGen record before agreeing. One share cannot spend the 0zk wallet.",
11110
+ prerequisites: ["keyGenId", "spendId"],
11111
+ followUp: ["ctm_railgun_fetch_private_balances"],
11112
+ handler: { importPath: "protocols/evm/railgun", exportName: "railgunFetchPrivateBalancesSummary" },
11113
+ inputZod: mcpRailgunAgreeSpendInputSchema,
11114
+ outputZod: mcpRailgunPrivateActionOutputSchema
10727
11115
  })
10728
11116
  ];
10729
11117
  var MCP_TOOL_DEFINITIONS = [
@@ -10840,6 +11228,222 @@ var lidoProtocolModule = {
10840
11228
  ]
10841
11229
  };
10842
11230
  registerProtocolModule(lidoProtocolModule);
11231
+
11232
+ // src/protocols/evm/railgun/networks.ts
11233
+ function selectRailgunNetworks(config) {
11234
+ const rows = [];
11235
+ for (const entry of Object.values(config)) {
11236
+ if (!entry || entry.deprecated || entry.isDevOnlyNetwork) continue;
11237
+ const chainId = Number(entry.chain?.id);
11238
+ const proxyContract = String(entry.proxyContract ?? "").trim();
11239
+ const wrappedAddress = String(entry.baseToken?.wrappedAddress ?? "").trim();
11240
+ if (!Number.isFinite(chainId) || chainId <= 0 || !proxyContract || !wrappedAddress) continue;
11241
+ rows.push({
11242
+ chainId,
11243
+ networkName: String(entry.name ?? ""),
11244
+ publicName: String(entry.publicName ?? entry.name ?? ""),
11245
+ proxyContract,
11246
+ deploymentBlock: Number(entry.deploymentBlock ?? 0),
11247
+ wrappedAddress,
11248
+ wrappedSymbol: String(entry.baseToken?.wrappedSymbol ?? entry.baseToken?.symbol ?? ""),
11249
+ wrappedDecimals: Number(entry.baseToken?.decimals ?? 18),
11250
+ isTestnet: Boolean(entry.isTestnet)
11251
+ });
11252
+ }
11253
+ rows.sort((a, b) => a.chainId - b.chainId);
11254
+ return rows;
11255
+ }
11256
+ var cached = null;
11257
+ async function loadRailgunNetworks() {
11258
+ if (cached) return cached;
11259
+ const mod = await import('@railgun-community/shared-models');
11260
+ cached = selectRailgunNetworks(mod.NETWORK_CONFIG);
11261
+ return cached;
11262
+ }
11263
+ async function loadRailgunSupportedChainIds() {
11264
+ const rows = await loadRailgunNetworks();
11265
+ return new Set(rows.map((row) => row.chainId));
11266
+ }
11267
+ async function railgunNetworkByChainId(chainId) {
11268
+ const rows = await loadRailgunNetworks();
11269
+ return rows.find((row) => row.chainId === chainId);
11270
+ }
11271
+
11272
+ // src/protocols/evm/railgun/popular-assets.ts
11273
+ init_constants();
11274
+ var RAILGUN_POPULAR_ASSET_LIMIT = 5;
11275
+ var POPULAR_ASSET_CACHE_MS = 10 * 60 * 1e3;
11276
+ var RECENT_SHIELD_LIMIT = 200;
11277
+ var SHIELD_INDEX_BY_NETWORK_NAME = {
11278
+ Ethereum: "https://rail-squid.squids.live/squid-railgun-ethereum-v2/graphql",
11279
+ BNB_Chain: "https://rail-squid.squids.live/squid-railgun-bsc-v2/graphql",
11280
+ Polygon: "https://rail-squid.squids.live/squid-railgun-polygon-v2/graphql",
11281
+ Arbitrum: "https://rail-squid.squids.live/squid-railgun-arbitrum-v2/graphql"
11282
+ };
11283
+ var RECENT_SHIELDS_QUERY = `query RecentShields($limit: Int!) {
11284
+ shieldCommitments(orderBy: [blockNumber_DESC], limit: $limit) {
11285
+ preimage { token { tokenType tokenAddress } }
11286
+ }
11287
+ }`;
11288
+ var cache = /* @__PURE__ */ new Map();
11289
+ function rankPopularShieldTokens(rows, limit = RAILGUN_POPULAR_ASSET_LIMIT) {
11290
+ const counts = /* @__PURE__ */ new Map();
11291
+ for (const row of rows) {
11292
+ if (Number(row.tokenType) !== 0) continue;
11293
+ let address;
11294
+ try {
11295
+ address = viem.getAddress(row.tokenAddress);
11296
+ } catch {
11297
+ continue;
11298
+ }
11299
+ if (address === viem.zeroAddress) continue;
11300
+ const key = address.toLowerCase();
11301
+ counts.set(key, (counts.get(key) ?? 0) + 1);
11302
+ }
11303
+ return [...counts.entries()].sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0)).slice(0, limit).map(([address]) => viem.getAddress(address));
11304
+ }
11305
+ function shieldIndexEndpoint(networkName) {
11306
+ return SHIELD_INDEX_BY_NETWORK_NAME[networkName] ?? null;
11307
+ }
11308
+ function commitmentsFromShieldIndex(payload) {
11309
+ const rows = payload?.data?.shieldCommitments;
11310
+ if (!Array.isArray(rows)) return [];
11311
+ return rows.map((row) => {
11312
+ const token = row?.preimage?.token;
11313
+ const tokenType = token?.tokenType === "ERC20" || token?.tokenType === 0 ? 0 : Number(token?.tokenType ?? -1);
11314
+ return {
11315
+ tokenAddress: String(token?.tokenAddress ?? ""),
11316
+ tokenType: Number.isFinite(tokenType) ? tokenType : -1
11317
+ };
11318
+ });
11319
+ }
11320
+ var shieldLogReaderOverride = null;
11321
+ async function readShieldCommitments(args) {
11322
+ const endpoint = shieldIndexEndpoint(args.networkName);
11323
+ if (!endpoint) return [];
11324
+ const response = await fetch(endpoint, {
11325
+ method: "POST",
11326
+ headers: { "content-type": "application/json" },
11327
+ body: JSON.stringify({
11328
+ query: RECENT_SHIELDS_QUERY,
11329
+ variables: { limit: RECENT_SHIELD_LIMIT }
11330
+ })
11331
+ });
11332
+ if (!response.ok) throw new Error(`Railgun shield index returned ${response.status}`);
11333
+ return commitmentsFromShieldIndex(await response.json());
11334
+ }
11335
+ function applyContinuumToken(chainId, result) {
11336
+ const ctm = ctmTokenAddressOnEvmChain(chainId);
11337
+ if (!ctm) return result;
11338
+ const present = result.tokens.some((token) => token.address.toLowerCase() === ctm.toLowerCase());
11339
+ {
11340
+ if (!present) return result;
11341
+ return {
11342
+ ...result,
11343
+ tokens: result.tokens.filter((token) => token.address.toLowerCase() !== ctm.toLowerCase())
11344
+ };
11345
+ }
11346
+ }
11347
+ async function loadRailgunPopularAssets(args) {
11348
+ const network = await railgunNetworkByChainId(args.chainId);
11349
+ if (!network) {
11350
+ return { tokens: [], notes: "Railgun is not deployed on this chain." };
11351
+ }
11352
+ const cached3 = cache.get(args.chainId);
11353
+ if (cached3 && Date.now() - cached3.at < POPULAR_ASSET_CACHE_MS) {
11354
+ return applyContinuumToken(args.chainId, {
11355
+ tokens: cached3.tokens,
11356
+ nativeWrapped: cached3.nativeWrapped,
11357
+ notes: cached3.notes
11358
+ });
11359
+ }
11360
+ const rpcUrl = args.rpcUrl?.trim() ?? "";
11361
+ if (!shieldIndexEndpoint(network.networkName) && !shieldLogReaderOverride) {
11362
+ return applyContinuumToken(args.chainId, {
11363
+ tokens: [],
11364
+ nativeWrapped: network.wrappedAddress,
11365
+ notes: "This chain has no indexed Railgun shield feed."
11366
+ });
11367
+ }
11368
+ try {
11369
+ const commitments = await (shieldLogReaderOverride ?? readShieldCommitments)({
11370
+ rpcUrl,
11371
+ chainId: args.chainId,
11372
+ proxy: viem.getAddress(network.proxyContract),
11373
+ deploymentBlock: network.deploymentBlock,
11374
+ networkName: network.networkName
11375
+ });
11376
+ const tokens = rankPopularShieldTokens(commitments).map((address) => ({ address }));
11377
+ const notes = tokens.length === 0 ? "No recent ERC-20 shields were returned for this chain." : `Top ${tokens.length} ERC-20s by recent indexed shield count.`;
11378
+ const entry = {
11379
+ at: Date.now(),
11380
+ tokens,
11381
+ nativeWrapped: network.wrappedAddress,
11382
+ notes
11383
+ };
11384
+ cache.set(args.chainId, entry);
11385
+ return applyContinuumToken(args.chainId, { tokens, nativeWrapped: network.wrappedAddress, notes });
11386
+ } catch {
11387
+ return applyContinuumToken(args.chainId, {
11388
+ tokens: [],
11389
+ nativeWrapped: network.wrappedAddress,
11390
+ notes: "The Railgun shield index could not be read."
11391
+ });
11392
+ }
11393
+ }
11394
+
11395
+ // src/protocols/evm/railgun/index.ts
11396
+ var RAILGUN_PROTOCOL_ID = "railgun";
11397
+ var railgunProtocolModule = {
11398
+ id: RAILGUN_PROTOCOL_ID,
11399
+ chainCategory: "evm",
11400
+ isChainSupported(ctx) {
11401
+ if (ctx.chainCategory !== "evm") return false;
11402
+ return loadRailgunSupportedChainIds().then((ids) => ids.has(Number(ctx.chainId)));
11403
+ },
11404
+ isTokenSupported(token) {
11405
+ return token.category === "evm" && (token.kind === "native" || token.kind === "erc20");
11406
+ },
11407
+ actions: [
11408
+ {
11409
+ id: "railgun.shield",
11410
+ protocolId: RAILGUN_PROTOCOL_ID,
11411
+ chainCategory: "evm",
11412
+ description: "Shield an ERC-20 into a Railgun 0zk address",
11413
+ commonParams: ["keyGen", "purposeText", "useCustomGas"],
11414
+ params: {
11415
+ tokenAddress: { type: "string", required: true, description: "ERC-20 to shield" },
11416
+ amountWei: { type: "string", required: true, description: "Amount in wei" },
11417
+ railgunAddress: { type: "string", required: true, description: "Recipient 0zk address" }
11418
+ }
11419
+ },
11420
+ {
11421
+ id: "railgun.private-transfer",
11422
+ protocolId: RAILGUN_PROTOCOL_ID,
11423
+ chainCategory: "evm",
11424
+ description: "Private transfer from the unlocked Railgun wallet",
11425
+ commonParams: ["purposeText"],
11426
+ params: {
11427
+ tokenAddress: { type: "string", required: true, description: "Shielded ERC-20" },
11428
+ amountWei: { type: "string", required: true, description: "Amount in wei" },
11429
+ recipientAddress: { type: "string", required: true, description: "Recipient 0zk address" }
11430
+ }
11431
+ },
11432
+ {
11433
+ id: "railgun.unshield",
11434
+ protocolId: RAILGUN_PROTOCOL_ID,
11435
+ chainCategory: "evm",
11436
+ description: "Unshield from the unlocked Railgun wallet to a public address",
11437
+ commonParams: ["purposeText"],
11438
+ params: {
11439
+ tokenAddress: { type: "string", required: true, description: "Shielded ERC-20" },
11440
+ amountWei: { type: "string", required: true, description: "Amount in wei" },
11441
+ recipientAddress: { type: "string", required: true, description: "Public recipient" }
11442
+ }
11443
+ }
11444
+ ]
11445
+ };
11446
+ registerProtocolModule(railgunProtocolModule);
10843
11447
  var USDE_ETHEREUM_MAINNET = "0x4c9edd5852cd905f086c759e8383e09bff1e68b3";
10844
11448
  var SUSDE_ETHEREUM_MAINNET = "0x9d39a5de30e57443bff2a8307a4256c8797a3497";
10845
11449
  var USDE_MOST_L2S = "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34";
@@ -11033,83 +11637,6 @@ var skyProtocolModule = {
11033
11637
  };
11034
11638
  registerProtocolModule(skyProtocolModule);
11035
11639
 
11036
- // src/protocols/evm/aave-v4/api.ts
11037
- init_defiProxy();
11038
- var AAVE_V4_GRAPHQL_URL = "https://api.v4.aave.com/graphql";
11039
- async function aaveV4Gql(query, variables) {
11040
- const body = { query, variables: variables ?? {} };
11041
- const j = await postJsonViaOptionalProxy({
11042
- directUrl: AAVE_V4_GRAPHQL_URL,
11043
- body,
11044
- proxyUrl: getAaveGraphqlProxyUrl(),
11045
- proxyEnvelope: body
11046
- });
11047
- if (j.errors?.length) {
11048
- const msg = j.errors.map((e) => e.message ?? "Unknown").join("; ");
11049
- throw new Error(msg);
11050
- }
11051
- if (j.data == null) {
11052
- throw new Error("Aave V4 API: empty response");
11053
- }
11054
- return j.data;
11055
- }
11056
- async function fetchAaveV4Chains() {
11057
- const d = await aaveV4Gql(`
11058
- query C($c: ChainsRequest!) { chains(request: $c) { chainId name nativeWrappedToken } }
11059
- `, { c: { query: { filter: "ALL" } } });
11060
- return d.chains ?? [];
11061
- }
11062
- async function loadAaveV4SupportedChainIdsFromV4Api() {
11063
- const rows = await fetchAaveV4Chains();
11064
- const s = /* @__PURE__ */ new Set();
11065
- for (const c of rows) s.add(c.chainId);
11066
- return s;
11067
- }
11068
- var RESERVES_ADDRESS_FRAGMENT = `
11069
- asset { underlying { address } }
11070
- `;
11071
- async function fetchAaveV4NativeWrappedToken(chainId) {
11072
- const all = await fetchAaveV4Chains();
11073
- const c = all.find((x) => x.chainId === chainId);
11074
- const t = (c?.nativeWrappedToken ?? "").trim();
11075
- if (t && viem.isAddress(t)) return viem.getAddress(t);
11076
- return null;
11077
- }
11078
- async function fetchAaveV4SupportedUnderlyingAddressSet(chainId) {
11079
- const d = await aaveV4Gql(
11080
- `
11081
- query A($r: ReservesRequest!) { reserves(request: $r) { ${RESERVES_ADDRESS_FRAGMENT} } }
11082
- `,
11083
- {
11084
- r: {
11085
- query: { chainIds: [chainId] },
11086
- filter: "ALL",
11087
- orderBy: { supplyApy: "DESC" }
11088
- }
11089
- }
11090
- );
11091
- const s = /* @__PURE__ */ new Set();
11092
- for (const r of d.reserves ?? []) {
11093
- const a = (r.asset?.underlying?.address ?? "").trim();
11094
- if (a && viem.isAddress(a)) s.add(a.toLowerCase());
11095
- }
11096
- return s;
11097
- }
11098
- var aaveV4ChainTokenCache = /* @__PURE__ */ new Map();
11099
- function ensureAaveV4ChainTokenCache(chainId) {
11100
- const hit = aaveV4ChainTokenCache.get(chainId);
11101
- if (hit) return hit;
11102
- const p = (async () => {
11103
- const [nativeWrapped, supportedUnderlying] = await Promise.all([
11104
- fetchAaveV4NativeWrappedToken(chainId),
11105
- fetchAaveV4SupportedUnderlyingAddressSet(chainId)
11106
- ]);
11107
- return { supportedUnderlying, nativeWrapped };
11108
- })();
11109
- aaveV4ChainTokenCache.set(chainId, p);
11110
- return p;
11111
- }
11112
-
11113
11640
  // src/protocols/evm/aave-v4/index.ts
11114
11641
  var AAVE_V4_PROTOCOL_ID = "aave-v4";
11115
11642
  var aaveV4ProtocolModule = {
@@ -11309,19 +11836,19 @@ function ensureEulerV2ChainAssetCache(chainId) {
11309
11836
  }
11310
11837
 
11311
11838
  // src/protocols/evm/euler-v2/loadEulerV2SupportedChainIds.ts
11312
- var cached = null;
11839
+ var cached2 = null;
11313
11840
  async function loadEulerV2SupportedChainIds() {
11314
- if (cached) return cached;
11841
+ if (cached2) return cached2;
11315
11842
  try {
11316
11843
  const ids = await fetchEulerV3ActiveChainIds();
11317
11844
  if (ids.length) {
11318
- cached = new Set(ids);
11319
- return cached;
11845
+ cached2 = new Set(ids);
11846
+ return cached2;
11320
11847
  }
11321
11848
  } catch {
11322
11849
  }
11323
- cached = new Set(Object.keys(EULER_V2_GOLDSKY_SUBGRAPH_URL_BY_CHAIN_ID).map((k) => Number(k)));
11324
- return cached;
11850
+ cached2 = new Set(Object.keys(EULER_V2_GOLDSKY_SUBGRAPH_URL_BY_CHAIN_ID).map((k) => Number(k)));
11851
+ return cached2;
11325
11852
  }
11326
11853
 
11327
11854
  // src/protocols/evm/euler-v2/index.ts
@@ -12102,9 +12629,9 @@ async function ensureMorphoChainAssetCache(chainId) {
12102
12629
  }
12103
12630
  } catch {
12104
12631
  }
12105
- const cache = { modesByUnderlying: modes, nativeWrapped: null };
12106
- chainAssetCache.set(chainId, cache);
12107
- return cache;
12632
+ const cache2 = { modesByUnderlying: modes, nativeWrapped: null };
12633
+ chainAssetCache.set(chainId, cache2);
12634
+ return cache2;
12108
12635
  }
12109
12636
 
12110
12637
  // src/protocols/evm/morpho/index.ts
@@ -13602,8 +14129,8 @@ async function pendleFetchMarketsPage(args) {
13602
14129
  }
13603
14130
  async function pendleFetchMarketsForChain(chainId) {
13604
14131
  const now = Date.now();
13605
- const cached2 = marketsCacheByChain.get(chainId);
13606
- if (cached2 && now - cached2.at < PENDLE_ICON_CACHE_MS) return cached2.rows;
14132
+ const cached3 = marketsCacheByChain.get(chainId);
14133
+ if (cached3 && now - cached3.at < PENDLE_ICON_CACHE_MS) return cached3.rows;
13607
14134
  const rows = [];
13608
14135
  for (let page = 0; page < PENDLE_LISTING_MAX_PAGES; page++) {
13609
14136
  const batch = await pendleFetchMarketsPage({
@@ -14142,6 +14669,7 @@ var skillsDir = path.join(path.dirname(url.fileURLToPath((typeof document === 'u
14142
14669
  var SKILL_PROTOCOL_IDS = [
14143
14670
  "aave-v4",
14144
14671
  "lido",
14672
+ "railgun",
14145
14673
  "uniswap-v4",
14146
14674
  "curve-dao",
14147
14675
  "ethena",
@@ -14209,6 +14737,7 @@ function getProtocolDiscoverySummary(protocolId) {
14209
14737
  }))
14210
14738
  };
14211
14739
  }
14740
+ init_coinbaseB20();
14212
14741
  init_support();
14213
14742
  init_support2();
14214
14743
  init_addresses();
@@ -14217,7 +14746,8 @@ init_constants();
14217
14746
  function advisor(protocolId, tokenFilter, impl) {
14218
14747
  return { protocolId, tokenFilter, ...impl };
14219
14748
  }
14220
- function aerodromeAdvisorPriorityTokens() {
14749
+ async function aerodromeAdvisorPriorityTokens() {
14750
+ const stocks = await ensureCoinbaseB20StockCatalog().catch(() => []);
14221
14751
  return [
14222
14752
  {
14223
14753
  address: "0x0000000000000000000000000000000000000000",
@@ -14243,11 +14773,11 @@ function aerodromeAdvisorPriorityTokens() {
14243
14773
  decimals: 18,
14244
14774
  roles: ["swappable"]
14245
14775
  },
14246
- ...COINBASE_B20_STOCK_TOKENS.map((t) => ({
14776
+ ...stocks.map((t) => ({
14247
14777
  address: t.address,
14248
14778
  symbol: t.symbol,
14249
14779
  name: t.name,
14250
- decimals: COINBASE_B20_STOCK_DECIMALS,
14780
+ decimals: t.decimals || COINBASE_B20_STOCK_DECIMALS,
14251
14781
  roles: ["swappable", "listed", "coinbase_b20"]
14252
14782
  }))
14253
14783
  ];
@@ -14259,36 +14789,44 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14259
14789
  return [...set].sort((a, b) => a - b);
14260
14790
  },
14261
14791
  async supportedTokens(chainId) {
14262
- const cache = await ensureAaveV4ChainTokenCache(chainId);
14263
- const tokens = [...cache.supportedUnderlying].map((address) => ({
14264
- address,
14265
- roles: ["underlying"]
14266
- }));
14267
- if (cache.nativeWrapped) {
14792
+ const cache2 = await ensureAaveV4ChainTokenCache(chainId);
14793
+ await ensureCoinbaseB20StockCatalog().catch(() => []);
14794
+ const tokens = [...cache2.supportedUnderlying].map((address) => {
14795
+ const known = lookupCoinbaseB20StockToken(address);
14796
+ if (!known) return { address, roles: ["underlying"] };
14797
+ return {
14798
+ address,
14799
+ symbol: known.symbol,
14800
+ name: "name" in known ? known.name : void 0,
14801
+ decimals: COINBASE_B20_STOCK_DECIMALS,
14802
+ roles: ["underlying", "coinbase_b20", "collateral"]
14803
+ };
14804
+ });
14805
+ if (cache2.nativeWrapped) {
14268
14806
  tokens.unshift({
14269
- address: cache.nativeWrapped,
14807
+ address: cache2.nativeWrapped,
14270
14808
  symbol: "WETH",
14271
14809
  roles: ["native_wrapped"]
14272
14810
  });
14273
14811
  }
14274
14812
  return {
14275
14813
  tokens,
14276
- nativeWrapped: cache.nativeWrapped ?? void 0,
14277
- notes: "Native ETH deposits use wrapped native token address from Aave v4 API."
14814
+ nativeWrapped: cache2.nativeWrapped ?? void 0,
14815
+ notes: "Native ETH deposits use wrapped native token address from Aave v4 API. Base chainId 8453 Coinbase Stocks hub is marketId bstocks. Listed equities come from the Aave v4 API; tickers resolve from the live Coinbase catalog. Equities are collateral-only; USDC is the borrow asset."
14278
14816
  };
14279
14817
  },
14280
14818
  async isTokenSupported(chainId, address) {
14281
- const cache = await ensureAaveV4ChainTokenCache(chainId);
14819
+ const cache2 = await ensureAaveV4ChainTokenCache(chainId);
14282
14820
  let normalized;
14283
14821
  try {
14284
14822
  normalized = viem.getAddress(address).toLowerCase();
14285
14823
  } catch {
14286
14824
  return false;
14287
14825
  }
14288
- if (cache.nativeWrapped && viem.getAddress(cache.nativeWrapped).toLowerCase() === normalized) {
14826
+ if (cache2.nativeWrapped && viem.getAddress(cache2.nativeWrapped).toLowerCase() === normalized) {
14289
14827
  return true;
14290
14828
  }
14291
- return cache.supportedUnderlying.has(normalized);
14829
+ return cache2.supportedUnderlying.has(normalized);
14292
14830
  }
14293
14831
  }),
14294
14832
  "uniswap-v4": advisor("uniswap-v4", "any_erc20_on_chain", {
@@ -14421,8 +14959,8 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14421
14959
  return [...set].sort((a, b) => a - b);
14422
14960
  },
14423
14961
  async supportedTokens(chainId) {
14424
- const cache = await ensureMorphoChainAssetCache(chainId);
14425
- const tokens = [...cache.modesByUnderlying.entries()].map(([address, modes]) => ({
14962
+ const cache2 = await ensureMorphoChainAssetCache(chainId);
14963
+ const tokens = [...cache2.modesByUnderlying.entries()].map(([address, modes]) => ({
14426
14964
  address,
14427
14965
  roles: [
14428
14966
  ...modes.earn ? ["vault_underlying"] : [],
@@ -14436,14 +14974,14 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14436
14974
  };
14437
14975
  },
14438
14976
  async isTokenSupported(chainId, address) {
14439
- const cache = await ensureMorphoChainAssetCache(chainId);
14977
+ const cache2 = await ensureMorphoChainAssetCache(chainId);
14440
14978
  let normalized;
14441
14979
  try {
14442
14980
  normalized = viem.getAddress(address).toLowerCase();
14443
14981
  } catch {
14444
14982
  return false;
14445
14983
  }
14446
- return cache.modesByUnderlying.has(normalized);
14984
+ return cache2.modesByUnderlying.has(normalized);
14447
14985
  }
14448
14986
  }),
14449
14987
  "euler-v2": advisor("euler-v2", "subgraph_vaults", {
@@ -14452,8 +14990,8 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14452
14990
  return [...set].sort((a, b) => a - b);
14453
14991
  },
14454
14992
  async supportedTokens(chainId) {
14455
- const cache = await ensureEulerV2ChainAssetCache(chainId);
14456
- const tokens = [...cache.modesByUnderlying.entries()].map(([address, modes]) => ({
14993
+ const cache2 = await ensureEulerV2ChainAssetCache(chainId);
14994
+ const tokens = [...cache2.modesByUnderlying.entries()].map(([address, modes]) => ({
14457
14995
  address,
14458
14996
  roles: [
14459
14997
  ...modes.lend ? ["vault_underlying"] : [],
@@ -14463,19 +15001,19 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14463
15001
  }));
14464
15002
  return {
14465
15003
  tokens,
14466
- nativeWrapped: cache.nativeWrapped ?? void 0,
15004
+ nativeWrapped: cache2.nativeWrapped ?? void 0,
14467
15005
  notes: "Euler EVK vault underlyings and Earn vault assets from the Euler V3 API. Use address as underlyingAddress for ctm_euler_v2_fetch_lend_vaults."
14468
15006
  };
14469
15007
  },
14470
15008
  async isTokenSupported(chainId, address) {
14471
- const cache = await ensureEulerV2ChainAssetCache(chainId);
15009
+ const cache2 = await ensureEulerV2ChainAssetCache(chainId);
14472
15010
  let normalized;
14473
15011
  try {
14474
15012
  normalized = viem.getAddress(address).toLowerCase();
14475
15013
  } catch {
14476
15014
  return false;
14477
15015
  }
14478
- return cache.modesByUnderlying.has(normalized);
15016
+ return cache2.modesByUnderlying.has(normalized);
14479
15017
  }
14480
15018
  }),
14481
15019
  [MAPLE_PROTOCOL_ID]: advisor(MAPLE_PROTOCOL_ID, "fixed_addresses", {
@@ -14560,9 +15098,9 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14560
15098
  return { tokens: [], notes: "Aerodrome is Base-only (chainId 8453)." };
14561
15099
  }
14562
15100
  return {
14563
- tokens: aerodromeAdvisorPriorityTokens(),
15101
+ tokens: await aerodromeAdvisorPriorityTokens(),
14564
15102
  nativeWrapped: AERODROME_WETH_BASE,
14565
- notes: "Slim directory: ETH, WETH, USDC, AERO, and Coinbase B20 stocks (AAPLc, \u2026). For a price call ctm_aerodrome_quote with tickers. To see pools for one token call ctm_aerodrome_discover_pools. Do not dump LpSugar."
15103
+ notes: "ETH, WETH, USDC, AERO, plus the live Coinbase B20 catalog. For a price call ctm_aerodrome_quote with a ticker. To see pools for one token call ctm_aerodrome_discover_pools. Do not dump LpSugar."
14566
15104
  };
14567
15105
  }
14568
15106
  }),
@@ -14625,7 +15163,7 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14625
15163
  return listCompoundV3SupportedChainIds();
14626
15164
  },
14627
15165
  async supportedTokens(chainId, ctx) {
14628
- const cache = await ensureCompoundV3ChainAssetCache({ chainId, rpcUrl: ctx?.rpcUrl });
15166
+ const cache2 = await ensureCompoundV3ChainAssetCache({ chainId, rpcUrl: ctx?.rpcUrl });
14629
15167
  const nativeWrapped = compoundV3WrappedNative(chainId);
14630
15168
  const tokens = [];
14631
15169
  if (nativeWrapped) {
@@ -14641,7 +15179,7 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14641
15179
  roles: ["native_wrapped"]
14642
15180
  });
14643
15181
  }
14644
- for (const [address, modes] of cache) {
15182
+ for (const [address, modes] of cache2) {
14645
15183
  if (nativeWrapped && address === nativeWrapped.toLowerCase()) continue;
14646
15184
  tokens.push({
14647
15185
  address,
@@ -14655,7 +15193,7 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14655
15193
  };
14656
15194
  },
14657
15195
  async isTokenSupported(chainId, address, ctx) {
14658
- const cache = await ensureCompoundV3ChainAssetCache({ chainId, rpcUrl: ctx?.rpcUrl });
15196
+ const cache2 = await ensureCompoundV3ChainAssetCache({ chainId, rpcUrl: ctx?.rpcUrl });
14659
15197
  let normalized;
14660
15198
  try {
14661
15199
  normalized = viem.getAddress(address).toLowerCase();
@@ -14665,7 +15203,7 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14665
15203
  if (normalized === "0x0000000000000000000000000000000000000000") return true;
14666
15204
  const wrapped = compoundV3WrappedNative(chainId);
14667
15205
  if (wrapped && wrapped.toLowerCase() === normalized) return true;
14668
- return cache.has(normalized);
15206
+ return cache2.has(normalized);
14669
15207
  }
14670
15208
  }),
14671
15209
  [PENDLE_PROTOCOL_ID]: advisor(PENDLE_PROTOCOL_ID, "api_underlyings", {
@@ -14793,6 +15331,32 @@ var PROTOCOL_SUPPORT_ADVISORS = {
14793
15331
  return false;
14794
15332
  }
14795
15333
  }
15334
+ }),
15335
+ railgun: advisor("railgun", "api_underlyings", {
15336
+ async supportedChainIds() {
15337
+ return [...await loadRailgunSupportedChainIds()];
15338
+ },
15339
+ async supportedTokens(chainId, ctx) {
15340
+ const result = await loadRailgunPopularAssets({ chainId, rpcUrl: ctx?.rpcUrl });
15341
+ return {
15342
+ tokens: result.tokens.map((token) => ({ address: token.address, roles: ["shield"] })),
15343
+ nativeWrapped: result.nativeWrapped,
15344
+ notes: result.notes
15345
+ };
15346
+ },
15347
+ async isTokenSupported(chainId, address, ctx) {
15348
+ const result = await loadRailgunPopularAssets({ chainId, rpcUrl: ctx?.rpcUrl });
15349
+ const listed = new Set(result.tokens.map((token) => token.address.toLowerCase()));
15350
+ try {
15351
+ const normalized = viem.getAddress(address);
15352
+ if (normalized === viem.zeroAddress) {
15353
+ return Boolean(result.nativeWrapped && listed.has(result.nativeWrapped.toLowerCase()));
15354
+ }
15355
+ return listed.has(normalized.toLowerCase());
15356
+ } catch {
15357
+ return false;
15358
+ }
15359
+ }
14796
15360
  })
14797
15361
  };
14798
15362
  function getProtocolSupportAdvisor(protocolId) {
@@ -14814,6 +15378,7 @@ function getAgentCatalog() {
14814
15378
  uniswapV4: uniswapV4ProtocolModule,
14815
15379
  curveDao: curveDaoProtocolModule,
14816
15380
  lido: lidoProtocolModule,
15381
+ railgun: railgunProtocolModule,
14817
15382
  ethena: ethenaProtocolModule,
14818
15383
  maple: mapleProtocolModule,
14819
15384
  sky: skyProtocolModule,
@@ -14872,6 +15437,8 @@ exports.mcpAaveV4FetchMarketInputSchema = mcpAaveV4FetchMarketInputSchema;
14872
15437
  exports.mcpAaveV4FetchMarketOutputSchema = mcpAaveV4FetchMarketOutputSchema;
14873
15438
  exports.mcpAaveV4FetchMarketsInputSchema = mcpAaveV4FetchMarketsInputSchema;
14874
15439
  exports.mcpAaveV4FetchMarketsOutputSchema = mcpAaveV4FetchMarketsOutputSchema;
15440
+ exports.mcpAaveV4FetchStockMarketsInputSchema = mcpAaveV4FetchStockMarketsInputSchema;
15441
+ exports.mcpAaveV4FetchStockMarketsOutputSchema = mcpAaveV4FetchStockMarketsOutputSchema;
14875
15442
  exports.mcpAaveV4MerklClaimInputSchema = mcpAaveV4MerklClaimInputSchema;
14876
15443
  exports.mcpAaveV4RepayInputSchema = mcpAaveV4RepayInputSchema;
14877
15444
  exports.mcpAaveV4WithdrawInputSchema = mcpAaveV4WithdrawInputSchema;
@@ -15258,6 +15825,17 @@ exports.mcpPendleQuoteSwapInputSchema = mcpPendleQuoteSwapInputSchema;
15258
15825
  exports.mcpPendleSearchAssetsInputSchema = mcpPendleSearchAssetsInputSchema;
15259
15826
  exports.mcpPendleSearchAssetsOutputSchema = mcpPendleSearchAssetsOutputSchema;
15260
15827
  exports.mcpPredictionMarketRowSchema = mcpPredictionMarketRowSchema;
15828
+ exports.mcpRailgunAgreeSpendInputSchema = mcpRailgunAgreeSpendInputSchema;
15829
+ exports.mcpRailgunEnsureWalletInputSchema = mcpRailgunEnsureWalletInputSchema;
15830
+ exports.mcpRailgunEnsureWalletOutputSchema = mcpRailgunEnsureWalletOutputSchema;
15831
+ exports.mcpRailgunFetchPopularAssetsInputSchema = mcpRailgunFetchPopularAssetsInputSchema;
15832
+ exports.mcpRailgunFetchPopularAssetsOutputSchema = mcpRailgunFetchPopularAssetsOutputSchema;
15833
+ exports.mcpRailgunFetchPrivateBalancesInputSchema = mcpRailgunFetchPrivateBalancesInputSchema;
15834
+ exports.mcpRailgunFetchPrivateBalancesOutputSchema = mcpRailgunFetchPrivateBalancesOutputSchema;
15835
+ exports.mcpRailgunPrivateActionOutputSchema = mcpRailgunPrivateActionOutputSchema;
15836
+ exports.mcpRailgunPrivateTransferInputSchema = mcpRailgunPrivateTransferInputSchema;
15837
+ exports.mcpRailgunShieldInputSchema = mcpRailgunShieldInputSchema;
15838
+ exports.mcpRailgunUnshieldInputSchema = mcpRailgunUnshieldInputSchema;
15261
15839
  exports.mcpSearchPredictionMarketsInputSchema = mcpSearchPredictionMarketsInputSchema;
15262
15840
  exports.mcpSearchPredictionMarketsOutputSchema = mcpSearchPredictionMarketsOutputSchema;
15263
15841
  exports.mcpServerCommonInputSchema = mcpServerCommonInputSchema;