@continuumdao/ctm-mpc-defi 0.2.55 → 0.2.57
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.
- package/dist/agent/catalog.cjs +692 -310
- package/dist/agent/catalog.cjs.map +1 -1
- package/dist/agent/catalog.d.ts +279 -99
- package/dist/agent/catalog.js +687 -312
- package/dist/agent/catalog.js.map +1 -1
- package/dist/agent/skills/aave-v4/SKILL.md +26 -3
- package/dist/agent/skills/aerodrome/SKILL.md +3 -1
- package/dist/agent/skills/circle-cctp/SKILL.md +5 -4
- package/dist/agent/skills/continuum-dao-marketplace/SKILL.md +4 -4
- package/dist/agent/skills/curve-dao/SKILL.md +2 -2
- package/dist/agent/skills/uniswap-v4/SKILL.md +2 -2
- package/dist/index.cjs +165 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +166 -20
- package/dist/index.js.map +1 -1
- package/dist/protocols/evm/aave-v4/index.cjs +198 -15
- package/dist/protocols/evm/aave-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/aave-v4/index.d.ts +62 -7
- package/dist/protocols/evm/aave-v4/index.js +189 -16
- package/dist/protocols/evm/aave-v4/index.js.map +1 -1
- package/dist/protocols/evm/aerodrome/index.cjs +152 -63
- package/dist/protocols/evm/aerodrome/index.cjs.map +1 -1
- package/dist/protocols/evm/aerodrome/index.d.ts +30 -58
- package/dist/protocols/evm/aerodrome/index.js +151 -64
- package/dist/protocols/evm/aerodrome/index.js.map +1 -1
- package/dist/protocols/evm/circle-cctp/index.cjs +77 -19
- package/dist/protocols/evm/circle-cctp/index.cjs.map +1 -1
- package/dist/protocols/evm/circle-cctp/index.d.ts +53 -3
- package/dist/protocols/evm/circle-cctp/index.js +76 -20
- package/dist/protocols/evm/circle-cctp/index.js.map +1 -1
- package/dist/protocols/evm/compound-v3/index.cjs +115 -2
- package/dist/protocols/evm/compound-v3/index.cjs.map +1 -1
- package/dist/protocols/evm/compound-v3/index.js +116 -3
- package/dist/protocols/evm/compound-v3/index.js.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.cjs +288 -32
- package/dist/protocols/evm/continuum-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/continuum-dao/index.d.ts +14 -1
- package/dist/protocols/evm/continuum-dao/index.js +287 -33
- package/dist/protocols/evm/continuum-dao/index.js.map +1 -1
- package/dist/protocols/evm/curve-dao/index.cjs +120 -5
- package/dist/protocols/evm/curve-dao/index.cjs.map +1 -1
- package/dist/protocols/evm/curve-dao/index.js +120 -5
- package/dist/protocols/evm/curve-dao/index.js.map +1 -1
- package/dist/protocols/evm/euler-v2/index.cjs +121 -6
- package/dist/protocols/evm/euler-v2/index.cjs.map +1 -1
- package/dist/protocols/evm/euler-v2/index.js +121 -6
- package/dist/protocols/evm/euler-v2/index.js.map +1 -1
- package/dist/protocols/evm/morpho/index.cjs +129 -57
- package/dist/protocols/evm/morpho/index.cjs.map +1 -1
- package/dist/protocols/evm/morpho/index.d.ts +2 -1
- package/dist/protocols/evm/morpho/index.js +129 -58
- package/dist/protocols/evm/morpho/index.js.map +1 -1
- package/dist/protocols/evm/pendle/index.cjs +129 -10
- package/dist/protocols/evm/pendle/index.cjs.map +1 -1
- package/dist/protocols/evm/pendle/index.js +129 -10
- package/dist/protocols/evm/pendle/index.js.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.cjs +164 -17
- package/dist/protocols/evm/uniswap-v4/index.cjs.map +1 -1
- package/dist/protocols/evm/uniswap-v4/index.js +165 -18
- package/dist/protocols/evm/uniswap-v4/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseAbi, parseAbiParameters, parseAbiItem, getAddress, createPublicClient, defineChain, zeroAddress, formatUnits, parseUnits, encodeFunctionData, keccak256, encodeAbiParameters, decodeEventLog, http, decodeFunctionData, parseGwei, serializeTransaction, erc20Abi, hashTypedData, stringToHex } from 'viem';
|
|
1
|
+
import { parseAbi, parseAbiParameters, parseAbiItem, getAddress, createPublicClient, defineChain, zeroAddress, formatUnits, parseUnits, encodeFunctionData, keccak256, encodeAbiParameters, decodeEventLog, http, isAddress, decodeFunctionData, parseGwei, serializeTransaction, erc20Abi, hashTypedData, stringToHex } from 'viem';
|
|
2
2
|
import { nodeFetchWithReadAuth, fetchChainFeeParams, gasLimitFromEstimateAndChainConfig, gweiToDecimalString, proposalTxParamsToFeeSnapshot, alignEip1559FeesWithLatestBase, getClientIdFromKeyGenResult } from '@continuumdao/continuum-node-sdk';
|
|
3
3
|
|
|
4
4
|
// src/core/registry.ts
|
|
@@ -260,6 +260,119 @@ var UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK = 120000n;
|
|
|
260
260
|
var UNISWAP_V4_LP_PERMIT2_APPROVE_FALLBACK = 100000n;
|
|
261
261
|
var UNISWAP_V4_PERMISSION_FLAG_SWAP = 1;
|
|
262
262
|
var UNISWAP_V4_PERMISSION_FLAG_LIQUIDITY = 2;
|
|
263
|
+
var COINBASE_B20_STOCK_DECIMALS = 8;
|
|
264
|
+
var COINBASE_B20_ASSET_PREFIX = "0xb200000000000000000000";
|
|
265
|
+
function isCoinbaseB20AssetToken(address) {
|
|
266
|
+
try {
|
|
267
|
+
return getAddress(address).toLowerCase().startsWith(COINBASE_B20_ASSET_PREFIX);
|
|
268
|
+
} catch {
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function looksLikeCoinbaseStockSymbol(symbol) {
|
|
273
|
+
return /^[A-Za-z][A-Za-z0-9]{0,8}(?:\.[A-Za-z][A-Za-z0-9]{0,4})?c$/.test((symbol ?? "").trim());
|
|
274
|
+
}
|
|
275
|
+
var COINBASE_TOKENIZED_STOCKS_API_URL = "https://api.coinbase.com/v1/tokenized-stocks";
|
|
276
|
+
var CATALOG_TTL_MS = 15 * 60 * 1e3;
|
|
277
|
+
var CATALOG_MAX = 500;
|
|
278
|
+
var catalogRows = null;
|
|
279
|
+
var catalogAt = 0;
|
|
280
|
+
var catalogInflight = null;
|
|
281
|
+
var catalogBySymbol = /* @__PURE__ */ new Map();
|
|
282
|
+
var catalogByAddress = /* @__PURE__ */ new Map();
|
|
283
|
+
function indexCatalog(rows) {
|
|
284
|
+
catalogRows = rows;
|
|
285
|
+
catalogAt = Date.now();
|
|
286
|
+
catalogBySymbol.clear();
|
|
287
|
+
catalogByAddress.clear();
|
|
288
|
+
for (const row of rows) {
|
|
289
|
+
catalogBySymbol.set(row.symbol.toLowerCase(), row);
|
|
290
|
+
catalogByAddress.set(row.address.toLowerCase(), row);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function parseCoinbaseTokenizedStocksPayload(payload) {
|
|
294
|
+
const tokens = Array.isArray(payload) ? payload : payload && typeof payload === "object" && Array.isArray(payload.tokens) ? payload.tokens : [];
|
|
295
|
+
const out = [];
|
|
296
|
+
const seen = /* @__PURE__ */ new Set();
|
|
297
|
+
for (const row of tokens) {
|
|
298
|
+
if (!row || typeof row !== "object") continue;
|
|
299
|
+
const rec = row;
|
|
300
|
+
const symbol = typeof rec.symbol === "string" ? rec.symbol.trim() : "";
|
|
301
|
+
const addressRaw = typeof rec.contract_address === "string" ? rec.contract_address.trim() : "";
|
|
302
|
+
if (!looksLikeCoinbaseStockSymbol(symbol) || !isCoinbaseB20AssetToken(addressRaw)) continue;
|
|
303
|
+
const address = getAddress(addressRaw);
|
|
304
|
+
const key = address.toLowerCase();
|
|
305
|
+
if (seen.has(key)) continue;
|
|
306
|
+
seen.add(key);
|
|
307
|
+
const name = typeof rec.name === "string" && rec.name.trim() ? rec.name.trim() : symbol;
|
|
308
|
+
const iconUrl = typeof rec.icon_url === "string" && rec.icon_url.trim() ? rec.icon_url.trim() : void 0;
|
|
309
|
+
const decimals = typeof rec.decimals === "number" && Number.isInteger(rec.decimals) && rec.decimals >= 0 && rec.decimals <= 18 ? rec.decimals : COINBASE_B20_STOCK_DECIMALS;
|
|
310
|
+
out.push({ address, symbol, name, decimals, iconUrl });
|
|
311
|
+
if (out.length >= CATALOG_MAX) break;
|
|
312
|
+
}
|
|
313
|
+
return out;
|
|
314
|
+
}
|
|
315
|
+
async function fetchCoinbaseB20StockCatalog() {
|
|
316
|
+
const merged = [];
|
|
317
|
+
const seen = /* @__PURE__ */ new Set();
|
|
318
|
+
let pageToken = "";
|
|
319
|
+
for (let page = 0; page < 4; page++) {
|
|
320
|
+
const url = new URL(COINBASE_TOKENIZED_STOCKS_API_URL);
|
|
321
|
+
url.searchParams.set("page_size", "500");
|
|
322
|
+
if (pageToken) url.searchParams.set("page_token", pageToken);
|
|
323
|
+
const res = await fetch(url, { cache: "no-store", signal: AbortSignal.timeout(8e3) });
|
|
324
|
+
if (!res.ok) break;
|
|
325
|
+
const json = await res.json();
|
|
326
|
+
for (const row of parseCoinbaseTokenizedStocksPayload(json)) {
|
|
327
|
+
const key = row.address.toLowerCase();
|
|
328
|
+
if (seen.has(key)) continue;
|
|
329
|
+
seen.add(key);
|
|
330
|
+
merged.push(row);
|
|
331
|
+
if (merged.length >= CATALOG_MAX) break;
|
|
332
|
+
}
|
|
333
|
+
pageToken = typeof json.next_page_token === "string" ? json.next_page_token.trim() : "";
|
|
334
|
+
if (!pageToken || merged.length >= CATALOG_MAX) break;
|
|
335
|
+
}
|
|
336
|
+
if (merged.length > 0) indexCatalog(merged);
|
|
337
|
+
return catalogRows ?? [];
|
|
338
|
+
}
|
|
339
|
+
async function ensureCoinbaseB20StockCatalog() {
|
|
340
|
+
if (catalogRows && catalogRows.length > 0 && Date.now() - catalogAt < CATALOG_TTL_MS) return catalogRows;
|
|
341
|
+
if (!catalogInflight) {
|
|
342
|
+
catalogInflight = fetchCoinbaseB20StockCatalog().finally(() => {
|
|
343
|
+
catalogInflight = null;
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
return await catalogInflight;
|
|
348
|
+
} catch {
|
|
349
|
+
return catalogRows ?? [];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function lookupCoinbaseB20StockToken(token) {
|
|
353
|
+
const key = (token ?? "").trim();
|
|
354
|
+
if (!key) return null;
|
|
355
|
+
const fromCatalog = catalogBySymbol.get(key.toLowerCase());
|
|
356
|
+
if (fromCatalog) return fromCatalog;
|
|
357
|
+
try {
|
|
358
|
+
return catalogByAddress.get(getAddress(key).toLowerCase()) ?? null;
|
|
359
|
+
} catch {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async function canonicalizeEvmTokenInput(token) {
|
|
364
|
+
const raw = (token ?? "").trim();
|
|
365
|
+
if (!raw || isAddress(raw)) return raw;
|
|
366
|
+
if (!looksLikeCoinbaseStockSymbol(raw)) return raw;
|
|
367
|
+
await ensureCoinbaseB20StockCatalog().catch(() => []);
|
|
368
|
+
const hit = lookupCoinbaseB20StockToken(raw);
|
|
369
|
+
if (!hit) {
|
|
370
|
+
throw new Error(
|
|
371
|
+
`Unknown Coinbase stock ticker "${raw}". It is not in the live tokenized-stocks catalog.`
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
return hit.address;
|
|
375
|
+
}
|
|
263
376
|
function defiEvmTransport(rpcUrl, opts) {
|
|
264
377
|
const url = rpcUrl.trim();
|
|
265
378
|
return http(url, opts);
|
|
@@ -712,6 +825,11 @@ function messageFromUniswapHttpResponseBody(text, status, statusText = "") {
|
|
|
712
825
|
return short;
|
|
713
826
|
}
|
|
714
827
|
async function uniswapTradeQuote(args) {
|
|
828
|
+
args = {
|
|
829
|
+
...args,
|
|
830
|
+
tokenIn: await canonicalizeEvmTokenInput(args.tokenIn),
|
|
831
|
+
tokenOut: await canonicalizeEvmTokenInput(args.tokenOut)
|
|
832
|
+
};
|
|
715
833
|
const apiKey = (args.uniswapApiKey || "").trim();
|
|
716
834
|
if (!apiKey) {
|
|
717
835
|
throw new Error("uniswapApiKey (x-api-key) is required");
|
|
@@ -1617,7 +1735,7 @@ async function buildEvmMultisignBodyUniswapV4NativeInOnly(args, quoteInputWei) {
|
|
|
1617
1735
|
});
|
|
1618
1736
|
}
|
|
1619
1737
|
async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
|
|
1620
|
-
const tokenIn = getAddress(args.tokenIn);
|
|
1738
|
+
const tokenIn = getAddress(await canonicalizeEvmTokenInput(args.tokenIn));
|
|
1621
1739
|
const parsedInOut = parseUniswapQuoteClassicInOut(args.fullQuoteSnapshot);
|
|
1622
1740
|
const quoteInputWei = parsedInOut?.inputWei;
|
|
1623
1741
|
if (quoteInputWei == null || quoteInputWei <= 0n) {
|
|
@@ -2212,36 +2330,47 @@ function extractUniswapLpTokenAmounts(response) {
|
|
|
2212
2330
|
return { token0: read("token0"), token1: read("token1") };
|
|
2213
2331
|
}
|
|
2214
2332
|
async function uniswapLpCreatePosition(args) {
|
|
2333
|
+
const independentAddress = await canonicalizeEvmTokenInput(args.independentToken.tokenAddress);
|
|
2334
|
+
const existingPool = args.existingPool ? {
|
|
2335
|
+
...args.existingPool,
|
|
2336
|
+
token0Address: await canonicalizeEvmTokenInput(args.existingPool.token0Address),
|
|
2337
|
+
token1Address: await canonicalizeEvmTokenInput(args.existingPool.token1Address)
|
|
2338
|
+
} : void 0;
|
|
2339
|
+
const newPool = args.newPool ? {
|
|
2340
|
+
...args.newPool,
|
|
2341
|
+
token0Address: await canonicalizeEvmTokenInput(args.newPool.token0Address),
|
|
2342
|
+
token1Address: await canonicalizeEvmTokenInput(args.newPool.token1Address)
|
|
2343
|
+
} : void 0;
|
|
2215
2344
|
const body = {
|
|
2216
2345
|
protocol: "V4",
|
|
2217
2346
|
walletAddress: trimAddr2(args.walletAddress),
|
|
2218
2347
|
chainId: args.chainId,
|
|
2219
2348
|
independentToken: {
|
|
2220
|
-
tokenAddress: trimAddr2(
|
|
2349
|
+
tokenAddress: trimAddr2(independentAddress),
|
|
2221
2350
|
amount: String(args.independentToken.amount).trim()
|
|
2222
2351
|
},
|
|
2223
2352
|
slippageTolerance: args.slippageTolerance ?? UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,
|
|
2224
2353
|
deadline: args.deadline ?? lpDeadlineUnix(),
|
|
2225
2354
|
simulateTransaction: args.simulateTransaction ?? false
|
|
2226
2355
|
};
|
|
2227
|
-
if (
|
|
2356
|
+
if (existingPool) {
|
|
2228
2357
|
body.existingPool = {
|
|
2229
|
-
token0Address: trimAddr2(
|
|
2230
|
-
token1Address: trimAddr2(
|
|
2231
|
-
poolReference: trimAddr2(
|
|
2358
|
+
token0Address: trimAddr2(existingPool.token0Address),
|
|
2359
|
+
token1Address: trimAddr2(existingPool.token1Address),
|
|
2360
|
+
poolReference: trimAddr2(existingPool.poolReference)
|
|
2232
2361
|
};
|
|
2233
2362
|
}
|
|
2234
|
-
if (
|
|
2363
|
+
if (newPool) {
|
|
2235
2364
|
body.newPool = {
|
|
2236
|
-
token0Address: trimAddr2(
|
|
2237
|
-
token1Address: trimAddr2(
|
|
2238
|
-
fee:
|
|
2239
|
-
tickSpacing:
|
|
2240
|
-
initialPrice: String(
|
|
2241
|
-
...
|
|
2365
|
+
token0Address: trimAddr2(newPool.token0Address),
|
|
2366
|
+
token1Address: trimAddr2(newPool.token1Address),
|
|
2367
|
+
fee: newPool.fee,
|
|
2368
|
+
tickSpacing: newPool.tickSpacing,
|
|
2369
|
+
initialPrice: String(newPool.initialPrice).trim(),
|
|
2370
|
+
...newPool.hooks ? { hooks: trimAddr2(newPool.hooks) } : {}
|
|
2242
2371
|
};
|
|
2243
2372
|
}
|
|
2244
|
-
if (!
|
|
2373
|
+
if (!existingPool && !newPool) {
|
|
2245
2374
|
throw new Error("Provide existingPool or newPool for LP create.");
|
|
2246
2375
|
}
|
|
2247
2376
|
if (args.priceBounds) {
|
|
@@ -2276,11 +2405,11 @@ async function uniswapLpIncreasePosition(args) {
|
|
|
2276
2405
|
protocol: "V4",
|
|
2277
2406
|
walletAddress: trimAddr2(args.walletAddress),
|
|
2278
2407
|
chainId: args.chainId,
|
|
2279
|
-
token0Address: trimAddr2(args.token0Address),
|
|
2280
|
-
token1Address: trimAddr2(args.token1Address),
|
|
2408
|
+
token0Address: trimAddr2(await canonicalizeEvmTokenInput(args.token0Address)),
|
|
2409
|
+
token1Address: trimAddr2(await canonicalizeEvmTokenInput(args.token1Address)),
|
|
2281
2410
|
nftTokenId: String(args.nftTokenId),
|
|
2282
2411
|
independentToken: {
|
|
2283
|
-
tokenAddress: trimAddr2(args.independentToken.tokenAddress),
|
|
2412
|
+
tokenAddress: trimAddr2(await canonicalizeEvmTokenInput(args.independentToken.tokenAddress)),
|
|
2284
2413
|
amount: String(args.independentToken.amount).trim()
|
|
2285
2414
|
},
|
|
2286
2415
|
slippageTolerance: args.slippageTolerance ?? UNISWAP_LP_DEFAULT_SLIPPAGE_PERCENT,
|
|
@@ -4192,6 +4321,19 @@ async function fetchFromSwapsTier(args) {
|
|
|
4192
4321
|
};
|
|
4193
4322
|
}
|
|
4194
4323
|
async function uniswapV4FetchOhlcv(args) {
|
|
4324
|
+
if (args.existingPool) {
|
|
4325
|
+
args = {
|
|
4326
|
+
...args,
|
|
4327
|
+
existingPool: {
|
|
4328
|
+
...args.existingPool,
|
|
4329
|
+
token0Address: await canonicalizeEvmTokenInput(args.existingPool.token0Address),
|
|
4330
|
+
token1Address: await canonicalizeEvmTokenInput(args.existingPool.token1Address)
|
|
4331
|
+
}
|
|
4332
|
+
};
|
|
4333
|
+
}
|
|
4334
|
+
if (args.currencyAddress?.trim()) {
|
|
4335
|
+
args = { ...args, currencyAddress: await canonicalizeEvmTokenInput(args.currencyAddress) };
|
|
4336
|
+
}
|
|
4195
4337
|
const chainId = parseUniswapChainId(args.chainId);
|
|
4196
4338
|
const interval = assertUniswapV4OhlcvInterval(args.interval ?? "1h");
|
|
4197
4339
|
const { startTimeMs, endTimeMs } = windowFromArgs(args);
|
|
@@ -4458,6 +4600,11 @@ async function uniswapLimitOrderQuote(args) {
|
|
|
4458
4600
|
args.nodeReadAuth ?? { bearerOnGet: true, jwt: null }
|
|
4459
4601
|
);
|
|
4460
4602
|
}
|
|
4603
|
+
args = {
|
|
4604
|
+
...args,
|
|
4605
|
+
tokenIn: await canonicalizeEvmTokenInput(args.tokenIn),
|
|
4606
|
+
tokenOut: await canonicalizeEvmTokenInput(args.tokenOut)
|
|
4607
|
+
};
|
|
4461
4608
|
const chainIdForGuard = parseUniswapChainId(resolveInputChainId(args));
|
|
4462
4609
|
assertUniswapLimitOrderChain(chainIdForGuard);
|
|
4463
4610
|
const base = args.baseUrl && args.baseUrl.trim() ? args.baseUrl.trim().replace(/\/$/, "") : "https://trade-api.gateway.uniswap.org/v1";
|