import { useState, useEffect } from 'react' import { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi' import { parseUnits } from 'viem' import { abis, getContractAddress } from '@/lib/contracts' import { handleContractCatchError, isValidAmount, parseContractError } from '@/lib/errors' import { SWAP_GAS_LIMIT } from '@/lib/constants' type DepositStatus = 'idle' | 'approving' | 'approved' | 'depositing' | 'success' | 'error' /** * Hook for adding liquidity to YT Pool * Accepts token contract address and decimals directly — no hardcoded token symbols. */ export function usePoolDeposit() { const { address, chainId } = useAccount() const [status, setStatus] = useState('idle') const [error, setError] = useState(null) const [approveHash, setApproveHash] = useState<`0x${string}` | undefined>() const [depositHash, setDepositHash] = useState<`0x${string}` | undefined>() const { writeContractAsync: approveWrite } = useWriteContract() const { writeContractAsync: depositWrite } = useWriteContract() const { isLoading: isApproving, isSuccess: isApproveSuccess, isError: isApproveError, error: approveReceiptError } = useWaitForTransactionReceipt({ hash: approveHash, }) const { isLoading: isDepositing, isSuccess: isDepositSuccess, isError: isDepositError, error: depositReceiptError } = useWaitForTransactionReceipt({ hash: depositHash, }) const executeApprove = async (tokenAddress: string, tokenDecimals: number, amount: string) => { if (status !== 'idle') return false if (!chainId) { setError('Please connect your wallet') return false } if (!isValidAmount(amount)) { setError('Invalid amount') return false } try { setStatus('approving') setError(null) const rewardRouterAddress = getContractAddress('YTRewardRouter', chainId) if (!tokenAddress || !rewardRouterAddress) { throw new Error('Contract not deployed on this chain') } const amountInWei = parseUnits(amount, tokenDecimals) const hash = await approveWrite({ address: tokenAddress as `0x${string}`, abi: abis.USDY, functionName: 'approve', args: [rewardRouterAddress, amountInWei], }) setApproveHash(hash) return true } catch (err: unknown) { handleContractCatchError(err, 'Approval failed', setError, setStatus as (s: string) => void) return false } } const executeDeposit = async ( tokenAddress: string, tokenDecimals: number, amount: string, minUsdy: string = '0', minYtLP: string = '0' ) => { if (status === 'depositing' || status === 'success' || status === 'error') return false if (!chainId) { setError('Please connect your wallet') return false } if (!isValidAmount(amount)) { setError('Invalid amount') return false } try { setStatus('depositing') setError(null) const rewardRouterAddress = getContractAddress('YTRewardRouter', chainId) if (!tokenAddress || !rewardRouterAddress) { throw new Error('Contract not deployed on this chain') } const amountInWei = parseUnits(amount, tokenDecimals) const minUsdyInWei = parseUnits(minUsdy, 18) const minYtLPInWei = parseUnits(minYtLP, 18) const hash = await depositWrite({ address: rewardRouterAddress, abi: abis.YTRewardRouter, functionName: 'addLiquidity', args: [tokenAddress as `0x${string}`, amountInWei, minUsdyInWei, minYtLPInWei], gas: SWAP_GAS_LIMIT, }) setDepositHash(hash) return true } catch (err: unknown) { handleContractCatchError(err, 'Transaction failed', setError, setStatus as (s: string) => void) return false } } const executeApproveAndDeposit = async ( tokenAddress: string, tokenDecimals: number, amount: string, minUsdy: string = '0', minYtLP: string = '0' ) => { if (status !== 'idle') return const approved = await executeApprove(tokenAddress, tokenDecimals, amount) if (!approved) return await new Promise(resolve => setTimeout(resolve, 2000)) await executeDeposit(tokenAddress, tokenDecimals, amount, minUsdy, minYtLP) } const reset = () => { setStatus('idle') setError(null) setApproveHash(undefined) setDepositHash(undefined) } useEffect(() => { if (isApproveSuccess && status === 'approving') { setStatus('approved') } }, [isApproveSuccess, status]) useEffect(() => { if (isApproveError && status === 'approving') { setError(parseContractError(approveReceiptError)) setStatus('error') } }, [isApproveError, status, approveReceiptError]) useEffect(() => { if (isDepositSuccess && status === 'depositing') { setStatus('success') } }, [isDepositSuccess, status]) useEffect(() => { if (isDepositError && status === 'depositing') { setError(parseContractError(depositReceiptError)) setStatus('error') } }, [isDepositError, status, depositReceiptError]) return { status, error, isLoading: isApproving || isDepositing, approveHash, depositHash, executeApprove, executeDeposit, executeApproveAndDeposit, reset, } }