mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Remove the SHOW_EIP_1559_UI environment variable, replace with network detection where appropriate (#11694)
Fixing up tests and add back old custom gas modal for non-eip1559 compliant networks Remove unnecessary props from send-gas-row.component fix breaking test Fix primary and secondary title overrides fix rebase issue Fix rebase conflict Co-authored-by: David Walsh <davidwalsh83@gmail.com>
This commit is contained in:
parent
e0953d9f68
commit
8a42258e10
app
development/build
test/e2e
ui
components/app
advanced-gas-controls
edit-gas-popover
modals
transaction-breakdown
transaction-detail
transaction-list-item
hooks
useCancelTransaction.jsuseCancelTransaction.test.jsuseGasFeeInputs.jsuseRetryTransaction.jsuseRetryTransaction.test.js
pages
confirm-approve
confirm-transaction-base
send/send-content
@ -156,9 +156,6 @@
|
||||
"amount": {
|
||||
"message": "Amount"
|
||||
},
|
||||
"amountGasFee": {
|
||||
"message": "Amount + Gas Fee"
|
||||
},
|
||||
"amountWithColon": {
|
||||
"message": "Amount:"
|
||||
},
|
||||
|
@ -162,9 +162,6 @@ export default class NetworkController extends EventEmitter {
|
||||
*/
|
||||
async getEIP1559Compatibility() {
|
||||
const { EIPS } = this.networkDetails.getState();
|
||||
if (process.env.SHOW_EIP_1559_UI === false) {
|
||||
return false;
|
||||
}
|
||||
if (EIPS[1559] !== undefined) {
|
||||
return EIPS[1559];
|
||||
}
|
||||
|
@ -528,9 +528,6 @@ function getEnvironmentVariables({ devMode, testing }) {
|
||||
PUBNUB_SUB_KEY: process.env.PUBNUB_SUB_KEY || '',
|
||||
PUBNUB_PUB_KEY: process.env.PUBNUB_PUB_KEY || '',
|
||||
CONF: devMode ? metamaskrc : {},
|
||||
SHOW_EIP_1559_UI:
|
||||
process.env.SHOW_EIP_1559_UI === '1' ||
|
||||
metamaskrc.SHOW_EIP_1559_UI === '1',
|
||||
SENTRY_DSN: process.env.SENTRY_DSN,
|
||||
SENTRY_DSN_DEV: metamaskrc.SENTRY_DSN_DEV,
|
||||
INFURA_PROJECT_ID: testing
|
||||
|
@ -487,23 +487,17 @@ describe('MetaMask', function () {
|
||||
const popup = windowHandles[2];
|
||||
await driver.switchToWindow(popup);
|
||||
await driver.delay(regularDelayMs);
|
||||
await driver.clickElement({ text: 'Edit', tag: 'button' }, 10000);
|
||||
|
||||
await driver.clickElement('.confirm-detail-row__header-text--edit');
|
||||
await driver.delay(regularDelayMs);
|
||||
const inputs = await driver.findElements('input[type="number"]');
|
||||
const gasLimitInput = inputs[0];
|
||||
const gasPriceInput = inputs[1];
|
||||
await gasLimitInput.fill('4700000');
|
||||
await gasPriceInput.fill('20');
|
||||
await driver.delay(1000);
|
||||
await driver.clickElement({ text: 'Save', tag: 'button' }, 10000);
|
||||
await driver.clickElement({ text: 'Confirm', tag: 'button' }, 10000);
|
||||
|
||||
await driver.clickElement({ text: 'Advanced', tag: 'button' });
|
||||
await driver.delay(tinyDelayMs);
|
||||
|
||||
const [gasPriceInput, gasLimitInput] = await driver.findElements(
|
||||
'.advanced-gas-inputs__gas-edit-row__input',
|
||||
);
|
||||
assert(gasPriceInput.getAttribute('value'), 20);
|
||||
assert(gasLimitInput.getAttribute('value'), 4700000);
|
||||
|
||||
await driver.clickElement({ text: 'Save', tag: 'button' });
|
||||
await driver.delay(regularDelayMs);
|
||||
|
||||
await driver.clickElement({ text: 'Confirm', tag: 'button' });
|
||||
await driver.delay(regularDelayMs);
|
||||
|
||||
await driver.switchToWindow(dapp);
|
||||
@ -675,35 +669,21 @@ describe('MetaMask', function () {
|
||||
});
|
||||
|
||||
it('customizes gas', async function () {
|
||||
// Set the gas limit
|
||||
await driver.clickElement('.confirm-detail-row__header-text--edit');
|
||||
await driver.clickElement({ text: 'Edit', tag: 'button' });
|
||||
await driver.delay(regularDelayMs);
|
||||
// wait for gas modal to be visible
|
||||
const gasModal = await driver.findVisibleElement('span .modal');
|
||||
await driver.clickElement('.page-container__tab:nth-of-type(2)');
|
||||
await driver.delay(regularDelayMs);
|
||||
|
||||
const [gasPriceInput, gasLimitInput] = await driver.findElements(
|
||||
'.advanced-gas-inputs__gas-edit-row__input',
|
||||
await driver.clickElement(
|
||||
{ text: 'Edit suggested gas fee', tag: 'button' },
|
||||
10000,
|
||||
);
|
||||
|
||||
await gasPriceInput.fill('10');
|
||||
await driver.delay(50);
|
||||
|
||||
await gasLimitInput.fill('60000');
|
||||
|
||||
await driver.delay(1000);
|
||||
|
||||
await driver.clickElement('.page-container__footer-button');
|
||||
|
||||
// wait for gas modal to be removed from DOM.
|
||||
await gasModal.waitForElementState('hidden');
|
||||
|
||||
const gasFeeInputs = await driver.findElements(
|
||||
'.confirm-detail-row__primary',
|
||||
);
|
||||
const renderedGasFee = await gasFeeInputs[0].getText();
|
||||
assert.equal(renderedGasFee, '0.0006');
|
||||
const inputs = await driver.findElements('input[type="number"]');
|
||||
const gasLimitInput = inputs[0];
|
||||
const gasPriceInput = inputs[1];
|
||||
await gasLimitInput.fill('60000');
|
||||
await gasPriceInput.fill('10');
|
||||
await driver.delay(1000);
|
||||
await driver.clickElement({ text: 'Save', tag: 'button' }, 10000);
|
||||
await driver.findElement({ tag: 'span', text: '0.0006' });
|
||||
});
|
||||
|
||||
it('submits the transaction', async function () {
|
||||
|
@ -232,6 +232,7 @@ describe('Send ETH from dapp using advanced gas controls', function () {
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
it('should display the correct gas price on the transaction', async function () {
|
||||
await withFixtures(
|
||||
{
|
||||
@ -293,18 +294,18 @@ describe('Send ETH from dapp using advanced gas controls', function () {
|
||||
windowHandles,
|
||||
);
|
||||
await driver.assertElementNotPresent({ text: 'Data', tag: 'li' });
|
||||
const [gasPriceInput, gasLimitInput] = await driver.findElements(
|
||||
'.advanced-gas-inputs__gas-edit-row__input',
|
||||
);
|
||||
await gasPriceInput.clear();
|
||||
await driver.delay(50);
|
||||
await gasPriceInput.fill('10');
|
||||
await driver.delay(50);
|
||||
await driver.delay(50);
|
||||
await gasLimitInput.fill('');
|
||||
await driver.delay(50);
|
||||
await gasLimitInput.fill('25000');
|
||||
await driver.clickElement({ text: 'Edit', tag: 'button' });
|
||||
await driver.delay(1000);
|
||||
await driver.clickElement(
|
||||
{ text: 'Edit suggested gas fee', tag: 'button' },
|
||||
10000,
|
||||
);
|
||||
await driver.delay(1000);
|
||||
const inputs = await driver.findElements('input[type="number"]');
|
||||
const gasPriceInput = inputs[1];
|
||||
await gasPriceInput.fill('100');
|
||||
await driver.delay(1000);
|
||||
await driver.clickElement({ text: 'Save', tag: 'button' }, 10000);
|
||||
await driver.clickElement({ text: 'Confirm', tag: 'button' }, 10000);
|
||||
await driver.waitUntilXWindowHandles(2);
|
||||
await driver.switchToWindow(extension);
|
||||
@ -327,9 +328,9 @@ describe('Send ETH from dapp using advanced gas controls', function () {
|
||||
await txValue.click();
|
||||
const gasPrice = await driver.waitForSelector({
|
||||
css: '[data-testid="transaction-breakdown__gas-price"]',
|
||||
text: '10',
|
||||
text: '100',
|
||||
});
|
||||
assert.equal(await gasPrice.getText(), '10');
|
||||
assert.equal(await gasPrice.getText(), '100');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
@ -1,6 +1,8 @@
|
||||
import React, { useContext } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { isEIP1559Network } from '../../../ducks/metamask/metamask';
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import Typography from '../../ui/typography/typography';
|
||||
import {
|
||||
@ -37,6 +39,7 @@ export default function AdvancedGasControls({
|
||||
networkSupportsEIP1559,
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
const networkSupports1559 = useSelector(isEIP1559Network);
|
||||
|
||||
const suggestedValues = {};
|
||||
|
||||
@ -60,7 +63,10 @@ export default function AdvancedGasControls({
|
||||
}
|
||||
}
|
||||
|
||||
const showFeeMarketFields = networkSupportsEIP1559;
|
||||
const showFeeMarketFields =
|
||||
networkSupports1559 &&
|
||||
(gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET ||
|
||||
gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE);
|
||||
|
||||
return (
|
||||
<div className="advanced-gas-controls">
|
||||
|
@ -42,12 +42,12 @@ export default function EditGasPopover({
|
||||
const t = useContext(I18nContext);
|
||||
const dispatch = useDispatch();
|
||||
const showSidebar = useSelector((state) => state.appState.sidebar.isOpen);
|
||||
const supportsEIP1559 = useSelector(isEIP1559Network);
|
||||
const networkSupports1559 = useSelector(isEIP1559Network);
|
||||
|
||||
const shouldAnimate = useShouldAnimateGasEstimations();
|
||||
|
||||
const showEducationButton =
|
||||
mode === EDIT_GAS_MODES.MODIFY_IN_PLACE && process.env.SHOW_EIP_1559_UI;
|
||||
mode === EDIT_GAS_MODES.MODIFY_IN_PLACE && networkSupports1559;
|
||||
const [showEducationContent, setShowEducationContent] = useState(false);
|
||||
|
||||
const [warning] = useState(null);
|
||||
@ -109,7 +109,7 @@ export default function EditGasPopover({
|
||||
closePopover();
|
||||
}
|
||||
|
||||
const newGasSettings = supportsEIP1559
|
||||
const newGasSettings = networkSupports1559
|
||||
? {
|
||||
gas: decimalToHex(gasLimit),
|
||||
gasLimit: decimalToHex(gasLimit),
|
||||
@ -144,7 +144,7 @@ export default function EditGasPopover({
|
||||
break;
|
||||
case EDIT_GAS_MODES.SWAPS:
|
||||
// This popover component should only be used for the "FEE_MARKET" type in Swaps.
|
||||
if (supportsEIP1559) {
|
||||
if (networkSupports1559) {
|
||||
dispatch(updateCustomSwapsEIP1559GasParams(newGasSettings));
|
||||
}
|
||||
break;
|
||||
@ -162,7 +162,7 @@ export default function EditGasPopover({
|
||||
gasPrice,
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
supportsEIP1559,
|
||||
networkSupports1559,
|
||||
]);
|
||||
|
||||
let title = t('editGasTitle');
|
||||
@ -177,7 +177,6 @@ export default function EditGasPopover({
|
||||
}
|
||||
|
||||
const footerButtonText = confirmButtonText || t('save');
|
||||
|
||||
return (
|
||||
<Popover
|
||||
title={title}
|
||||
@ -205,7 +204,9 @@ export default function EditGasPopover({
|
||||
<EditGasDisplayEducation />
|
||||
) : (
|
||||
<>
|
||||
<LoadingHeartBeat active={shouldAnimate} />
|
||||
{process.env.IN_TEST === 'true' ? null : (
|
||||
<LoadingHeartBeat active={shouldAnimate} />
|
||||
)}
|
||||
<EditGasDisplay
|
||||
showEducationButton={showEducationButton}
|
||||
warning={warning}
|
||||
|
@ -247,11 +247,36 @@ const MODALS = {
|
||||
},
|
||||
|
||||
CUSTOMIZE_GAS: {
|
||||
contents: process.env.SHOW_EIP_1559_UI ? (
|
||||
<EditGasPopover />
|
||||
) : (
|
||||
<ConfirmCustomizeGasModal />
|
||||
),
|
||||
contents: <EditGasPopover />,
|
||||
mobileModalStyle: {
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
top: '0',
|
||||
transform: 'none',
|
||||
left: '0',
|
||||
right: '0',
|
||||
margin: '0 auto',
|
||||
},
|
||||
laptopModalStyle: {
|
||||
width: 'auto',
|
||||
height: '0px',
|
||||
top: '80px',
|
||||
left: '0px',
|
||||
transform: 'none',
|
||||
margin: '0 auto',
|
||||
position: 'relative',
|
||||
},
|
||||
contentStyle: {
|
||||
borderRadius: '8px',
|
||||
},
|
||||
customOnHideOpts: {
|
||||
action: resetCustomGasData,
|
||||
args: [],
|
||||
},
|
||||
},
|
||||
|
||||
LEGACY_CUSTOMIZE_GAS: {
|
||||
contents: <ConfirmCustomizeGasModal />,
|
||||
mobileModalStyle: {
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
|
@ -31,7 +31,7 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
baseFee: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
priorityFee: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
hexGasTotal: PropTypes.string,
|
||||
supportsEIP1559: PropTypes.bool,
|
||||
isEIP1559Transaction: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@ -54,7 +54,7 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
baseFee,
|
||||
priorityFee,
|
||||
hexGasTotal,
|
||||
supportsEIP1559,
|
||||
isEIP1559Transaction,
|
||||
} = this.props;
|
||||
return (
|
||||
<div className={classnames('transaction-breakdown', className)}>
|
||||
@ -98,7 +98,7 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
/>
|
||||
</TransactionBreakdownRow>
|
||||
)}
|
||||
{process.env.SHOW_EIP_1559_UI && supportsEIP1559 && (
|
||||
{isEIP1559Transaction && (
|
||||
<TransactionBreakdownRow title={t('transactionHistoryBaseFee')}>
|
||||
{typeof baseFee === 'undefined' ? (
|
||||
'?'
|
||||
@ -115,7 +115,7 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
)}
|
||||
</TransactionBreakdownRow>
|
||||
)}
|
||||
{process.env.SHOW_EIP_1559_UI && supportsEIP1559 && (
|
||||
{isEIP1559Transaction && (
|
||||
<TransactionBreakdownRow title={t('transactionHistoryPriorityFee')}>
|
||||
{typeof priorityFee === 'undefined' ? (
|
||||
'?'
|
||||
@ -132,7 +132,7 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
)}
|
||||
</TransactionBreakdownRow>
|
||||
)}
|
||||
{(!process.env.SHOW_EIP_1559_UI || !supportsEIP1559) && (
|
||||
{!isEIP1559Transaction && (
|
||||
<TransactionBreakdownRow title={t('advancedGasPriceTitle')}>
|
||||
{typeof gasPrice === 'undefined' ? (
|
||||
'?'
|
||||
@ -148,7 +148,7 @@ export default class TransactionBreakdown extends PureComponent {
|
||||
)}
|
||||
</TransactionBreakdownRow>
|
||||
)}
|
||||
{process.env.SHOW_EIP_1559_UI && supportsEIP1559 && (
|
||||
{isEIP1559Transaction && (
|
||||
<TransactionBreakdownRow
|
||||
title={t('transactionHistoryEffectiveGasPrice')}
|
||||
>
|
||||
|
@ -1,12 +1,10 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { getShouldShowFiat } from '../../../selectors';
|
||||
import {
|
||||
getNativeCurrency,
|
||||
isEIP1559Network,
|
||||
} from '../../../ducks/metamask/metamask';
|
||||
import { getNativeCurrency } from '../../../ducks/metamask/metamask';
|
||||
import { getHexGasTotal } from '../../../helpers/utils/confirm-tx.util';
|
||||
import { subtractHexes } from '../../../helpers/utils/conversions.util';
|
||||
import { sumHexes } from '../../../helpers/utils/transactions.util';
|
||||
import { isEIP1559Transaction } from '../../../../shared/modules/transaction.utils';
|
||||
import TransactionBreakdown from './transaction-breakdown.component';
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
@ -37,8 +35,6 @@ const mapStateToProps = (state, ownProps) => {
|
||||
'0x0';
|
||||
const totalInHex = sumHexes(hexGasTotal, value);
|
||||
|
||||
const supportsEIP1559 = isEIP1559Network(state);
|
||||
|
||||
return {
|
||||
nativeCurrency: getNativeCurrency(state),
|
||||
showFiat: getShouldShowFiat(state),
|
||||
@ -47,11 +43,10 @@ const mapStateToProps = (state, ownProps) => {
|
||||
gasPrice,
|
||||
gasUsed,
|
||||
isTokenApprove,
|
||||
effectiveGasPrice,
|
||||
hexGasTotal,
|
||||
priorityFee,
|
||||
baseFee: baseFeePerGas,
|
||||
supportsEIP1559,
|
||||
isEIP1559Transaction: isEIP1559Transaction(transaction),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -13,7 +13,9 @@ export default function TransactionDetail({ rows = [], onEdit }) {
|
||||
|
||||
return (
|
||||
<div className="transaction-detail">
|
||||
<LoadingHeartBeat active={shouldAnimate} />
|
||||
{process.env.IN_TEST === 'true' ? null : (
|
||||
<LoadingHeartBeat active={shouldAnimate} />
|
||||
)}
|
||||
{onEdit && (
|
||||
<div className="transaction-detail-edit">
|
||||
<button onClick={onEdit}>{t('edit')}</button>
|
||||
|
@ -210,14 +210,14 @@ export default function TransactionListItem({
|
||||
cancelDisabled={!cancelEnabled}
|
||||
/>
|
||||
)}
|
||||
{process.env.SHOW_EIP_1559_UI && showRetryEditGasPopover && (
|
||||
{showRetryEditGasPopover && (
|
||||
<EditGasPopover
|
||||
onClose={closeRetryEditGasPopover}
|
||||
mode={EDIT_GAS_MODES.SPEED_UP}
|
||||
transaction={transactionGroup.primaryTransaction}
|
||||
/>
|
||||
)}
|
||||
{process.env.SHOW_EIP_1559_UI && showCancelEditGasPopover && (
|
||||
{showCancelEditGasPopover && (
|
||||
<EditGasPopover
|
||||
onClose={closeCancelEditGasPopover}
|
||||
mode={EDIT_GAS_MODES.CANCEL}
|
||||
|
@ -1,13 +1,9 @@
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useCallback, useState } from 'react';
|
||||
import { showModal, showSidebar } from '../store/actions';
|
||||
import { isBalanceSufficient } from '../pages/send/send.utils';
|
||||
import { getSelectedAccount, getIsMainnet } from '../selectors';
|
||||
import { getSelectedAccount } from '../selectors';
|
||||
import { getConversionRate } from '../ducks/metamask/metamask';
|
||||
|
||||
import { setCustomGasLimit, setCustomGasPrice } from '../ducks/gas/gas.duck';
|
||||
import { GAS_LIMITS } from '../../shared/constants/gas';
|
||||
import { isLegacyTransaction } from '../../shared/modules/transaction.utils';
|
||||
import { getMaximumGasTotalInHexWei } from '../../shared/modules/gas.utils';
|
||||
import { useIncrementedGasFees } from './useIncrementedGasFees';
|
||||
|
||||
@ -26,11 +22,8 @@ export function useCancelTransaction(transactionGroup) {
|
||||
|
||||
const customGasSettings = useIncrementedGasFees(transactionGroup);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const selectedAccount = useSelector(getSelectedAccount);
|
||||
const conversionRate = useSelector(getConversionRate);
|
||||
const isMainnet = useSelector(getIsMainnet);
|
||||
const hideBasic = !(isMainnet || process.env.IN_TEST);
|
||||
|
||||
const [showCancelEditGasPopover, setShowCancelEditGasPopover] = useState(
|
||||
false,
|
||||
@ -38,53 +31,10 @@ export function useCancelTransaction(transactionGroup) {
|
||||
|
||||
const closeCancelEditGasPopover = () => setShowCancelEditGasPopover(false);
|
||||
|
||||
const cancelTransaction = useCallback(
|
||||
(event) => {
|
||||
event.stopPropagation();
|
||||
if (process.env.SHOW_EIP_1559_UI) {
|
||||
return setShowCancelEditGasPopover(true);
|
||||
}
|
||||
if (isLegacyTransaction(primaryTransaction)) {
|
||||
// To support the current process of cancelling or speeding up
|
||||
// a transaction, we have to inform the custom gas state of the new
|
||||
// gasPrice/gasLimit to start at.
|
||||
dispatch(setCustomGasPrice(customGasSettings.gasPrice));
|
||||
dispatch(setCustomGasLimit(GAS_LIMITS.SIMPLE));
|
||||
}
|
||||
const tx = {
|
||||
...primaryTransaction,
|
||||
txParams: {
|
||||
...primaryTransaction.txParams,
|
||||
gas: GAS_LIMITS.SIMPLE,
|
||||
value: '0x0',
|
||||
},
|
||||
};
|
||||
return dispatch(
|
||||
showSidebar({
|
||||
transitionName: 'sidebar-left',
|
||||
type: 'customize-gas',
|
||||
props: {
|
||||
hideBasic,
|
||||
transaction: tx,
|
||||
onSubmit: (newGasSettings) => {
|
||||
const userCustomizedGasTotal = getMaximumGasTotalInHexWei(
|
||||
newGasSettings,
|
||||
);
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'CANCEL_TRANSACTION',
|
||||
newGasFee: userCustomizedGasTotal,
|
||||
transactionId: primaryTransaction.id,
|
||||
customGasSettings: newGasSettings,
|
||||
}),
|
||||
);
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
},
|
||||
[dispatch, primaryTransaction, customGasSettings, hideBasic],
|
||||
);
|
||||
const cancelTransaction = useCallback((event) => {
|
||||
event.stopPropagation();
|
||||
return setShowCancelEditGasPopover(true);
|
||||
}, []);
|
||||
|
||||
const hasEnoughCancelGas =
|
||||
primaryTransaction.txParams &&
|
||||
|
@ -3,10 +3,7 @@ import { renderHook } from '@testing-library/react-hooks';
|
||||
import sinon from 'sinon';
|
||||
import transactions from '../../test/data/transaction-data.json';
|
||||
import { getConversionRate, getSelectedAccount } from '../selectors';
|
||||
import { showModal } from '../store/actions';
|
||||
import { increaseLastGasPrice } from '../helpers/utils/confirm-tx.util';
|
||||
import * as actionConstants from '../store/actionConstants';
|
||||
import { GAS_LIMITS } from '../../shared/constants/gas';
|
||||
import { useCancelTransaction } from './useCancelTransaction';
|
||||
|
||||
describe('useCancelTransaction', function () {
|
||||
@ -61,42 +58,6 @@ describe('useCancelTransaction', function () {
|
||||
expect(typeof result.current[1].cancelTransaction).toStrictEqual(
|
||||
'function',
|
||||
);
|
||||
result.current[1].cancelTransaction({
|
||||
preventDefault: () => undefined,
|
||||
stopPropagation: () => undefined,
|
||||
});
|
||||
const dispatchAction = dispatch.args;
|
||||
|
||||
// calls customize-gas sidebar
|
||||
// also check type= customize-gas
|
||||
expect(dispatchAction[dispatchAction.length - 1][0].type).toStrictEqual(
|
||||
actionConstants.SIDEBAR_OPEN,
|
||||
);
|
||||
|
||||
expect(
|
||||
dispatchAction[dispatchAction.length - 1][0].value.props.transaction
|
||||
.id,
|
||||
).toStrictEqual(transactionId);
|
||||
|
||||
// call onSubmit myself
|
||||
dispatchAction[dispatchAction.length - 1][0].value.props.onSubmit({
|
||||
gasLimit: GAS_LIMITS.SIMPLE,
|
||||
gasPrice: '0x1',
|
||||
});
|
||||
|
||||
expect(
|
||||
dispatch.calledWith(
|
||||
showModal({
|
||||
name: 'CANCEL_TRANSACTION',
|
||||
transactionId,
|
||||
newGasFee: GAS_LIMITS.SIMPLE,
|
||||
customGasSettings: {
|
||||
gasPrice: '0x1',
|
||||
gasLimit: GAS_LIMITS.SIMPLE,
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toStrictEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -132,45 +93,13 @@ describe('useCancelTransaction', function () {
|
||||
);
|
||||
expect(result.current[0]).toStrictEqual(true);
|
||||
});
|
||||
it(`should return a function that opens the gas sidebar onsubmit kicks off cancellation for id ${transactionId}`, function () {
|
||||
it(`should return a function that opens the gas popover onsubmit kicks off cancellation for id ${transactionId}`, function () {
|
||||
const { result } = renderHook(() =>
|
||||
useCancelTransaction(transactionGroup),
|
||||
);
|
||||
expect(typeof result.current[1].cancelTransaction).toStrictEqual(
|
||||
'function',
|
||||
);
|
||||
result.current[1].cancelTransaction({
|
||||
preventDefault: () => undefined,
|
||||
stopPropagation: () => undefined,
|
||||
});
|
||||
const dispatchAction = dispatch.args;
|
||||
|
||||
expect(dispatchAction[dispatchAction.length - 1][0].type).toStrictEqual(
|
||||
actionConstants.SIDEBAR_OPEN,
|
||||
);
|
||||
expect(
|
||||
dispatchAction[dispatchAction.length - 1][0].value.props.transaction
|
||||
.id,
|
||||
).toStrictEqual(transactionId);
|
||||
|
||||
dispatchAction[dispatchAction.length - 1][0].value.props.onSubmit({
|
||||
gasLimit: GAS_LIMITS.SIMPLE,
|
||||
gasPrice: '0x1',
|
||||
});
|
||||
|
||||
expect(
|
||||
dispatch.calledWith(
|
||||
showModal({
|
||||
name: 'CANCEL_TRANSACTION',
|
||||
transactionId,
|
||||
newGasFee: GAS_LIMITS.SIMPLE,
|
||||
customGasSettings: {
|
||||
gasPrice: '0x1',
|
||||
gasLimit: GAS_LIMITS.SIMPLE,
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toStrictEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -107,10 +107,11 @@ function getMatchingEstimateFromGasFees(
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
gasPrice,
|
||||
supportsEIP1559,
|
||||
) {
|
||||
return (
|
||||
findKey(gasFeeEstimates, (estimate) => {
|
||||
if (process.env.SHOW_EIP_1559_UI) {
|
||||
if (supportsEIP1559) {
|
||||
return (
|
||||
Number(estimate?.suggestedMaxPriorityFeePerGas) ===
|
||||
Number(maxPriorityFeePerGas) &&
|
||||
@ -180,6 +181,7 @@ export function useGasFeeInputs(
|
||||
// default our fiat values to empty strings if showing fiat is not wanted or
|
||||
// possible.
|
||||
const showFiat = useSelector(getShouldShowFiat);
|
||||
const supportsEIP1559 = useSelector(isEIP1559Network);
|
||||
|
||||
// We need to know the current network's currency and its decimal precision
|
||||
// to calculate the amount to display to the user.
|
||||
@ -235,6 +237,7 @@ export function useGasFeeInputs(
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
gasPrice,
|
||||
supportsEIP1559,
|
||||
)
|
||||
: defaultEstimateToUse,
|
||||
);
|
||||
|
@ -1,12 +1,5 @@
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
import { useCallback, useState } from 'react';
|
||||
import { showSidebar } from '../store/actions';
|
||||
import { setCustomGasLimit, setCustomGasPrice } from '../ducks/gas/gas.duck';
|
||||
import { getIsMainnet } from '../selectors';
|
||||
import { isLegacyTransaction } from '../../shared/modules/transaction.utils';
|
||||
import { useMetricEvent } from './useMetricEvent';
|
||||
import { useIncrementedGasFees } from './useIncrementedGasFees';
|
||||
|
||||
/**
|
||||
* @typedef {Object} RetryTransactionReturnValue
|
||||
@ -22,12 +15,7 @@ import { useIncrementedGasFees } from './useIncrementedGasFees';
|
||||
* @param {Object} transactionGroup - the transaction group
|
||||
* @return {RetryTransactionReturnValue}
|
||||
*/
|
||||
export function useRetryTransaction(transactionGroup) {
|
||||
const { primaryTransaction } = transactionGroup;
|
||||
const isMainnet = useSelector(getIsMainnet);
|
||||
|
||||
const hideBasic = !(isMainnet || process.env.IN_TEST);
|
||||
const customGasSettings = useIncrementedGasFees(transactionGroup);
|
||||
export function useRetryTransaction() {
|
||||
const trackMetricsEvent = useMetricEvent({
|
||||
eventOpts: {
|
||||
category: 'Navigation',
|
||||
@ -35,7 +23,6 @@ export function useRetryTransaction(transactionGroup) {
|
||||
name: 'Clicked "Speed Up"',
|
||||
},
|
||||
});
|
||||
const dispatch = useDispatch();
|
||||
const [showRetryEditGasPopover, setShowRetryEditGasPopover] = useState(false);
|
||||
|
||||
const closeRetryEditGasPopover = () => setShowRetryEditGasPopover(false);
|
||||
@ -43,35 +30,10 @@ export function useRetryTransaction(transactionGroup) {
|
||||
const retryTransaction = useCallback(
|
||||
async (event) => {
|
||||
event.stopPropagation();
|
||||
|
||||
setShowRetryEditGasPopover(true);
|
||||
trackMetricsEvent();
|
||||
if (process.env.SHOW_EIP_1559_UI) {
|
||||
setShowRetryEditGasPopover(true);
|
||||
} else {
|
||||
if (isLegacyTransaction(primaryTransaction)) {
|
||||
// To support the current process of cancelling or speeding up
|
||||
// a transaction, we have to inform the custom gas state of the new
|
||||
// gasPrice to start at.
|
||||
dispatch(setCustomGasPrice(customGasSettings.gasPrice));
|
||||
dispatch(setCustomGasLimit(primaryTransaction.txParams.gas));
|
||||
}
|
||||
|
||||
dispatch(
|
||||
showSidebar({
|
||||
transitionName: 'sidebar-left',
|
||||
type: 'customize-gas',
|
||||
props: { transaction: primaryTransaction, hideBasic },
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
[
|
||||
dispatch,
|
||||
trackMetricsEvent,
|
||||
customGasSettings,
|
||||
primaryTransaction,
|
||||
hideBasic,
|
||||
],
|
||||
[trackMetricsEvent],
|
||||
);
|
||||
|
||||
return {
|
||||
|
@ -1,8 +1,7 @@
|
||||
import * as reactRedux from 'react-redux';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
import sinon from 'sinon';
|
||||
import transactions from '../../test/data/transaction-data.json';
|
||||
import { showSidebar } from '../store/actions';
|
||||
import { getIsMainnet } from '../selectors';
|
||||
import * as methodDataHook from './useMethodData';
|
||||
import * as metricEventHook from './useMetricEvent';
|
||||
@ -58,74 +57,21 @@ describe('useRetryTransaction', () => {
|
||||
useRetryTransaction(retryEnabledTransaction, true),
|
||||
);
|
||||
const { retryTransaction } = result.current;
|
||||
retryTransaction(event);
|
||||
act(() => {
|
||||
retryTransaction(event);
|
||||
});
|
||||
expect(trackEvent.calledOnce).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('retryTransaction function should show retry sidebar', async () => {
|
||||
it('retryTransaction function should show retry popover', async () => {
|
||||
const { result } = renderHook(() =>
|
||||
useRetryTransaction(retryEnabledTransaction, true),
|
||||
);
|
||||
const { retryTransaction } = result.current;
|
||||
await retryTransaction(event);
|
||||
expect(
|
||||
dispatch.calledWith(
|
||||
showSidebar({
|
||||
transitionName: 'sidebar-left',
|
||||
type: 'customize-gas',
|
||||
props: {
|
||||
transaction: retryEnabledTransaction.initialTransaction,
|
||||
hideBasic: false,
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toStrictEqual(true);
|
||||
});
|
||||
|
||||
it('should handle cancelled or multiple speedup transactions', async () => {
|
||||
const cancelledTransaction = {
|
||||
initialTransaction: {
|
||||
...transactions[0].initialTransaction,
|
||||
txParams: {
|
||||
...transactions[0].initialTransaction.txParams,
|
||||
},
|
||||
},
|
||||
primaryTransaction: {
|
||||
...transactions[0].primaryTransaction,
|
||||
txParams: {
|
||||
from: '0xee014609ef9e09776ac5fe00bdbfef57bcdefebb',
|
||||
gas: '0x5308',
|
||||
gasPrice: '0x77359400',
|
||||
nonce: '0x3',
|
||||
to: '0xabca64466f257793eaa52fcfff5066894b76a149',
|
||||
value: '0x0',
|
||||
},
|
||||
},
|
||||
transactions: [
|
||||
{
|
||||
submittedTime: new Date() - 5001,
|
||||
},
|
||||
],
|
||||
hasRetried: false,
|
||||
};
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useRetryTransaction(cancelledTransaction, true),
|
||||
);
|
||||
const { retryTransaction } = result.current;
|
||||
await retryTransaction(event);
|
||||
expect(
|
||||
dispatch.calledWith(
|
||||
showSidebar({
|
||||
transitionName: 'sidebar-left',
|
||||
type: 'customize-gas',
|
||||
props: {
|
||||
transaction: cancelledTransaction.primaryTransaction,
|
||||
hideBasic: false,
|
||||
},
|
||||
}),
|
||||
),
|
||||
).toStrictEqual(true);
|
||||
await act(async () => {
|
||||
await retryTransaction(event);
|
||||
});
|
||||
expect(result.current.showRetryEditGasPopover).toStrictEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -14,7 +14,11 @@ import {
|
||||
getTokenValueParam,
|
||||
} from '../../helpers/utils/token-util';
|
||||
import { useTokenTracker } from '../../hooks/useTokenTracker';
|
||||
import { getTokens, getNativeCurrency } from '../../ducks/metamask/metamask';
|
||||
import {
|
||||
getTokens,
|
||||
getNativeCurrency,
|
||||
isEIP1559Network,
|
||||
} from '../../ducks/metamask/metamask';
|
||||
import {
|
||||
transactionFeeSelector,
|
||||
txDataSelector,
|
||||
@ -49,6 +53,7 @@ export default function ConfirmApprove() {
|
||||
const useNonceField = useSelector(getUseNonceField);
|
||||
const nextNonce = useSelector(getNextSuggestedNonce);
|
||||
const customNonceValue = useSelector(getCustomNonceValue);
|
||||
const onEIP1559Network = useSelector(isEIP1559Network);
|
||||
|
||||
const transaction =
|
||||
currentNetworkTxList.find(
|
||||
@ -145,7 +150,9 @@ export default function ConfirmApprove() {
|
||||
showCustomizeGasModal={() =>
|
||||
dispatch(
|
||||
showModal({
|
||||
name: 'CUSTOMIZE_GAS',
|
||||
name: onEIP1559Network
|
||||
? 'CUSTOMIZE_GAS'
|
||||
: 'LEGACY_CUSTOMIZE_GAS',
|
||||
txData,
|
||||
hideBasic,
|
||||
}),
|
||||
|
@ -2,9 +2,7 @@ import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ENVIRONMENT_TYPE_NOTIFICATION } from '../../../shared/constants/app';
|
||||
import { getEnvironmentType } from '../../../app/scripts/lib/util';
|
||||
import ConfirmPageContainer, {
|
||||
ConfirmDetailRow,
|
||||
} from '../../components/app/confirm-page-container';
|
||||
import ConfirmPageContainer from '../../components/app/confirm-page-container';
|
||||
import { isBalanceSufficient } from '../send/send.utils';
|
||||
import { getHexGasTotal } from '../../helpers/utils/confirm-tx.util';
|
||||
import { addHexes, hexToDecimal } from '../../helpers/utils/conversions.util';
|
||||
@ -22,15 +20,12 @@ import {
|
||||
import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display';
|
||||
import { PRIMARY, SECONDARY } from '../../helpers/constants/common';
|
||||
|
||||
import AdvancedGasInputs from '../../components/app/gas-customization/advanced-gas-inputs';
|
||||
import TextField from '../../components/ui/text-field';
|
||||
import AdvancedGasControls from '../../components/app/advanced-gas-controls';
|
||||
import {
|
||||
TRANSACTION_TYPES,
|
||||
TRANSACTION_STATUSES,
|
||||
} from '../../../shared/constants/transaction';
|
||||
import { getTransactionTypeTitle } from '../../helpers/utils/transactions.util';
|
||||
import ErrorMessage from '../../components/ui/error-message';
|
||||
import { toBuffer } from '../../../shared/modules/buffer-utils';
|
||||
|
||||
import TransactionDetail from '../../components/app/transaction-detail/transaction-detail.component';
|
||||
@ -72,7 +67,6 @@ export default class ConfirmTransactionBase extends Component {
|
||||
updateCustomNonce: PropTypes.func,
|
||||
assetImage: PropTypes.string,
|
||||
sendTransaction: PropTypes.func,
|
||||
showCustomizeGasModal: PropTypes.func,
|
||||
showTransactionConfirmedModal: PropTypes.func,
|
||||
showRejectTransactionsConfirmationModal: PropTypes.func,
|
||||
toAddress: PropTypes.string,
|
||||
@ -85,26 +79,17 @@ export default class ConfirmTransactionBase extends Component {
|
||||
txData: PropTypes.object,
|
||||
unapprovedTxCount: PropTypes.number,
|
||||
currentNetworkUnapprovedTxs: PropTypes.object,
|
||||
updateGasAndCalculate: PropTypes.func,
|
||||
customGas: PropTypes.object,
|
||||
// Component props
|
||||
actionKey: PropTypes.string,
|
||||
contentComponent: PropTypes.node,
|
||||
dataComponent: PropTypes.node,
|
||||
primaryTotalTextOverride: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.node,
|
||||
]),
|
||||
secondaryTotalTextOverride: PropTypes.string,
|
||||
hideData: PropTypes.bool,
|
||||
hideSubtitle: PropTypes.bool,
|
||||
identiconAddress: PropTypes.string,
|
||||
onEdit: PropTypes.func,
|
||||
subtitleComponent: PropTypes.node,
|
||||
title: PropTypes.string,
|
||||
advancedInlineGasShown: PropTypes.bool,
|
||||
insufficientBalance: PropTypes.bool,
|
||||
hideFiatConversion: PropTypes.bool,
|
||||
type: PropTypes.string,
|
||||
getNextNonce: PropTypes.func,
|
||||
nextNonce: PropTypes.number,
|
||||
@ -112,10 +97,11 @@ export default class ConfirmTransactionBase extends Component {
|
||||
hideSenderToRecipient: PropTypes.bool,
|
||||
showAccountInHeader: PropTypes.bool,
|
||||
mostRecentOverviewPage: PropTypes.string.isRequired,
|
||||
isMainnet: PropTypes.bool,
|
||||
isEthGasPrice: PropTypes.bool,
|
||||
noGasPrice: PropTypes.bool,
|
||||
setDefaultHomeActiveTabName: PropTypes.func,
|
||||
primaryTotalTextOverride: PropTypes.string,
|
||||
secondaryTotalTextOverride: PropTypes.string,
|
||||
};
|
||||
|
||||
state = {
|
||||
@ -248,7 +234,6 @@ export default class ConfirmTransactionBase extends Component {
|
||||
|
||||
handleEditGas() {
|
||||
const {
|
||||
showCustomizeGasModal,
|
||||
actionKey,
|
||||
txData: { origin },
|
||||
methodData = {},
|
||||
@ -270,16 +255,10 @@ export default class ConfirmTransactionBase extends Component {
|
||||
},
|
||||
});
|
||||
|
||||
if (process.env.SHOW_EIP_1559_UI) {
|
||||
this.setState({ editingGas: true });
|
||||
} else {
|
||||
showCustomizeGasModal();
|
||||
}
|
||||
this.setState({ editingGas: true });
|
||||
}
|
||||
|
||||
// TODO: rename this 'handleCloseEditGas' later when we remove the
|
||||
// SHOW_EIP_1559_UI flag/branch
|
||||
handleCloseNewGasPopover() {
|
||||
handleCloseEditGas() {
|
||||
this.setState({ editingGas: false });
|
||||
}
|
||||
|
||||
@ -292,16 +271,8 @@ export default class ConfirmTransactionBase extends Component {
|
||||
useNonceField,
|
||||
customNonceValue,
|
||||
updateCustomNonce,
|
||||
advancedInlineGasShown,
|
||||
customGas,
|
||||
insufficientBalance,
|
||||
updateGasAndCalculate,
|
||||
hideFiatConversion,
|
||||
nextNonce,
|
||||
getNextNonce,
|
||||
isMainnet,
|
||||
isEthGasPrice,
|
||||
noGasPrice,
|
||||
txData,
|
||||
} = this.props;
|
||||
const { t } = this.context;
|
||||
@ -314,27 +285,6 @@ export default class ConfirmTransactionBase extends Component {
|
||||
}
|
||||
};
|
||||
|
||||
const notMainnetOrTest = !(isMainnet || process.env.IN_TEST);
|
||||
const gasPriceFetchFailure = isEthGasPrice || noGasPrice;
|
||||
|
||||
const inlineGasControls = process.env.SHOW_EIP_1559_UI ? (
|
||||
<AdvancedGasControls />
|
||||
) : (
|
||||
<AdvancedGasInputs
|
||||
updateCustomGasPrice={(newGasPrice) =>
|
||||
updateGasAndCalculate({ ...customGas, gasPrice: newGasPrice })
|
||||
}
|
||||
updateCustomGasLimit={(newGasLimit) =>
|
||||
updateGasAndCalculate({ ...customGas, gasLimit: newGasLimit })
|
||||
}
|
||||
customGasPrice={customGas.gasPrice}
|
||||
customGasLimit={customGas.gasLimit}
|
||||
insufficientBalance={insufficientBalance}
|
||||
customPriceIsSafe
|
||||
isSpeedUp={false}
|
||||
/>
|
||||
);
|
||||
|
||||
const nonceField = useNonceField ? (
|
||||
<div>
|
||||
<div className="confirm-detail-row">
|
||||
@ -365,180 +315,126 @@ export default class ConfirmTransactionBase extends Component {
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
const showInlineControls = process.env.SHOW_EIP_1559_UI
|
||||
? advancedInlineGasShown
|
||||
: advancedInlineGasShown || notMainnetOrTest || gasPriceFetchFailure;
|
||||
|
||||
const showGasEditButton = process.env.SHOW_EIP_1559_UI
|
||||
? !showInlineControls
|
||||
: !(notMainnetOrTest || gasPriceFetchFailure);
|
||||
|
||||
if (process.env.SHOW_EIP_1559_UI) {
|
||||
return (
|
||||
<div className="confirm-page-container-content__details">
|
||||
<TransactionDetail
|
||||
onEdit={() => this.handleEditGas()}
|
||||
rows={[
|
||||
<TransactionDetailItem
|
||||
key="gas-item"
|
||||
detailTitle={
|
||||
txData.dappSuggestedGasFees ? (
|
||||
<>
|
||||
{t('transactionDetailDappGasHeading', [
|
||||
getRequestingOrigin(),
|
||||
])}
|
||||
<InfoTooltip
|
||||
contentText={t('transactionDetailDappGasTooltip')}
|
||||
position="top"
|
||||
iconFillColor="#f66a0a"
|
||||
>
|
||||
<i className="fa fa-info-circle" />
|
||||
</InfoTooltip>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{t('transactionDetailGasHeading')}
|
||||
<InfoTooltip
|
||||
contentText={
|
||||
<>
|
||||
<p>{t('transactionDetailGasTooltipIntro')}</p>
|
||||
<p>{t('transactionDetailGasTooltipExplanation')}</p>
|
||||
<p>
|
||||
<a
|
||||
href="https://community.metamask.io/t/what-is-gas-why-do-transactions-take-so-long/3172"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t('transactionDetailGasTooltipConversion')}
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
position="top"
|
||||
>
|
||||
<i className="fa fa-info-circle" />
|
||||
</InfoTooltip>
|
||||
</>
|
||||
)
|
||||
}
|
||||
detailTitleColor={
|
||||
txData.dappSuggestedGasFees ? COLORS.SECONDARY1 : COLORS.BLACK
|
||||
}
|
||||
detailText={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={PRIMARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel={false}
|
||||
/>
|
||||
}
|
||||
detailTotal={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={SECONDARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel
|
||||
/>
|
||||
}
|
||||
subText={t('editGasSubTextFee', [
|
||||
<UserPreferencedCurrencyDisplay
|
||||
key="gas-subtext"
|
||||
type={SECONDARY}
|
||||
value={getHexGasTotal({
|
||||
gasPrice: txData.txParams.maxFeePerGas,
|
||||
gasLimit: txData.txParams.gas,
|
||||
})}
|
||||
hideLabel
|
||||
/>,
|
||||
])}
|
||||
subTitle={
|
||||
<GasTiming
|
||||
maxPriorityFeePerGas={txData.txParams.maxPriorityFeePerGas}
|
||||
maxFeePerGas={txData.txParams.maxFeePerGas}
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
<TransactionDetailItem
|
||||
key="total-item"
|
||||
detailTitle={t('total')}
|
||||
detailText={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={PRIMARY}
|
||||
value={hexTransactionTotal}
|
||||
hideLabel={false}
|
||||
/>
|
||||
}
|
||||
detailTotal={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={SECONDARY}
|
||||
value={hexTransactionTotal}
|
||||
hideLabel
|
||||
/>
|
||||
}
|
||||
subTitle={t('transactionDetailGasTotalSubtitle')}
|
||||
subText={t('editGasSubTextAmount', [
|
||||
<UserPreferencedCurrencyDisplay
|
||||
key="gas-total-subtext"
|
||||
type={SECONDARY}
|
||||
value={addHexes(
|
||||
txData.txParams.value,
|
||||
getHexGasTotal({
|
||||
gasPrice: txData.txParams.maxFeePerGas,
|
||||
gasLimit: txData.txParams.gas,
|
||||
}),
|
||||
)}
|
||||
hideLabel
|
||||
/>,
|
||||
])}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
{nonceField}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="confirm-page-container-content__details">
|
||||
<div className="confirm-page-container-content__gas-fee">
|
||||
<ConfirmDetailRow
|
||||
label={t('gasFee')}
|
||||
value={hexMinimumTransactionFee}
|
||||
headerText={showGasEditButton ? t('edit') : ''}
|
||||
headerTextClassName={
|
||||
showGasEditButton ? 'confirm-detail-row__header-text--edit' : ''
|
||||
}
|
||||
onHeaderClick={
|
||||
showGasEditButton ? () => this.handleEditGas() : null
|
||||
}
|
||||
secondaryText={
|
||||
hideFiatConversion ? t('noConversionRateAvailable') : ''
|
||||
}
|
||||
/>
|
||||
{showInlineControls ? inlineGasControls : null}
|
||||
{noGasPrice ? (
|
||||
<div className="confirm-page-container-content__error-container">
|
||||
<ErrorMessage errorKey={GAS_PRICE_FETCH_FAILURE_ERROR_KEY} />
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div
|
||||
className={
|
||||
useNonceField ? 'confirm-page-container-content__gas-fee' : null
|
||||
}
|
||||
>
|
||||
<ConfirmDetailRow
|
||||
label={t('total')}
|
||||
value={hexTransactionTotal}
|
||||
primaryText={primaryTotalTextOverride}
|
||||
secondaryText={
|
||||
hideFiatConversion
|
||||
? t('noConversionRateAvailable')
|
||||
: secondaryTotalTextOverride
|
||||
}
|
||||
headerText={t('amountGasFee')}
|
||||
headerTextClassName="confirm-detail-row__header-text--total"
|
||||
primaryValueTextColor="#2f9ae0"
|
||||
/>
|
||||
</div>
|
||||
<TransactionDetail
|
||||
onEdit={() => this.handleEditGas()}
|
||||
rows={[
|
||||
<TransactionDetailItem
|
||||
key="gas-item"
|
||||
detailTitle={
|
||||
txData.dappSuggestedGasFees ? (
|
||||
<>
|
||||
{t('transactionDetailDappGasHeading', [
|
||||
getRequestingOrigin(),
|
||||
])}
|
||||
<InfoTooltip
|
||||
contentText={t('transactionDetailDappGasTooltip')}
|
||||
position="top"
|
||||
iconFillColor="#f66a0a"
|
||||
>
|
||||
<i className="fa fa-info-circle" />
|
||||
</InfoTooltip>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{t('transactionDetailGasHeading')}
|
||||
<InfoTooltip
|
||||
contentText={
|
||||
<>
|
||||
<p>{t('transactionDetailGasTooltipIntro')}</p>
|
||||
<p>{t('transactionDetailGasTooltipExplanation')}</p>
|
||||
<p>
|
||||
<a
|
||||
href="https://community.metamask.io/t/what-is-gas-why-do-transactions-take-so-long/3172"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{t('transactionDetailGasTooltipConversion')}
|
||||
</a>
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
position="top"
|
||||
>
|
||||
<i className="fa fa-info-circle" />
|
||||
</InfoTooltip>
|
||||
</>
|
||||
)
|
||||
}
|
||||
detailTitleColor={
|
||||
txData.dappSuggestedGasFees ? COLORS.SECONDARY1 : COLORS.BLACK
|
||||
}
|
||||
detailText={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={PRIMARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel={false}
|
||||
/>
|
||||
}
|
||||
detailTotal={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={SECONDARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel
|
||||
/>
|
||||
}
|
||||
subText={t('editGasSubTextFee', [
|
||||
<UserPreferencedCurrencyDisplay
|
||||
key="gas-subtext"
|
||||
type={SECONDARY}
|
||||
value={getHexGasTotal({
|
||||
gasPrice: txData.txParams.maxFeePerGas,
|
||||
gasLimit: txData.txParams.gas,
|
||||
})}
|
||||
hideLabel
|
||||
/>,
|
||||
])}
|
||||
subTitle={
|
||||
<GasTiming
|
||||
maxPriorityFeePerGas={txData.txParams.maxPriorityFeePerGas}
|
||||
maxFeePerGas={txData.txParams.maxFeePerGas}
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
<TransactionDetailItem
|
||||
key="total-item"
|
||||
detailTitle={primaryTotalTextOverride || t('total')}
|
||||
detailText={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={PRIMARY}
|
||||
value={hexTransactionTotal}
|
||||
hideLabel={false}
|
||||
/>
|
||||
}
|
||||
detailTotal={
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={SECONDARY}
|
||||
value={hexTransactionTotal}
|
||||
hideLabel
|
||||
/>
|
||||
}
|
||||
subTitle={
|
||||
secondaryTotalTextOverride ||
|
||||
t('transactionDetailGasTotalSubtitle')
|
||||
}
|
||||
subText={t('editGasSubTextAmount', [
|
||||
<UserPreferencedCurrencyDisplay
|
||||
key="gas-total-subtext"
|
||||
type={SECONDARY}
|
||||
value={addHexes(
|
||||
txData.txParams.value,
|
||||
getHexGasTotal({
|
||||
gasPrice: txData.txParams.maxFeePerGas,
|
||||
gasLimit: txData.txParams.gas,
|
||||
}),
|
||||
)}
|
||||
hideLabel
|
||||
/>,
|
||||
])}
|
||||
/>,
|
||||
]}
|
||||
/>
|
||||
{nonceField}
|
||||
</div>
|
||||
);
|
||||
@ -924,7 +820,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
origin={txData.origin}
|
||||
ethGasPriceWarning={ethGasPriceWarning}
|
||||
editingGas={editingGas}
|
||||
handleCloseEditGas={() => this.handleCloseNewGasPopover()}
|
||||
handleCloseEditGas={() => this.handleCloseEditGas()}
|
||||
currentTransaction={txData}
|
||||
/>
|
||||
);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { getBasicGasEstimateLoadingStatus } from '../../../../../selectors';
|
||||
import {
|
||||
getSendMaxModeState,
|
||||
isSendFormInvalid,
|
||||
@ -11,7 +10,6 @@ import { useI18nContext } from '../../../../../hooks/useI18nContext';
|
||||
import { useMetricEvent } from '../../../../../hooks/useMetricEvent';
|
||||
|
||||
export default function AmountMaxButton() {
|
||||
const buttonDataLoading = useSelector(getBasicGasEstimateLoadingStatus);
|
||||
const isDraftTransactionInvalid = useSelector(isSendFormInvalid);
|
||||
const maxModeOn = useSelector(getSendMaxModeState);
|
||||
const dispatch = useDispatch();
|
||||
@ -29,9 +27,7 @@ export default function AmountMaxButton() {
|
||||
dispatch(toggleSendMaxMode());
|
||||
};
|
||||
|
||||
const disabled = process.env.SHOW_EIP_1559_UI
|
||||
? isDraftTransactionInvalid
|
||||
: buttonDataLoading || isDraftTransactionInvalid;
|
||||
const disabled = isDraftTransactionInvalid;
|
||||
|
||||
return (
|
||||
<button
|
||||
|
@ -9,9 +9,9 @@ import {
|
||||
UNSENDABLE_ASSET_ERROR_KEY,
|
||||
} from '../../../helpers/constants/error-keys';
|
||||
import SendAmountRow from './send-amount-row';
|
||||
import SendGasRow from './send-gas-row';
|
||||
import SendHexDataRow from './send-hex-data-row';
|
||||
import SendAssetRow from './send-asset-row';
|
||||
import SendGasRow from './send-gas-row';
|
||||
|
||||
export default class SendContent extends Component {
|
||||
static contextTypes = {
|
||||
@ -29,6 +29,7 @@ export default class SendContent extends Component {
|
||||
gasIsExcessive: PropTypes.bool.isRequired,
|
||||
isEthGasPrice: PropTypes.bool,
|
||||
noGasPrice: PropTypes.bool,
|
||||
isEIP1559Network: PropTypes.bool,
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -39,6 +40,7 @@ export default class SendContent extends Component {
|
||||
isEthGasPrice,
|
||||
noGasPrice,
|
||||
isAssetSendable,
|
||||
isEIP1559Network,
|
||||
} = this.props;
|
||||
|
||||
let gasError;
|
||||
@ -57,7 +59,7 @@ export default class SendContent extends Component {
|
||||
{this.maybeRenderAddContact()}
|
||||
<SendAssetRow />
|
||||
<SendAmountRow />
|
||||
{process.env.SHOW_EIP_1559_UI ? null : <SendGasRow />}
|
||||
{!isEIP1559Network && <SendGasRow />}
|
||||
{this.props.showHexData && <SendHexDataRow />}
|
||||
</div>
|
||||
</PageContainerContent>
|
||||
|
@ -5,7 +5,6 @@ import Dialog from '../../../components/ui/dialog';
|
||||
import SendContent from './send-content.component';
|
||||
|
||||
import SendAmountRow from './send-amount-row/send-amount-row.container';
|
||||
import SendGasRow from './send-gas-row/send-gas-row.container';
|
||||
import SendHexDataRow from './send-hex-data-row/send-hex-data-row.container';
|
||||
import SendAssetRow from './send-asset-row/send-asset-row.container';
|
||||
|
||||
@ -15,6 +14,7 @@ describe('SendContent Component', () => {
|
||||
const defaultProps = {
|
||||
showHexData: true,
|
||||
gasIsExcessive: false,
|
||||
isEIP1559Network: true,
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
@ -51,11 +51,8 @@ describe('SendContent Component', () => {
|
||||
expect(
|
||||
PageContainerContentChild.childAt(2).is(SendAmountRow),
|
||||
).toStrictEqual(true);
|
||||
expect(PageContainerContentChild.childAt(3).is(SendGasRow)).toStrictEqual(
|
||||
true,
|
||||
);
|
||||
expect(
|
||||
PageContainerContentChild.childAt(4).is(SendHexDataRow),
|
||||
PageContainerContentChild.childAt(3).is(SendHexDataRow),
|
||||
).toStrictEqual(true);
|
||||
});
|
||||
|
||||
@ -73,9 +70,6 @@ describe('SendContent Component', () => {
|
||||
expect(
|
||||
PageContainerContentChild.childAt(2).is(SendAmountRow),
|
||||
).toStrictEqual(true);
|
||||
expect(PageContainerContentChild.childAt(3).is(SendGasRow)).toStrictEqual(
|
||||
true,
|
||||
);
|
||||
expect(wrapper.find(SendHexDataRow)).toHaveLength(0);
|
||||
});
|
||||
|
||||
@ -93,9 +87,6 @@ describe('SendContent Component', () => {
|
||||
expect(
|
||||
PageContainerContentChild.childAt(1).is(SendAmountRow),
|
||||
).toStrictEqual(true);
|
||||
expect(PageContainerContentChild.childAt(2).is(SendGasRow)).toStrictEqual(
|
||||
true,
|
||||
);
|
||||
expect(wrapper.find(Dialog)).toHaveLength(0);
|
||||
});
|
||||
|
||||
@ -113,9 +104,6 @@ describe('SendContent Component', () => {
|
||||
expect(
|
||||
PageContainerContentChild.childAt(1).is(SendAmountRow),
|
||||
).toStrictEqual(true);
|
||||
expect(PageContainerContentChild.childAt(2).is(SendGasRow)).toStrictEqual(
|
||||
true,
|
||||
);
|
||||
expect(wrapper.find(Dialog)).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
getIsEthGasPriceFetched,
|
||||
getNoGasPriceFetched,
|
||||
} from '../../../selectors';
|
||||
|
||||
import { isEIP1559Network } from '../../../ducks/metamask/metamask';
|
||||
import { getIsAssetSendable, getSendTo } from '../../../ducks/send';
|
||||
|
||||
import * as actions from '../../../store/actions';
|
||||
@ -25,6 +25,7 @@ function mapStateToProps(state) {
|
||||
isEthGasPrice: getIsEthGasPriceFetched(state),
|
||||
noGasPrice: getNoGasPriceFetched(state),
|
||||
to,
|
||||
isEIP1559Network: isEIP1559Network(state),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ export default class SendGasRow extends Component {
|
||||
gasFeeError: PropTypes.bool,
|
||||
gasLoadingError: PropTypes.bool,
|
||||
gasTotal: PropTypes.string,
|
||||
showCustomizeGasModal: PropTypes.func,
|
||||
showLegacyCustomizeGasModal: PropTypes.func,
|
||||
updateGasPrice: PropTypes.func,
|
||||
updateGasLimit: PropTypes.func,
|
||||
gasInputMode: PropTypes.oneOf(Object.values(GAS_INPUT_MODES)),
|
||||
@ -31,7 +31,7 @@ export default class SendGasRow extends Component {
|
||||
|
||||
renderAdvancedOptionsButton() {
|
||||
const { trackEvent } = this.context;
|
||||
const { showCustomizeGasModal } = this.props;
|
||||
const { showLegacyCustomizeGasModal } = this.props;
|
||||
return (
|
||||
<div
|
||||
className="advanced-gas-options-btn"
|
||||
@ -40,7 +40,7 @@ export default class SendGasRow extends Component {
|
||||
category: 'Transactions',
|
||||
event: 'Clicked "Advanced Options"',
|
||||
});
|
||||
showCustomizeGasModal();
|
||||
showLegacyCustomizeGasModal();
|
||||
}}
|
||||
>
|
||||
{this.context.t('advancedOptions')}
|
||||
@ -52,7 +52,6 @@ export default class SendGasRow extends Component {
|
||||
const {
|
||||
gasLoadingError,
|
||||
gasTotal,
|
||||
showCustomizeGasModal,
|
||||
gasPriceButtonGroupProps,
|
||||
gasInputMode,
|
||||
resetGasButtons,
|
||||
@ -89,7 +88,6 @@ export default class SendGasRow extends Component {
|
||||
gasLoadingError={gasLoadingError}
|
||||
gasTotal={gasTotal}
|
||||
onReset={resetGasButtons}
|
||||
onClick={showCustomizeGasModal}
|
||||
/>
|
||||
);
|
||||
const advancedGasInputs = (
|
||||
|
@ -10,6 +10,7 @@ import GasFeeDisplay from './gas-fee-display/gas-fee-display.component';
|
||||
|
||||
const propsMethodSpies = {
|
||||
showCustomizeGasModal: sinon.spy(),
|
||||
showLegacyCustomizeGasModal: sinon.spy(),
|
||||
resetGasButtons: sinon.spy(),
|
||||
};
|
||||
|
||||
@ -27,6 +28,9 @@ describe('SendGasRow Component', () => {
|
||||
gasTotal="mockGasTotal"
|
||||
gasInputMode={GAS_INPUT_MODES.CUSTOM}
|
||||
showCustomizeGasModal={propsMethodSpies.showCustomizeGasModal}
|
||||
showLegacyCustomizeGasModal={
|
||||
propsMethodSpies.showLegacyCustomizeGasModal
|
||||
}
|
||||
resetGasButtons={propsMethodSpies.resetGasButtons}
|
||||
gasPriceButtonGroupProps={{
|
||||
someGasPriceButtonGroupProp: 'foo',
|
||||
@ -104,9 +108,13 @@ describe('SendGasRow Component', () => {
|
||||
const advancedOptionsButton = rendered.childAt(0);
|
||||
expect(advancedOptionsButton.text()).toStrictEqual('advancedOptions_t');
|
||||
|
||||
expect(propsMethodSpies.showCustomizeGasModal.callCount).toStrictEqual(0);
|
||||
expect(
|
||||
propsMethodSpies.showLegacyCustomizeGasModal.callCount,
|
||||
).toStrictEqual(0);
|
||||
advancedOptionsButton.props().onClick();
|
||||
expect(propsMethodSpies.showCustomizeGasModal.callCount).toStrictEqual(1);
|
||||
expect(
|
||||
propsMethodSpies.showLegacyCustomizeGasModal.callCount,
|
||||
).toStrictEqual(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -67,8 +67,8 @@ function mapStateToProps(state) {
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
showCustomizeGasModal: () =>
|
||||
dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })),
|
||||
showLegacyCustomizeGasModal: () =>
|
||||
dispatch(showModal({ name: 'LEGACY_CUSTOMIZE_GAS', hideBasic: true })),
|
||||
updateGasPrice: (gasPrice) => {
|
||||
dispatch(updateGasPrice(gasPrice));
|
||||
dispatch(setCustomGasPrice(gasPrice));
|
||||
|
@ -60,12 +60,12 @@ describe('send-gas-row container', () => {
|
||||
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy);
|
||||
});
|
||||
|
||||
describe('showCustomizeGasModal()', () => {
|
||||
describe('showLegacyCustomizeGasModal()', () => {
|
||||
it('should dispatch an action', () => {
|
||||
mapDispatchToPropsObject.showCustomizeGasModal();
|
||||
mapDispatchToPropsObject.showLegacyCustomizeGasModal();
|
||||
expect(dispatchSpy.calledOnce).toStrictEqual(true);
|
||||
expect(showModal).toHaveBeenCalledWith({
|
||||
name: 'CUSTOMIZE_GAS',
|
||||
name: 'LEGACY_CUSTOMIZE_GAS',
|
||||
hideBasic: true,
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user