1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Adds insufficient gas error to edit-gas-display (#11524)

This commit is contained in:
Dan J Miller 2021-07-30 20:16:31 -02:30 committed by GitHub
parent a1f8a65519
commit f1140087b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 122 additions and 4 deletions

View File

@ -19,6 +19,7 @@ import {
import { areDappSuggestedAndTxParamGasFeesTheSame } from '../../../helpers/utils/confirm-tx.util';
import InfoTooltip from '../../ui/info-tooltip';
import ErrorMessage from '../../ui/error-message';
import TransactionTotalBanner from '../transaction-total-banner/transaction-total-banner.component';
import RadioGroup from '../../ui/radio-group/radio-group.component';
import AdvancedGasControls from '../advanced-gas-controls/advanced-gas-controls.component';
@ -59,6 +60,7 @@ export default function EditGasDisplay({
gasErrors,
onManualChange,
minimumGasLimit,
balanceError,
}) {
const t = useContext(I18nContext);
@ -73,6 +75,12 @@ export default function EditGasDisplay({
);
const networkSupports1559 = useSelector(isEIP1559Network);
const showTopError = balanceError;
let errorKey;
if (balanceError) {
errorKey = 'insufficientFunds';
}
return (
<div className="edit-gas-display">
@ -85,6 +93,11 @@ export default function EditGasDisplay({
/>
</div>
)}
{showTopError && (
<div className="edit-gas-display__warning">
<ErrorMessage errorKey={errorKey} />
</div>
)}
{requireDappAcknowledgement && (
<div className="edit-gas-display__dapp-acknowledgement-warning">
<ActionableMessage
@ -255,4 +268,5 @@ EditGasDisplay.propTypes = {
gasErrors: PropTypes.object,
onManualChange: PropTypes.func,
minimumGasLimit: PropTypes.number,
balanceError: PropTypes.bool,
};

View File

@ -61,4 +61,8 @@
color: $primary-1;
}
}
&__warning {
margin-bottom: 24px;
}
}

View File

@ -1,6 +1,5 @@
import React, { useCallback, useContext, useState } from 'react';
import PropTypes from 'prop-types';
import { useDispatch, useSelector } from 'react-redux';
import { useGasFeeInputs } from '../../../hooks/useGasFeeInputs';
import { useShouldAnimateGasEstimations } from '../../../hooks/useShouldAnimateGasEstimations';
@ -83,6 +82,7 @@ export default function EditGasPopover({
hasGasErrors,
gasErrors,
onManualChange,
balanceError,
} = useGasFeeInputs(defaultEstimateToUse, transaction, minimumGasLimit, mode);
const [showAdvancedForm, setShowAdvancedForm] = useState(
@ -182,6 +182,7 @@ export default function EditGasPopover({
<Popover
title={title}
onClose={closePopover}
className="edit-gas-popover__wrapper"
onBack={
showEducationContent ? () => setShowEducationContent(false) : undefined
}
@ -191,7 +192,7 @@ export default function EditGasPopover({
<Button
type="primary"
onClick={onSubmit}
disabled={hasGasErrors || isGasEstimatesLoading}
disabled={hasGasErrors || isGasEstimatesLoading || balanceError}
>
{footerButtonText}
</Button>
@ -238,6 +239,7 @@ export default function EditGasPopover({
gasErrors={gasErrors}
onManualChange={onManualChange}
minimumGasLimit={minimumGasLimitDec}
balanceError={balanceError}
{...editGasDisplayProps}
/>
</>

View File

@ -0,0 +1,7 @@
.edit-gas-popover {
&__wrapper {
@media screen and (min-width: 576px) {
max-height: 84vh;
}
}
}

View File

@ -11,6 +11,7 @@ import {
import {
multiplyCurrencies,
conversionLessThan,
conversionGreaterThan,
} from '../../shared/modules/conversion.utils';
import {
getMaximumGasTotalInHexWei,
@ -22,9 +23,14 @@ import {
decGWEIToHexWEI,
decimalToHex,
hexToDecimal,
addHexes,
} from '../helpers/utils/conversions.util';
import { getShouldShowFiat } from '../selectors';
import { GAS_FORM_ERRORS } from '../helpers/constants/gas';
import {
getShouldShowFiat,
getSelectedAccount,
txDataSelector,
} from '../selectors';
import { useCurrencyDisplay } from './useCurrencyDisplay';
import { useGasFeeEstimates } from './useGasFeeEstimates';
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
@ -165,6 +171,9 @@ export function useGasFeeInputs(
minimumGasLimit,
editGasMode,
) {
const { balance: ethBalance } = useSelector(getSelectedAccount);
const txData = useSelector(txDataSelector);
// We need to know whether to show fiat conversions or not, so that we can
// default our fiat values to empty strings if showing fiat is not wanted or
// possible.
@ -413,6 +422,16 @@ export function useGasFeeInputs(
...gasWarnings,
};
const minimumTxCostInHexWei = addHexes(
minimumCostInHexWei,
txData?.txParams?.value,
);
const balanceError = conversionGreaterThan(
{ value: minimumTxCostInHexWei, fromNumericBase: 'hex' },
{ value: ethBalance, fromNumericBase: 'hex' },
);
return {
maxFeePerGas: maxFeePerGasToUse,
maxFeePerGasFiat: showFiat ? maxFeePerGasFiat : '',
@ -443,5 +462,6 @@ export function useGasFeeInputs(
setMaxFeePerGas(maxFeePerGasToUse);
setMaxPriorityFeePerGas(maxPriorityFeePerGasToUse);
},
balanceError,
};
}

View File

@ -7,7 +7,12 @@ import {
getNativeCurrency,
} from '../ducks/metamask/metamask';
import { ETH, PRIMARY } from '../helpers/constants/common';
import { getCurrentCurrency, getShouldShowFiat } from '../selectors';
import {
getCurrentCurrency,
getShouldShowFiat,
txDataSelector,
getSelectedAccount,
} from '../selectors';
import { useGasFeeEstimates } from './useGasFeeEstimates';
import { useGasFeeInputs } from './useGasFeeInputs';
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
@ -71,6 +76,32 @@ const FEE_MARKET_ESTIMATE_RETURN_VALUE = {
estimatedGasFeeTimeBounds: {},
};
const HIGH_FEE_MARKET_ESTIMATE_RETURN_VALUE = {
gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET,
gasFeeEstimates: {
low: {
minWaitTimeEstimate: 180000,
maxWaitTimeEstimate: 300000,
suggestedMaxPriorityFeePerGas: '3',
suggestedMaxFeePerGas: '53000',
},
medium: {
minWaitTimeEstimate: 15000,
maxWaitTimeEstimate: 60000,
suggestedMaxPriorityFeePerGas: '7',
suggestedMaxFeePerGas: '70000',
},
high: {
minWaitTimeEstimate: 0,
maxWaitTimeEstimate: 15000,
suggestedMaxPriorityFeePerGas: '10',
suggestedMaxFeePerGas: '100000',
},
estimatedBaseFee: '50000',
},
estimatedGasFeeTimeBounds: {},
};
const generateUseSelectorRouter = () => (selector) => {
if (selector === getConversionRate) {
return MOCK_ETH_USD_CONVERSION_RATE;
@ -84,6 +115,18 @@ const generateUseSelectorRouter = () => (selector) => {
if (selector === getShouldShowFiat) {
return true;
}
if (selector === txDataSelector) {
return {
txParams: {
value: '0x5555',
},
};
}
if (selector === getSelectedAccount) {
return {
balance: '0x440aa47cc2556',
};
}
return undefined;
};
@ -234,4 +277,32 @@ describe('useGasFeeInputs', () => {
// expect(result.current.estimatedMinimumFiat).toBe(`$${totalMaxFiat}`);
});
});
describe('when balance is sufficient for minimum transaction cost', () => {
beforeEach(() => {
useGasFeeEstimates.mockImplementation(
() => FEE_MARKET_ESTIMATE_RETURN_VALUE,
);
useSelector.mockImplementation(generateUseSelectorRouter());
});
it('should return false', () => {
const { result } = renderHook(() => useGasFeeInputs());
expect(result.current.balanceError).toBe(false);
});
});
describe('when balance is insufficient for minimum transaction cost', () => {
beforeEach(() => {
useGasFeeEstimates.mockImplementation(
() => HIGH_FEE_MARKET_ESTIMATE_RETURN_VALUE,
);
useSelector.mockImplementation(generateUseSelectorRouter());
});
it('should return true', () => {
const { result } = renderHook(() => useGasFeeInputs());
expect(result.current.balanceError).toBe(true);
});
});
});