2021-06-28 16:45:08 +02:00
|
|
|
import React, { useCallback, useContext, useState } from 'react';
|
|
|
|
import PropTypes from 'prop-types';
|
2022-12-08 19:37:06 +01:00
|
|
|
import { useDispatch } from 'react-redux';
|
2021-10-22 19:14:28 +02:00
|
|
|
import { useGasFeeInputs } from '../../../hooks/gasFeeInput/useGasFeeInputs';
|
2021-08-17 22:08:13 +02:00
|
|
|
import { txParamsAreDappSuggested } from '../../../../shared/modules/transaction.utils';
|
2021-11-06 01:59:23 +01:00
|
|
|
import {
|
|
|
|
EDIT_GAS_MODES,
|
|
|
|
GAS_LIMITS,
|
|
|
|
CUSTOM_GAS_ESTIMATE,
|
2022-12-08 19:37:06 +01:00
|
|
|
GAS_RECOMMENDATIONS,
|
2021-11-06 01:59:23 +01:00
|
|
|
} from '../../../../shared/constants/gas';
|
2021-07-14 18:45:37 +02:00
|
|
|
|
2022-09-16 21:05:21 +02:00
|
|
|
import { decGWEIToHexWEI } from '../../../helpers/utils/conversions.util';
|
2021-07-14 18:45:37 +02:00
|
|
|
|
2021-06-28 16:45:08 +02:00
|
|
|
import Popover from '../../ui/popover';
|
|
|
|
import Button from '../../ui/button';
|
|
|
|
import EditGasDisplay from '../edit-gas-display';
|
|
|
|
|
|
|
|
import { I18nContext } from '../../../contexts/i18n';
|
2021-07-12 21:35:54 +02:00
|
|
|
import {
|
|
|
|
createCancelTransaction,
|
|
|
|
createSpeedUpTransaction,
|
|
|
|
hideModal,
|
2022-03-25 18:11:04 +01:00
|
|
|
updateTransactionGasFees,
|
|
|
|
hideLoadingIndication,
|
|
|
|
showLoadingIndication,
|
2021-07-12 21:35:54 +02:00
|
|
|
} from '../../../store/actions';
|
2021-07-26 17:24:44 +02:00
|
|
|
import LoadingHeartBeat from '../../ui/loading-heartbeat';
|
2021-09-15 17:59:51 +02:00
|
|
|
import { useIncrementedGasFees } from '../../../hooks/useIncrementedGasFees';
|
2022-09-16 21:05:21 +02:00
|
|
|
import { hexToDecimal } from '../../../../shared/lib/metamask-controller-utils';
|
|
|
|
import { decimalToHex } from '../../../../shared/lib/transactions-controller-utils';
|
2021-07-12 21:35:54 +02:00
|
|
|
|
2021-06-28 16:45:08 +02:00
|
|
|
export default function EditGasPopover({
|
2021-07-14 18:45:37 +02:00
|
|
|
popoverTitle = '',
|
|
|
|
confirmButtonText = '',
|
|
|
|
editGasDisplayProps = {},
|
2021-07-12 21:35:54 +02:00
|
|
|
transaction,
|
|
|
|
mode,
|
2021-07-08 22:23:00 +02:00
|
|
|
onClose,
|
2021-07-31 15:02:14 +02:00
|
|
|
minimumGasLimit = GAS_LIMITS.SIMPLE,
|
2021-06-28 16:45:08 +02:00
|
|
|
}) {
|
|
|
|
const t = useContext(I18nContext);
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
2022-07-31 20:26:40 +02:00
|
|
|
const [dappSuggestedGasFeeAcknowledged, setDappSuggestedGasFeeAcknowledged] =
|
|
|
|
useState(false);
|
2021-07-14 18:45:37 +02:00
|
|
|
|
2021-07-30 13:35:30 +02:00
|
|
|
const minimumGasLimitDec = hexToDecimal(minimumGasLimit);
|
2021-09-15 17:59:51 +02:00
|
|
|
const updatedCustomGasSettings = useIncrementedGasFees(transaction);
|
|
|
|
|
|
|
|
let updatedTransaction = transaction;
|
|
|
|
if (mode === EDIT_GAS_MODES.SPEED_UP || mode === EDIT_GAS_MODES.CANCEL) {
|
|
|
|
updatedTransaction = {
|
|
|
|
...transaction,
|
2021-11-06 01:59:23 +01:00
|
|
|
userFeeLevel: CUSTOM_GAS_ESTIMATE,
|
2021-09-15 17:59:51 +02:00
|
|
|
txParams: {
|
|
|
|
...transaction.txParams,
|
|
|
|
...updatedCustomGasSettings,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
2021-07-30 13:35:30 +02:00
|
|
|
|
2021-07-14 18:45:37 +02:00
|
|
|
const {
|
2021-08-03 19:51:02 +02:00
|
|
|
estimatedMinimumNative,
|
2021-07-14 18:45:37 +02:00
|
|
|
gasPrice,
|
|
|
|
setGasPrice,
|
|
|
|
gasLimit,
|
|
|
|
setGasLimit,
|
2022-01-21 16:58:59 +01:00
|
|
|
properGasLimit,
|
2021-07-14 18:45:37 +02:00
|
|
|
estimateToUse,
|
2021-07-20 21:34:32 +02:00
|
|
|
hasGasErrors,
|
|
|
|
gasErrors,
|
2021-07-22 18:32:59 +02:00
|
|
|
onManualChange,
|
2021-07-31 00:46:31 +02:00
|
|
|
balanceError,
|
2021-09-15 17:59:51 +02:00
|
|
|
} = useGasFeeInputs(
|
2022-12-08 19:37:06 +01:00
|
|
|
GAS_RECOMMENDATIONS.MEDIUM,
|
2021-09-15 17:59:51 +02:00
|
|
|
updatedTransaction,
|
|
|
|
minimumGasLimit,
|
|
|
|
mode,
|
|
|
|
);
|
2021-07-14 18:45:37 +02:00
|
|
|
|
2021-08-17 22:08:13 +02:00
|
|
|
const txParamsHaveBeenCustomized =
|
2021-11-06 01:59:23 +01:00
|
|
|
estimateToUse === CUSTOM_GAS_ESTIMATE ||
|
|
|
|
txParamsAreDappSuggested(updatedTransaction);
|
2021-08-17 22:08:13 +02:00
|
|
|
|
2021-06-28 16:45:08 +02:00
|
|
|
/**
|
|
|
|
* Temporary placeholder, this should be managed by the parent component but
|
2021-09-09 17:14:07 +02:00
|
|
|
* we will be extracting this component from the hard to maintain modal
|
|
|
|
* component. For now this is just to be able to appropriately close
|
2021-06-28 16:45:08 +02:00
|
|
|
* the modal in testing
|
|
|
|
*/
|
|
|
|
const closePopover = useCallback(() => {
|
2021-07-08 22:23:00 +02:00
|
|
|
if (onClose) {
|
|
|
|
onClose();
|
2021-06-28 16:45:08 +02:00
|
|
|
} else {
|
|
|
|
dispatch(hideModal());
|
|
|
|
}
|
2021-09-09 17:14:07 +02:00
|
|
|
}, [onClose, dispatch]);
|
2021-06-28 16:45:08 +02:00
|
|
|
|
2022-03-25 18:11:04 +01:00
|
|
|
const onSubmit = useCallback(async () => {
|
2021-09-15 17:59:51 +02:00
|
|
|
if (!updatedTransaction || !mode) {
|
2021-07-12 21:35:54 +02:00
|
|
|
closePopover();
|
|
|
|
}
|
2021-07-14 18:45:37 +02:00
|
|
|
|
2021-10-22 22:42:20 +02:00
|
|
|
const newGasSettings = {
|
|
|
|
gas: decimalToHex(gasLimit),
|
|
|
|
gasLimit: decimalToHex(gasLimit),
|
|
|
|
estimateUsed: estimateToUse,
|
2022-12-08 19:37:06 +01:00
|
|
|
gasPrice: decGWEIToHexWEI(gasPrice),
|
2021-10-22 22:42:20 +02:00
|
|
|
};
|
|
|
|
|
2021-09-15 17:59:51 +02:00
|
|
|
const cleanTransactionParams = { ...updatedTransaction.txParams };
|
2021-08-17 22:08:13 +02:00
|
|
|
|
2021-08-06 21:31:30 +02:00
|
|
|
const updatedTxMeta = {
|
2021-09-15 17:59:51 +02:00
|
|
|
...updatedTransaction,
|
2022-01-21 16:58:59 +01:00
|
|
|
userEditedGasLimit: gasLimit !== Number(transaction.originalGasEstimate),
|
2021-11-06 01:59:23 +01:00
|
|
|
userFeeLevel: estimateToUse || CUSTOM_GAS_ESTIMATE,
|
2021-08-06 21:31:30 +02:00
|
|
|
txParams: {
|
2021-08-17 22:08:13 +02:00
|
|
|
...cleanTransactionParams,
|
2021-08-06 21:31:30 +02:00
|
|
|
...newGasSettings,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2021-07-12 21:35:54 +02:00
|
|
|
switch (mode) {
|
2021-07-14 18:45:37 +02:00
|
|
|
case EDIT_GAS_MODES.CANCEL:
|
2021-08-07 00:18:53 +02:00
|
|
|
dispatch(
|
2022-12-08 19:37:06 +01:00
|
|
|
createCancelTransaction(updatedTransaction.id, newGasSettings),
|
2021-08-07 00:18:53 +02:00
|
|
|
);
|
2021-07-12 21:35:54 +02:00
|
|
|
break;
|
2021-07-14 18:45:37 +02:00
|
|
|
case EDIT_GAS_MODES.SPEED_UP:
|
2021-08-07 00:18:53 +02:00
|
|
|
dispatch(
|
2022-12-08 19:37:06 +01:00
|
|
|
createSpeedUpTransaction(updatedTransaction.id, newGasSettings),
|
2021-08-07 00:18:53 +02:00
|
|
|
);
|
2021-07-12 21:35:54 +02:00
|
|
|
break;
|
2021-07-14 18:45:37 +02:00
|
|
|
case EDIT_GAS_MODES.MODIFY_IN_PLACE:
|
2022-03-25 18:11:04 +01:00
|
|
|
newGasSettings.userEditedGasLimit = updatedTxMeta.userEditedGasLimit;
|
|
|
|
newGasSettings.userFeeLevel = updatedTxMeta.userFeeLevel;
|
|
|
|
|
|
|
|
dispatch(showLoadingIndication());
|
|
|
|
await dispatch(
|
|
|
|
updateTransactionGasFees(updatedTxMeta.id, newGasSettings),
|
|
|
|
);
|
|
|
|
dispatch(hideLoadingIndication());
|
2021-07-12 21:35:54 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
closePopover();
|
2021-07-14 18:45:37 +02:00
|
|
|
}, [
|
2021-09-15 17:59:51 +02:00
|
|
|
updatedTransaction,
|
2021-07-14 18:45:37 +02:00
|
|
|
mode,
|
|
|
|
dispatch,
|
|
|
|
closePopover,
|
|
|
|
gasLimit,
|
|
|
|
gasPrice,
|
2022-01-21 16:58:59 +01:00
|
|
|
transaction.originalGasEstimate,
|
2021-08-06 21:31:30 +02:00
|
|
|
estimateToUse,
|
2021-07-14 18:45:37 +02:00
|
|
|
]);
|
|
|
|
|
|
|
|
let title = t('editGasTitle');
|
|
|
|
if (popoverTitle) {
|
|
|
|
title = popoverTitle;
|
|
|
|
} else if (mode === EDIT_GAS_MODES.SPEED_UP) {
|
|
|
|
title = t('speedUpPopoverTitle');
|
|
|
|
} else if (mode === EDIT_GAS_MODES.CANCEL) {
|
|
|
|
title = t('cancelPopoverTitle');
|
|
|
|
}
|
2021-07-12 21:35:54 +02:00
|
|
|
|
2021-06-28 16:45:08 +02:00
|
|
|
const footerButtonText = confirmButtonText || t('save');
|
|
|
|
return (
|
|
|
|
<Popover
|
|
|
|
title={title}
|
|
|
|
onClose={closePopover}
|
2021-07-31 00:46:31 +02:00
|
|
|
className="edit-gas-popover__wrapper"
|
2021-06-28 16:45:08 +02:00
|
|
|
footer={
|
2022-12-08 19:37:06 +01:00
|
|
|
<Button
|
|
|
|
type="primary"
|
|
|
|
onClick={onSubmit}
|
|
|
|
disabled={hasGasErrors || balanceError || !txParamsHaveBeenCustomized}
|
|
|
|
>
|
|
|
|
{footerButtonText}
|
|
|
|
</Button>
|
2021-06-28 16:45:08 +02:00
|
|
|
}
|
|
|
|
>
|
2021-07-26 17:24:44 +02:00
|
|
|
<div style={{ padding: '0 20px 20px 20px', position: 'relative' }}>
|
2022-12-08 19:37:06 +01:00
|
|
|
{process.env.IN_TEST ? null : <LoadingHeartBeat />}
|
|
|
|
<EditGasDisplay
|
|
|
|
dappSuggestedGasFeeAcknowledged={dappSuggestedGasFeeAcknowledged}
|
|
|
|
setDappSuggestedGasFeeAcknowledged={
|
|
|
|
setDappSuggestedGasFeeAcknowledged
|
|
|
|
}
|
|
|
|
estimatedMinimumNative={estimatedMinimumNative}
|
|
|
|
gasPrice={gasPrice}
|
|
|
|
setGasPrice={setGasPrice}
|
|
|
|
gasLimit={gasLimit}
|
|
|
|
setGasLimit={setGasLimit}
|
|
|
|
properGasLimit={properGasLimit}
|
|
|
|
mode={mode}
|
|
|
|
transaction={updatedTransaction}
|
|
|
|
onManualChange={onManualChange}
|
|
|
|
minimumGasLimit={minimumGasLimitDec}
|
|
|
|
balanceError={balanceError}
|
|
|
|
txParamsHaveBeenCustomized={txParamsHaveBeenCustomized}
|
|
|
|
gasErrors={gasErrors}
|
|
|
|
{...editGasDisplayProps}
|
|
|
|
/>
|
2021-06-28 16:45:08 +02:00
|
|
|
</div>
|
|
|
|
</Popover>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
EditGasPopover.propTypes = {
|
|
|
|
popoverTitle: PropTypes.string,
|
|
|
|
editGasDisplayProps: PropTypes.object,
|
|
|
|
confirmButtonText: PropTypes.string,
|
2021-07-08 22:23:00 +02:00
|
|
|
onClose: PropTypes.func,
|
2021-07-12 21:35:54 +02:00
|
|
|
transaction: PropTypes.object,
|
2021-07-14 18:45:37 +02:00
|
|
|
mode: PropTypes.oneOf(Object.values(EDIT_GAS_MODES)),
|
2021-07-30 13:35:30 +02:00
|
|
|
minimumGasLimit: PropTypes.string,
|
2021-06-28 16:45:08 +02:00
|
|
|
};
|