{"version":3,"file":"liquidity.mjs","names":[],"sources":["../../../src/tools/liquidity.ts"],"sourcesContent":["/**\n * Liquidity Tool — Uniswap V4/V3 liquidity position management.\n *\n * Actions:\n *   - positions: List all V3 positions for the connected wallet\n *   - v4_position: Read a specific V4 position by token ID\n *   - v4_pool: Read V4 pool state (price, liquidity, tick)\n *   - v3_mint: Mint a new V3 liquidity position\n *   - v4_mint: Mint a new V4 liquidity position\n *   - v3_add: Add liquidity to an existing V3 position\n *   - v3_remove: Remove liquidity from a V3 position\n *   - v3_collect: Collect accumulated fees from a V3 position\n *\n * Uses ClawnchLiquidity from @clawnch/clawncher-sdk.\n * Write operations go through ClawnchConnect for approval.\n */\n\nimport { Type } from '@sinclair/typebox';\nimport { stringEnum, jsonResult, errorResult, readStringParam, readNumberParam } from '../lib/tool-helpers.js';\nimport {\n  getWalletState,\n  requireWalletClient,\n  requirePublicClient,\n} from '../services/walletconnect-service.js';\nimport { checkBalance } from '../services/safety-service.js';\n\n/** Validate and convert a token ID string to BigInt. */\nfunction validateTokenId(raw: string): bigint {\n  const trimmed = raw.trim();\n  if (!/^\\d+$/.test(trimmed)) {\n    throw new Error(`Invalid token_id: \"${raw}\". Must be a non-negative integer.`);\n  }\n  return BigInt(trimmed);\n}\n\n/** Validate a numeric amount string. */\nfunction validateAmount(raw: string): string {\n  const trimmed = raw.trim();\n  if (!trimmed || !/^\\d+(\\.\\d+)?$/.test(trimmed)) {\n    throw new Error(`Invalid amount: \"${raw}\". Must be a positive number (e.g. \"1.5\" or \"100\").`);\n  }\n  return trimmed;\n}\n\nconst ACTIONS = [\n  'positions', 'v4_position', 'v4_pool',\n  'v3_mint', 'v4_mint', 'v3_add', 'v3_remove', 'v3_collect',\n] as const;\n\nconst LiquiditySchema = Type.Object({\n  action: stringEnum(ACTIONS, {\n    description:\n      'positions: list V3 positions. v4_position: read V4 position. v4_pool: read pool state. ' +\n      'v3_mint/v4_mint: open new position. v3_add: add to existing. v3_remove: withdraw. v3_collect: claim fees.',\n  }),\n  token_id: Type.Optional(Type.String({\n    description: 'Position NFT token ID (for v4_position, v3_add, v3_remove, v3_collect).',\n  })),\n  token0: Type.Optional(Type.String({\n    description: 'Token 0 address — must be the lower address (for mint and v4_pool).',\n  })),\n  token1: Type.Optional(Type.String({\n    description: 'Token 1 address — must be the higher address (for mint and v4_pool).',\n  })),\n  fee: Type.Optional(Type.Number({\n    description: 'Fee tier in hundredths of bps (e.g. 3000 = 0.3%). Default: 3000.',\n  })),\n  tick_spacing: Type.Optional(Type.Number({\n    description: 'Tick spacing for V4 pool. Default: 60.',\n  })),\n  hook_address: Type.Optional(Type.String({\n    description: 'V4 hook contract address. Default: zero address (no hook).',\n  })),\n  tick_lower: Type.Optional(Type.Number({\n    description: 'Lower tick boundary for new positions.',\n  })),\n  tick_upper: Type.Optional(Type.Number({\n    description: 'Upper tick boundary for new positions.',\n  })),\n  amount0: Type.Optional(Type.String({\n    description: 'Amount of token0 in human-readable units (for mint/add).',\n  })),\n  amount1: Type.Optional(Type.String({\n    description: 'Amount of token1 in human-readable units (for mint/add).',\n  })),\n  percentage: Type.Optional(Type.Number({\n    description: 'Percentage of liquidity to remove (0-100). Default: 100. For v3_remove.',\n  })),\n  slippage_bps: Type.Optional(Type.Number({\n    description: 'Slippage tolerance in basis points (e.g. 50 = 0.5%). Default: 50.',\n  })),\n});\n\nexport function createLiquidityTool() {\n  return {\n    name: 'liquidity',\n    label: 'Liquidity',\n    ownerOnly: true,\n    description:\n      'Manage Uniswap V4 and V3 liquidity positions on Base. ' +\n      'List positions, read pool state, mint/add/remove liquidity, and collect fees. ' +\n      'Write operations go through ClawnchConnect for approval.',\n    parameters: LiquiditySchema,\n    execute: async (_toolCallId: string, args: unknown) => {\n      const params = args as Record<string, unknown>;\n      const action = readStringParam(params, 'action', { required: true })!;\n\n      const state = getWalletState();\n      if (!state.connected) {\n        return errorResult('No wallet connected. Use clawnchconnect tool to connect first.');\n      }\n\n      try {\n        const { ClawnchLiquidity } = await import('@clawnch/clawncher-sdk');\n        const wallet = requireWalletClient();\n        const publicClient = requirePublicClient();\n\n        const liquidity = new ClawnchLiquidity({\n          wallet,\n          publicClient,\n          network: 'mainnet',\n        });\n\n        switch (action) {\n          case 'positions':\n            return handlePositions(liquidity);\n          case 'v4_position':\n            return handleV4Position(liquidity, params);\n          case 'v4_pool':\n            return handleV4Pool(liquidity, params);\n          case 'v3_mint':\n            return handleV3Mint(liquidity, params);\n          case 'v4_mint':\n            return handleV4Mint(liquidity, params);\n          case 'v3_add':\n            return handleV3Add(liquidity, params);\n          case 'v3_remove':\n            return handleV3Remove(liquidity, params);\n          case 'v3_collect':\n            return handleV3Collect(liquidity, params);\n          default:\n            return errorResult(`Unknown action: ${action}`);\n        }\n      } catch (err) {\n        return errorResult(`Liquidity operation failed: ${err instanceof Error ? err.message : String(err)}`);\n      }\n    },\n  };\n}\n\n// ─── Read Operations ──────────────────────────────────────────────────────\n\nasync function handlePositions(liquidity: any) {\n  const positions = await liquidity.v3GetPositionsForWallet();\n\n  if (positions.length === 0) {\n    return jsonResult({\n      count: 0,\n      message: 'No V3 liquidity positions found for this wallet.',\n    });\n  }\n\n  const formatted = positions.map((p: any, i: number) => ({\n    index: i + 1,\n    tokenId: p.tokenId.toString(),\n    version: p.version,\n    token0: p.token0,\n    token1: p.token1,\n    feeTier: `${p.fee / 10000}%`,\n    tickRange: `${p.tickLower} → ${p.tickUpper}`,\n    liquidity: p.liquidity.toString(),\n    isActive: p.liquidity > 0n,\n    unclaimedFees: {\n      token0: p.unclaimedFees.token0.toString(),\n      token1: p.unclaimedFees.token1.toString(),\n    },\n  }));\n\n  return jsonResult({ count: positions.length, positions: formatted });\n}\n\nasync function handleV4Position(liquidity: any, params: Record<string, unknown>) {\n  const tokenId = readStringParam(params, 'token_id');\n  if (!tokenId) return errorResult('token_id is required for v4_position.');\n\n  const pos = await liquidity.v4GetPosition(validateTokenId(tokenId));\n\n  return jsonResult({\n    tokenId: pos.tokenId.toString(),\n    token0: pos.token0,\n    token1: pos.token1,\n    feeTier: `${pos.fee / 10000}%`,\n    tickRange: `${pos.tickLower} → ${pos.tickUpper}`,\n    liquidity: pos.liquidity.toString(),\n    unclaimedFees: {\n      token0: pos.unclaimedFees.token0.toString(),\n      token1: pos.unclaimedFees.token1.toString(),\n    },\n  });\n}\n\nasync function handleV4Pool(liquidity: any, params: Record<string, unknown>) {\n  const token0 = readStringParam(params, 'token0', { required: true })!;\n  const token1 = readStringParam(params, 'token1', { required: true })!;\n  const fee = readNumberParam(params, 'fee') ?? 3000;\n  const tickSpacing = readNumberParam(params, 'tick_spacing') ?? 60;\n  const hookAddress = readStringParam(params, 'hook_address') ?? '0x0000000000000000000000000000000000000000';\n\n  const poolKey = {\n    currency0: token0 as `0x${string}`,\n    currency1: token1 as `0x${string}`,\n    fee,\n    tickSpacing,\n    hooks: hookAddress as `0x${string}`,\n  };\n\n  const state = await liquidity.v4GetPoolState(poolKey);\n\n  // Convert sqrtPriceX96 to human-readable price\n  const sqrtPrice = Number(state.sqrtPriceX96) / Number(2n ** 96n);\n  const price = sqrtPrice * sqrtPrice;\n\n  return jsonResult({\n    poolId: state.poolId,\n    sqrtPriceX96: state.sqrtPriceX96.toString(),\n    price_token1_per_token0: price,\n    tick: state.tick,\n    liquidity: state.liquidity.toString(),\n  });\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\n/** Read on-chain decimals for a token, with well-known fallbacks. */\nasync function getTokenDecimals(tokenAddress: string): Promise<number> {\n  // Well-known tokens on Base\n  const KNOWN_DECIMALS: Record<string, number> = {\n    '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913': 6,  // USDC\n    '0xfde4c96c8593536e31f229ea8f37b2ada2699bb2': 6,  // USDT\n  };\n  const known = KNOWN_DECIMALS[tokenAddress.toLowerCase()];\n  if (known !== undefined) return known;\n  // Native ETH sentinel\n  if (tokenAddress.toLowerCase() === '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee') return 18;\n  try {\n    const publicClient = requirePublicClient();\n    const { erc20Abi } = await import('viem');\n    const dec = await publicClient.readContract({\n      address: tokenAddress as `0x${string}`,\n      abi: erc20Abi,\n      functionName: 'decimals',\n    }) as number;\n    return dec;\n  } catch {\n    return 18; // fallback\n  }\n}\n\n/** Convert a human-readable amount string to BigInt wei using actual token decimals. */\nasync function toTokenWei(amount: string, tokenAddress: string): Promise<bigint> {\n  const trimmed = validateAmount(amount);\n  const decimals = await getTokenDecimals(tokenAddress);\n  const { parseUnits } = await import('viem');\n  return parseUnits(trimmed, decimals);\n}\n\n// ─── Write Operations ─────────────────────────────────────────────────────\n\nasync function handleV3Mint(liquidity: any, params: Record<string, unknown>) {\n  const token0 = readStringParam(params, 'token0', { required: true })!;\n  const token1 = readStringParam(params, 'token1', { required: true })!;\n  const tickLower = readNumberParam(params, 'tick_lower', { required: true })!;\n  const tickUpper = readNumberParam(params, 'tick_upper', { required: true })!;\n  const amount0 = readStringParam(params, 'amount0', { required: true })!;\n  const amount1 = readStringParam(params, 'amount1', { required: true })!;\n  const fee = readNumberParam(params, 'fee') ?? 3000;\n\n  // Pre-flight gas check\n  const safety = await checkBalance({ requiredEth: 0 });\n  if (!safety.safe) {\n    return errorResult(`Insufficient gas: ${safety.blockers.join('; ')}`);\n  }\n\n  const amount0Wei = await toTokenWei(amount0, token0);\n  const amount1Wei = await toTokenWei(amount1, token1);\n\n  const result = await liquidity.v3MintPosition({\n    token0: token0 as `0x${string}`,\n    token1: token1 as `0x${string}`,\n    fee,\n    tickLower,\n    tickUpper,\n    amount0Desired: amount0Wei,\n    amount1Desired: amount1Wei,\n    deadline: 1200,\n  });\n\n  return jsonResult({\n    status: 'success',\n    action: 'v3_mint',\n    tokenId: result.tokenId.toString(),\n    liquidity: result.liquidity.toString(),\n    amount0: result.amount0.toString(),\n    amount1: result.amount1.toString(),\n    txHash: result.txHash,\n  });\n}\n\nasync function handleV4Mint(liquidity: any, params: Record<string, unknown>) {\n  const token0 = readStringParam(params, 'token0', { required: true })!;\n  const token1 = readStringParam(params, 'token1', { required: true })!;\n  const tickLower = readNumberParam(params, 'tick_lower', { required: true })!;\n  const tickUpper = readNumberParam(params, 'tick_upper', { required: true })!;\n  const amount0 = readStringParam(params, 'amount0', { required: true })!;\n  const amount1 = readStringParam(params, 'amount1', { required: true })!;\n  const fee = readNumberParam(params, 'fee') ?? 3000;\n  const tickSpacing = readNumberParam(params, 'tick_spacing') ?? 60;\n  const hookAddress = readStringParam(params, 'hook_address');\n  const slippageBps = readNumberParam(params, 'slippage_bps') ?? 50;\n\n  // Pre-flight gas check\n  const safety = await checkBalance({ requiredEth: 0 });\n  if (!safety.safe) {\n    return errorResult(`Insufficient gas: ${safety.blockers.join('; ')}`);\n  }\n\n  const amount0Wei = await toTokenWei(amount0, token0);\n  const amount1Wei = await toTokenWei(amount1, token1);\n\n  const result = await liquidity.v4MintPosition({\n    token0: token0 as `0x${string}`,\n    token1: token1 as `0x${string}`,\n    fee,\n    tickSpacing,\n    hookAddress: hookAddress as `0x${string}` | undefined,\n    tickLower,\n    tickUpper,\n    amount0Desired: amount0Wei,\n    amount1Desired: amount1Wei,\n    slippageBps,\n    deadline: 1200,\n  });\n\n  return jsonResult({\n    status: 'success',\n    action: 'v4_mint',\n    tokenId: result.tokenId.toString(),\n    liquidity: result.liquidity.toString(),\n    amount0: result.amount0.toString(),\n    amount1: result.amount1.toString(),\n    txHash: result.txHash,\n  });\n}\n\nasync function handleV3Add(liquidity: any, params: Record<string, unknown>) {\n  const tokenId = readStringParam(params, 'token_id', { required: true })!;\n  const amount0 = readStringParam(params, 'amount0', { required: true })!;\n  const amount1 = readStringParam(params, 'amount1', { required: true })!;\n  const token0 = readStringParam(params, 'token0');\n  const token1 = readStringParam(params, 'token1');\n\n  const safety = await checkBalance({ requiredEth: 0 });\n  if (!safety.safe) {\n    return errorResult(`Insufficient gas: ${safety.blockers.join('; ')}`);\n  }\n\n  // Validate amounts before conversion\n  const a0 = validateAmount(amount0);\n  const a1 = validateAmount(amount1);\n  // Use actual token decimals when addresses are provided, otherwise fall back to 18\n  const amount0Wei = token0 ? await toTokenWei(a0, token0) : BigInt(Math.round(parseFloat(a0) * 1e18));\n  const amount1Wei = token1 ? await toTokenWei(a1, token1) : BigInt(Math.round(parseFloat(a1) * 1e18));\n\n  const result = await liquidity.v3AddLiquidity(validateTokenId(tokenId), {\n    amount0Desired: amount0Wei,\n    amount1Desired: amount1Wei,\n    deadline: 1200,\n  });\n\n  return jsonResult({\n    status: 'success',\n    action: 'v3_add',\n    tokenId,\n    amount0: result.amount0.toString(),\n    amount1: result.amount1.toString(),\n    txHash: result.txHash,\n  });\n}\n\nasync function handleV3Remove(liquidity: any, params: Record<string, unknown>) {\n  const tokenId = readStringParam(params, 'token_id', { required: true })!;\n  const percentage = readNumberParam(params, 'percentage') ?? 100;\n\n  const safety = await checkBalance({ requiredEth: 0 });\n  if (!safety.safe) {\n    return errorResult(`Insufficient gas: ${safety.blockers.join('; ')}`);\n  }\n\n  const pct = percentage / 100;\n  const result = await liquidity.v3RemoveLiquidity(validateTokenId(tokenId), {\n    percentageToRemove: pct,\n    burnToken: pct === 1,\n    deadline: 1200,\n  });\n\n  return jsonResult({\n    status: 'success',\n    action: 'v3_remove',\n    tokenId,\n    percentage,\n    amount0: result.amount0.toString(),\n    amount1: result.amount1.toString(),\n    txHash: result.txHash,\n  });\n}\n\nasync function handleV3Collect(liquidity: any, params: Record<string, unknown>) {\n  const tokenId = readStringParam(params, 'token_id', { required: true })!;\n\n  const safety = await checkBalance({ requiredEth: 0 });\n  if (!safety.safe) {\n    return errorResult(`Insufficient gas: ${safety.blockers.join('; ')}`);\n  }\n\n  const result = await liquidity.v3CollectFees(validateTokenId(tokenId));\n\n  return jsonResult({\n    status: 'success',\n    action: 'v3_collect',\n    tokenId,\n    feesCollected: {\n      token0: result.amount0.toString(),\n      token1: result.amount1.toString(),\n    },\n    txHash: result.txHash,\n  });\n}\n"],"mappings":"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"}