@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
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { parseAbi, parseAbiItem, http, hashTypedData, getAddress, zeroAddress, defineChain, createPublicClient, parseGwei, serializeTransaction, keccak256, parseUnits, formatUnits, encodeFunctionData, stringToHex, decodeFunctionData, erc20Abi, isAddress } from 'viem';
1
+ import { parseAbi, parseAbiItem, http, hashTypedData, getAddress, zeroAddress, defineChain, createPublicClient, parseGwei, serializeTransaction, keccak256, parseUnits, formatUnits, encodeFunctionData, stringToHex, isAddress, decodeFunctionData, erc20Abi } from 'viem';
2
2
  import { getClientIdFromKeyGenResult, gasLimitFromEstimateAndChainConfig, fetchChainFeeParams, gweiToDecimalString, proposalTxParamsToFeeSnapshot, alignEip1559FeesWithLatestBase, nodeFetchWithReadAuth } from '@continuumdao/continuum-node-sdk';
3
3
  export { getClientIdFromKeyGenResult as firstClientIdFromKeyGen } from '@continuumdao/continuum-node-sdk';
4
4
 
@@ -50,6 +50,124 @@ var init_expiry = __esm({
50
50
  ]);
51
51
  }
52
52
  });
53
+ function isCoinbaseB20AssetToken(address) {
54
+ try {
55
+ return getAddress(address).toLowerCase().startsWith(COINBASE_B20_ASSET_PREFIX);
56
+ } catch {
57
+ return false;
58
+ }
59
+ }
60
+ function looksLikeCoinbaseStockSymbol(symbol) {
61
+ return /^[A-Za-z][A-Za-z0-9]{0,8}(?:\.[A-Za-z][A-Za-z0-9]{0,4})?c$/.test((symbol ?? "").trim());
62
+ }
63
+ function indexCatalog(rows) {
64
+ catalogRows = rows;
65
+ catalogAt = Date.now();
66
+ catalogBySymbol.clear();
67
+ catalogByAddress.clear();
68
+ for (const row of rows) {
69
+ catalogBySymbol.set(row.symbol.toLowerCase(), row);
70
+ catalogByAddress.set(row.address.toLowerCase(), row);
71
+ }
72
+ }
73
+ function parseCoinbaseTokenizedStocksPayload(payload) {
74
+ const tokens = Array.isArray(payload) ? payload : payload && typeof payload === "object" && Array.isArray(payload.tokens) ? payload.tokens : [];
75
+ const out = [];
76
+ const seen = /* @__PURE__ */ new Set();
77
+ for (const row of tokens) {
78
+ if (!row || typeof row !== "object") continue;
79
+ const rec = row;
80
+ const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
81
+ const addressRaw = typeof rec.contract_address === "string" ? rec.contract_address.trim() : "";
82
+ if (!looksLikeCoinbaseStockSymbol(symbol) || !isCoinbaseB20AssetToken(addressRaw)) continue;
83
+ const address = getAddress(addressRaw);
84
+ const key = address.toLowerCase();
85
+ if (seen.has(key)) continue;
86
+ seen.add(key);
87
+ const name = typeof rec.name === "string" && rec.name.trim() ? rec.name.trim() : symbol;
88
+ const iconUrl = typeof rec.icon_url === "string" && rec.icon_url.trim() ? rec.icon_url.trim() : void 0;
89
+ const decimals = typeof rec.decimals === "number" && Number.isInteger(rec.decimals) && rec.decimals >= 0 && rec.decimals <= 18 ? rec.decimals : COINBASE_B20_STOCK_DECIMALS;
90
+ out.push({ address, symbol, name, decimals, iconUrl });
91
+ if (out.length >= CATALOG_MAX) break;
92
+ }
93
+ return out;
94
+ }
95
+ async function fetchCoinbaseB20StockCatalog() {
96
+ const merged = [];
97
+ const seen = /* @__PURE__ */ new Set();
98
+ let pageToken = "";
99
+ for (let page = 0; page < 4; page++) {
100
+ const url = new URL(COINBASE_TOKENIZED_STOCKS_API_URL);
101
+ url.searchParams.set("page_size", "500");
102
+ if (pageToken) url.searchParams.set("page_token", pageToken);
103
+ const res = await fetch(url, { cache: "no-store", signal: AbortSignal.timeout(8e3) });
104
+ if (!res.ok) break;
105
+ const json = await res.json();
106
+ for (const row of parseCoinbaseTokenizedStocksPayload(json)) {
107
+ const key = row.address.toLowerCase();
108
+ if (seen.has(key)) continue;
109
+ seen.add(key);
110
+ merged.push(row);
111
+ if (merged.length >= CATALOG_MAX) break;
112
+ }
113
+ pageToken = typeof json.next_page_token === "string" ? json.next_page_token.trim() : "";
114
+ if (!pageToken || merged.length >= CATALOG_MAX) break;
115
+ }
116
+ if (merged.length > 0) indexCatalog(merged);
117
+ return catalogRows ?? [];
118
+ }
119
+ async function ensureCoinbaseB20StockCatalog() {
120
+ if (catalogRows && catalogRows.length > 0 && Date.now() - catalogAt < CATALOG_TTL_MS) return catalogRows;
121
+ if (!catalogInflight) {
122
+ catalogInflight = fetchCoinbaseB20StockCatalog().finally(() => {
123
+ catalogInflight = null;
124
+ });
125
+ }
126
+ try {
127
+ return await catalogInflight;
128
+ } catch {
129
+ return catalogRows ?? [];
130
+ }
131
+ }
132
+ function lookupCoinbaseB20StockToken(token) {
133
+ const key = (token ?? "").trim();
134
+ if (!key) return null;
135
+ const fromCatalog = catalogBySymbol.get(key.toLowerCase());
136
+ if (fromCatalog) return fromCatalog;
137
+ try {
138
+ return catalogByAddress.get(getAddress(key).toLowerCase()) ?? null;
139
+ } catch {
140
+ return null;
141
+ }
142
+ }
143
+ async function canonicalizeEvmTokenInput(token) {
144
+ const raw = (token ?? "").trim();
145
+ if (!raw || isAddress(raw)) return raw;
146
+ if (!looksLikeCoinbaseStockSymbol(raw)) return raw;
147
+ await ensureCoinbaseB20StockCatalog().catch(() => []);
148
+ const hit = lookupCoinbaseB20StockToken(raw);
149
+ if (!hit) {
150
+ throw new Error(
151
+ `Unknown Coinbase stock ticker "${raw}". It is not in the live tokenized-stocks catalog.`
152
+ );
153
+ }
154
+ return hit.address;
155
+ }
156
+ var COINBASE_B20_STOCK_DECIMALS, COINBASE_B20_ASSET_PREFIX, COINBASE_TOKENIZED_STOCKS_API_URL, CATALOG_TTL_MS, CATALOG_MAX, catalogRows, catalogAt, catalogInflight, catalogBySymbol, catalogByAddress;
157
+ var init_coinbaseB20 = __esm({
158
+ "src/protocols/evm/shared/coinbaseB20.ts"() {
159
+ COINBASE_B20_STOCK_DECIMALS = 8;
160
+ COINBASE_B20_ASSET_PREFIX = "0xb200000000000000000000";
161
+ COINBASE_TOKENIZED_STOCKS_API_URL = "https://api.coinbase.com/v1/tokenized-stocks";
162
+ CATALOG_TTL_MS = 15 * 60 * 1e3;
163
+ CATALOG_MAX = 500;
164
+ catalogRows = null;
165
+ catalogAt = 0;
166
+ catalogInflight = null;
167
+ catalogBySymbol = /* @__PURE__ */ new Map();
168
+ catalogByAddress = /* @__PURE__ */ new Map();
169
+ }
170
+ });
53
171
  function isAerodromeChainSupported(chainId) {
54
172
  const n = typeof chainId === "number" ? chainId : Number.parseInt(String(chainId), 10);
55
173
  return n === AERODROME_CHAIN_ID;
@@ -945,6 +1063,9 @@ var UNISWAP_V4_LP_COLLECT_DEFAULT_GAS_UNITS = 900000n;
945
1063
  var UNISWAP_V4_LP_ERC20_APPROVE_FALLBACK = 100000n;
946
1064
  var UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK = 120000n;
947
1065
  var UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK = 100000n;
1066
+
1067
+ // src/protocols/evm/uniswap-v4/quote.ts
1068
+ init_coinbaseB20();
948
1069
  parseAbi([
949
1070
  "function isAllowed(address account, uint8 permission) view returns (bool)",
950
1071
  "function PERMISSIONED_TOKEN() view returns (address)"
@@ -1311,6 +1432,11 @@ function messageFromUniswapHttpResponseBody(text, status, statusText = "") {
1311
1432
  return short;
1312
1433
  }
1313
1434
  async function uniswapTradeQuote(args) {
1435
+ args = {
1436
+ ...args,
1437
+ tokenIn: await canonicalizeEvmTokenInput(args.tokenIn),
1438
+ tokenOut: await canonicalizeEvmTokenInput(args.tokenOut)
1439
+ };
1314
1440
  const apiKey = (args.uniswapApiKey || "").trim();
1315
1441
  if (!apiKey) {
1316
1442
  throw new Error("uniswapApiKey (x-api-key) is required");
@@ -1430,6 +1556,7 @@ function parseUniswapQuoteClassicInOut(res) {
1430
1556
  }
1431
1557
 
1432
1558
  // src/protocols/evm/uniswap-v4/swapMultisign.ts
1559
+ init_coinbaseB20();
1433
1560
  init_defiEvmClient();
1434
1561
  function parseOptionalGasLimitString(raw) {
1435
1562
  if (raw == null) return null;
@@ -1762,7 +1889,7 @@ async function buildEvmMultisignBodyUniswapV4NativeInOnly(args, quoteInputWei) {
1762
1889
  });
1763
1890
  }
1764
1891
  async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
1765
- const tokenIn = getAddress(args.tokenIn);
1892
+ const tokenIn = getAddress(await canonicalizeEvmTokenInput(args.tokenIn));
1766
1893
  const parsedInOut = parseUniswapQuoteClassicInOut(args.fullQuoteSnapshot);
1767
1894
  const quoteInputWei = parsedInOut?.inputWei;
1768
1895
  if (quoteInputWei == null || quoteInputWei <= 0n) {
@@ -2037,6 +2164,7 @@ async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
2037
2164
  var UNISWAP_V4_LP_POOL_LOOKUP_HINT = "Pool may not be initialized on this chain. Call ctm_uniswap_v4_list_lp_pools for other presets, pass a custom existingPool.poolReference, or use newPool to initialize a pool.";
2038
2165
 
2039
2166
  // src/protocols/evm/uniswap-v4/liquidityApi.ts
2167
+ init_coinbaseB20();
2040
2168
  var LP_HEADERS_BASE = {
2041
2169
  "Content-Type": "application/json",
2042
2170
  Accept: "application/json",
@@ -2141,36 +2269,47 @@ function extractUniswapLpTokenAmounts(response) {
2141
2269
  return { token0: read("token0"), token1: read("token1") };
2142
2270
  }
2143
2271
  async function uniswapLpCreatePosition(args) {
2272
+ const independentAddress = await canonicalizeEvmTokenInput(args.independentToken.tokenAddress);
2273
+ const existingPool = args.existingPool ? {
2274
+ ...args.existingPool,
2275
+ token0Address: await canonicalizeEvmTokenInput(args.existingPool.token0Address),
2276
+ token1Address: await canonicalizeEvmTokenInput(args.existingPool.token1Address)
2277
+ } : void 0;
2278
+ const newPool = args.newPool ? {
2279
+ ...args.newPool,
2280
+ token0Address: await canonicalizeEvmTokenInput(args.newPool.token0Address),
2281
+ token1Address: await canonicalizeEvmTokenInput(args.newPool.token1Address)
2282
+ } : void 0;
2144
2283
  const body = {
2145
2284
  protocol: "V4",
2146
2285
  walletAddress: trimAddr2(args.walletAddress),
2147
2286
  chainId: args.chainId,
2148
2287
  independentToken: {
2149
- tokenAddress: trimAddr2(args.independentToken.tokenAddress),
2288
+ tokenAddress: trimAddr2(independentAddress),
2150
2289
  amount: String(args.independentToken.amount).trim()
2151
2290
  },
2152
2291
  slippageTolerance: args.slippageTolerance ?? UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,
2153
2292
  deadline: args.deadline ?? lpDeadlineUnix(),
2154
2293
  simulateTransaction: args.simulateTransaction ?? false
2155
2294
  };
2156
- if (args.existingPool) {
2295
+ if (existingPool) {
2157
2296
  body.existingPool = {
2158
- token0Address: trimAddr2(args.existingPool.token0Address),
2159
- token1Address: trimAddr2(args.existingPool.token1Address),
2160
- poolReference: trimAddr2(args.existingPool.poolReference)
2297
+ token0Address: trimAddr2(existingPool.token0Address),
2298
+ token1Address: trimAddr2(existingPool.token1Address),
2299
+ poolReference: trimAddr2(existingPool.poolReference)
2161
2300
  };
2162
2301
  }
2163
- if (args.newPool) {
2302
+ if (newPool) {
2164
2303
  body.newPool = {
2165
- token0Address: trimAddr2(args.newPool.token0Address),
2166
- token1Address: trimAddr2(args.newPool.token1Address),
2167
- fee: args.newPool.fee,
2168
- tickSpacing: args.newPool.tickSpacing,
2169
- initialPrice: String(args.newPool.initialPrice).trim(),
2170
- ...args.newPool.hooks ? { hooks: trimAddr2(args.newPool.hooks) } : {}
2304
+ token0Address: trimAddr2(newPool.token0Address),
2305
+ token1Address: trimAddr2(newPool.token1Address),
2306
+ fee: newPool.fee,
2307
+ tickSpacing: newPool.tickSpacing,
2308
+ initialPrice: String(newPool.initialPrice).trim(),
2309
+ ...newPool.hooks ? { hooks: trimAddr2(newPool.hooks) } : {}
2171
2310
  };
2172
2311
  }
2173
- if (!args.existingPool && !args.newPool) {
2312
+ if (!existingPool && !newPool) {
2174
2313
  throw new Error("Provide existingPool or newPool for LP create.");
2175
2314
  }
2176
2315
  if (args.priceBounds) {
@@ -2205,11 +2344,11 @@ async function uniswapLpIncreasePosition(args) {
2205
2344
  protocol: "V4",
2206
2345
  walletAddress: trimAddr2(args.walletAddress),
2207
2346
  chainId: args.chainId,
2208
- token0Address: trimAddr2(args.token0Address),
2209
- token1Address: trimAddr2(args.token1Address),
2347
+ token0Address: trimAddr2(await canonicalizeEvmTokenInput(args.token0Address)),
2348
+ token1Address: trimAddr2(await canonicalizeEvmTokenInput(args.token1Address)),
2210
2349
  nftTokenId: String(args.nftTokenId),
2211
2350
  independentToken: {
2212
- tokenAddress: trimAddr2(args.independentToken.tokenAddress),
2351
+ tokenAddress: trimAddr2(await canonicalizeEvmTokenInput(args.independentToken.tokenAddress)),
2213
2352
  amount: String(args.independentToken.amount).trim()
2214
2353
  },
2215
2354
  slippageTolerance: args.slippageTolerance ?? UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,
@@ -2819,6 +2958,7 @@ async function swapExactInput(args) {
2819
2958
  }
2820
2959
 
2821
2960
  // src/protocols/evm/uniswap-v4/limitOrder.ts
2961
+ init_coinbaseB20();
2822
2962
  function trimAddr3(a) {
2823
2963
  return a.trim();
2824
2964
  }
@@ -2919,6 +3059,11 @@ async function uniswapLimitOrderQuote(args) {
2919
3059
  args.nodeReadAuth ?? { bearerOnGet: true, jwt: null }
2920
3060
  );
2921
3061
  }
3062
+ args = {
3063
+ ...args,
3064
+ tokenIn: await canonicalizeEvmTokenInput(args.tokenIn),
3065
+ tokenOut: await canonicalizeEvmTokenInput(args.tokenOut)
3066
+ };
2922
3067
  const chainIdForGuard = parseUniswapChainId(resolveInputChainId(args));
2923
3068
  assertUniswapLimitOrderChain(chainIdForGuard);
2924
3069
  const base = args.baseUrl && args.baseUrl.trim() ? args.baseUrl.trim().replace(/\/$/, "") : "https://trade-api.gateway.uniswap.org/v1";
@@ -3371,6 +3516,7 @@ async function loadFullCurveSessionForRpc(rpcUrl) {
3371
3516
  var CURVE_ROUTER_EXCHANGE_DEFAULT_GAS_UNITS = 1200000n;
3372
3517
 
3373
3518
  // src/protocols/evm/curve-dao/multisign.ts
3519
+ init_coinbaseB20();
3374
3520
  init_defiEvmClient();
3375
3521
  var ETH_PLACEHOLDER2 = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
3376
3522
  function txToViemStep(tx) {
@@ -3386,7 +3532,7 @@ function txToViemStep(tx) {
3386
3532
  return { to, data, value };
3387
3533
  }
3388
3534
  async function buildEvmMultisignBodyCurveDaoBatch(args) {
3389
- const tokenIn = getAddress(args.tokenIn);
3535
+ const tokenIn = getAddress(await canonicalizeEvmTokenInput(args.tokenIn));
3390
3536
  const executor = getAddress(args.executorAddress);
3391
3537
  const session = await loadFullCurveSessionForRpc(args.rpcUrl);
3392
3538
  if (!session?.curve?.router?.populateSwap) {
@@ -3395,7 +3541,7 @@ async function buildEvmMultisignBodyCurveDaoBatch(args) {
3395
3541
  const { curve, wrappedNative } = session;
3396
3542
  const wn = wrappedNative;
3397
3543
  const tokenInId = toCurveRouterTokenId(tokenIn, wn);
3398
- const outTrim = (args.tokenOut ?? "").trim();
3544
+ const outTrim = (await canonicalizeEvmTokenInput(args.tokenOut ?? "")).trim();
3399
3545
  const tokenOutId = toCurveRouterTokenId(
3400
3546
  outTrim.toLowerCase() === ETH_PLACEHOLDER2 ? ETH_PLACEHOLDER2 : getAddress(outTrim),
3401
3547
  wn