mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
EIP-1559 - Elevate gas properties to the Popover, disable submission if errors (#11510)
This commit is contained in:
parent
91e744a705
commit
a294f02b1d
@ -29,3 +29,12 @@ export const GAS_RECOMMENDATIONS = {
|
||||
MEDIUM: 'medium',
|
||||
HIGH: 'high',
|
||||
};
|
||||
|
||||
/**
|
||||
* These represent the different edit modes presented in the UI
|
||||
*/
|
||||
export const EDIT_GAS_MODES = {
|
||||
SPEED_UP: 'speed-up',
|
||||
CANCEL: 'cancel',
|
||||
MODIFY_IN_PLACE: 'modify-in-place',
|
||||
};
|
||||
|
@ -1,7 +1,10 @@
|
||||
import React, { useState, useContext } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { GAS_RECOMMENDATIONS } from '../../../../shared/constants/gas';
|
||||
import {
|
||||
GAS_RECOMMENDATIONS,
|
||||
EDIT_GAS_MODES,
|
||||
} from '../../../../shared/constants/gas';
|
||||
|
||||
import Button from '../../ui/button';
|
||||
import Typography from '../../ui/typography/typography';
|
||||
@ -19,55 +22,48 @@ import AdvancedGasControls from '../advanced-gas-controls/advanced-gas-controls.
|
||||
import ActionableMessage from '../../ui/actionable-message/actionable-message';
|
||||
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import { useGasFeeInputs } from '../../../hooks/useGasFeeInputs';
|
||||
|
||||
export default function EditGasDisplay({
|
||||
alwaysShowForm,
|
||||
type,
|
||||
showEducationButton,
|
||||
mode = EDIT_GAS_MODES.MODIFY_IN_PLACE,
|
||||
alwaysShowForm = false,
|
||||
showEducationButton = false,
|
||||
onEducationClick,
|
||||
dappSuggestedGasFee,
|
||||
dappOrigin,
|
||||
defaultEstimateToUse = 'medium',
|
||||
dappSuggestedGasFee = 0,
|
||||
dappOrigin = '',
|
||||
defaultEstimateToUse,
|
||||
maxPriorityFeePerGas,
|
||||
setMaxPriorityFeePerGas,
|
||||
maxPriorityFeePerGasFiat,
|
||||
maxFeePerGas,
|
||||
setMaxFeePerGas,
|
||||
maxFeePerGasFiat,
|
||||
estimatedMaximumNative,
|
||||
isGasEstimatesLoading,
|
||||
gasFeeEstimates,
|
||||
gasEstimateType,
|
||||
gasPrice,
|
||||
setGasPrice,
|
||||
gasLimit,
|
||||
setGasLimit,
|
||||
estimateToUse,
|
||||
setEstimateToUse,
|
||||
estimatedMinimumFiat,
|
||||
estimatedMaximumFiat,
|
||||
isMaxFeeError,
|
||||
isMaxPriorityFeeError,
|
||||
isGasTooLow,
|
||||
dappSuggestedGasFeeAcknowledged,
|
||||
setDappSuggestedGasFeeAcknowledged,
|
||||
showAdvancedForm,
|
||||
setShowAdvancedForm,
|
||||
warning,
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
|
||||
const [warning] = useState(null);
|
||||
|
||||
const [showAdvancedForm, setShowAdvancedForm] = useState(false);
|
||||
const [
|
||||
dappSuggestedGasFeeAcknowledged,
|
||||
setDappSuggestedGasFeeAcknowledged,
|
||||
] = useState(false);
|
||||
|
||||
const requireDappAcknowledgement = Boolean(
|
||||
dappSuggestedGasFee && !dappSuggestedGasFeeAcknowledged,
|
||||
);
|
||||
|
||||
const {
|
||||
maxPriorityFeePerGas,
|
||||
setMaxPriorityFeePerGas,
|
||||
maxPriorityFeePerGasFiat,
|
||||
maxFeePerGas,
|
||||
setMaxFeePerGas,
|
||||
maxFeePerGasFiat,
|
||||
estimatedMaximumNative,
|
||||
isGasEstimatesLoading,
|
||||
gasFeeEstimates,
|
||||
gasEstimateType,
|
||||
gasPrice,
|
||||
setGasPrice,
|
||||
gasLimit,
|
||||
setGasLimit,
|
||||
estimateToUse,
|
||||
setEstimateToUse,
|
||||
estimatedMinimumFiat,
|
||||
estimatedMaximumFiat,
|
||||
isMaxFeeError,
|
||||
isMaxPriorityFeeError,
|
||||
isGasTooLow,
|
||||
} = useGasFeeInputs(defaultEstimateToUse);
|
||||
|
||||
return (
|
||||
<div className="edit-gas-display">
|
||||
<div className="edit-gas-display__content">
|
||||
@ -88,7 +84,7 @@ export default function EditGasDisplay({
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{type === 'speed-up' && (
|
||||
{mode === EDIT_GAS_MODES.SPEED_UP && (
|
||||
<div className="edit-gas-display__top-tooltip">
|
||||
<Typography
|
||||
color={COLORS.BLACK}
|
||||
@ -141,31 +137,33 @@ export default function EditGasDisplay({
|
||||
</Typography>
|
||||
</div>
|
||||
)}
|
||||
{!requireDappAcknowledgement && (
|
||||
<RadioGroup
|
||||
name="gas-recommendation"
|
||||
options={[
|
||||
{
|
||||
value: GAS_RECOMMENDATIONS.LOW,
|
||||
label: t('editGasLow'),
|
||||
recommended: defaultEstimateToUse === GAS_RECOMMENDATIONS.LOW,
|
||||
},
|
||||
{
|
||||
value: GAS_RECOMMENDATIONS.MEDIUM,
|
||||
label: t('editGasMedium'),
|
||||
recommended:
|
||||
defaultEstimateToUse === GAS_RECOMMENDATIONS.MEDIUM,
|
||||
},
|
||||
{
|
||||
value: GAS_RECOMMENDATIONS.HIGH,
|
||||
label: t('editGasHigh'),
|
||||
recommended: defaultEstimateToUse === GAS_RECOMMENDATIONS.HIGH,
|
||||
},
|
||||
]}
|
||||
selectedValue={estimateToUse}
|
||||
onChange={setEstimateToUse}
|
||||
/>
|
||||
)}
|
||||
{!requireDappAcknowledgement &&
|
||||
![EDIT_GAS_MODES.SPEED_UP, EDIT_GAS_MODES.CANCEL].includes(mode) && (
|
||||
<RadioGroup
|
||||
name="gas-recommendation"
|
||||
options={[
|
||||
{
|
||||
value: GAS_RECOMMENDATIONS.LOW,
|
||||
label: t('editGasLow'),
|
||||
recommended: defaultEstimateToUse === GAS_RECOMMENDATIONS.LOW,
|
||||
},
|
||||
{
|
||||
value: GAS_RECOMMENDATIONS.MEDIUM,
|
||||
label: t('editGasMedium'),
|
||||
recommended:
|
||||
defaultEstimateToUse === GAS_RECOMMENDATIONS.MEDIUM,
|
||||
},
|
||||
{
|
||||
value: GAS_RECOMMENDATIONS.HIGH,
|
||||
label: t('editGasHigh'),
|
||||
recommended:
|
||||
defaultEstimateToUse === GAS_RECOMMENDATIONS.HIGH,
|
||||
},
|
||||
]}
|
||||
selectedValue={estimateToUse}
|
||||
onChange={setEstimateToUse}
|
||||
/>
|
||||
)}
|
||||
{!alwaysShowForm && (
|
||||
<button
|
||||
className="edit-gas-display__advanced-button"
|
||||
@ -216,19 +214,36 @@ export default function EditGasDisplay({
|
||||
|
||||
EditGasDisplay.propTypes = {
|
||||
alwaysShowForm: PropTypes.bool,
|
||||
type: PropTypes.oneOf(['customize-gas', 'speed-up']),
|
||||
mode: PropTypes.oneOf(Object.values(EDIT_GAS_MODES)),
|
||||
showEducationButton: PropTypes.bool,
|
||||
onEducationClick: PropTypes.func,
|
||||
dappSuggestedGasFee: PropTypes.number,
|
||||
dappOrigin: PropTypes.string,
|
||||
defaultEstimateToUse: PropTypes.oneOf(Object.values(GAS_RECOMMENDATIONS)),
|
||||
};
|
||||
|
||||
EditGasDisplay.defaultProps = {
|
||||
alwaysShowForm: false,
|
||||
type: 'customize-gas',
|
||||
showEducationButton: false,
|
||||
onEducationClick: undefined,
|
||||
dappSuggestedGasFee: 0,
|
||||
dappOrigin: '',
|
||||
maxPriorityFeePerGas: PropTypes.string,
|
||||
setMaxPriorityFeePerGas: PropTypes.func,
|
||||
maxPriorityFeePerGasFiat: PropTypes.string,
|
||||
maxFeePerGas: PropTypes.string,
|
||||
setMaxFeePerGas: PropTypes.func,
|
||||
maxFeePerGasFiat: PropTypes.string,
|
||||
estimatedMaximumNative: PropTypes.string,
|
||||
isGasEstimatesLoading: PropTypes.boolean,
|
||||
gasFeeEstimates: PropTypes.object,
|
||||
gasEstimateType: PropTypes.string,
|
||||
gasPrice: PropTypes.string,
|
||||
setGasPrice: PropTypes.func,
|
||||
gasLimit: PropTypes.number,
|
||||
setGasLimit: PropTypes.func,
|
||||
estimateToUse: PropTypes.string,
|
||||
setEstimateToUse: PropTypes.func,
|
||||
estimatedMinimumFiat: PropTypes.string,
|
||||
estimatedMaximumFiat: PropTypes.string,
|
||||
isMaxFeeError: PropTypes.boolean,
|
||||
isMaxPriorityFeeError: PropTypes.boolean,
|
||||
isGasTooLow: PropTypes.boolean,
|
||||
dappSuggestedGasFeeAcknowledged: PropTypes.boolean,
|
||||
setDappSuggestedGasFeeAcknowledged: PropTypes.func,
|
||||
showAdvancedForm: PropTypes.bool,
|
||||
setShowAdvancedForm: PropTypes.func,
|
||||
warning: PropTypes.string,
|
||||
};
|
||||
|
@ -2,6 +2,18 @@ import React, { useCallback, useContext, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useGasFeeInputs } from '../../../hooks/useGasFeeInputs';
|
||||
|
||||
import {
|
||||
GAS_ESTIMATE_TYPES,
|
||||
EDIT_GAS_MODES,
|
||||
} from '../../../../shared/constants/gas';
|
||||
|
||||
import {
|
||||
decGWEIToHexWEI,
|
||||
decimalToHex,
|
||||
} from '../../../helpers/utils/conversions.util';
|
||||
|
||||
import Popover from '../../ui/popover';
|
||||
import Button from '../../ui/button';
|
||||
import EditGasDisplay from '../edit-gas-display';
|
||||
@ -16,16 +28,11 @@ import {
|
||||
updateTransaction,
|
||||
} from '../../../store/actions';
|
||||
|
||||
export const EDIT_GAS_MODE = {
|
||||
SPEED_UP: 'speed-up',
|
||||
CANCEL: 'cancel',
|
||||
MODIFY_IN_PLACE: 'modify-in-place',
|
||||
};
|
||||
|
||||
export default function EditGasPopover({
|
||||
popoverTitle,
|
||||
confirmButtonText,
|
||||
editGasDisplayProps,
|
||||
popoverTitle = '',
|
||||
confirmButtonText = '',
|
||||
editGasDisplayProps = {},
|
||||
defaultEstimateToUse = 'medium',
|
||||
transaction,
|
||||
mode,
|
||||
onClose,
|
||||
@ -33,8 +40,42 @@ export default function EditGasPopover({
|
||||
const t = useContext(I18nContext);
|
||||
const dispatch = useDispatch();
|
||||
const showSidebar = useSelector((state) => state.appState.sidebar.isOpen);
|
||||
|
||||
const showEducationButton = mode === EDIT_GAS_MODES.MODIFY_IN_PLACE;
|
||||
const [showEducationContent, setShowEducationContent] = useState(false);
|
||||
|
||||
const [warning] = useState(null);
|
||||
|
||||
const [showAdvancedForm, setShowAdvancedForm] = useState(false);
|
||||
const [
|
||||
dappSuggestedGasFeeAcknowledged,
|
||||
setDappSuggestedGasFeeAcknowledged,
|
||||
] = useState(false);
|
||||
|
||||
const {
|
||||
maxPriorityFeePerGas,
|
||||
setMaxPriorityFeePerGas,
|
||||
maxPriorityFeePerGasFiat,
|
||||
maxFeePerGas,
|
||||
setMaxFeePerGas,
|
||||
maxFeePerGasFiat,
|
||||
estimatedMaximumNative,
|
||||
isGasEstimatesLoading,
|
||||
gasFeeEstimates,
|
||||
gasEstimateType,
|
||||
gasPrice,
|
||||
setGasPrice,
|
||||
gasLimit,
|
||||
setGasLimit,
|
||||
estimateToUse,
|
||||
setEstimateToUse,
|
||||
estimatedMinimumFiat,
|
||||
estimatedMaximumFiat,
|
||||
isMaxFeeError,
|
||||
isMaxPriorityFeeError,
|
||||
isGasTooLow,
|
||||
} = useGasFeeInputs(defaultEstimateToUse);
|
||||
|
||||
/**
|
||||
* Temporary placeholder, this should be managed by the parent component but
|
||||
* we will be extracting this component from the hard to maintain modal/
|
||||
@ -55,26 +96,36 @@ export default function EditGasPopover({
|
||||
if (!transaction || !mode) {
|
||||
closePopover();
|
||||
}
|
||||
|
||||
const newGasSettings =
|
||||
gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET
|
||||
? {
|
||||
gas: decimalToHex(gasLimit),
|
||||
gasLimit: decimalToHex(gasLimit),
|
||||
maxFeePerGas: decGWEIToHexWEI(maxFeePerGas),
|
||||
maxPriorityFeePerGas: decGWEIToHexWEI(maxPriorityFeePerGas),
|
||||
}
|
||||
: {
|
||||
gas: decimalToHex(gasLimit),
|
||||
gasLimit: decimalToHex(gasLimit),
|
||||
gasPrice: decGWEIToHexWEI(gasPrice),
|
||||
};
|
||||
|
||||
switch (mode) {
|
||||
case EDIT_GAS_MODE.CANCEL:
|
||||
dispatch(
|
||||
createCancelTransaction(transaction.id, {
|
||||
/** new gas settings */
|
||||
}),
|
||||
);
|
||||
case EDIT_GAS_MODES.CANCEL:
|
||||
dispatch(createCancelTransaction(transaction.id, newGasSettings));
|
||||
break;
|
||||
case EDIT_GAS_MODE.SPEED_UP:
|
||||
dispatch(
|
||||
createSpeedUpTransaction(transaction.id, {
|
||||
/** new gas settings */
|
||||
}),
|
||||
);
|
||||
case EDIT_GAS_MODES.SPEED_UP:
|
||||
dispatch(createSpeedUpTransaction(transaction.id, newGasSettings));
|
||||
break;
|
||||
case EDIT_GAS_MODE.MODIFY_IN_PLACE:
|
||||
case EDIT_GAS_MODES.MODIFY_IN_PLACE:
|
||||
dispatch(
|
||||
updateTransaction({
|
||||
...transaction,
|
||||
txParams: { ...transaction.txParams /** ...newGasSettings */ },
|
||||
txParams: {
|
||||
...transaction.txParams,
|
||||
...newGasSettings,
|
||||
},
|
||||
}),
|
||||
);
|
||||
break;
|
||||
@ -83,11 +134,29 @@ export default function EditGasPopover({
|
||||
}
|
||||
|
||||
closePopover();
|
||||
}, [transaction, mode, dispatch, closePopover]);
|
||||
}, [
|
||||
transaction,
|
||||
mode,
|
||||
dispatch,
|
||||
closePopover,
|
||||
gasLimit,
|
||||
gasPrice,
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
gasEstimateType,
|
||||
]);
|
||||
|
||||
let title = t('editGasTitle');
|
||||
if (popoverTitle) {
|
||||
title = popoverTitle;
|
||||
} else if (showEducationContent) {
|
||||
title = t('editGasEducationModalTitle');
|
||||
} else if (mode === EDIT_GAS_MODES.SPEED_UP) {
|
||||
title = t('speedUpPopoverTitle');
|
||||
} else if (mode === EDIT_GAS_MODES.CANCEL) {
|
||||
title = t('cancelPopoverTitle');
|
||||
}
|
||||
|
||||
const title = showEducationContent
|
||||
? t('editGasEducationModalTitle')
|
||||
: popoverTitle || t('editGasTitle');
|
||||
const footerButtonText = confirmButtonText || t('save');
|
||||
|
||||
return (
|
||||
@ -99,7 +168,11 @@ export default function EditGasPopover({
|
||||
}
|
||||
footer={
|
||||
<>
|
||||
<Button type="primary" onClick={onSubmit}>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={onSubmit}
|
||||
disabled={isMaxFeeError || isMaxPriorityFeeError || isGasTooLow}
|
||||
>
|
||||
{footerButtonText}
|
||||
</Button>
|
||||
</>
|
||||
@ -110,8 +183,38 @@ export default function EditGasPopover({
|
||||
<EditGasDisplayEducation />
|
||||
) : (
|
||||
<EditGasDisplay
|
||||
{...editGasDisplayProps}
|
||||
showEducationButton={showEducationButton}
|
||||
warning={warning}
|
||||
showAdvancedForm={showAdvancedForm}
|
||||
setShowAdvancedForm={setShowAdvancedForm}
|
||||
dappSuggestedGasFeeAcknowledged={dappSuggestedGasFeeAcknowledged}
|
||||
setDappSuggestedGasFeeAcknowledged={
|
||||
setDappSuggestedGasFeeAcknowledged
|
||||
}
|
||||
maxPriorityFeePerGas={maxPriorityFeePerGas}
|
||||
setMaxPriorityFeePerGas={setMaxPriorityFeePerGas}
|
||||
maxPriorityFeePerGasFiat={maxPriorityFeePerGasFiat}
|
||||
maxFeePerGas={maxFeePerGas}
|
||||
setMaxFeePerGas={setMaxFeePerGas}
|
||||
maxFeePerGasFiat={maxFeePerGasFiat}
|
||||
estimatedMaximumNative={estimatedMaximumNative}
|
||||
isGasEstimatesLoading={isGasEstimatesLoading}
|
||||
gasFeeEstimates={gasFeeEstimates}
|
||||
gasEstimateType={gasEstimateType}
|
||||
gasPrice={gasPrice}
|
||||
setGasPrice={setGasPrice}
|
||||
gasLimit={gasLimit}
|
||||
setGasLimit={setGasLimit}
|
||||
estimateToUse={estimateToUse}
|
||||
setEstimateToUse={setEstimateToUse}
|
||||
estimatedMinimumFiat={estimatedMinimumFiat}
|
||||
estimatedMaximumFiat={estimatedMaximumFiat}
|
||||
isMaxFeeError={isMaxFeeError}
|
||||
isMaxPriorityFeeError={isMaxPriorityFeeError}
|
||||
isGasTooLow={isGasTooLow}
|
||||
onEducationClick={() => setShowEducationContent(true)}
|
||||
mode={mode}
|
||||
{...editGasDisplayProps}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@ -123,15 +226,8 @@ EditGasPopover.propTypes = {
|
||||
popoverTitle: PropTypes.string,
|
||||
editGasDisplayProps: PropTypes.object,
|
||||
confirmButtonText: PropTypes.string,
|
||||
showEducationButton: PropTypes.bool,
|
||||
onClose: PropTypes.func,
|
||||
transaction: PropTypes.object,
|
||||
mode: PropTypes.oneOf(Object.values(EDIT_GAS_MODE)),
|
||||
};
|
||||
|
||||
EditGasPopover.defaultProps = {
|
||||
popoverTitle: '',
|
||||
editGasDisplayProps: {},
|
||||
confirmButtonText: '',
|
||||
showEducationButton: false,
|
||||
mode: PropTypes.oneOf(Object.values(EDIT_GAS_MODES)),
|
||||
defaultEstimateToUse: PropTypes.string,
|
||||
};
|
||||
|
@ -18,8 +18,8 @@ import {
|
||||
TRANSACTION_GROUP_CATEGORIES,
|
||||
TRANSACTION_STATUSES,
|
||||
} from '../../../../shared/constants/transaction';
|
||||
import { EDIT_GAS_MODES } from '../../../../shared/constants/gas';
|
||||
import EditGasPopover from '../edit-gas-popover';
|
||||
import { EDIT_GAS_MODE } from '../edit-gas-popover/edit-gas-popover.component';
|
||||
|
||||
export default function TransactionListItem({
|
||||
transactionGroup,
|
||||
@ -212,17 +212,15 @@ export default function TransactionListItem({
|
||||
)}
|
||||
{process.env.SHOW_EIP_1559_UI && showRetryEditGasPopover && (
|
||||
<EditGasPopover
|
||||
popoverTitle={t('cancelPopoverTitle')}
|
||||
onClose={closeRetryEditGasPopover}
|
||||
mode={EDIT_GAS_MODE.SPEED_UP}
|
||||
mode={EDIT_GAS_MODES.SPEED_UP}
|
||||
transaction={transactionGroup.primaryTransaction}
|
||||
/>
|
||||
)}
|
||||
{process.env.SHOW_EIP_1559_UI && showCancelEditGasPopover && (
|
||||
<EditGasPopover
|
||||
popoverTitle={t('speedUpPopoverTitle')}
|
||||
onClose={closeCancelEditGasPopover}
|
||||
mode={EDIT_GAS_MODE.CANCEL}
|
||||
mode={EDIT_GAS_MODES.CANCEL}
|
||||
transaction={transactionGroup.primaryTransaction}
|
||||
/>
|
||||
)}
|
||||
|
Loading…
Reference in New Issue
Block a user