Commit eb75e0dc authored by Zach Pomerantz's avatar Zach Pomerantz Committed by GitHub

fix: set approval to pending on wallet request (#3570)

parent c26ecdfc
...@@ -57,7 +57,7 @@ export const Overlay = styled(Row)<{ hasAction: boolean }>` ...@@ -57,7 +57,7 @@ export const Overlay = styled(Row)<{ hasAction: boolean }>`
export interface Action { export interface Action {
message: ReactNode message: ReactNode
icon?: Icon icon?: Icon
onClick: () => void onClick?: () => void
children: ReactNode children: ReactNode
} }
......
...@@ -26,10 +26,12 @@ export default function EtherscanLink({ data, type, color = 'currentColor', chil ...@@ -26,10 +26,12 @@ export default function EtherscanLink({ data, type, color = 'currentColor', chil
() => data && getExplorerLink(chainId || SupportedChainId.MAINNET, data, type), () => data && getExplorerLink(chainId || SupportedChainId.MAINNET, data, type),
[chainId, data, type] [chainId, data, type]
) )
return ( return (
<StyledExternalLink href={url} color={color} target="_blank"> <StyledExternalLink href={url} color={color} target="_blank">
<Row gap={0.25}> <Row gap={0.25}>
{children} <Link /> {children}
{url && <Link />}
</Row> </Row>
</StyledExternalLink> </StyledExternalLink>
) )
......
...@@ -87,12 +87,11 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -87,12 +87,11 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
) )
const addTransaction = useAddTransaction() const addTransaction = useAddTransaction()
const onApprove = useCallback(() => { const onApprove = useCallback(async () => {
handleApproveOrPermit().then((transaction) => { const transaction = await handleApproveOrPermit()
if (transaction) { if (transaction) {
addTransaction({ type: TransactionType.APPROVAL, ...transaction }) addTransaction({ type: TransactionType.APPROVAL, ...transaction })
} }
})
}, [addTransaction, handleApproveOrPermit]) }, [addTransaction, handleApproveOrPermit])
const { type: wrapType, callback: wrapCallback, error: wrapError, loading: wrapLoading } = useWrapCallback() const { type: wrapType, callback: wrapCallback, error: wrapError, loading: wrapLoading } = useWrapCallback()
...@@ -104,7 +103,6 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -104,7 +103,6 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
!chainId || !chainId ||
wrapLoading || wrapLoading ||
(wrapType !== WrapType.NOT_APPLICABLE && wrapError) || (wrapType !== WrapType.NOT_APPLICABLE && wrapError) ||
approvalState === ApproveOrPermitState.PENDING_SIGNATURE ||
!(inputTradeCurrencyAmount && inputCurrencyBalance) || !(inputTradeCurrencyAmount && inputCurrencyBalance) ||
inputCurrencyBalance.lessThan(inputTradeCurrencyAmount), inputCurrencyBalance.lessThan(inputTradeCurrencyAmount),
[ [
...@@ -114,7 +112,6 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -114,7 +112,6 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
wrapLoading, wrapLoading,
wrapType, wrapType,
wrapError, wrapError,
approvalState,
inputTradeCurrencyAmount, inputTradeCurrencyAmount,
inputCurrencyBalance, inputCurrencyBalance,
] ]
...@@ -155,11 +152,20 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) { ...@@ -155,11 +152,20 @@ export default memo(function SwapButton({ disabled }: SwapButtonProps) {
</EtherscanLink> </EtherscanLink>
), ),
icon: Spinner, icon: Spinner,
onClick: () => void 0, // @TODO: should not require an onclick
children: <Trans>Approve</Trans>, children: <Trans>Approve</Trans>,
}, },
} }
} }
if (approvalState === ApproveOrPermitState.PENDING_SIGNATURE) {
return {
disabled: true,
action: {
message: <Trans>Allowance pending</Trans>,
icon: Spinner,
children: <Trans>Allow</Trans>,
},
}
}
return {} return {}
}, [approvalCurrencyAmount?.currency, approvalHash, approvalState, disableSwap, inputCurrency, onApprove, wrapType]) }, [approvalCurrencyAmount?.currency, approvalHash, approvalState, disableSwap, inputCurrency, onApprove, wrapType])
......
...@@ -6,7 +6,7 @@ import { SWAP_ROUTER_ADDRESSES, V2_ROUTER_ADDRESS, V3_ROUTER_ADDRESS } from 'con ...@@ -6,7 +6,7 @@ import { SWAP_ROUTER_ADDRESSES, V2_ROUTER_ADDRESS, V3_ROUTER_ADDRESS } from 'con
import useActiveWeb3React from 'hooks/useActiveWeb3React' import useActiveWeb3React from 'hooks/useActiveWeb3React'
import { useERC20PermitFromTrade, UseERC20PermitState } from 'hooks/useERC20Permit' import { useERC20PermitFromTrade, UseERC20PermitState } from 'hooks/useERC20Permit'
import useTransactionDeadline from 'lib/hooks/useTransactionDeadline' import useTransactionDeadline from 'lib/hooks/useTransactionDeadline'
import { useCallback, useMemo } from 'react' import { useCallback, useMemo, useState } from 'react'
import invariant from 'tiny-invariant' import invariant from 'tiny-invariant'
import { getTxOptimizedSwapRouter, SwapRouterVersion } from 'utils/getTxOptimizedSwapRouter' import { getTxOptimizedSwapRouter, SwapRouterVersion } from 'utils/getTxOptimizedSwapRouter'
...@@ -171,39 +171,45 @@ export const useApproveOrPermit = ( ...@@ -171,39 +171,45 @@ export const useApproveOrPermit = (
gatherPermitSignature, gatherPermitSignature,
} = useERC20PermitFromTrade(trade, allowedSlippage, deadline) } = useERC20PermitFromTrade(trade, allowedSlippage, deadline)
const notApproved = approval === ApprovalState.NOT_APPROVED && !(signatureState === UseERC20PermitState.SIGNED) // Track when the interaction is blocked on a wallet so a PENDING state can be returned.
const [isPendingWallet, setIsPendingWallet] = useState(false)
// If permit is supported, trigger a signature, if not create approval transaction. // If permit is supported, trigger a signature, if not create approval transaction.
const handleApproveOrPermit = useCallback(async () => { const handleApproveOrPermit = useCallback(async () => {
if (signatureState === UseERC20PermitState.NOT_SIGNED && gatherPermitSignature) { setIsPendingWallet(true)
try { try {
return await gatherPermitSignature() if (signatureState === UseERC20PermitState.NOT_SIGNED && gatherPermitSignature) {
} catch (error) { try {
// Try to approve if gatherPermitSignature failed for any reason other than the user rejecting it. return await gatherPermitSignature()
if (error?.code !== 4001) { } catch (error) {
return getApproval() // Try to approve if gatherPermitSignature failed for any reason other than the user rejecting it.
if (error?.code !== 4001) {
return await getApproval()
}
} }
} else {
return await getApproval()
} }
} else { } catch (e) {
return getApproval() // Swallow approval errors - user rejections do not need to be displayed.
} finally {
setIsPendingWallet(false)
} }
}, [signatureState, gatherPermitSignature, getApproval]) }, [signatureState, gatherPermitSignature, getApproval])
const approvalState = useMemo(() => { const approvalState = useMemo(() => {
if (approval === ApprovalState.PENDING) { if (approval === ApprovalState.PENDING) {
return ApproveOrPermitState.PENDING_APPROVAL return ApproveOrPermitState.PENDING_APPROVAL
} } else if (signatureState === UseERC20PermitState.LOADING) {
if (signatureState === UseERC20PermitState.LOADING) {
return ApproveOrPermitState.PENDING_SIGNATURE return ApproveOrPermitState.PENDING_SIGNATURE
} else if (approval !== ApprovalState.NOT_APPROVED || signatureState === UseERC20PermitState.SIGNED) {
return ApproveOrPermitState.APPROVED
} else if (gatherPermitSignature) {
return isPendingWallet ? ApproveOrPermitState.PENDING_SIGNATURE : ApproveOrPermitState.REQUIRES_SIGNATURE
} else {
return isPendingWallet ? ApproveOrPermitState.PENDING_APPROVAL : ApproveOrPermitState.REQUIRES_APPROVAL
} }
if (notApproved && Boolean(gatherPermitSignature)) { }, [approval, gatherPermitSignature, isPendingWallet, signatureState])
return ApproveOrPermitState.REQUIRES_SIGNATURE
}
if (notApproved) {
return ApproveOrPermitState.REQUIRES_APPROVAL
}
return ApproveOrPermitState.APPROVED
}, [approval, gatherPermitSignature, notApproved, signatureState])
return { return {
approvalState, approvalState,
......
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