Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: handle rejected tx & messages #2172

Merged
merged 9 commits into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions src/components/SwapForm/AddMEVProtectionModal.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ChainId } from '@kyberswap/ks-sdk-core'
import { Trans, t } from '@lingui/macro'
import { Connector } from '@web3-react/types'
import { darken } from 'polished'
import { useCallback, useState } from 'react'
import { X } from 'react-feather'
Expand All @@ -14,12 +13,12 @@ import { NotificationType } from 'components/Announcement/type'
import { ButtonEmpty, ButtonOutlined, ButtonPrimary } from 'components/Button'
import Modal from 'components/Modal'
import Row, { RowBetween } from 'components/Row'
import { didUserReject } from 'constants/connectors/utils'
import { Z_INDEXS } from 'constants/styles'
import useMixpanel, { MIXPANEL_TYPE } from 'hooks/useMixpanel'
import { useChangeNetwork } from 'hooks/web3/useChangeNetwork'
import { useNotify } from 'state/application/hooks'
import { ExternalLink, MEDIA_WIDTHS } from 'theme'
import { friendlyError } from 'utils/errorMessage'

const Wrapper = styled.div`
padding: 20px;
Expand Down Expand Up @@ -113,10 +112,9 @@ export default function AddMEVProtectionModal({ isOpen, onClose }: { isOpen: boo
onClose?.()
mixpanelHandler(MIXPANEL_TYPE.MEV_ADD_RESULT, { type: addingOption.name, result: 'success' })
},
(connector: Connector, error: Error) => {
let reason = error?.message || 'Unknown reason'
if (didUserReject(connector, error)) reason = 'User rejected'
mixpanelHandler(MIXPANEL_TYPE.MEV_ADD_RESULT, { type: addingOption.name, result: 'fail', reason })
(error: Error) => {
const message = friendlyError(error)
mixpanelHandler(MIXPANEL_TYPE.MEV_ADD_RESULT, { type: addingOption.name, result: 'fail', reason: message })
namgold marked this conversation as resolved.
Show resolved Hide resolved
},
)
}, [addNewNetwork, notify, onClose, selectedOption, mixpanelHandler])
Expand Down
8 changes: 4 additions & 4 deletions src/components/SwapForm/SwapModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Props = {
const SwapModal: React.FC<Props> = props => {
const { isOpen, tokenAddToMetaMask, onDismiss, swapCallback, buildResult, isBuildingRoute } = props
const { chainId, account } = useActiveWeb3React()

const dispatch = useDispatch()
// modal and loading
const [{ error, isAttemptingTx, txHash }, setSwapState] = useState<{
Expand All @@ -48,7 +49,7 @@ const SwapModal: React.FC<Props> = props => {

const amountOut = currencyOut && CurrencyAmount.fromRawAmount(currencyOut, buildResult?.data?.amountOut || '0')
// text to show while loading
const pendingText = `Swapping ${routeSummary?.parsedAmountIn?.toSignificant(6)} ${
const pendingText = t`Swapping ${routeSummary?.parsedAmountIn?.toSignificant(6)} ${
currencyIn?.symbol
} for ${amountOut?.toSignificant(6)} ${currencyOut?.symbol}`

Expand Down Expand Up @@ -107,9 +108,8 @@ const SwapModal: React.FC<Props> = props => {
const hash = await swapCallback()
handleTxSubmitted(hash)
} catch (e) {
if (e?.code !== 4001 && e?.code !== 'ACTION_REJECTED') captureSwapError(e)
const msg = t`Something went wrong. Please try again`
handleError(e.message === '[object Object]' ? msg : e.message || msg)
captureSwapError(e)
handleError(e.message)
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/components/TransactionConfirmationModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { VIEW_MODE } from 'state/user/reducer'
import { ExternalLink } from 'theme'
import { CloseIcon } from 'theme/components'
import { getEtherscanLink, getTokenLogoURL } from 'utils'
import { errorFriendly } from 'utils/dmm'
import { friendlyError } from 'utils/errorMessage'

const Wrapper = styled.div`
width: 100%;
Expand Down Expand Up @@ -280,9 +280,9 @@ export function TransactionErrorContent({
lineHeight={'24px'}
style={{ textAlign: 'center', width: '85%' }}
>
{errorFriendly(message)}
{friendlyError(message)}
</Text>
{message !== errorFriendly(message) && (
{message !== friendlyError(message) && (
<AutoColumn justify="center" style={{ width: '100%' }}>
<Text
color={theme.primary}
Expand Down
4 changes: 2 additions & 2 deletions src/components/WalletPopup/SendToken/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { useCurrencyBalance } from 'state/wallet/hooks'
import { useCheckAddressSolana } from 'state/wallet/solanaHooks'
import { TransactionFlowState } from 'types/TransactionFlowState'
import { formattedNum, shortenAddress } from 'utils'
import { errorFriendly } from 'utils/dmm'
import { friendlyError } from 'utils/errorMessage'
import { maxAmountSpend } from 'utils/maxAmountSpend'

const Label = styled.label<{ color?: string }>`
Expand Down Expand Up @@ -142,7 +142,7 @@ export default function SendToken({
setFlowState(state => ({
...state,
attemptingTxn: false,
errorMessage: errorFriendly(error?.message ?? 'Error occur, please try again'),
errorMessage: friendlyError(error),
}))
}
}
Expand Down
1 change: 1 addition & 0 deletions src/components/swapv2/LimitOrder/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export const calcPercentFilledOrder = (value: string, total: string, decimals: n
}
}

// todo: move to friendlyError
export const getErrorMessage = (error: any) => {
console.error('Limit order error: ', error)
const errorCode: string = error?.response?.data?.code || error.code || ''
Expand Down
6 changes: 3 additions & 3 deletions src/components/swapv2/styleds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AutoColumn } from 'components/Column'
import Modal, { ModalProps } from 'components/Modal'
import { Z_INDEXS } from 'constants/styles'
import useTheme from 'hooks/useTheme'
import { errorFriendly } from 'utils/dmm'
import { friendlyError } from 'utils/errorMessage'

export const PageWrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -136,9 +136,9 @@ export function SwapCallbackError({ error, style = {} }: { error: string; style?
<Alert style={{ marginBottom: 'auto' }} />
<AutoColumn style={{ flexBasis: '100%', margin: '10px 0 auto 8px' }}>
<Text fontSize="16px" fontWeight="500" color={theme.red} lineHeight={'24px'}>
{errorFriendly(error)}
{friendlyError(error)}
</Text>
{error !== errorFriendly(error) && (
{error !== friendlyError(error) && (
<Text
color={theme.primary}
fontSize="12px"
Expand Down
24 changes: 12 additions & 12 deletions src/constants/connectors/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { Connector } from '@web3-react/types'

import { coinbaseWallet, walletConnectV2 } from 'constants/connectors/evm'
import checkForBraveBrowser from 'utils/checkForBraveBrowser'

export const getIsInjected = () => Boolean(window.ethereum)
Expand Down Expand Up @@ -51,21 +48,24 @@ export enum ErrorCode {
MM_ALREADY_PENDING = -32002,

ACTION_REJECTED = 'ACTION_REJECTED',
WC_MODAL_CLOSED = 'Error: User closed modal',
CB_REJECTED_REQUEST = 'Error: User denied account authorization',
ALPHA_WALLET_USER_REJECTED_REQUEST = -32050,
WALLETCONNECT_MODAL_CLOSED = 'Error: User closed modal',
WALLETCONNECT_CANCELED = 'The transaction was cancelled',
COINBASE_REJECTED_REQUEST = 'Error: User denied account authorization',
ALPHA_WALLET_REJECTED_CODE = -32050,
ALPHA_WALLET_REJECTED = 'Request rejected',
CANCELED = 'The transaction was cancelled',
}

export function didUserReject(connector: Connector, error: any): boolean {
const rejectedPhrases: string[] = ['user rejected transaction', 'user denied transaction', 'you must accept']

export function didUserReject(error: any): boolean {
return (
error?.code === ErrorCode.USER_REJECTED_REQUEST ||
error?.code === ErrorCode.ACTION_REJECTED ||
error?.code === ErrorCode.ALPHA_WALLET_USER_REJECTED_REQUEST ||
error?.code === ErrorCode.ALPHA_WALLET_REJECTED_CODE ||
error?.message === ErrorCode.ALPHA_WALLET_REJECTED ||
(connector === walletConnectV2 && error?.toString?.() === ErrorCode.WC_MODAL_CLOSED) ||
(connector === walletConnectV2 && error?.message === ErrorCode.CANCELED) ||
(connector === coinbaseWallet && error?.toString?.() === ErrorCode.CB_REJECTED_REQUEST)
error?.message === ErrorCode.WALLETCONNECT_MODAL_CLOSED ||
error?.message === ErrorCode.WALLETCONNECT_CANCELED ||
error?.message === ErrorCode.WALLETCONNECT_MODAL_CLOSED ||
rejectedPhrases.some(phrase => error?.message?.toLowerCase?.()?.includes?.(phrase.toLowerCase()))
)
}
45 changes: 18 additions & 27 deletions src/hooks/kyberdao/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { useTransactionAdder } from 'state/transactions/hooks'
import { TRANSACTION_TYPE } from 'state/transactions/type'
import { calculateGasMargin } from 'utils'
import { aggregateValue } from 'utils/array'
import { formatWalletErrorMessage } from 'utils/errorMessage'
import { friendlyError } from 'utils/errorMessage'
import { formatUnitsToFixed } from 'utils/formatBalance'
import { sendEVMTransaction } from 'utils/sendTransaction'

Expand Down Expand Up @@ -89,7 +89,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -120,7 +120,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -155,7 +155,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand All @@ -181,7 +181,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand All @@ -208,7 +208,7 @@ export function useKyberDaoStakeActions() {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -272,7 +272,7 @@ export function useClaimVotingRewards() {
})
return tx.hash as string
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -312,7 +312,7 @@ export const useVotingActions = () => {
})
return tx.hash
} catch (error) {
if (error?.code === 4001 || error?.code === 'ACTION_REJECTED') {
if (didUserReject(error)) {
throw new Error('Transaction rejected.')
} else {
throw error
Expand Down Expand Up @@ -620,7 +620,7 @@ export function useGasRefundInfo({ rewardStatus = KNCUtilityTabs.Available }: {

export function useClaimGasRefundRewards() {
const { account, chainId } = useActiveWeb3React()
const { library, connector } = useWeb3React()
const { library } = useWeb3React()
const addTransactionWithType = useTransactionAdder()
const { claimableReward } = useGasRefundInfo({})
const refetch = useRefetchGasRefundInfo()
Expand Down Expand Up @@ -669,25 +669,16 @@ export function useClaimGasRefundRewards() {
return tx.hash as string
} catch (error) {
refetch()
if (didUserReject(connector, error)) {
notify({
title: t`Transaction rejected`,
summary: t`In order to claim, you must accept in your wallet.`,
type: NotificationType.ERROR,
})
throw new Error('Transaction rejected.')
} else {
const message = formatWalletErrorMessage(error)
console.error('Claim error:', { error, message })
notify({
title: t`Claim Error`,
summary: message,
type: NotificationType.ERROR,
})
throw error
}
const message = friendlyError(error)
console.error('Claim error:', { message, error })
notify({
title: t`Claim Error`,
summary: message,
type: NotificationType.ERROR,
})
throw error
}
}, [account, addTransactionWithType, chainId, claimableReward, library, notify, connector, refetch])
}, [account, addTransactionWithType, chainId, claimableReward, library, notify, refetch])
return claimGasRefundRewards
}

Expand Down
18 changes: 16 additions & 2 deletions src/hooks/useApproveCallback.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import { MaxUint256 } from '@ethersproject/constants'
import { TransactionResponse } from '@ethersproject/providers'
import { Currency, CurrencyAmount, TokenAmount } from '@kyberswap/ks-sdk-core'
import { t } from '@lingui/macro'
import JSBI from 'jsbi'
import { useCallback, useMemo } from 'react'

import { NotificationType } from 'components/Announcement/type'
import { useTokenAllowance } from 'data/Allowances'
import { useNotify } from 'state/application/hooks'
import { Field } from 'state/swap/actions'
import { useHasPendingApproval, useTransactionAdder } from 'state/transactions/hooks'
import { TRANSACTION_TYPE } from 'state/transactions/type'
import { calculateGasMargin } from 'utils'
import { Aggregator } from 'utils/aggregator'
import { friendlyError } from 'utils/errorMessage'
import { computeSlippageAdjustedAmounts } from 'utils/prices'

import { useActiveWeb3React } from './index'
Expand Down Expand Up @@ -55,6 +59,7 @@ export function useApproveCallback(
: ApprovalState.NOT_APPROVED
: ApprovalState.APPROVED
}, [amountToApprove, currentAllowance, isSolana, pendingApproval, spender])
const notify = useNotify()

const tokenContract = useTokenContract(token?.address)
const addTransactionWithType = useTransactionAdder()
Expand Down Expand Up @@ -123,11 +128,20 @@ export function useApproveCallback(
})
})
.catch((error: Error) => {
console.debug('Failed to approve token', error)
const message = friendlyError(error)
console.error('Approve token error:', { message, error })
notify(
{
title: t`Approve Error`,
summary: message,
type: NotificationType.ERROR,
},
8000,
)
throw error
})
},
[approvalState, token, tokenContract, amountToApprove, spender, addTransactionWithType, forceApprove],
[approvalState, token, tokenContract, amountToApprove, spender, addTransactionWithType, forceApprove, notify],
)

return [approvalState, approve, currentAllowance]
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/useElasticLegacy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import JSBI from 'jsbi'
import { useEffect, useRef, useState } from 'react'

import TickReaderABI from 'constants/abis/v2/ProAmmTickReader.json'
import { didUserReject } from 'constants/connectors/utils'
import { EVMNetworkInfo } from 'constants/networks/type'
import { useActiveWeb3React, useWeb3React } from 'hooks'
import { useTransactionAdder } from 'state/transactions/hooks'
Expand Down Expand Up @@ -464,7 +465,7 @@ export const useRemoveLiquidityLegacy = (
setShowPendingModal('removeLiquidity')
setAttemptingTxn(false)

if (error?.code !== 'ACTION_REJECTED') {
if (!didUserReject(error)) {
const e = new Error('Remove Legacy Elastic Liquidity Error', { cause: error })
e.name = ErrorName.RemoveElasticLiquidityError
captureException(e, {
Expand Down
Loading
Loading