fix: track swap approvals (#3183)
* fix: track swap approvals * fix: type ambiguous return value
This commit is contained in:
parent
cee4b8c77a
commit
ffe2bd315e
@ -1,4 +1,3 @@
|
|||||||
import { TransactionResponse } from '@ethersproject/providers'
|
|
||||||
import { Trade } from '@uniswap/router-sdk'
|
import { Trade } from '@uniswap/router-sdk'
|
||||||
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
|
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
|
||||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||||
@ -6,31 +5,30 @@ import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
|||||||
import useSwapApproval, { useSwapApprovalOptimizedTrade } from 'lib/hooks/swap/useSwapApproval'
|
import useSwapApproval, { useSwapApprovalOptimizedTrade } from 'lib/hooks/swap/useSwapApproval'
|
||||||
import { ApprovalState, useApproval } from 'lib/hooks/useApproval'
|
import { ApprovalState, useApproval } from 'lib/hooks/useApproval'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import invariant from 'tiny-invariant'
|
|
||||||
|
|
||||||
import { TransactionType } from '../state/transactions/actions'
|
import { TransactionType } from '../state/transactions/actions'
|
||||||
import { useHasPendingApproval, useTransactionAdder } from '../state/transactions/hooks'
|
import { useHasPendingApproval, useTransactionAdder } from '../state/transactions/hooks'
|
||||||
export { ApprovalState } from 'lib/hooks/useApproval'
|
export { ApprovalState } from 'lib/hooks/useApproval'
|
||||||
|
|
||||||
|
function useGetAndTrackApproval(getApproval: ReturnType<typeof useApproval>[1]) {
|
||||||
|
const addTransaction = useTransactionAdder()
|
||||||
|
return useCallback(() => {
|
||||||
|
return getApproval().then((pending) => {
|
||||||
|
if (pending) {
|
||||||
|
const { response, tokenAddress, spenderAddress: spender } = pending
|
||||||
|
addTransaction(response, { type: TransactionType.APPROVAL, tokenAddress, spender })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [addTransaction, getApproval])
|
||||||
|
}
|
||||||
|
|
||||||
// returns a variable indicating the state of the approval and a function which approves if necessary or early returns
|
// returns a variable indicating the state of the approval and a function which approves if necessary or early returns
|
||||||
export function useApproveCallback(
|
export function useApproveCallback(
|
||||||
amountToApprove?: CurrencyAmount<Currency>,
|
amountToApprove?: CurrencyAmount<Currency>,
|
||||||
spender?: string
|
spender?: string
|
||||||
): [ApprovalState, () => Promise<void>] {
|
): [ApprovalState, () => Promise<void>] {
|
||||||
const token = amountToApprove?.currency?.isToken ? amountToApprove.currency : undefined
|
const [approval, getApproval] = useApproval(amountToApprove, spender, useHasPendingApproval)
|
||||||
const addTransaction = useTransactionAdder()
|
return [approval, useGetAndTrackApproval(getApproval)]
|
||||||
const [approval, approvalCallback] = useApproval(amountToApprove, spender, useHasPendingApproval)
|
|
||||||
|
|
||||||
const approveCallback = useCallback(() => {
|
|
||||||
return approvalCallback().then((response?: TransactionResponse) => {
|
|
||||||
if (response) {
|
|
||||||
invariant(token && spender)
|
|
||||||
addTransaction(response, { type: TransactionType.APPROVAL, tokenAddress: token.address, spender })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}, [approvalCallback, token, spender, addTransaction])
|
|
||||||
|
|
||||||
return [approval, approveCallback]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useApprovalOptimizedTrade(
|
export function useApprovalOptimizedTrade(
|
||||||
@ -47,6 +45,7 @@ export function useApproveCallbackFromTrade(
|
|||||||
| Trade<Currency, Currency, TradeType>
|
| Trade<Currency, Currency, TradeType>
|
||||||
| undefined,
|
| undefined,
|
||||||
allowedSlippage: Percent
|
allowedSlippage: Percent
|
||||||
) {
|
): [ApprovalState, () => Promise<void>] {
|
||||||
return useSwapApproval(trade, allowedSlippage, useHasPendingApproval)
|
const [approval, getApproval] = useSwapApproval(trade, allowedSlippage, useHasPendingApproval)
|
||||||
|
return [approval, useGetAndTrackApproval(getApproval)]
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,10 @@ export function useApproval(
|
|||||||
amountToApprove: CurrencyAmount<Currency> | undefined,
|
amountToApprove: CurrencyAmount<Currency> | undefined,
|
||||||
spender: string | undefined,
|
spender: string | undefined,
|
||||||
useIsPendingApproval: (token?: Token, spender?: string) => boolean
|
useIsPendingApproval: (token?: Token, spender?: string) => boolean
|
||||||
): [ApprovalState, () => Promise<TransactionResponse | undefined>] {
|
): [
|
||||||
|
ApprovalState,
|
||||||
|
() => Promise<{ response: TransactionResponse; tokenAddress: string; spenderAddress: string } | undefined>
|
||||||
|
] {
|
||||||
const { chainId } = useActiveWeb3React()
|
const { chainId } = useActiveWeb3React()
|
||||||
const token = amountToApprove?.currency?.isToken ? amountToApprove.currency : undefined
|
const token = amountToApprove?.currency?.isToken ? amountToApprove.currency : undefined
|
||||||
|
|
||||||
@ -53,7 +56,7 @@ export function useApproval(
|
|||||||
|
|
||||||
const tokenContract = useTokenContract(token?.address)
|
const tokenContract = useTokenContract(token?.address)
|
||||||
|
|
||||||
const approve = useCallback(async (): Promise<TransactionResponse | undefined> => {
|
const approve = useCallback(async () => {
|
||||||
function logFailure(error: Error | string): undefined {
|
function logFailure(error: Error | string): undefined {
|
||||||
console.warn(`${token?.symbol || 'Token'} approval failed:`, error)
|
console.warn(`${token?.symbol || 'Token'} approval failed:`, error)
|
||||||
return
|
return
|
||||||
@ -85,6 +88,11 @@ export function useApproval(
|
|||||||
.approve(spender, useExact ? amountToApprove.quotient.toString() : MaxUint256, {
|
.approve(spender, useExact ? amountToApprove.quotient.toString() : MaxUint256, {
|
||||||
gasLimit: calculateGasMargin(estimatedGas),
|
gasLimit: calculateGasMargin(estimatedGas),
|
||||||
})
|
})
|
||||||
|
.then((response) => ({
|
||||||
|
response,
|
||||||
|
tokenAddress: token.address,
|
||||||
|
spenderAddress: spender,
|
||||||
|
}))
|
||||||
.catch((error: Error) => {
|
.catch((error: Error) => {
|
||||||
logFailure(error)
|
logFailure(error)
|
||||||
throw error
|
throw error
|
||||||
|
Loading…
Reference in New Issue
Block a user