import { Currency, currencyEquals, DEV, WDEV } from 'moonbeamswap' import { useMemo } from 'react' import { tryParseAmount } from '../state/swap/hooks' import { useTransactionAdder } from '../state/transactions/hooks' import { useCurrencyBalance } from '../state/wallet/hooks' import { useActiveWeb3React } from './index' import { useWDEVContract } from './useContract' export enum WrapType { NOT_APPLICABLE, WRAP, UNWRAP } const NOT_APPLICABLE = { wrapType: WrapType.NOT_APPLICABLE } /** * Given the selected input and output currency, return a wrap callback * @param inputCurrency the selected input currency * @param outputCurrency the selected output currency * @param typedValue the user input value */ export default function useWrapCallback( inputCurrency: Currency | undefined, outputCurrency: Currency | undefined, typedValue: string | undefined ): { wrapType: WrapType; execute?: undefined | (() => Promise); inputError?: string } { const { chainId, account } = useActiveWeb3React() const wethContract = useWDEVContract() const balance = useCurrencyBalance(account ?? undefined, inputCurrency) // we can always parse the amount typed as the input currency, since wrapping is 1:1 const inputAmount = useMemo(() => tryParseAmount(typedValue, inputCurrency), [inputCurrency, typedValue]) const addTransaction = useTransactionAdder() return useMemo(() => { if (!wethContract || !chainId || !inputCurrency || !outputCurrency) return NOT_APPLICABLE const sufficientBalance = inputAmount && balance && !balance.lessThan(inputAmount) if (inputCurrency === DEV && currencyEquals(WDEV[chainId], outputCurrency)) { return { wrapType: WrapType.WRAP, execute: sufficientBalance && inputAmount ? async () => { try { const txReceipt = await wethContract.deposit({ value: `0x${inputAmount.raw.toString(16)}` }) addTransaction(txReceipt, { summary: `Wrap ${inputAmount.toSignificant(6)} ETH to WDEV` }) } catch (error) { console.error('Could not deposit', error) } } : undefined, inputError: sufficientBalance ? undefined : 'Insufficient ETH balance' } } else if (currencyEquals(WDEV[chainId], inputCurrency) && outputCurrency === DEV) { return { wrapType: WrapType.UNWRAP, execute: sufficientBalance && inputAmount ? async () => { try { const txReceipt = await wethContract.withdraw(`0x${inputAmount.raw.toString(16)}`) addTransaction(txReceipt, { summary: `Unwrap ${inputAmount.toSignificant(6)} WDEV to ETH` }) } catch (error) { console.error('Could not withdraw', error) } } : undefined, inputError: sufficientBalance ? undefined : 'Insufficient WDEV balance' } } else { return NOT_APPLICABLE } }, [wethContract, chainId, inputCurrency, outputCurrency, inputAmount, balance, addTransaction]) }