import { useState, useCallback, useEffect } from 'react' import { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi' import { parseUnits } from 'viem' import { abis, getContractAddress } from '@/lib/contracts' import { useTokenList } from './useTokenList' import { handleContractCatchError, isValidAmount, parseContractError } from '@/lib/errors' import { WITHDRAW_GAS_LIMIT } from '@/lib/constants' type WithdrawStatus = 'idle' | 'withdrawing' | 'success' | 'error' export function useLendingWithdraw() { const { address, chainId } = useAccount() const { bySymbol } = useTokenList() const usdcToken = bySymbol['USDC'] const [status, setStatus] = useState('idle') const [error, setError] = useState(null) const { writeContractAsync: withdrawWrite, data: withdrawHash, isPending: isWithdrawPending, reset: resetWithdraw, } = useWriteContract() const { isLoading: isWithdrawConfirming, isSuccess: isWithdrawSuccess, isError: isWithdrawError, error: withdrawReceiptError, } = useWaitForTransactionReceipt({ hash: withdrawHash }) const executeWithdraw = useCallback(async (amount: string) => { if (status !== 'idle') return false if (!address || !chainId || !usdcToken || !amount) { setError('Missing required parameters') return false } if (!isValidAmount(amount)) { setError('Invalid amount') return false } try { setError(null) setStatus('withdrawing') const lendingProxyAddress = getContractAddress('lendingProxy', chainId) if (!lendingProxyAddress) { throw new Error('Contract not deployed on this chain') } const usdcDecimals = usdcToken.onChainDecimals ?? usdcToken.decimals const amountInWei = parseUnits(amount, usdcDecimals) await withdrawWrite({ address: lendingProxyAddress, abi: abis.lendingProxy, functionName: 'withdraw', args: [amountInWei], gas: WITHDRAW_GAS_LIMIT, }) return true } catch (err: unknown) { handleContractCatchError(err, 'Withdraw failed', setError, setStatus as (s: string) => void) return false } }, [address, chainId, withdrawWrite, usdcToken, status]) useEffect(() => { if (isWithdrawSuccess && status === 'withdrawing') { setStatus('success') } }, [isWithdrawSuccess, status]) useEffect(() => { if (isWithdrawError && status === 'withdrawing') { setError(parseContractError(withdrawReceiptError)) setStatus('error') } }, [isWithdrawError, status, withdrawReceiptError]) const reset = useCallback(() => { setStatus('idle') setError(null) resetWithdraw() }, [resetWithdraw]) return { status, error, isLoading: isWithdrawPending || isWithdrawConfirming, withdrawHash, executeWithdraw, reset, } }