import React, { useContext, useState } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { I18nContext } from '../../../contexts/i18n'; import { useGasFeeContext } from '../../../contexts/gasFee'; import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; import { isLegacyTransaction } from '../../../helpers/utils/transactions.util'; import { hexWEIToDecGWEI } from '../../../../shared/lib/transactions-controller-utils'; import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'; import GasTiming from '../../../components/app/gas-timing'; import InfoTooltip from '../../../components/ui/info-tooltip'; import Typography from '../../../components/ui/typography'; import Button from '../../../components/ui/button'; import Box from '../../../components/ui/box'; import { TYPOGRAPHY, DISPLAY, FLEX_DIRECTION, BLOCK_SIZES, COLORS, FONT_STYLE, FONT_WEIGHT, } from '../../../helpers/constants/design-system'; import { ERC1155, ERC20, ERC721, } from '../../../../shared/constants/transaction'; import LoadingHeartBeat from '../../../components/ui/loading-heartbeat'; import TransactionDetailItem from '../../../components/app/transaction-detail-item'; import { NETWORK_TO_NAME_MAP } from '../../../../shared/constants/network'; import TransactionDetail from '../../../components/app/transaction-detail'; import ActionableMessage from '../../../components/ui/actionable-message'; import DepositPopover from '../../../components/app/deposit-popover'; import { getProvider, getPreferences, getIsBuyableChain, transactionFeeSelector, getIsMainnet, getEIP1559V2Enabled, checkNetworkAndAccountSupports1559, } from '../../../selectors'; import { hexWEIToDecETH, addHexes, } from '../../../helpers/utils/conversions.util'; import { INSUFFICIENT_TOKENS_ERROR } from '../send.constants'; import { getCurrentDraftTransaction } from '../../../ducks/send'; import { showModal } from '../../../store/actions'; export default function GasDisplay({ gasError }) { const t = useContext(I18nContext); const dispatch = useDispatch(); const { estimateUsed } = useGasFeeContext(); const [showDepositPopover, setShowDepositPopover] = useState(false); const currentProvider = useSelector(getProvider); const isMainnet = useSelector(getIsMainnet); const isBuyableChain = useSelector(getIsBuyableChain); const draftTransaction = useSelector(getCurrentDraftTransaction); const eip1559V2Enabled = useSelector(getEIP1559V2Enabled); const networkAndAccountSupports1559 = useSelector( checkNetworkAndAccountSupports1559, ); const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences); const { nativeCurrency, provider, unapprovedTxs } = useSelector( (state) => state.metamask, ); const { confirmTransaction } = useSelector((state) => state); const { txData } = confirmTransaction; const { txParams = {} } = txData; const supportsEIP1559 = networkAndAccountSupports1559 && !isLegacyTransaction(txParams); const { chainId } = provider; const networkName = NETWORK_TO_NAME_MAP[chainId]; const isInsufficientTokenError = draftTransaction?.amount.error === INSUFFICIENT_TOKENS_ERROR; const editingTransaction = unapprovedTxs[draftTransaction.id]; const supportsEIP1559V2 = eip1559V2Enabled && supportsEIP1559; const transactionData = { txParams: { gasPrice: draftTransaction.gas?.gasPrice, gas: editingTransaction?.userEditedGasLimit ? editingTransaction?.txParams?.gas : draftTransaction.gas?.gasLimit, maxFeePerGas: editingTransaction?.txParams?.maxFeePerGas ? editingTransaction?.txParams?.maxFeePerGas : draftTransaction.gas?.maxFeePerGas, maxPriorityFeePerGas: editingTransaction?.txParams?.maxPriorityFeePerGas ? editingTransaction?.txParams?.maxPriorityFeePerGas : draftTransaction.gas?.maxPriorityFeePerGas, value: draftTransaction.amount?.value, type: draftTransaction.transactionType, }, userFeeLevel: editingTransaction?.userFeeLevel, }; const { hexMinimumTransactionFee, hexMaximumTransactionFee, hexTransactionTotal, } = useSelector((state) => transactionFeeSelector(state, transactionData)); let title; if ( draftTransaction?.asset.details?.standard === ERC721 || draftTransaction?.asset.details?.standard === ERC1155 ) { title = draftTransaction?.asset.details?.name; } else if (draftTransaction?.asset.details?.standard === ERC20) { title = `${hexWEIToDecETH(draftTransaction.amount.value)} ${ draftTransaction?.asset.details?.symbol }`; } const ethTransactionTotalMaxAmount = Number( hexWEIToDecETH(hexMaximumTransactionFee), ); const primaryTotalTextOverrideMaxAmount = `${title} + ${ethTransactionTotalMaxAmount} ${nativeCurrency}`; let detailTotal, maxAmount; if (draftTransaction?.asset.type === 'NATIVE') { detailTotal = ( ); maxAmount = ( ); } else if (useNativeCurrencyAsPrimaryCurrency) { detailTotal = primaryTotalTextOverrideMaxAmount; maxAmount = primaryTotalTextOverrideMaxAmount; } return ( <> {showDepositPopover && ( setShowDepositPopover(false)} /> )} {t('gas')} ({t('transactionDetailGasInfoV2')}) {t('transactionDetailGasTooltipIntro', [ isMainnet ? t('networkNameEthereum') : '', ])} {t('transactionDetailGasTooltipExplanation')} {t('transactionDetailGasTooltipConversion')} > } position="right" /> } detailTitleColor={COLORS.TEXT_DEFAULT} detailText={ } detailTotal={ } subText={ <> {estimateUsed === 'high' && '⚠ '} {t('editGasSubTextFeeLabel')} > } subTitle={ } /> ) : ( {t('transactionDetailGasHeading')} {t('transactionDetailGasTooltipIntro', [ isMainnet ? t('networkNameEthereum') : '', ])} {t('transactionDetailGasTooltipExplanation')} {t('transactionDetailGasTooltipConversion')} > } position="right" > > } detailText={ } detailTotal={ } subText={ <> {t('editGasSubTextFeeLabel')} > } subTitle={ <> > } /> ), (gasError || isInsufficientTokenError) && ( } detailTotal={detailTotal} subTitle={t('transactionDetailGasTotalSubtitle')} subText={ {t('editGasSubTextAmountLabel')} {' '} {maxAmount} } /> ), ]} /> {(gasError || isInsufficientTokenError) && ( {t('insufficientCurrencyBuyOrReceive', [ nativeCurrency, networkName ?? currentProvider.nickname, { setShowDepositPopover(true); }} key={`${nativeCurrency}-buy-button`} > {t('buyAsset', [nativeCurrency])} , dispatch(showModal({ name: 'ACCOUNT_DETAILS' })) } key="receive-button" > {t('deposit')} , ])} ) : ( {t('insufficientCurrencyBuyOrReceive', [ draftTransaction.asset.details?.symbol ?? nativeCurrency, networkName ?? currentProvider.nickname, `${t('buyAsset', [ draftTransaction.asset.details?.symbol ?? nativeCurrency, ])}`, dispatch(showModal({ name: 'ACCOUNT_DETAILS' })) } key="receive-button" > {t('deposit')} , ])} ) } useIcon iconFillColor="var(--color-error-default)" type="danger" /> )} > ); } GasDisplay.propTypes = { gasError: PropTypes.string, };
{t('transactionDetailGasTooltipIntro', [ isMainnet ? t('networkNameEthereum') : '', ])}
{t('transactionDetailGasTooltipExplanation')}
{t('transactionDetailGasTooltipConversion')}