import React, { useContext } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { I18nContext } from '../../../contexts/i18n'; import { useGasFeeContext } from '../../../contexts/gasFee'; import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'; import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'; import Typography from '../../../components/ui/typography'; import Button from '../../../components/ui/button'; import Box from '../../../components/ui/box'; import { TypographyVariant, DISPLAY, FLEX_DIRECTION, BLOCK_SIZES, } from '../../../helpers/constants/design-system'; import { TokenStandard } from '../../../../shared/constants/transaction'; import LoadingHeartBeat from '../../../components/ui/loading-heartbeat'; import TransactionDetailItem from '../../../components/app/transaction-detail-item'; import { ConfirmGasDisplay } from '../../../components/app/confirm-gas-display'; import { NETWORK_TO_NAME_MAP } from '../../../../shared/constants/network'; import TransactionDetail from '../../../components/app/transaction-detail'; import ActionableMessage from '../../../components/ui/actionable-message'; import { getPreferences, getIsBuyableChain, transactionFeeSelector, getIsTestnet, getUseCurrencyRateCheck, getUnapprovedTransactions, } from '../../../selectors'; import { INSUFFICIENT_TOKENS_ERROR } from '../send.constants'; import { getCurrentDraftTransaction } from '../../../ducks/send'; import { getNativeCurrency, getProviderConfig, } from '../../../ducks/metamask/metamask'; import { showModal } from '../../../store/actions'; import { addHexes, hexWEIToDecETH, } from '../../../../shared/modules/conversion.utils'; import { MetaMetricsEventCategory, MetaMetricsEventName, } from '../../../../shared/constants/metametrics'; import { MetaMetricsContext } from '../../../contexts/metametrics'; import useRamps from '../../../hooks/experiences/useRamps'; export default function GasDisplay({ gasError }) { const t = useContext(I18nContext); const dispatch = useDispatch(); const { estimateUsed } = useGasFeeContext(); const trackEvent = useContext(MetaMetricsContext); const { openBuyCryptoInPdapp } = useRamps(); const providerConfig = useSelector(getProviderConfig); const isTestnet = useSelector(getIsTestnet); const isBuyableChain = useSelector(getIsBuyableChain); const draftTransaction = useSelector(getCurrentDraftTransaction); const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck); const { showFiatInTestnets, useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences); const unapprovedTxs = useSelector(getUnapprovedTransactions); const nativeCurrency = useSelector(getNativeCurrency); const { chainId } = providerConfig; const networkName = NETWORK_TO_NAME_MAP[chainId]; const isInsufficientTokenError = draftTransaction?.amount?.error === INSUFFICIENT_TOKENS_ERROR; const editingTransaction = unapprovedTxs[draftTransaction.id]; const currentNetworkName = networkName || providerConfig.nickname; 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 { hexMaximumTransactionFee, hexTransactionTotal } = useSelector( (state) => transactionFeeSelector(state, transactionData), ); let title; if ( draftTransaction?.asset.details?.standard === TokenStandard.ERC721 || draftTransaction?.asset.details?.standard === TokenStandard.ERC1155 ) { title = draftTransaction?.asset.details?.name; } else if ( draftTransaction?.asset.details?.standard === TokenStandard.ERC20 ) { title = `${hexWEIToDecETH(draftTransaction.amount.value)} ${ draftTransaction?.asset.details?.symbol }`; } const ethTransactionTotalMaxAmount = Number( hexWEIToDecETH(hexMaximumTransactionFee), ); const primaryTotalTextOverrideMaxAmount = `${title} + ${ethTransactionTotalMaxAmount} ${nativeCurrency}`; const showCurrencyRateCheck = useCurrencyRateCheck && (!isTestnet || showFiatInTestnets); let detailTotal, maxAmount; if (draftTransaction?.asset.type === 'NATIVE') { detailTotal = ( ); maxAmount = ( ); } else if (useNativeCurrencyAsPrimaryCurrency) { detailTotal = primaryTotalTextOverrideMaxAmount; maxAmount = primaryTotalTextOverrideMaxAmount; } return ( <> , (gasError || isInsufficientTokenError) && ( ) } detailTotal={detailTotal} subTitle={t('transactionDetailGasTotalSubtitle')} subText={ {t('editGasSubTextAmountLabel')} {' '} {maxAmount} } /> ), ]} /> {(gasError || isInsufficientTokenError) && currentNetworkName && ( {t('insufficientCurrencyBuyOrReceive', [ nativeCurrency, currentNetworkName, , , ])} ) : ( {t('insufficientCurrencyBuyOrReceive', [ nativeCurrency, currentNetworkName, `${t('buyAsset', [nativeCurrency])}`, , ])} ) } useIcon iconFillColor="var(--color-error-default)" type="danger" /> )} ); } GasDisplay.propTypes = { gasError: PropTypes.string, };