Commit 76cbd82c authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

fix: bring wrap ui to spec (#3577)

parent 6c4f7ab9
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import ErrorDialog, { StatusHeader } from 'lib/components/Error/ErrorDialog' import ErrorDialog, { StatusHeader } from 'lib/components/Error/ErrorDialog'
import EtherscanLink from 'lib/components/EtherscanLink' import EtherscanLink from 'lib/components/EtherscanLink'
import Rule from 'lib/components/Rule'
import SwapSummary from 'lib/components/Swap/Summary' import SwapSummary from 'lib/components/Swap/Summary'
import useInterval from 'lib/hooks/useInterval' import useInterval from 'lib/hooks/useInterval'
import { CheckCircle, Clock, Spinner } from 'lib/icons' import { CheckCircle, Clock, Spinner } from 'lib/icons'
...@@ -84,6 +85,7 @@ function TransactionStatus({ tx, onClose }: TransactionStatusProps) { ...@@ -84,6 +85,7 @@ function TransactionStatus({ tx, onClose }: TransactionStatusProps) {
<SwapSummary input={tx.info.inputCurrencyAmount} output={tx.info.outputCurrencyAmount} /> <SwapSummary input={tx.info.inputCurrencyAmount} output={tx.info.outputCurrencyAmount} />
) : null} ) : null}
</StatusHeader> </StatusHeader>
<Rule />
<TransactionRow flex> <TransactionRow flex>
<ThemedText.ButtonSmall> <ThemedText.ButtonSmall>
<EtherscanLink type={ExplorerDataType.TRANSACTION} data={tx.info.response.hash}> <EtherscanLink type={ExplorerDataType.TRANSACTION} data={tx.info.response.hash}>
......
import { Trans } from '@lingui/macro' import { Trans } from '@lingui/macro'
import { Token } from '@uniswap/sdk-core' import { Token } from '@uniswap/sdk-core'
import { useAtomValue, useUpdateAtom } from 'jotai/utils' import { useAtomValue, useUpdateAtom } from 'jotai/utils'
import { WrapErrorText } from 'lib/components/Swap/WrapErrorText'
import { useSwapCurrencyAmount, useSwapInfo, useSwapTradeType } from 'lib/hooks/swap' import { useSwapCurrencyAmount, useSwapInfo, useSwapTradeType } from 'lib/hooks/swap'
import { import {
ApproveOrPermitState, ApproveOrPermitState,
...@@ -10,7 +9,7 @@ import { ...@@ -10,7 +9,7 @@ import {
useSwapRouterAddress, useSwapRouterAddress,
} from 'lib/hooks/swap/useSwapApproval' } from 'lib/hooks/swap/useSwapApproval'
import { useSwapCallback } from 'lib/hooks/swap/useSwapCallback' import { useSwapCallback } from 'lib/hooks/swap/useSwapCallback'
import useWrapCallback, { WrapError, WrapType } from 'lib/hooks/swap/useWrapCallback' import useWrapCallback, { WrapType } from 'lib/hooks/swap/useWrapCallback'
import { useAddTransaction, usePendingApproval } from 'lib/hooks/transactions' import { useAddTransaction, usePendingApproval } from 'lib/hooks/transactions'
import useActiveWeb3React from 'lib/hooks/useActiveWeb3React' import useActiveWeb3React from 'lib/hooks/useActiveWeb3React'
import { useSetOldestValidBlock } from 'lib/hooks/useIsValidBlock' import { useSetOldestValidBlock } from 'lib/hooks/useIsValidBlock'
...@@ -44,11 +43,11 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -44,11 +43,11 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
const { const {
[Field.INPUT]: { [Field.INPUT]: {
currency: inputCurrency, currency: inputCurrency,
amount: inputTradeCurrencyAmount, amount: inputCurrencyAmount,
balance: inputCurrencyBalance, balance: inputCurrencyBalance,
usdc: inputUSDC, usdc: inputUSDC,
}, },
[Field.OUTPUT]: { amount: outputTradeCurrencyAmount, usdc: outputUSDC }, [Field.OUTPUT]: { amount: outputCurrencyAmount, usdc: outputUSDC },
trade, trade,
slippage, slippage,
impact, impact,
...@@ -94,35 +93,23 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -94,35 +93,23 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
} }
}, [addTransaction, handleApproveOrPermit]) }, [addTransaction, handleApproveOrPermit])
const { type: wrapType, callback: wrapCallback, error: wrapError, loading: wrapLoading } = useWrapCallback() const { type: wrapType, callback: wrapCallback } = useWrapCallback()
const disableSwap = useMemo( const disableSwap = useMemo(
() => () =>
disabled || disabled ||
!optimizedTrade || (wrapType === WrapType.NONE && !optimizedTrade) ||
!chainId || !chainId ||
wrapLoading || !(inputCurrencyAmount && inputCurrencyBalance) ||
(wrapType !== WrapType.NOT_APPLICABLE && wrapError) || inputCurrencyBalance.lessThan(inputCurrencyAmount),
!(inputTradeCurrencyAmount && inputCurrencyBalance) || [disabled, wrapType, optimizedTrade, chainId, inputCurrencyAmount, inputCurrencyBalance]
inputCurrencyBalance.lessThan(inputTradeCurrencyAmount),
[
disabled,
optimizedTrade,
chainId,
wrapLoading,
wrapType,
wrapError,
inputTradeCurrencyAmount,
inputCurrencyBalance,
]
) )
const actionProps = useMemo((): Partial<ActionButtonProps> | undefined => { const actionProps = useMemo((): Partial<ActionButtonProps> | undefined => {
if (disableSwap) { if (disableSwap) return { disabled: true }
return { disabled: true }
}
if ( if (
wrapType === WrapType.NOT_APPLICABLE && wrapType === WrapType.NONE &&
(approvalState === ApproveOrPermitState.REQUIRES_APPROVAL || (approvalState === ApproveOrPermitState.REQUIRES_APPROVAL ||
approvalState === ApproveOrPermitState.REQUIRES_SIGNATURE) approvalState === ApproveOrPermitState.REQUIRES_SIGNATURE)
) { ) {
...@@ -189,13 +176,13 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -189,13 +176,13 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
swapCallback?.() swapCallback?.()
.then((response) => { .then((response) => {
setDisplayTxHash(response.hash) setDisplayTxHash(response.hash)
invariant(inputTradeCurrencyAmount && outputTradeCurrencyAmount) invariant(inputCurrencyAmount && outputCurrencyAmount)
addTransaction({ addTransaction({
response, response,
type: TransactionType.SWAP, type: TransactionType.SWAP,
tradeType, tradeType,
inputCurrencyAmount: inputTradeCurrencyAmount, inputCurrencyAmount,
outputCurrencyAmount: outputTradeCurrencyAmount, outputCurrencyAmount,
}) })
// Set the block containing the response to the oldest valid block to ensure that the // Set the block containing the response to the oldest valid block to ensure that the
...@@ -213,8 +200,8 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -213,8 +200,8 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
}) })
}, [ }, [
addTransaction, addTransaction,
inputTradeCurrencyAmount, inputCurrencyAmount,
outputTradeCurrencyAmount, outputCurrencyAmount,
setDisplayTxHash, setDisplayTxHash,
setOldestValidBlock, setOldestValidBlock,
swapCallback, swapCallback,
...@@ -222,29 +209,28 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -222,29 +209,28 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
]) ])
const ButtonText = useCallback(() => { const ButtonText = useCallback(() => {
if ((wrapType === WrapType.WRAP || wrapType === WrapType.UNWRAP) && wrapError !== WrapError.NO_ERROR) {
return <WrapErrorText wrapError={wrapError} />
}
switch (wrapType) { switch (wrapType) {
case WrapType.UNWRAP: case WrapType.UNWRAP:
return <Trans>Unwrap</Trans> return <Trans>Unwrap {inputCurrency?.symbol}</Trans>
case WrapType.WRAP: case WrapType.WRAP:
return <Trans>Wrap</Trans> return <Trans>Wrap {inputCurrency?.symbol}</Trans>
case WrapType.NOT_APPLICABLE: case WrapType.NONE:
default: default:
return <Trans>Review swap</Trans> return <Trans>Review swap</Trans>
} }
}, [wrapError, wrapType]) }, [inputCurrency?.symbol, wrapType])
const handleDialogClose = useCallback(() => { const handleDialogClose = useCallback(() => {
setActiveTrade(undefined) setActiveTrade(undefined)
}, []) }, [])
const handleActionButtonClick = useCallback(async () => { const handleActionButtonClick = useCallback(async () => {
if (wrapType === WrapType.NOT_APPLICABLE) { if (wrapType === WrapType.NONE) {
setActiveTrade(trade.trade) setActiveTrade(trade.trade)
} else { } else {
const transaction = await wrapCallback() const transaction = await wrapCallback()
if (!transaction) return
addTransaction({ addTransaction({
response: transaction, response: transaction,
type: TransactionType.WRAP, type: TransactionType.WRAP,
......
...@@ -4,7 +4,6 @@ import Column from 'lib/components/Column' ...@@ -4,7 +4,6 @@ import Column from 'lib/components/Column'
import Rule from 'lib/components/Rule' import Rule from 'lib/components/Rule'
import Tooltip from 'lib/components/Tooltip' import Tooltip from 'lib/components/Tooltip'
import { loadingCss } from 'lib/css/loading' import { loadingCss } from 'lib/css/loading'
import { WrapType } from 'lib/hooks/swap/useWrapCallback'
import { PriceImpact } from 'lib/hooks/useUSDCPriceImpact' import { PriceImpact } from 'lib/hooks/useUSDCPriceImpact'
import { AlertTriangle, Icon, Info, InlineSpinner } from 'lib/icons' import { AlertTriangle, Icon, Info, InlineSpinner } from 'lib/icons'
import styled, { ThemedText } from 'lib/theme' import styled, { ThemedText } from 'lib/theme'
...@@ -38,7 +37,7 @@ export function ConnectWallet() { ...@@ -38,7 +37,7 @@ export function ConnectWallet() {
} }
export function UnsupportedNetwork() { export function UnsupportedNetwork() {
return <Caption caption={<Trans>Unsupported network - switch to another to trade.</Trans>} /> return <Caption caption={<Trans>Unsupported network - switch to another to trade</Trans>} />
} }
export function InsufficientBalance({ currency }: { currency: Currency }) { export function InsufficientBalance({ currency }: { currency: Currency }) {
...@@ -66,15 +65,17 @@ export function LoadingTrade() { ...@@ -66,15 +65,17 @@ export function LoadingTrade() {
) )
} }
export function WrapCurrency({ loading, wrapType }: { loading: boolean; wrapType: WrapType.UNWRAP | WrapType.WRAP }) { export function WrapCurrency({ inputCurrency, outputCurrency }: { inputCurrency: Currency; outputCurrency: Currency }) {
const WrapText = useCallback(() => { const Text = useCallback(
if (wrapType === WrapType.WRAP) { () => (
return loading ? <Trans>Wrapping native currency.</Trans> : <Trans>Wrap native currency.</Trans> <Trans>
} Convert {inputCurrency.symbol} to {outputCurrency.symbol} with no slippage
return loading ? <Trans>Unwrapping native currency.</Trans> : <Trans>Unwrap native currency.</Trans> </Trans>
}, [loading, wrapType]) ),
[inputCurrency.symbol, outputCurrency.symbol]
)
return <Caption icon={Info} caption={<WrapText />} /> return <Caption icon={Info} caption={<Text />} />
} }
export function Trade({ export function Trade({
......
...@@ -20,14 +20,14 @@ const ToolbarRow = styled(Row)` ...@@ -20,14 +20,14 @@ const ToolbarRow = styled(Row)`
export default memo(function Toolbar({ disabled }: { disabled?: boolean }) { export default memo(function Toolbar({ disabled }: { disabled?: boolean }) {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()
const { const {
[Field.INPUT]: { currency: inputCurrency, balance }, [Field.INPUT]: { currency: inputCurrency, balance: inputBalance, amount: inputAmount },
[Field.OUTPUT]: { currency: outputCurrency, usdc: outputUSDC }, [Field.OUTPUT]: { currency: outputCurrency, usdc: outputUSDC },
trade: { trade, state }, trade: { trade, state },
impact, impact,
} = useSwapInfo() } = useSwapInfo()
const isRouteLoading = state === TradeState.SYNCING || state === TradeState.LOADING const isRouteLoading = state === TradeState.SYNCING || state === TradeState.LOADING
const isAmountPopulated = useIsAmountPopulated() const isAmountPopulated = useIsAmountPopulated()
const { type: wrapType, loading: wrapLoading } = useWrapCallback() const { type: wrapType } = useWrapCallback()
const caption = useMemo(() => { const caption = useMemo(() => {
if (disabled) { if (disabled) {
return <Caption.ConnectWallet /> return <Caption.ConnectWallet />
...@@ -38,8 +38,11 @@ export default memo(function Toolbar({ disabled }: { disabled?: boolean }) { ...@@ -38,8 +38,11 @@ export default memo(function Toolbar({ disabled }: { disabled?: boolean }) {
} }
if (inputCurrency && outputCurrency && isAmountPopulated) { if (inputCurrency && outputCurrency && isAmountPopulated) {
if (wrapType !== WrapType.NOT_APPLICABLE) { if (inputBalance && inputAmount?.greaterThan(inputBalance)) {
return <Caption.WrapCurrency wrapType={wrapType} loading={wrapLoading} /> return <Caption.InsufficientBalance currency={inputCurrency} />
}
if (wrapType !== WrapType.NONE) {
return <Caption.WrapCurrency inputCurrency={inputCurrency} outputCurrency={outputCurrency} />
} }
if (isRouteLoading) { if (isRouteLoading) {
return <Caption.LoadingTrade /> return <Caption.LoadingTrade />
...@@ -47,9 +50,6 @@ export default memo(function Toolbar({ disabled }: { disabled?: boolean }) { ...@@ -47,9 +50,6 @@ export default memo(function Toolbar({ disabled }: { disabled?: boolean }) {
if (!trade?.swaps) { if (!trade?.swaps) {
return <Caption.InsufficientLiquidity /> return <Caption.InsufficientLiquidity />
} }
if (balance && trade?.inputAmount.greaterThan(balance)) {
return <Caption.InsufficientBalance currency={trade.inputAmount.currency} />
}
if (trade.inputAmount && trade.outputAmount) { if (trade.inputAmount && trade.outputAmount) {
return <Caption.Trade trade={trade} outputUSDC={outputUSDC} impact={impact} /> return <Caption.Trade trade={trade} outputUSDC={outputUSDC} impact={impact} />
} }
...@@ -57,17 +57,17 @@ export default memo(function Toolbar({ disabled }: { disabled?: boolean }) { ...@@ -57,17 +57,17 @@ export default memo(function Toolbar({ disabled }: { disabled?: boolean }) {
return <Caption.Empty /> return <Caption.Empty />
}, [ }, [
balance,
chainId, chainId,
disabled, disabled,
impact, impact,
inputAmount,
inputBalance,
inputCurrency, inputCurrency,
isAmountPopulated, isAmountPopulated,
isRouteLoading, isRouteLoading,
outputCurrency, outputCurrency,
outputUSDC, outputUSDC,
trade, trade,
wrapLoading,
wrapType, wrapType,
]) ])
......
import { Trans } from '@lingui/macro'
import { WrapError } from 'lib/hooks/swap/useWrapCallback'
import useNativeCurrency from 'lib/hooks/useNativeCurrency'
export function WrapErrorText({ wrapError }: { wrapError: WrapError }) {
const native = useNativeCurrency()
const wrapped = native?.wrapped
switch (wrapError) {
case WrapError.ENTER_NATIVE_AMOUNT:
return <Trans>Enter {native?.symbol} amount</Trans>
case WrapError.ENTER_WRAPPED_AMOUNT:
return <Trans>Enter {wrapped?.symbol} amount</Trans>
case WrapError.INSUFFICIENT_NATIVE_BALANCE:
return <Trans>Insufficient {native?.symbol} balance</Trans>
case WrapError.INSUFFICIENT_WRAPPED_BALANCE:
return <Trans>Insufficient {wrapped?.symbol} balance</Trans>
case WrapError.NO_ERROR:
default:
return null
}
}
...@@ -72,7 +72,7 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr ...@@ -72,7 +72,7 @@ export default function useClientSideSmartOrderRouterTrade<TTradeType extends Tr
const { type: wrapType } = useWrapCallback() const { type: wrapType } = useWrapCallback()
const getQuoteResult = useCallback(async (): Promise<{ data?: GetQuoteResult; error?: unknown }> => { const getQuoteResult = useCallback(async (): Promise<{ data?: GetQuoteResult; error?: unknown }> => {
if (wrapType !== WrapType.NOT_APPLICABLE) return { error: undefined } if (wrapType !== WrapType.NONE) return { error: undefined }
if (!queryArgs || !params) return { error: undefined } if (!queryArgs || !params) return { error: undefined }
try { try {
return await getClientSideQuote(queryArgs, params, config) return await getClientSideQuote(queryArgs, params, config)
......
import { ContractTransaction } from '@ethersproject/contracts' import { ContractTransaction } from '@ethersproject/contracts'
import { useWETHContract } from 'hooks/useContract' import { useWETHContract } from 'hooks/useContract'
import { atom, useAtom } from 'jotai'
import { useAtomValue } from 'jotai/utils' import { useAtomValue } from 'jotai/utils'
import { Field, swapAtom } from 'lib/state/swap' import { Field, swapAtom } from 'lib/state/swap'
import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount' import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { useCallback, useEffect, useMemo } from 'react' import { useCallback, useMemo } from 'react'
import { WRAPPED_NATIVE_CURRENCY } from '../../../constants/tokens' import { WRAPPED_NATIVE_CURRENCY } from '../../../constants/tokens'
import useActiveWeb3React from '../useActiveWeb3React' import useActiveWeb3React from '../useActiveWeb3React'
import { useCurrencyBalances } from '../useCurrencyBalance' import useCurrencyBalance from '../useCurrencyBalance'
export enum WrapType { export enum WrapType {
NOT_APPLICABLE, NONE,
WRAP, WRAP,
UNWRAP, UNWRAP,
} }
interface UseWrapCallbackReturns { interface UseWrapCallbackReturns {
callback: () => Promise<ContractTransaction> callback: () => Promise<ContractTransaction | undefined>
error: WrapError
loading: boolean
type: WrapType type: WrapType
} }
export enum WrapError {
NO_ERROR = 0, // must be equal to 0 so all other errors are truthy
ENTER_NATIVE_AMOUNT,
ENTER_WRAPPED_AMOUNT,
INSUFFICIENT_NATIVE_BALANCE,
INSUFFICIENT_WRAPPED_BALANCE,
}
interface WrapState {
loading: boolean
error: WrapError
}
const wrapState = atom<WrapState>({
loading: false,
error: WrapError.NO_ERROR,
})
export default function useWrapCallback(): UseWrapCallbackReturns { export default function useWrapCallback(): UseWrapCallbackReturns {
const { account, chainId } = useActiveWeb3React() const { account, chainId } = useActiveWeb3React()
const [{ loading, error }, setWrapState] = useAtom(wrapState)
const wrappedNativeCurrencyContract = useWETHContract() const wrappedNativeCurrencyContract = useWETHContract()
const { amount, [Field.INPUT]: inputCurrency, [Field.OUTPUT]: outputCurrency } = useAtomValue(swapAtom) const { amount, [Field.INPUT]: inputCurrency, [Field.OUTPUT]: outputCurrency } = useAtomValue(swapAtom)
const wrapType = useMemo(() => { const wrapType = useMemo(() => {
if (!inputCurrency || !outputCurrency || !chainId) { if (chainId && inputCurrency && outputCurrency) {
return WrapType.NOT_APPLICABLE
}
if (inputCurrency.isNative && WRAPPED_NATIVE_CURRENCY[chainId]?.equals(outputCurrency)) { if (inputCurrency.isNative && WRAPPED_NATIVE_CURRENCY[chainId]?.equals(outputCurrency)) {
return WrapType.WRAP return WrapType.WRAP
} }
if (WRAPPED_NATIVE_CURRENCY[chainId]?.equals(inputCurrency) && outputCurrency.isNative) { if (outputCurrency.isNative && WRAPPED_NATIVE_CURRENCY[chainId]?.equals(inputCurrency)) {
return WrapType.UNWRAP return WrapType.UNWRAP
} }
return WrapType.NOT_APPLICABLE }
return WrapType.NONE
}, [chainId, inputCurrency, outputCurrency]) }, [chainId, inputCurrency, outputCurrency])
const parsedAmountIn = useMemo( const parsedAmountIn = useMemo(
() => tryParseCurrencyAmount(amount, inputCurrency ?? undefined), () => tryParseCurrencyAmount(amount, inputCurrency ?? undefined),
[inputCurrency, amount] [inputCurrency, amount]
) )
const balanceIn = useCurrencyBalance(account, inputCurrency)
const relevantTokenBalances = useCurrencyBalances(
account,
useMemo(() => [inputCurrency ?? undefined, outputCurrency ?? undefined], [inputCurrency, outputCurrency])
)
const currencyBalances = useMemo(
() => ({
[Field.INPUT]: relevantTokenBalances[0],
[Field.OUTPUT]: relevantTokenBalances[1],
}),
[relevantTokenBalances]
)
const hasInputAmount = Boolean(parsedAmountIn?.greaterThan('0'))
const sufficientBalance = parsedAmountIn && !currencyBalances[Field.INPUT]?.lessThan(parsedAmountIn)
useEffect(() => {
if (sufficientBalance) {
setWrapState((state) => ({ ...state, error: WrapError.NO_ERROR }))
} else if (wrapType === WrapType.WRAP) {
setWrapState((state) => ({
...state,
error: hasInputAmount ? WrapError.INSUFFICIENT_NATIVE_BALANCE : WrapError.ENTER_NATIVE_AMOUNT,
}))
} else if (wrapType === WrapType.UNWRAP) {
setWrapState((state) => ({
...state,
error: hasInputAmount ? WrapError.INSUFFICIENT_WRAPPED_BALANCE : WrapError.ENTER_WRAPPED_AMOUNT,
}))
}
}, [hasInputAmount, setWrapState, sufficientBalance, wrapType])
const callback = useCallback(async () => { const callback = useCallback(async () => {
if (wrapType === WrapType.NONE) {
return Promise.reject('Wrapping not applicable to this asset.')
}
if (!parsedAmountIn) { if (!parsedAmountIn) {
return Promise.reject('Must provide an input amount to wrap.') return Promise.reject('Must provide an input amount to wrap.')
} }
if (wrapType === WrapType.NOT_APPLICABLE) { if (!balanceIn || balanceIn.lessThan(parsedAmountIn)) {
return Promise.reject('Wrapping not applicable to this asset.')
}
if (!sufficientBalance) {
return Promise.reject('Insufficient balance to wrap desired amount.') return Promise.reject('Insufficient balance to wrap desired amount.')
} }
if (!wrappedNativeCurrencyContract) { if (!wrappedNativeCurrencyContract) {
return Promise.reject('Wrap contract not found.') return Promise.reject('Wrap contract not found.')
} }
setWrapState((state) => ({ ...state, loading: true }))
const result = await (wrapType === WrapType.WRAP try {
return await (wrapType === WrapType.WRAP
? wrappedNativeCurrencyContract.deposit({ value: `0x${parsedAmountIn.quotient.toString(16)}` }) ? wrappedNativeCurrencyContract.deposit({ value: `0x${parsedAmountIn.quotient.toString(16)}` })
: wrappedNativeCurrencyContract.withdraw(`0x${parsedAmountIn.quotient.toString(16)}`) : wrappedNativeCurrencyContract.withdraw(`0x${parsedAmountIn.quotient.toString(16)}`))
).catch((e: unknown) => { } catch (e) {
setWrapState((state) => ({ ...state, loading: false })) // TODO(zzmp): add error handling
throw e console.error(e)
}) return
// resolve loading state after one confirmation }
result.wait(1).finally(() => setWrapState((state) => ({ ...state, loading: false }))) }, [wrapType, parsedAmountIn, balanceIn, wrappedNativeCurrencyContract])
return Promise.resolve(result)
}, [wrappedNativeCurrencyContract, sufficientBalance, parsedAmountIn, wrapType, setWrapState])
return useMemo( return useMemo(() => ({ callback, type: wrapType }), [callback, wrapType])
() => ({
callback,
error,
loading,
type: wrapType,
}),
[callback, error, loading, wrapType]
)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment