Commit 9ddedd8d authored by Moody Salem's avatar Moody Salem

fix(pending approves): pending approves that are too old should not cause 'approving' to get stuck

parent 95030a52
import React, { useMemo } from 'react'
import { AbstractConnector } from '@web3-react/abstract-connector' import { AbstractConnector } from '@web3-react/abstract-connector'
import styled, { css } from 'styled-components' import { UnsupportedChainIdError, useWeb3React } from '@web3-react/core'
import { useTranslation } from 'react-i18next'
import { useWeb3React, UnsupportedChainIdError } from '@web3-react/core'
import { darken, lighten } from 'polished' import { darken, lighten } from 'polished'
import React, { useMemo } from 'react'
import { Activity } from 'react-feather' import { Activity } from 'react-feather'
import { useTranslation } from 'react-i18next'
import styled, { css } from 'styled-components'
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
import PortisIcon from '../../assets/images/portisIcon.png'
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
import { fortmatic, injected, portis, walletconnect, walletlink } from '../../connectors'
import { NetworkContextName } from '../../constants'
import useENSName from '../../hooks/useENSName' import useENSName from '../../hooks/useENSName'
import { useHasSocks } from '../../hooks/useSocksBalance' import { useHasSocks } from '../../hooks/useSocksBalance'
import { useWalletModalToggle } from '../../state/application/hooks' import { useWalletModalToggle } from '../../state/application/hooks'
import { isTransactionRecent, useAllTransactions } from '../../state/transactions/hooks'
import { TransactionDetails } from '../../state/transactions/reducer' import { TransactionDetails } from '../../state/transactions/reducer'
import { shortenAddress } from '../../utils'
import { ButtonSecondary } from '../Button'
import Identicon from '../Identicon' import Identicon from '../Identicon'
import PortisIcon from '../../assets/images/portisIcon.png' import Loader from '../Loader'
import WalletModal from '../WalletModal'
import { ButtonSecondary } from '../Button'
import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
import { RowBetween } from '../Row' import { RowBetween } from '../Row'
import { shortenAddress } from '../../utils' import WalletModal from '../WalletModal'
import { useAllTransactions } from '../../state/transactions/hooks'
import { NetworkContextName } from '../../constants'
import { injected, walletconnect, walletlink, fortmatic, portis } from '../../connectors'
import Loader from '../Loader'
const IconWrapper = styled.div<{ size?: number }>` const IconWrapper = styled.div<{ size?: number }>`
${({ theme }) => theme.flexColumnNoWrap}; ${({ theme }) => theme.flexColumnNoWrap};
...@@ -119,14 +119,10 @@ const NetworkIcon = styled(Activity)` ...@@ -119,14 +119,10 @@ const NetworkIcon = styled(Activity)`
` `
// we want the latest one to come first, so return negative if a is after b // we want the latest one to come first, so return negative if a is after b
function newTranscationsFirst(a: TransactionDetails, b: TransactionDetails) { function newTransactionsFirst(a: TransactionDetails, b: TransactionDetails) {
return b.addedTime - a.addedTime return b.addedTime - a.addedTime
} }
function recentTransactionsOnly(a: TransactionDetails) {
return new Date().getTime() - a.addedTime < 86_400_000
}
const SOCK = ( const SOCK = (
<span role="img" aria-label="has socks emoji" style={{ marginTop: -4, marginBottom: -4 }}> <span role="img" aria-label="has socks emoji" style={{ marginTop: -4, marginBottom: -4 }}>
🧦 🧦
...@@ -175,7 +171,7 @@ function Web3StatusInner() { ...@@ -175,7 +171,7 @@ function Web3StatusInner() {
const sortedRecentTransactions = useMemo(() => { const sortedRecentTransactions = useMemo(() => {
const txs = Object.values(allTransactions) const txs = Object.values(allTransactions)
return txs.filter(recentTransactionsOnly).sort(newTranscationsFirst) return txs.filter(isTransactionRecent).sort(newTransactionsFirst)
}, [allTransactions]) }, [allTransactions])
const pending = sortedRecentTransactions.filter(tx => !tx.receipt).map(tx => tx.hash) const pending = sortedRecentTransactions.filter(tx => !tx.receipt).map(tx => tx.hash)
...@@ -226,7 +222,7 @@ export default function Web3Status() { ...@@ -226,7 +222,7 @@ export default function Web3Status() {
const sortedRecentTransactions = useMemo(() => { const sortedRecentTransactions = useMemo(() => {
const txs = Object.values(allTransactions) const txs = Object.values(allTransactions)
return txs.filter(recentTransactionsOnly).sort(newTranscationsFirst) return txs.filter(isTransactionRecent).sort(newTransactionsFirst)
}, [allTransactions]) }, [allTransactions])
const pending = sortedRecentTransactions.filter(tx => !tx.receipt).map(tx => tx.hash) const pending = sortedRecentTransactions.filter(tx => !tx.receipt).map(tx => tx.hash)
......
...@@ -50,6 +50,14 @@ export function useIsTransactionPending(transactionHash?: string): boolean { ...@@ -50,6 +50,14 @@ export function useIsTransactionPending(transactionHash?: string): boolean {
return !transactions[transactionHash].receipt return !transactions[transactionHash].receipt
} }
/**
* Returns whether a transaction happened in the last day (86400 seconds * 1000 milliseconds / second)
* @param tx to check for recency
*/
export function isTransactionRecent(tx: TransactionDetails): boolean {
return new Date().getTime() - tx.addedTime < 86_400_000
}
// returns whether a token has a pending approval transaction // returns whether a token has a pending approval transaction
export function useHasPendingApproval(tokenAddress: string | undefined, spender: string | undefined): boolean { export function useHasPendingApproval(tokenAddress: string | undefined, spender: string | undefined): boolean {
const allTransactions = useAllTransactions() const allTransactions = useAllTransactions()
...@@ -58,13 +66,14 @@ export function useHasPendingApproval(tokenAddress: string | undefined, spender: ...@@ -58,13 +66,14 @@ export function useHasPendingApproval(tokenAddress: string | undefined, spender:
typeof tokenAddress === 'string' && typeof tokenAddress === 'string' &&
typeof spender === 'string' && typeof spender === 'string' &&
Object.keys(allTransactions).some(hash => { Object.keys(allTransactions).some(hash => {
if (allTransactions[hash]?.receipt) { const tx = allTransactions[hash]
if (!tx) return false
if (tx.receipt) {
return false return false
} else { } else {
return ( const approval = tx.approval
allTransactions[hash]?.approval?.tokenAddress === tokenAddress && if (!approval) return false
allTransactions[hash]?.approval?.spender === spender return approval.spender === spender && approval.tokenAddress === tokenAddress && isTransactionRecent(tx)
)
} }
}), }),
[allTransactions, spender, tokenAddress] [allTransactions, spender, tokenAddress]
......
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