@continuumdao/ctm-mpc-defi 0.2.4 → 0.2.5

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.
@@ -1378,6 +1378,223 @@ async function buildEvmMultisignBodyUniswapV4SkipPermit2Batch(args) {
1378
1378
  }
1379
1379
  });
1380
1380
  }
1381
+ var POOL_KEY_ABI = viem.parseAbiParameters(
1382
+ "address currency0, address currency1, uint24 fee, int24 tickSpacing, address hooks"
1383
+ );
1384
+ var ZERO_HOOKS = "0x0000000000000000000000000000000000000000";
1385
+ function sortUniswapV4PoolCurrencies(token0Address, token1Address) {
1386
+ const a = normalizePoolCurrency(token0Address);
1387
+ const b = normalizePoolCurrency(token1Address);
1388
+ if (a.toLowerCase() === b.toLowerCase()) {
1389
+ throw new Error("Pool tokens must be distinct.");
1390
+ }
1391
+ return a.toLowerCase() < b.toLowerCase() ? { currency0: a, currency1: b } : { currency0: b, currency1: a };
1392
+ }
1393
+ function normalizePoolCurrency(raw) {
1394
+ const trimmed = raw.trim();
1395
+ if (!trimmed) {
1396
+ throw new Error("Pool token address is required.");
1397
+ }
1398
+ const lower = trimmed.toLowerCase();
1399
+ if (lower === "eth" || lower === "native" || lower === "native_eth" || lower === viem.zeroAddress.toLowerCase()) {
1400
+ return viem.zeroAddress;
1401
+ }
1402
+ return viem.getAddress(trimmed);
1403
+ }
1404
+ function computeUniswapV4PoolReference(args) {
1405
+ const { currency0, currency1 } = sortUniswapV4PoolCurrencies(
1406
+ args.token0Address,
1407
+ args.token1Address
1408
+ );
1409
+ const hooks = args.hooks?.trim() && args.hooks.trim() !== "0x" ? viem.getAddress(args.hooks.trim()) : ZERO_HOOKS;
1410
+ return viem.keccak256(
1411
+ viem.encodeAbiParameters(POOL_KEY_ABI, [
1412
+ currency0,
1413
+ currency1,
1414
+ args.fee,
1415
+ args.tickSpacing,
1416
+ hooks
1417
+ ])
1418
+ );
1419
+ }
1420
+
1421
+ // src/protocols/evm/uniswap-v4/knownLpPools.ts
1422
+ var ZERO_HOOKS2 = "0x0000000000000000000000000000000000000000";
1423
+ 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.";
1424
+ var FEE_TIERS = [
1425
+ { fee: 500, feeLabel: "0.05%", tickSpacing: 10 },
1426
+ { fee: 3e3, feeLabel: "0.3%", tickSpacing: 60 },
1427
+ { fee: 1e4, feeLabel: "1%", tickSpacing: 200 }
1428
+ ];
1429
+ var CHAIN_LP_CONFIGS = [
1430
+ {
1431
+ chainId: 1,
1432
+ chainLabel: "Ethereum",
1433
+ nativeWrapped: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
1434
+ tokens: {
1435
+ eth: { symbol: "ETH", address: "0x0000000000000000000000000000000000000000", native: true },
1436
+ usdc: { symbol: "USDC", address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" },
1437
+ usdt: { symbol: "USDT", address: "0xdAC17F958D2ee523a2206206994597C13D831ec7" },
1438
+ wbtc: { symbol: "WBTC", address: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599" }
1439
+ },
1440
+ pairs: [
1441
+ { slug: "eth-usdc", label: "ETH/USDC", token0Key: "eth", token1Key: "usdc", tiers: [...FEE_TIERS] },
1442
+ { slug: "eth-usdt", label: "ETH/USDT", token0Key: "eth", token1Key: "usdt", tiers: [...FEE_TIERS] },
1443
+ { slug: "eth-wbtc", label: "ETH/WBTC", token0Key: "eth", token1Key: "wbtc", tiers: [...FEE_TIERS] }
1444
+ ]
1445
+ },
1446
+ {
1447
+ chainId: 8453,
1448
+ chainLabel: "Base",
1449
+ nativeWrapped: "0x4200000000000000000000000000000000000006",
1450
+ tokens: {
1451
+ eth: { symbol: "ETH", address: "0x0000000000000000000000000000000000000000", native: true },
1452
+ usdc: { symbol: "USDC", address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }
1453
+ },
1454
+ pairs: [
1455
+ { slug: "eth-usdc", label: "ETH/USDC", token0Key: "eth", token1Key: "usdc", tiers: [...FEE_TIERS] }
1456
+ ]
1457
+ },
1458
+ {
1459
+ chainId: 42161,
1460
+ chainLabel: "Arbitrum",
1461
+ nativeWrapped: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
1462
+ tokens: {
1463
+ eth: { symbol: "ETH", address: "0x0000000000000000000000000000000000000000", native: true },
1464
+ usdc: { symbol: "USDC", address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831" }
1465
+ },
1466
+ pairs: [
1467
+ { slug: "eth-usdc", label: "ETH/USDC", token0Key: "eth", token1Key: "usdc", tiers: [...FEE_TIERS] }
1468
+ ]
1469
+ },
1470
+ {
1471
+ chainId: 10,
1472
+ chainLabel: "Optimism",
1473
+ nativeWrapped: "0x4200000000000000000000000000000000000006",
1474
+ tokens: {
1475
+ eth: { symbol: "ETH", address: "0x0000000000000000000000000000000000000000", native: true },
1476
+ usdc: { symbol: "USDC", address: "0x0b2C639c533813f4Aa9D7837CAa646c993D1B7926" }
1477
+ },
1478
+ pairs: [
1479
+ { slug: "eth-usdc", label: "ETH/USDC", token0Key: "eth", token1Key: "usdc", tiers: [...FEE_TIERS] }
1480
+ ]
1481
+ },
1482
+ {
1483
+ chainId: 137,
1484
+ chainLabel: "Polygon",
1485
+ nativeWrapped: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
1486
+ tokens: {
1487
+ eth: { symbol: "ETH", address: "0x0000000000000000000000000000000000000000", native: true },
1488
+ usdc: { symbol: "USDC", address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359" }
1489
+ },
1490
+ pairs: [
1491
+ { slug: "eth-usdc", label: "ETH/USDC", token0Key: "eth", token1Key: "usdc", tiers: [...FEE_TIERS] }
1492
+ ]
1493
+ }
1494
+ ];
1495
+ function buildPresetId(pairSlug, feeLabel) {
1496
+ const feeSlug = feeLabel.replace("%", "").replace(".", "-");
1497
+ return `${pairSlug}-${feeSlug}`;
1498
+ }
1499
+ function buildPoolRows(config) {
1500
+ const rows = [];
1501
+ for (const pair of config.pairs) {
1502
+ const token0 = config.tokens[pair.token0Key];
1503
+ const token1 = config.tokens[pair.token1Key];
1504
+ if (!token0 || !token1) continue;
1505
+ for (const tier of pair.tiers) {
1506
+ const poolReference = computeUniswapV4PoolReference({
1507
+ token0Address: token0.address,
1508
+ token1Address: token1.address,
1509
+ fee: tier.fee,
1510
+ tickSpacing: tier.tickSpacing,
1511
+ hooks: ZERO_HOOKS2
1512
+ });
1513
+ const usesNativeEth = Boolean(token0.native || token1.native);
1514
+ rows.push({
1515
+ presetId: buildPresetId(pair.slug, tier.feeLabel),
1516
+ pairSlug: pair.slug,
1517
+ pairLabel: pair.label,
1518
+ fee: tier.fee,
1519
+ feeLabel: tier.feeLabel,
1520
+ tickSpacing: tier.tickSpacing,
1521
+ token0Symbol: token0.symbol,
1522
+ token1Symbol: token1.symbol,
1523
+ token0Address: viem.getAddress(token0.address),
1524
+ token1Address: viem.getAddress(token1.address),
1525
+ poolReference,
1526
+ hooks: ZERO_HOOKS2,
1527
+ nativeWrapped: usesNativeEth ? viem.getAddress(config.nativeWrapped) : void 0,
1528
+ usesNativeEth
1529
+ });
1530
+ }
1531
+ }
1532
+ return rows;
1533
+ }
1534
+ function chainConfigOrThrow(chainId) {
1535
+ const config = CHAIN_LP_CONFIGS.find((row) => row.chainId === chainId);
1536
+ if (!config) {
1537
+ throw new Error(
1538
+ `No standard Uniswap V4 LP pool catalog for chainId ${chainId}. Supported catalog chains: ${CHAIN_LP_CONFIGS.map((c) => c.chainId).join(", ")}.`
1539
+ );
1540
+ }
1541
+ if (!isUniswapV4ChainSupported(chainId)) {
1542
+ throw new Error(`chainId ${chainId} is not supported for Uniswap V4 MCP tools.`);
1543
+ }
1544
+ return config;
1545
+ }
1546
+ function listUniswapV4StandardLpPools(args) {
1547
+ const chainId = parseUniswapChainId(args.chainId);
1548
+ const config = chainConfigOrThrow(chainId);
1549
+ let pools = buildPoolRows(config);
1550
+ const pairFilter = args.pair?.trim().toLowerCase();
1551
+ if (pairFilter) {
1552
+ pools = pools.filter(
1553
+ (row) => row.pairSlug.includes(pairFilter) || row.pairLabel.toLowerCase().includes(pairFilter) || row.presetId.includes(pairFilter)
1554
+ );
1555
+ }
1556
+ return {
1557
+ chainId,
1558
+ chainLabel: config.chainLabel,
1559
+ pools,
1560
+ notes: "poolReference is derived from token addresses, fee, tickSpacing, and hooks (no-hook pools). Pass presetId to ctm_uniswap_v4_lp_create_position as poolPreset, or copy existingPool fields. If LP create fails, the pool may not exist on-chain \u2014 try another preset, pass poolReference manually, or use newPool."
1561
+ };
1562
+ }
1563
+ function resolveUniswapV4LpPoolPreset(args) {
1564
+ const chainId = parseUniswapChainId(args.chainId);
1565
+ const preset = args.presetId.trim().toLowerCase();
1566
+ const row = buildPoolRows(chainConfigOrThrow(chainId)).find(
1567
+ (pool) => pool.presetId.toLowerCase() === preset
1568
+ );
1569
+ if (!row) {
1570
+ throw new Error(
1571
+ `Unknown LP pool preset "${args.presetId}" on chainId ${chainId}. Call ctm_uniswap_v4_list_lp_pools to list standard presets.`
1572
+ );
1573
+ }
1574
+ return row;
1575
+ }
1576
+ function resolveUniswapV4LpExistingPoolFromKey(args) {
1577
+ const poolReference = args.poolReference?.trim() || computeUniswapV4PoolReference({
1578
+ token0Address: args.token0Address,
1579
+ token1Address: args.token1Address,
1580
+ fee: args.fee,
1581
+ tickSpacing: args.tickSpacing,
1582
+ hooks: args.hooks
1583
+ });
1584
+ const sorted = sortTokensForExistingPool(args.token0Address, args.token1Address);
1585
+ return {
1586
+ token0Address: sorted.token0Address,
1587
+ token1Address: sorted.token1Address,
1588
+ poolReference
1589
+ };
1590
+ }
1591
+ function sortTokensForExistingPool(token0Address, token1Address) {
1592
+ const sorted = sortUniswapV4PoolCurrencies(token0Address, token1Address);
1593
+ return { token0Address: sorted.currency0, token1Address: sorted.currency1 };
1594
+ }
1595
+ function uniswapV4ListStandardLpPools(args) {
1596
+ return listUniswapV4StandardLpPools(args);
1597
+ }
1381
1598
 
1382
1599
  // src/protocols/evm/uniswap-v4/liquidityApi.ts
1383
1600
  var LP_HEADERS_BASE = {
@@ -1442,9 +1659,9 @@ async function postUniswapLpApi(args) {
1442
1659
  });
1443
1660
  const text = await res.text();
1444
1661
  if (!res.ok) {
1445
- throw new Error(
1446
- `Uniswap LP POST /${args.path} failed: ${messageFromUniswapHttpResponseBody(text, res.status, res.statusText)}`
1447
- );
1662
+ const base2 = messageFromUniswapHttpResponseBody(text, res.status, res.statusText);
1663
+ const hint = args.path === "create" && args.body.existingPool ? ` ${UNISWAP_V4_LP_POOL_LOOKUP_HINT}` : "";
1664
+ throw new Error(`Uniswap LP POST /${args.path} failed: ${base2}${hint}`);
1448
1665
  }
1449
1666
  return JSON.parse(text);
1450
1667
  }
@@ -2422,6 +2639,7 @@ exports.UNISWAP_V4_LP_INCREASE_DEFAULT_GAS_UNITS = UNISWAP_V4_LP_INCREASE_DEFAUL
2422
2639
  exports.UNISWAP_V4_LP_LOG_CHUNK_SIZE_DEFAULT = UNISWAP_V4_LP_LOG_CHUNK_SIZE_DEFAULT;
2423
2640
  exports.UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN = UNISWAP_V4_LP_LOG_CHUNK_SIZE_MIN;
2424
2641
  exports.UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS = UNISWAP_V4_LP_MINT_DEFAULT_GAS_UNITS;
2642
+ exports.UNISWAP_V4_LP_POOL_LOOKUP_HINT = UNISWAP_V4_LP_POOL_LOOKUP_HINT;
2425
2643
  exports.UNISWAP_V4_LP_POSITION_REGISTRY_HINT = UNISWAP_V4_LP_POSITION_REGISTRY_HINT;
2426
2644
  exports.UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK = UNISWAP_V4_LP_WETH_DEPOSIT_FALLBACK;
2427
2645
  exports.UNISWAP_V4_PROTOCOL_ID = UNISWAP_V4_PROTOCOL_ID;
@@ -2433,6 +2651,7 @@ exports.buildEvmMultisignBodyUniswapV4MintLiquidityBatch = buildEvmMultisignBody
2433
2651
  exports.buildEvmMultisignBodyUniswapV4SkipPermit2Batch = buildEvmMultisignBodyUniswapV4SkipPermit2Batch;
2434
2652
  exports.buildUniswapQuoteRequestBody = buildUniswapQuoteRequestBody;
2435
2653
  exports.buildUniswapV4PurposePrefill = buildUniswapV4PurposePrefill;
2654
+ exports.computeUniswapV4PoolReference = computeUniswapV4PoolReference;
2436
2655
  exports.computeUniswapV4Session = computeUniswapV4Session;
2437
2656
  exports.createSwap = createSwap;
2438
2657
  exports.errorMessageFromUniswapJsonBody = errorMessageFromUniswapJsonBody;
@@ -2456,6 +2675,7 @@ exports.isUniswapV4ChainSupported = isUniswapV4ChainSupported;
2456
2675
  exports.isUniswapV4LiquidityEvmSignRequest = isUniswapV4LiquidityEvmSignRequest;
2457
2676
  exports.isUniswapV4SwapEvmSignRequest = isUniswapV4SwapEvmSignRequest;
2458
2677
  exports.listUniswapV4PositionsForWallet = listUniswapV4PositionsForWallet;
2678
+ exports.listUniswapV4StandardLpPools = listUniswapV4StandardLpPools;
2459
2679
  exports.messageFromUniswapHttpResponseBody = messageFromUniswapHttpResponseBody;
2460
2680
  exports.parseUniswapChainId = parseUniswapChainId;
2461
2681
  exports.parseUniswapLpApiSnapshot = parseUniswapLpApiSnapshot;
@@ -2466,7 +2686,10 @@ exports.quoteSwap = quoteSwap;
2466
2686
  exports.readUniswapV4PositionInfoRaw = readUniswapV4PositionInfoRaw;
2467
2687
  exports.resolveBlockAtOrAfterUnixTime = resolveBlockAtOrAfterUnixTime;
2468
2688
  exports.resolveRouterSwapGasUnitsFromSignRequest = resolveRouterSwapGasUnitsFromSignRequest;
2689
+ exports.resolveUniswapV4LpExistingPoolFromKey = resolveUniswapV4LpExistingPoolFromKey;
2690
+ exports.resolveUniswapV4LpPoolPreset = resolveUniswapV4LpPoolPreset;
2469
2691
  exports.resolveUniswapV4PositionScanFromDate = resolveUniswapV4PositionScanFromDate;
2692
+ exports.sortUniswapV4PoolCurrencies = sortUniswapV4PoolCurrencies;
2470
2693
  exports.swapExactInput = swapExactInput;
2471
2694
  exports.swapFromQuote = swapFromQuote;
2472
2695
  exports.swapTransactionDeadlineUnixFromExpiryMinutes = swapTransactionDeadlineUnixFromExpiryMinutes;
@@ -2483,6 +2706,7 @@ exports.uniswapV4 = uniswapV4;
2483
2706
  exports.uniswapV4ListPositionsForMcp = uniswapV4ListPositionsForMcp;
2484
2707
  exports.uniswapV4ListPositionsFromRegistryForMcp = uniswapV4ListPositionsFromRegistryForMcp;
2485
2708
  exports.uniswapV4ListPositionsRegistryMcpPlaceholder = uniswapV4ListPositionsRegistryMcpPlaceholder;
2709
+ exports.uniswapV4ListStandardLpPools = uniswapV4ListStandardLpPools;
2486
2710
  exports.uniswapV4PositionMintedTokenIdsFromReceipt = uniswapV4PositionMintedTokenIdsFromReceipt;
2487
2711
  exports.uniswapV4ProtocolModule = uniswapV4ProtocolModule;
2488
2712
  exports.uniswapV4RegisterPositionFromMintTxPlaceholder = uniswapV4RegisterPositionFromMintTxPlaceholder;