Commit 01aa3291 authored by Jack Short's avatar Jack Short Committed by GitHub

chore: bubbling up pwat spender from route query (#6481)

* chore: bubbling up pwat spender from route query

* refactoring

* adding loading state

* moving to loading allowance

* responding to comments

* linting
parent 5539ebed
import gql from 'graphql-tag'
import { useNftUniversalRouterAddressQuery } from '../__generated__/types-and-hooks'
gql`
query NftUniversalRouterAddress($chain: Chain = ETHEREUM) {
nftRoute(chain: $chain, senderAddress: "", nftTrades: []) {
toAddress
}
}
`
export function useNftUniversalRouterAddress() {
const { data, loading } = useNftUniversalRouterAddressQuery({
// no cache because a different version of nftRoute query is going to be called around the same time
fetchPolicy: 'no-cache',
})
return {
universalRouterAddress: data?.nftRoute?.toAddress,
universalRouterAddressIsLoading: loading,
}
}
......@@ -14,6 +14,7 @@ import CurrencySearchModal from 'components/SearchModal/CurrencySearchModal'
import { LoadingBubble } from 'components/Tokens/loading'
import { MouseoverTooltip } from 'components/Tooltip'
import { SupportedChainId } from 'constants/chains'
import { useNftUniversalRouterAddress } from 'graphql/data/nft/NftUniversalRouterAddress'
import { useCurrency } from 'hooks/Tokens'
import { AllowanceState } from 'hooks/usePermit2Allowance'
import { useStablecoinValue } from 'hooks/useStablecoinPrice'
......@@ -316,6 +317,7 @@ export const BagFooter = ({ setModalIsOpen, eventProperties }: BagFooterProps) =
const isPending = PENDING_BAG_STATUSES.includes(bagStatus)
const activeCurrency = inputCurrency ?? defaultCurrency
const usingPayWithAnyToken = !!inputCurrency && chainId === SupportedChainId.MAINNET
const { universalRouterAddress, universalRouterAddressIsLoading } = useNftUniversalRouterAddress()
useSubscribeTransactionState(setModalIsOpen)
const fetchAssets = useFetchAssets()
......@@ -332,8 +334,9 @@ export const BagFooter = ({ setModalIsOpen, eventProperties }: BagFooterProps) =
const { allowance, isAllowancePending, isApprovalLoading, updateAllowance } = usePermit2Approval(
trade?.inputAmount.currency.isToken ? (trade?.inputAmount as CurrencyAmount<Token>) : undefined,
maximumAmountIn,
true
universalRouterAddress
)
const loadingAllowance = allowance.state === AllowanceState.LOADING || universalRouterAddressIsLoading
usePayWithAnyTokenSwap(trade, allowance, allowedSlippage)
const priceImpact = usePriceImpact(trade)
......@@ -423,11 +426,11 @@ export const BagFooter = ({ setModalIsOpen, eventProperties }: BagFooterProps) =
buttonTextColor = theme.textPrimary
helperText = <Trans>Insufficient pool liquidity to complete transaction</Trans>
}
} else if (allowance.state === AllowanceState.REQUIRED || allowance.state === AllowanceState.LOADING) {
} else if (allowance.state === AllowanceState.REQUIRED || loadingAllowance) {
handleClick = () => updateAllowance()
disabled = isAllowancePending || isApprovalLoading || allowance.state === AllowanceState.LOADING
disabled = isAllowancePending || isApprovalLoading || loadingAllowance
if (allowance.state === AllowanceState.LOADING) {
if (loadingAllowance) {
buttonText = <Trans>Loading Allowance</Trans>
} else if (isAllowancePending) {
buttonText = <Trans>Approve in your wallet</Trans>
......@@ -480,6 +483,7 @@ export const BagFooter = ({ setModalIsOpen, eventProperties }: BagFooterProps) =
usingPayWithAnyToken,
tradeState,
allowance.state,
loadingAllowance,
priceImpact,
connector,
toggleWalletDrawer,
......
import { CurrencyAmount } from '@uniswap/sdk-core'
import { USDC_MAINNET } from '@uniswap/smart-order-router'
import { UNIVERSAL_ROUTER_ADDRESS } from '@uniswap/universal-router-sdk'
import usePermit2Allowance, { AllowanceState } from 'hooks/usePermit2Allowance'
import { renderHook } from 'test-utils/render'
import usePermit2Approval from './usePermit2Approval'
const USDCAmount = CurrencyAmount.fromRawAmount(USDC_MAINNET, '10000')
const NFT_UNIVERSAL_ROUTER_MAINNET_ADDRESS = '0x4c60051384bd2d3c01bfc845cf5f4b44bcbe9de5'
jest.mock('hooks/usePermit2Allowance')
......@@ -15,7 +15,7 @@ const mockUsePermit2Allowance = usePermit2Allowance as jest.MockedFunction<typeo
describe('usePermit2Approval', () => {
it('sets spender of the correct UR contract from NFT side', async () => {
mockUsePermit2Allowance.mockReturnValue({ state: AllowanceState.LOADING })
renderHook(() => usePermit2Approval(USDCAmount, undefined, true))
expect(mockUsePermit2Allowance).toHaveBeenCalledWith(USDCAmount, NFT_UNIVERSAL_ROUTER_MAINNET_ADDRESS)
renderHook(() => usePermit2Approval(USDCAmount, undefined, UNIVERSAL_ROUTER_ADDRESS(1)))
expect(mockUsePermit2Allowance).toHaveBeenCalledWith(USDCAmount, UNIVERSAL_ROUTER_ADDRESS(1))
})
})
import { sendAnalyticsEvent } from '@uniswap/analytics'
import { InterfaceEventName } from '@uniswap/analytics-events'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { CurrencyAmount, SupportedChainId, Token } from '@uniswap/sdk-core'
import { UNIVERSAL_ROUTER_ADDRESS } from '@uniswap/universal-router-sdk'
import { useWeb3React } from '@web3-react/core'
import usePermit2Allowance, { AllowanceState } from 'hooks/usePermit2Allowance'
import { useCallback, useMemo, useState } from 'react'
import invariant from 'tiny-invariant'
// TODO: This should be removed when the sdk is updated to include the new UR address
const NFT_UNIVERSAL_ROUTER_MAINNET_ADDRESS = '0x4c60051384bd2d3c01bfc845cf5f4b44bcbe9de5'
function getURAddress(chainId?: number, nftURAddress?: string) {
if (!chainId) return
// if mainnet and on NFT flow, use the contract address returned by GQL
if (chainId === SupportedChainId.MAINNET) {
return nftURAddress ?? UNIVERSAL_ROUTER_ADDRESS(chainId)
}
return UNIVERSAL_ROUTER_ADDRESS(chainId)
}
export default function usePermit2Approval(
amount?: CurrencyAmount<Token>,
maximumAmount?: CurrencyAmount<Token>,
shouldUseNftRouter?: boolean
amount: CurrencyAmount<Token> | undefined,
maximumAmount: CurrencyAmount<Token> | undefined,
nftUniversalRouterContractAddress?: string
) {
const { chainId } = useWeb3React()
let contractToApprove: string | undefined
if (chainId) {
const forceNftRouter = shouldUseNftRouter && chainId === 1
contractToApprove = forceNftRouter ? NFT_UNIVERSAL_ROUTER_MAINNET_ADDRESS : UNIVERSAL_ROUTER_ADDRESS(chainId)
}
const allowance = usePermit2Allowance(
maximumAmount ?? (amount?.currency.isToken ? (amount as CurrencyAmount<Token>) : undefined),
contractToApprove
)
const universalRouterAddress = getURAddress(chainId, nftUniversalRouterContractAddress)
const allowanceAmount = maximumAmount ?? (amount?.currency.isToken ? (amount as CurrencyAmount<Token>) : undefined)
const allowance = usePermit2Allowance(allowanceAmount, universalRouterAddress)
const isApprovalLoading = allowance.state === AllowanceState.REQUIRED && allowance.isApprovalLoading
const [isAllowancePending, setIsAllowancePending] = useState(false)
const updateAllowance = useCallback(async () => {
......
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