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:
parent
a1f8a65519
commit
f1140087b7
@ -19,6 +19,7 @@ import {
|
|||||||
import { areDappSuggestedAndTxParamGasFeesTheSame } from '../../../helpers/utils/confirm-tx.util';
|
import { areDappSuggestedAndTxParamGasFeesTheSame } from '../../../helpers/utils/confirm-tx.util';
|
||||||
|
|
||||||
import InfoTooltip from '../../ui/info-tooltip';
|
import InfoTooltip from '../../ui/info-tooltip';
|
||||||
|
import ErrorMessage from '../../ui/error-message';
|
||||||
import TransactionTotalBanner from '../transaction-total-banner/transaction-total-banner.component';
|
import TransactionTotalBanner from '../transaction-total-banner/transaction-total-banner.component';
|
||||||
import RadioGroup from '../../ui/radio-group/radio-group.component';
|
import RadioGroup from '../../ui/radio-group/radio-group.component';
|
||||||
import AdvancedGasControls from '../advanced-gas-controls/advanced-gas-controls.component';
|
import AdvancedGasControls from '../advanced-gas-controls/advanced-gas-controls.component';
|
||||||
@ -59,6 +60,7 @@ export default function EditGasDisplay({
|
|||||||
gasErrors,
|
gasErrors,
|
||||||
onManualChange,
|
onManualChange,
|
||||||
minimumGasLimit,
|
minimumGasLimit,
|
||||||
|
balanceError,
|
||||||
}) {
|
}) {
|
||||||
const t = useContext(I18nContext);
|
const t = useContext(I18nContext);
|
||||||
|
|
||||||
@ -73,6 +75,12 @@ export default function EditGasDisplay({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const networkSupports1559 = useSelector(isEIP1559Network);
|
const networkSupports1559 = useSelector(isEIP1559Network);
|
||||||
|
const showTopError = balanceError;
|
||||||
|
|
||||||
|
let errorKey;
|
||||||
|
if (balanceError) {
|
||||||
|
errorKey = 'insufficientFunds';
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="edit-gas-display">
|
<div className="edit-gas-display">
|
||||||
@ -85,6 +93,11 @@ export default function EditGasDisplay({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{showTopError && (
|
||||||
|
<div className="edit-gas-display__warning">
|
||||||
|
<ErrorMessage errorKey={errorKey} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{requireDappAcknowledgement && (
|
{requireDappAcknowledgement && (
|
||||||
<div className="edit-gas-display__dapp-acknowledgement-warning">
|
<div className="edit-gas-display__dapp-acknowledgement-warning">
|
||||||
<ActionableMessage
|
<ActionableMessage
|
||||||
@ -255,4 +268,5 @@ EditGasDisplay.propTypes = {
|
|||||||
gasErrors: PropTypes.object,
|
gasErrors: PropTypes.object,
|
||||||
onManualChange: PropTypes.func,
|
onManualChange: PropTypes.func,
|
||||||
minimumGasLimit: PropTypes.number,
|
minimumGasLimit: PropTypes.number,
|
||||||
|
balanceError: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
@ -61,4 +61,8 @@
|
|||||||
color: $primary-1;
|
color: $primary-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__warning {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import React, { useCallback, useContext, useState } from 'react';
|
import React, { useCallback, useContext, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { useGasFeeInputs } from '../../../hooks/useGasFeeInputs';
|
import { useGasFeeInputs } from '../../../hooks/useGasFeeInputs';
|
||||||
import { useShouldAnimateGasEstimations } from '../../../hooks/useShouldAnimateGasEstimations';
|
import { useShouldAnimateGasEstimations } from '../../../hooks/useShouldAnimateGasEstimations';
|
||||||
@ -83,6 +82,7 @@ export default function EditGasPopover({
|
|||||||
hasGasErrors,
|
hasGasErrors,
|
||||||
gasErrors,
|
gasErrors,
|
||||||
onManualChange,
|
onManualChange,
|
||||||
|
balanceError,
|
||||||
} = useGasFeeInputs(defaultEstimateToUse, transaction, minimumGasLimit, mode);
|
} = useGasFeeInputs(defaultEstimateToUse, transaction, minimumGasLimit, mode);
|
||||||
|
|
||||||
const [showAdvancedForm, setShowAdvancedForm] = useState(
|
const [showAdvancedForm, setShowAdvancedForm] = useState(
|
||||||
@ -182,6 +182,7 @@ export default function EditGasPopover({
|
|||||||
<Popover
|
<Popover
|
||||||
title={title}
|
title={title}
|
||||||
onClose={closePopover}
|
onClose={closePopover}
|
||||||
|
className="edit-gas-popover__wrapper"
|
||||||
onBack={
|
onBack={
|
||||||
showEducationContent ? () => setShowEducationContent(false) : undefined
|
showEducationContent ? () => setShowEducationContent(false) : undefined
|
||||||
}
|
}
|
||||||
@ -191,7 +192,7 @@ export default function EditGasPopover({
|
|||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
onClick={onSubmit}
|
onClick={onSubmit}
|
||||||
disabled={hasGasErrors || isGasEstimatesLoading}
|
disabled={hasGasErrors || isGasEstimatesLoading || balanceError}
|
||||||
>
|
>
|
||||||
{footerButtonText}
|
{footerButtonText}
|
||||||
</Button>
|
</Button>
|
||||||
@ -238,6 +239,7 @@ export default function EditGasPopover({
|
|||||||
gasErrors={gasErrors}
|
gasErrors={gasErrors}
|
||||||
onManualChange={onManualChange}
|
onManualChange={onManualChange}
|
||||||
minimumGasLimit={minimumGasLimitDec}
|
minimumGasLimit={minimumGasLimitDec}
|
||||||
|
balanceError={balanceError}
|
||||||
{...editGasDisplayProps}
|
{...editGasDisplayProps}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
7
ui/components/app/edit-gas-popover/index.scss
Normal file
7
ui/components/app/edit-gas-popover/index.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
.edit-gas-popover {
|
||||||
|
&__wrapper {
|
||||||
|
@media screen and (min-width: 576px) {
|
||||||
|
max-height: 84vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import {
|
|||||||
import {
|
import {
|
||||||
multiplyCurrencies,
|
multiplyCurrencies,
|
||||||
conversionLessThan,
|
conversionLessThan,
|
||||||
|
conversionGreaterThan,
|
||||||
} from '../../shared/modules/conversion.utils';
|
} from '../../shared/modules/conversion.utils';
|
||||||
import {
|
import {
|
||||||
getMaximumGasTotalInHexWei,
|
getMaximumGasTotalInHexWei,
|
||||||
@ -22,9 +23,14 @@ import {
|
|||||||
decGWEIToHexWEI,
|
decGWEIToHexWEI,
|
||||||
decimalToHex,
|
decimalToHex,
|
||||||
hexToDecimal,
|
hexToDecimal,
|
||||||
|
addHexes,
|
||||||
} from '../helpers/utils/conversions.util';
|
} from '../helpers/utils/conversions.util';
|
||||||
import { getShouldShowFiat } from '../selectors';
|
|
||||||
import { GAS_FORM_ERRORS } from '../helpers/constants/gas';
|
import { GAS_FORM_ERRORS } from '../helpers/constants/gas';
|
||||||
|
import {
|
||||||
|
getShouldShowFiat,
|
||||||
|
getSelectedAccount,
|
||||||
|
txDataSelector,
|
||||||
|
} from '../selectors';
|
||||||
import { useCurrencyDisplay } from './useCurrencyDisplay';
|
import { useCurrencyDisplay } from './useCurrencyDisplay';
|
||||||
import { useGasFeeEstimates } from './useGasFeeEstimates';
|
import { useGasFeeEstimates } from './useGasFeeEstimates';
|
||||||
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
|
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
|
||||||
@ -165,6 +171,9 @@ export function useGasFeeInputs(
|
|||||||
minimumGasLimit,
|
minimumGasLimit,
|
||||||
editGasMode,
|
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
|
// 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
|
// default our fiat values to empty strings if showing fiat is not wanted or
|
||||||
// possible.
|
// possible.
|
||||||
@ -413,6 +422,16 @@ export function useGasFeeInputs(
|
|||||||
...gasWarnings,
|
...gasWarnings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const minimumTxCostInHexWei = addHexes(
|
||||||
|
minimumCostInHexWei,
|
||||||
|
txData?.txParams?.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
const balanceError = conversionGreaterThan(
|
||||||
|
{ value: minimumTxCostInHexWei, fromNumericBase: 'hex' },
|
||||||
|
{ value: ethBalance, fromNumericBase: 'hex' },
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
maxFeePerGas: maxFeePerGasToUse,
|
maxFeePerGas: maxFeePerGasToUse,
|
||||||
maxFeePerGasFiat: showFiat ? maxFeePerGasFiat : '',
|
maxFeePerGasFiat: showFiat ? maxFeePerGasFiat : '',
|
||||||
@ -443,5 +462,6 @@ export function useGasFeeInputs(
|
|||||||
setMaxFeePerGas(maxFeePerGasToUse);
|
setMaxFeePerGas(maxFeePerGasToUse);
|
||||||
setMaxPriorityFeePerGas(maxPriorityFeePerGasToUse);
|
setMaxPriorityFeePerGas(maxPriorityFeePerGasToUse);
|
||||||
},
|
},
|
||||||
|
balanceError,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,12 @@ import {
|
|||||||
getNativeCurrency,
|
getNativeCurrency,
|
||||||
} from '../ducks/metamask/metamask';
|
} from '../ducks/metamask/metamask';
|
||||||
import { ETH, PRIMARY } from '../helpers/constants/common';
|
import { ETH, PRIMARY } from '../helpers/constants/common';
|
||||||
import { getCurrentCurrency, getShouldShowFiat } from '../selectors';
|
import {
|
||||||
|
getCurrentCurrency,
|
||||||
|
getShouldShowFiat,
|
||||||
|
txDataSelector,
|
||||||
|
getSelectedAccount,
|
||||||
|
} from '../selectors';
|
||||||
import { useGasFeeEstimates } from './useGasFeeEstimates';
|
import { useGasFeeEstimates } from './useGasFeeEstimates';
|
||||||
import { useGasFeeInputs } from './useGasFeeInputs';
|
import { useGasFeeInputs } from './useGasFeeInputs';
|
||||||
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
|
import { useUserPreferencedCurrency } from './useUserPreferencedCurrency';
|
||||||
@ -71,6 +76,32 @@ const FEE_MARKET_ESTIMATE_RETURN_VALUE = {
|
|||||||
estimatedGasFeeTimeBounds: {},
|
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) => {
|
const generateUseSelectorRouter = () => (selector) => {
|
||||||
if (selector === getConversionRate) {
|
if (selector === getConversionRate) {
|
||||||
return MOCK_ETH_USD_CONVERSION_RATE;
|
return MOCK_ETH_USD_CONVERSION_RATE;
|
||||||
@ -84,6 +115,18 @@ const generateUseSelectorRouter = () => (selector) => {
|
|||||||
if (selector === getShouldShowFiat) {
|
if (selector === getShouldShowFiat) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (selector === txDataSelector) {
|
||||||
|
return {
|
||||||
|
txParams: {
|
||||||
|
value: '0x5555',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (selector === getSelectedAccount) {
|
||||||
|
return {
|
||||||
|
balance: '0x440aa47cc2556',
|
||||||
|
};
|
||||||
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -234,4 +277,32 @@ describe('useGasFeeInputs', () => {
|
|||||||
// expect(result.current.estimatedMinimumFiat).toBe(`$${totalMaxFiat}`);
|
// 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user