{"version":3,"file":"staking-service.mjs","names":[],"sources":["../../../src/services/staking-service.ts"],"sourcesContent":["/**\n * Staking Service — liquid staking protocol integrations.\n *\n * Supports:\n *   - Lido (stETH / wstETH) on Ethereum mainnet\n *   - Coinbase (cbETH) on Ethereum mainnet\n *   - Rocket Pool (rETH) on Ethereum mainnet\n *\n * Uses same ABI-call pattern as lending-service.ts. All protocols\n * are simple contract calls — no external SDK dependencies.\n *\n * APY data fetched from DeFiLlama yields API.\n */\n\nimport { formatUnits, parseEther } from 'viem';\nimport { getRpcManager } from './rpc-provider.js';\nimport { guardedFetch } from './endpoint-allowlist.js';\nimport { LIDO, ROCKET_POOL, CBETH } from '../lib/contract-registry.js';\n\n// ── Contract Addresses — sourced from contract-registry ─────────────────\n\nconst CONTRACTS = {\n  lido: {\n    stETH: LIDO.ethereum.stETH,\n    wstETH: LIDO.ethereum.wstETH,\n  },\n  rocketPool: {\n    rETH: ROCKET_POOL.ethereum.rETH,\n    depositPool: ROCKET_POOL.ethereum.depositPool,\n  },\n  cbETH: CBETH.ethereum,\n} as const;\n\n// Base bridged addresses (for position checking)\nconst BASE_TOKENS = {\n  wstETH: LIDO.base.wstETH,\n  cbETH: CBETH.base,\n  rETH: ROCKET_POOL.base.rETH,\n};\n\n// ── Minimal ABIs ────────────────────────────────────────────────────────────\n\nconst LIDO_STETH_ABI = [\n  {\n    name: 'submit',\n    inputs: [{ name: '_referral', type: 'address' }],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'payable',\n    type: 'function',\n  },\n  {\n    name: 'balanceOf',\n    inputs: [{ name: '_account', type: 'address' }],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    name: 'approve',\n    inputs: [\n      { name: '_spender', type: 'address' },\n      { name: '_amount', type: 'uint256' },\n    ],\n    outputs: [{ name: '', type: 'bool' }],\n    stateMutability: 'nonpayable',\n    type: 'function',\n  },\n  {\n    name: 'allowance',\n    inputs: [\n      { name: '_owner', type: 'address' },\n      { name: '_spender', type: 'address' },\n    ],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n] as const;\n\nconst WSTETH_ABI = [\n  {\n    name: 'wrap',\n    inputs: [{ name: '_stETHAmount', type: 'uint256' }],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'nonpayable',\n    type: 'function',\n  },\n  {\n    name: 'unwrap',\n    inputs: [{ name: '_wstETHAmount', type: 'uint256' }],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'nonpayable',\n    type: 'function',\n  },\n  {\n    name: 'balanceOf',\n    inputs: [{ name: '_account', type: 'address' }],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    name: 'stEthPerToken',\n    inputs: [],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    name: 'tokensPerStEth',\n    inputs: [],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n] as const;\n\nconst ROCKET_DEPOSIT_ABI = [\n  {\n    name: 'deposit',\n    inputs: [],\n    outputs: [],\n    stateMutability: 'payable',\n    type: 'function',\n  },\n] as const;\n\nconst RETH_ABI = [\n  {\n    name: 'burn',\n    inputs: [{ name: '_rethAmount', type: 'uint256' }],\n    outputs: [],\n    stateMutability: 'nonpayable',\n    type: 'function',\n  },\n  {\n    name: 'balanceOf',\n    inputs: [{ name: '_account', type: 'address' }],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n  {\n    name: 'getExchangeRate',\n    inputs: [],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n] as const;\n\nconst ERC20_BALANCE_ABI = [\n  {\n    name: 'balanceOf',\n    inputs: [{ name: 'account', type: 'address' }],\n    outputs: [{ name: '', type: 'uint256' }],\n    stateMutability: 'view',\n    type: 'function',\n  },\n] as const;\n\n// ── Types ───────────────────────────────────────────────────────────────────\n\nexport interface StakeResult {\n  hash: string;\n  protocol: string;\n  action: string;\n  asset: string;\n  amount: string;\n}\n\nexport interface StakingPosition {\n  protocol: string;\n  asset: string;\n  balance: string;\n  balanceEth: string;\n  chain: string;\n  apy?: string;\n}\n\ninterface ApyData {\n  protocol: string;\n  symbol: string;\n  apy: number;\n  tvl: number;\n  fetchedAt: number;\n}\n\n// ── Service ─────────────────────────────────────────────────────────────────\n\nexport class StakingService {\n  private apyCache: ApyData[] = [];\n  private apyCacheTimestamp = 0;\n  private readonly APY_CACHE_TTL = 600_000; // 10 minutes\n\n  // ── Protocol Registry ──────────────────────────────────────────────\n\n  getSupportedProtocols() {\n    return [\n      { id: 'lido', name: 'Lido', assets: ['stETH', 'wstETH'], chain: 'ethereum' },\n      { id: 'rocket_pool', name: 'Rocket Pool', assets: ['rETH'], chain: 'ethereum' },\n      { id: 'coinbase', name: 'Coinbase', assets: ['cbETH'], chain: 'ethereum' },\n    ];\n  }\n\n  resolveProtocol(input: string): string | null {\n    const lower = input.toLowerCase();\n    if (lower === 'lido' || lower === 'steth' || lower === 'wsteth') return 'lido';\n    if (lower === 'rocket_pool' || lower === 'rocketpool' || lower === 'reth') return 'rocket_pool';\n    if (lower === 'coinbase' || lower === 'cbeth' || lower === 'cb') return 'coinbase';\n    return null;\n  }\n\n  // ── Stake (ETH → LST) ─────────────────────────────────────────────\n\n  async stakeEth(\n    protocol: string,\n    amount: bigint,\n    userAddress: `0x${string}`,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<StakeResult> {\n    switch (protocol) {\n      case 'lido':\n        return this.stakeLido(amount, userAddress, walletClient, publicClient);\n      case 'rocket_pool':\n        return this.stakeRocketPool(amount, walletClient, publicClient);\n      case 'coinbase':\n        throw new Error(\n          'cbETH cannot be minted directly. Swap ETH for cbETH using defi_swap tool instead.',\n        );\n      default:\n        throw new Error(`Unknown protocol: ${protocol}`);\n    }\n  }\n\n  private async stakeLido(\n    amount: bigint,\n    _userAddress: `0x${string}`,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<StakeResult> {\n    const hash = await walletClient.writeContract({\n      address: CONTRACTS.lido.stETH,\n      abi: LIDO_STETH_ABI,\n      functionName: 'submit',\n      args: ['0x0000000000000000000000000000000000000000' as `0x${string}`],\n      value: amount,\n    });\n\n    await publicClient.waitForTransactionReceipt({ hash });\n\n    return {\n      hash,\n      protocol: 'lido',\n      action: 'stake',\n      asset: 'stETH',\n      amount: formatUnits(amount, 18),\n    };\n  }\n\n  private async stakeRocketPool(\n    amount: bigint,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<StakeResult> {\n    const hash = await walletClient.writeContract({\n      address: CONTRACTS.rocketPool.depositPool,\n      abi: ROCKET_DEPOSIT_ABI,\n      functionName: 'deposit',\n      args: [],\n      value: amount,\n    });\n\n    await publicClient.waitForTransactionReceipt({ hash });\n\n    return {\n      hash,\n      protocol: 'rocket_pool',\n      action: 'stake',\n      asset: 'rETH',\n      amount: formatUnits(amount, 18),\n    };\n  }\n\n  // ── Unstake (LST → ETH) ───────────────────────────────────────────\n\n  async unstake(\n    protocol: string,\n    amount: bigint,\n    _userAddress: `0x${string}`,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<StakeResult> {\n    switch (protocol) {\n      case 'rocket_pool':\n        return this.unstakeRocketPool(amount, walletClient, publicClient);\n      case 'lido':\n        throw new Error(\n          'Lido unstaking uses a withdrawal queue (7+ days). ' +\n          'For instant exit, swap stETH/wstETH for ETH using defi_swap tool.',\n        );\n      case 'coinbase':\n        throw new Error(\n          'cbETH cannot be redeemed directly. Swap cbETH for ETH using defi_swap tool.',\n        );\n      default:\n        throw new Error(`Unknown protocol: ${protocol}`);\n    }\n  }\n\n  private async unstakeRocketPool(\n    amount: bigint,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<StakeResult> {\n    const hash = await walletClient.writeContract({\n      address: CONTRACTS.rocketPool.rETH,\n      abi: RETH_ABI,\n      functionName: 'burn',\n      args: [amount],\n    });\n\n    await publicClient.waitForTransactionReceipt({ hash });\n\n    return {\n      hash,\n      protocol: 'rocket_pool',\n      action: 'unstake',\n      asset: 'rETH',\n      amount: formatUnits(amount, 18),\n    };\n  }\n\n  // ── Wrap / Unwrap (stETH ↔ wstETH) ────────────────────────────────\n\n  async wrap(\n    amount: bigint,\n    userAddress: `0x${string}`,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<StakeResult> {\n    // Check and approve stETH for wstETH contract\n    await this.ensureStEthApproval(amount, userAddress, walletClient, publicClient);\n\n    const hash = await walletClient.writeContract({\n      address: CONTRACTS.lido.wstETH,\n      abi: WSTETH_ABI,\n      functionName: 'wrap',\n      args: [amount],\n    });\n\n    await publicClient.waitForTransactionReceipt({ hash });\n\n    return {\n      hash,\n      protocol: 'lido',\n      action: 'wrap',\n      asset: 'wstETH',\n      amount: formatUnits(amount, 18),\n    };\n  }\n\n  async unwrap(\n    amount: bigint,\n    _userAddress: `0x${string}`,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<StakeResult> {\n    const hash = await walletClient.writeContract({\n      address: CONTRACTS.lido.wstETH,\n      abi: WSTETH_ABI,\n      functionName: 'unwrap',\n      args: [amount],\n    });\n\n    await publicClient.waitForTransactionReceipt({ hash });\n\n    return {\n      hash,\n      protocol: 'lido',\n      action: 'unwrap',\n      asset: 'stETH',\n      amount: formatUnits(amount, 18),\n    };\n  }\n\n  private async ensureStEthApproval(\n    amount: bigint,\n    userAddress: `0x${string}`,\n    walletClient: any,\n    publicClient: any,\n  ): Promise<void> {\n    const currentAllowance = await publicClient.readContract({\n      address: CONTRACTS.lido.stETH,\n      abi: LIDO_STETH_ABI,\n      functionName: 'allowance',\n      args: [userAddress, CONTRACTS.lido.wstETH],\n    }) as bigint;\n\n    if (currentAllowance < amount) {\n      // Approve exact amount + 0.5% buffer (not unlimited) to limit exposure\n      const approvalAmount = amount + (amount / 200n);\n      const approveHash = await walletClient.writeContract({\n        address: CONTRACTS.lido.stETH,\n        abi: LIDO_STETH_ABI,\n        functionName: 'approve',\n        args: [CONTRACTS.lido.wstETH, approvalAmount],\n      });\n\n      // Wait for approval to confirm before proceeding (prevents race condition)\n      await publicClient.waitForTransactionReceipt({ hash: approveHash });\n    }\n  }\n\n  // ── Positions ──────────────────────────────────────────────────────\n\n  async getPositions(\n    userAddress: `0x${string}`,\n    chainId: number,\n    publicClient: any,\n  ): Promise<StakingPosition[]> {\n    const positions: StakingPosition[] = [];\n\n    if (chainId === 1) {\n      // Ethereum mainnet — check native LST balances + exchange rates\n      const checks = [\n        this.checkBalance(publicClient, CONTRACTS.lido.stETH, LIDO_STETH_ABI, userAddress, 'Lido', 'stETH'),\n        this.checkBalance(publicClient, CONTRACTS.lido.wstETH, WSTETH_ABI, userAddress, 'Lido', 'wstETH'),\n        this.checkBalance(publicClient, CONTRACTS.rocketPool.rETH, RETH_ABI, userAddress, 'Rocket Pool', 'rETH'),\n        this.checkBalance(publicClient, CONTRACTS.cbETH, ERC20_BALANCE_ABI, userAddress, 'Coinbase', 'cbETH'),\n      ];\n\n      const results = await Promise.allSettled(checks);\n      for (const r of results) {\n        if (r.status === 'fulfilled' && r.value) {\n          positions.push({ ...r.value, chain: 'ethereum' });\n        }\n      }\n\n      // Fetch exchange rates for ETH equivalents\n      await this.enrichWithExchangeRates(positions, publicClient, 1);\n    } else if (chainId === 8453) {\n      // Base — check bridged LST balances\n      const checks = [\n        this.checkBalance(publicClient, BASE_TOKENS.wstETH, ERC20_BALANCE_ABI, userAddress, 'Lido', 'wstETH'),\n        this.checkBalance(publicClient, BASE_TOKENS.cbETH, ERC20_BALANCE_ABI, userAddress, 'Coinbase', 'cbETH'),\n        this.checkBalance(publicClient, BASE_TOKENS.rETH, ERC20_BALANCE_ABI, userAddress, 'Rocket Pool', 'rETH'),\n      ];\n\n      const results = await Promise.allSettled(checks);\n      for (const r of results) {\n        if (r.status === 'fulfilled' && r.value) {\n          positions.push({ ...r.value, chain: 'base' });\n        }\n      }\n    }\n\n    // Enrich with APY data\n    await this.enrichWithApy(positions);\n\n    return positions;\n  }\n\n  private async checkBalance(\n    publicClient: any,\n    tokenAddress: string,\n    abi: readonly any[],\n    userAddress: `0x${string}`,\n    protocol: string,\n    asset: string,\n  ): Promise<Omit<StakingPosition, 'chain'> | null> {\n    try {\n      const balance = await publicClient.readContract({\n        address: tokenAddress as `0x${string}`,\n        abi,\n        functionName: 'balanceOf',\n        args: [userAddress],\n      }) as bigint;\n\n      if (balance === 0n) return null;\n\n      return {\n        protocol,\n        asset,\n        balance: formatUnits(balance, 18),\n        balanceEth: formatUnits(balance, 18), // will be enriched with exchange rate\n      };\n    } catch {\n      return null;\n    }\n  }\n\n  private async enrichWithExchangeRates(\n    positions: StakingPosition[],\n    publicClient: any,\n    chainId: number,\n  ): Promise<void> {\n    if (chainId !== 1) return;\n\n    for (const pos of positions) {\n      try {\n        if (pos.asset === 'wstETH') {\n          const stEthPerToken = await publicClient.readContract({\n            address: CONTRACTS.lido.wstETH,\n            abi: WSTETH_ABI,\n            functionName: 'stEthPerToken',\n          }) as bigint;\n          const balanceWei = parseEther(pos.balance);\n          const ethEquiv = (balanceWei * stEthPerToken) / BigInt(1e18);\n          pos.balanceEth = formatUnits(ethEquiv, 18);\n        } else if (pos.asset === 'rETH') {\n          const exchangeRate = await publicClient.readContract({\n            address: CONTRACTS.rocketPool.rETH,\n            abi: RETH_ABI,\n            functionName: 'getExchangeRate',\n          }) as bigint;\n          const balanceWei = parseEther(pos.balance);\n          const ethEquiv = (balanceWei * exchangeRate) / BigInt(1e18);\n          pos.balanceEth = formatUnits(ethEquiv, 18);\n        }\n        // stETH and cbETH are ~1:1 with ETH (pos.balanceEth already set)\n      } catch {\n        // Keep balanceEth as-is\n      }\n    }\n  }\n\n  // ── APY Fetching ───────────────────────────────────────────────────\n\n  async getApys(): Promise<ApyData[]> {\n    if (this.apyCache.length > 0 && Date.now() - this.apyCacheTimestamp < this.APY_CACHE_TTL) {\n      return this.apyCache;\n    }\n\n    try {\n      const response = await guardedFetch('https://yields.llama.fi/pools', {\n        headers: { Accept: 'application/json' },\n        signal: AbortSignal.timeout(10_000),\n      });\n\n      if (!response.ok) return this.apyCache;\n\n      const data: any = await response.json();\n      const pools: any[] = data.data ?? [];\n\n      // Filter for ETH staking pools on Ethereum\n      const stakingPools = pools.filter((p: any) =>\n        (p.project === 'lido' || p.project === 'rocket-pool' || p.project === 'coinbase-wrapped-staked-eth') &&\n        p.chain === 'Ethereum' &&\n        (p.symbol?.includes('ETH') || p.symbol?.includes('stETH')),\n      );\n\n      this.apyCache = stakingPools.map((p: any) => ({\n        protocol: p.project,\n        symbol: p.symbol,\n        apy: p.apy ?? p.apyBase ?? 0,\n        tvl: p.tvlUsd ?? 0,\n        fetchedAt: Date.now(),\n      }));\n      this.apyCacheTimestamp = Date.now();\n\n      return this.apyCache;\n    } catch {\n      return this.apyCache;\n    }\n  }\n\n  private async enrichWithApy(positions: StakingPosition[]): Promise<void> {\n    const apys = await this.getApys();\n\n    for (const pos of positions) {\n      const match = apys.find(a => {\n        if (pos.protocol === 'Lido') return a.protocol === 'lido';\n        if (pos.protocol === 'Rocket Pool') return a.protocol === 'rocket-pool';\n        if (pos.protocol === 'Coinbase') return a.protocol === 'coinbase-wrapped-staked-eth';\n        return false;\n      });\n      if (match) {\n        pos.apy = `${match.apy.toFixed(2)}%`;\n      }\n    }\n  }\n}\n\n// ── Singleton ───────────────────────────────────────────────────────────────\n\nlet _instance: StakingService | null = null;\n\nexport function getStakingService(): StakingService {\n  if (!_instance) {\n    _instance = new StakingService();\n  }\n  return _instance;\n}\n\nexport function resetStakingService(): void {\n  _instance = null;\n}\n"],"mappings":"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"}