-
Notifications
You must be signed in to change notification settings - Fork 5.5k
fix: prevent flickering of insufficient balance alert until gas station checks complete #38306
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
Changes from 6 commits
9cacf14
6803f1d
b06d058
88dd0a6
c880adc
cd63bd9
0fde7ad
174348d
ba4bac1
2c63ed4
244bac1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,17 @@ | ||
| import { TransactionMeta } from '@metamask/transaction-controller'; | ||
| import { CaipChainId, Hex } from '@metamask/utils'; | ||
| import { useMemo } from 'react'; | ||
| import { useSelector } from 'react-redux'; | ||
|
|
||
| import { sumHexes } from '../../../../../../shared/modules/conversion.utils'; | ||
| import { | ||
| AlertActionKey, | ||
| RowAlertKey, | ||
| } from '../../../../../components/app/confirm/info/row/constants'; | ||
| import { Alert } from '../../../../../ducks/confirm-alerts/confirm-alerts'; | ||
| import { Severity } from '../../../../../helpers/constants/design-system'; | ||
| import { useI18nContext } from '../../../../../hooks/useI18nContext'; | ||
| import { | ||
| getMultichainNetworkConfigurationsByChainId, | ||
| getNativeTokenCachedBalanceByChainIdByAccountAddress, | ||
| getUseTransactionSimulations, | ||
| selectTransactionFeeById, | ||
| } from '../../../../../selectors'; | ||
| import { getUseTransactionSimulations } from '../../../../../selectors'; | ||
| import { useConfirmContext } from '../../../context/confirm'; | ||
| import { isBalanceSufficient } from '../../../send-legacy/send.utils'; | ||
| import { useIsGaslessSupported } from '../../gas/useIsGaslessSupported'; | ||
| import { useHasInsufficientBalance } from '../../useHasInsufficientBalance'; | ||
|
|
||
| export function useInsufficientBalanceAlerts({ | ||
| ignoreGasFeeToken, | ||
|
|
@@ -28,62 +20,41 @@ export function useInsufficientBalanceAlerts({ | |
| } = {}): Alert[] { | ||
| const t = useI18nContext(); | ||
| const { currentConfirmation } = useConfirmContext<TransactionMeta>(); | ||
| const { | ||
| id: transactionId, | ||
| chainId, | ||
| selectedGasFeeToken, | ||
| gasFeeTokens, | ||
| txParams: { value = '0x0', from: fromAddress = '' } = {}, | ||
| } = currentConfirmation ?? {}; | ||
|
|
||
| const batchTransactionValues = | ||
| currentConfirmation?.nestedTransactions?.map( | ||
| (trxn) => (trxn.value as Hex) ?? 0x0, | ||
| ) ?? []; | ||
|
|
||
| const { selectedGasFeeToken, gasFeeTokens } = currentConfirmation ?? {}; | ||
| const { hasInsufficientBalance, nativeCurrency } = | ||
| useHasInsufficientBalance(); | ||
| const isSimulationEnabled = useSelector(getUseTransactionSimulations); | ||
| const isSponsored = currentConfirmation?.isGasFeeSponsored; | ||
| const { | ||
| isSupported: isGaslessSupported, | ||
| pending: isGaslessSupportedPending, | ||
| } = useIsGaslessSupported(); | ||
|
|
||
| const chainBalances = useSelector((state) => | ||
| getNativeTokenCachedBalanceByChainIdByAccountAddress( | ||
| state, | ||
| fromAddress ?? '', | ||
| ), | ||
| ) as Record<Hex, Hex>; | ||
|
|
||
| const balance = chainBalances?.[chainId as Hex] ?? '0x0'; | ||
|
|
||
| const totalValue = sumHexes(value, ...batchTransactionValues); | ||
|
|
||
| const { hexMaximumTransactionFee } = useSelector((state) => | ||
| selectTransactionFeeById(state, transactionId), | ||
| ); | ||
| const isGasFeeTokensEmpty = gasFeeTokens?.length === 0; | ||
|
|
||
| const [multichainNetworks, evmNetworks] = useSelector( | ||
| getMultichainNetworkConfigurationsByChainId, | ||
| ); | ||
| // Check if gasless check has completed (regardless of result) | ||
| const isGaslessCheckComplete = !isGaslessSupportedPending; | ||
|
|
||
| const nativeCurrency = ( | ||
| multichainNetworks[chainId as CaipChainId] ?? evmNetworks[chainId] | ||
| )?.nativeCurrency; | ||
| // Transaction is sponsored only if it's marked as sponsored AND gasless is supported | ||
| const isSponsoredTransaction = isSponsored && isGaslessSupported; | ||
|
|
||
| const insufficientBalance = !isBalanceSufficient({ | ||
| amount: totalValue, | ||
| gasTotal: hexMaximumTransactionFee, | ||
| balance, | ||
| }); | ||
| // Simulation is complete if it's disabled, or if enabled and gasFeeTokens is loaded | ||
| const isSimulationComplete = !isSimulationEnabled || Boolean(gasFeeTokens); | ||
|
|
||
| const isSponsored = currentConfirmation?.isGasFeeSponsored; | ||
| const { isSupported: isGaslessSupported } = useIsGaslessSupported(); | ||
| const isSponsoredTransaction = isSponsored && isGaslessSupported; | ||
| // Check if user has selected a gas fee token (or we're ignoring that check) | ||
| const hasNoGasFeeTokenSelected = ignoreGasFeeToken || !selectedGasFeeToken; | ||
|
|
||
| const canSkipSimulationChecks = ignoreGasFeeToken || !isSimulationEnabled; | ||
| const hasGaslessSimulationFinished = | ||
| canSkipSimulationChecks || Boolean(gasFeeTokens); | ||
| // Show alert when gasless check is done and either: | ||
| // - Gasless is NOT supported (user needs native currency for gas) | ||
| // - Gasless IS supported but gasFeeTokens is empty (no alternative tokens available) | ||
| const shouldCheckGaslessConditions = | ||
| isGaslessCheckComplete && (!isGaslessSupported || isGasFeeTokensEmpty); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bug: Alert suppressed when simulation disabled but gasless supportedWhen simulation is disabled and gasless IS supported, the insufficient balance alert will never show. The old code had Additional Locations (1) |
||
|
|
||
| const showAlert = | ||
| insufficientBalance && | ||
| hasGaslessSimulationFinished && | ||
| (ignoreGasFeeToken || !selectedGasFeeToken) && | ||
| hasInsufficientBalance && | ||
| isSimulationComplete && | ||
| hasNoGasFeeTokenSelected && | ||
| shouldCheckGaslessConditions && | ||
| !isSponsoredTransaction; | ||
|
|
||
| return useMemo(() => { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.