mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
parent
3a5538bd50
commit
fc41321470
@ -405,8 +405,9 @@ export default class TransactionController extends EventEmitter {
|
||||
* @returns {Promise<object>} resolves with txMeta
|
||||
*/
|
||||
async addTxGasDefaults(txMeta, getCodeResponse) {
|
||||
const eip1559Compatibility = await this.getEIP1559Compatibility();
|
||||
|
||||
const eip1559Compatibility =
|
||||
txMeta.txParams.type !== TRANSACTION_ENVELOPE_TYPES.LEGACY &&
|
||||
(await this.getEIP1559Compatibility());
|
||||
const {
|
||||
gasPrice: defaultGasPrice,
|
||||
maxFeePerGas: defaultMaxFeePerGas,
|
||||
|
@ -525,6 +525,58 @@ describe('Transaction Controller', function () {
|
||||
stub2.restore();
|
||||
});
|
||||
|
||||
it('should not add maxFeePerGas and maxPriorityFeePerGas to type-0 transactions', async function () {
|
||||
const TEST_GASPRICE = '0x12a05f200';
|
||||
|
||||
const stub1 = sinon
|
||||
.stub(txController, 'getEIP1559Compatibility')
|
||||
.returns(true);
|
||||
|
||||
const stub2 = sinon
|
||||
.stub(txController, '_getDefaultGasFees')
|
||||
.callsFake(() => ({ gasPrice: TEST_GASPRICE }));
|
||||
|
||||
txController.txStateManager._addTransactionsToState([
|
||||
{
|
||||
id: 1,
|
||||
status: TRANSACTION_STATUSES.UNAPPROVED,
|
||||
metamaskNetworkId: currentNetworkId,
|
||||
txParams: {
|
||||
to: VALID_ADDRESS,
|
||||
from: VALID_ADDRESS_TWO,
|
||||
type: '0x0',
|
||||
},
|
||||
history: [{}],
|
||||
},
|
||||
]);
|
||||
const txMeta = {
|
||||
id: 1,
|
||||
txParams: {
|
||||
from: '0xc684832530fcbddae4b4230a47e991ddcec2831d',
|
||||
to: '0xc684832530fcbddae4b4230a47e991ddcec2831d',
|
||||
type: '0x0',
|
||||
},
|
||||
history: [{}],
|
||||
};
|
||||
providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' };
|
||||
providerResultStub.eth_estimateGas = '5209';
|
||||
|
||||
const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta);
|
||||
|
||||
assert.equal(
|
||||
txMetaWithDefaults.txParams.maxFeePerGas,
|
||||
undefined,
|
||||
'should not have maxFeePerGas',
|
||||
);
|
||||
assert.equal(
|
||||
txMetaWithDefaults.txParams.maxPriorityFeePerGas,
|
||||
undefined,
|
||||
'should not have max priority fee per gas',
|
||||
);
|
||||
stub1.restore();
|
||||
stub2.restore();
|
||||
});
|
||||
|
||||
it('should not add gasPrice if the fee data is available from the dapp', async function () {
|
||||
const TEST_GASPRICE = '0x12a05f200';
|
||||
const TEST_MAX_FEE_PER_GAS = '0x12a05f200';
|
||||
|
@ -6,7 +6,6 @@ import { I18nContext } from '../../../contexts/i18n';
|
||||
import FormField from '../../ui/form-field';
|
||||
import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas';
|
||||
import { getGasFormErrorText } from '../../../helpers/constants/gas';
|
||||
import { checkNetworkAndAccountSupports1559 } from '../../../selectors';
|
||||
import { getIsGasEstimatesLoading } from '../../../ducks/metamask/metamask';
|
||||
|
||||
export default function AdvancedGasControls({
|
||||
@ -24,15 +23,13 @@ export default function AdvancedGasControls({
|
||||
maxFeeFiat,
|
||||
gasErrors,
|
||||
minimumGasLimit,
|
||||
supportsEIP1559,
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
const networkAndAccountSupport1559 = useSelector(
|
||||
checkNetworkAndAccountSupports1559,
|
||||
);
|
||||
const isGasEstimatesLoading = useSelector(getIsGasEstimatesLoading);
|
||||
|
||||
const showFeeMarketFields =
|
||||
networkAndAccountSupport1559 &&
|
||||
supportsEIP1559 &&
|
||||
(gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET ||
|
||||
gasEstimateType === GAS_ESTIMATE_TYPES.ETH_GASPRICE ||
|
||||
isGasEstimatesLoading);
|
||||
@ -131,4 +128,5 @@ AdvancedGasControls.propTypes = {
|
||||
maxFeeFiat: PropTypes.string,
|
||||
gasErrors: PropTypes.object,
|
||||
minimumGasLimit: PropTypes.string,
|
||||
supportsEIP1559: PropTypes.bool,
|
||||
};
|
||||
|
@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
|
||||
import { GAS_ESTIMATE_TYPES } from '../../../../shared/constants/gas';
|
||||
import { renderWithProvider } from '../../../../test/jest/rendering';
|
||||
|
||||
import AdvancedGasControls from './advanced-gas-controls.component';
|
||||
|
||||
const renderComponent = (props) => {
|
||||
const store = configureMockStore([])({ metamask: { identities: [] } });
|
||||
return renderWithProvider(<AdvancedGasControls {...props} />, store);
|
||||
};
|
||||
|
||||
describe('AdvancedGasControls Component', () => {
|
||||
it('should render correctly', () => {
|
||||
expect(() => {
|
||||
renderComponent();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should not render maxFee and maxPriorityFee inputs if supportsEIP1559 is false', () => {
|
||||
const { queryByText } = renderComponent({ supportsEIP1559: false });
|
||||
expect(queryByText('Gas Limit')).toBeInTheDocument();
|
||||
expect(queryByText('Gas price')).toBeInTheDocument();
|
||||
expect(queryByText('Max fee')).not.toBeInTheDocument();
|
||||
expect(queryByText('Max priority fee')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render maxFee and maxPriorityFee inputs if supportsEIP1559 is true', () => {
|
||||
const { queryByText } = renderComponent({
|
||||
gasEstimateType: GAS_ESTIMATE_TYPES.FEE_MARKET,
|
||||
supportsEIP1559: true,
|
||||
});
|
||||
expect(queryByText('Gas price')).not.toBeInTheDocument();
|
||||
expect(queryByText('Gas Limit')).toBeInTheDocument();
|
||||
expect(queryByText('Max fee')).toBeInTheDocument();
|
||||
expect(queryByText('Max priority fee')).toBeInTheDocument();
|
||||
});
|
||||
});
|
@ -22,6 +22,7 @@ import {
|
||||
FONT_WEIGHT,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { areDappSuggestedAndTxParamGasFeesTheSame } from '../../../helpers/utils/confirm-tx.util';
|
||||
import { isLegacyTransaction } from '../../../helpers/utils/transactions.util';
|
||||
|
||||
import InfoTooltip from '../../ui/info-tooltip';
|
||||
import ErrorMessage from '../../ui/error-message';
|
||||
@ -73,17 +74,15 @@ export default function EditGasDisplay({
|
||||
const scrollRef = useRef(null);
|
||||
|
||||
const isMainnet = useSelector(getIsMainnet);
|
||||
const networkAndAccountSupport1559 = useSelector(
|
||||
checkNetworkAndAccountSupports1559,
|
||||
);
|
||||
const supportsEIP1559 =
|
||||
useSelector(checkNetworkAndAccountSupports1559) &&
|
||||
!isLegacyTransaction(transaction.txParams);
|
||||
const showAdvancedInlineGasIfPossible = useSelector(
|
||||
getAdvancedInlineGasShown,
|
||||
);
|
||||
|
||||
const [showAdvancedForm, setShowAdvancedForm] = useState(
|
||||
!estimateToUse ||
|
||||
estimateToUse === 'custom' ||
|
||||
!networkAndAccountSupport1559,
|
||||
!estimateToUse || estimateToUse === 'custom' || !supportsEIP1559,
|
||||
);
|
||||
const [hideRadioButtons, setHideRadioButtons] = useState(
|
||||
showAdvancedInlineGasIfPossible,
|
||||
@ -109,7 +108,7 @@ export default function EditGasDisplay({
|
||||
(balanceError || estimatesUnavailableWarning) &&
|
||||
(!isGasEstimatesLoading || txParamsHaveBeenCustomized);
|
||||
const radioButtonsEnabled =
|
||||
networkAndAccountSupport1559 &&
|
||||
supportsEIP1559 &&
|
||||
gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET &&
|
||||
!requireDappAcknowledgement;
|
||||
|
||||
@ -163,12 +162,12 @@ export default function EditGasDisplay({
|
||||
)}
|
||||
<TransactionTotalBanner
|
||||
total={
|
||||
(networkAndAccountSupport1559 || isMainnet) && estimatedMinimumFiat
|
||||
(supportsEIP1559 || isMainnet) && estimatedMinimumFiat
|
||||
? `~ ${estimatedMinimumFiat}`
|
||||
: estimatedMinimumNative
|
||||
}
|
||||
detail={
|
||||
networkAndAccountSupport1559 &&
|
||||
supportsEIP1559 &&
|
||||
estimatedMaximumFiat !== undefined && (
|
||||
<>
|
||||
<Typography
|
||||
@ -188,7 +187,8 @@ export default function EditGasDisplay({
|
||||
)
|
||||
}
|
||||
timing={
|
||||
hasGasErrors === false && (
|
||||
hasGasErrors === false &&
|
||||
supportsEIP1559 && (
|
||||
<GasTiming
|
||||
maxFeePerGas={maxFeePerGas}
|
||||
maxPriorityFeePerGas={maxPriorityFeePerGas}
|
||||
@ -281,18 +281,17 @@ export default function EditGasDisplay({
|
||||
gasErrors={gasErrors}
|
||||
onManualChange={onManualChange}
|
||||
minimumGasLimit={minimumGasLimit}
|
||||
supportsEIP1559={supportsEIP1559}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{networkAndAccountSupport1559 &&
|
||||
!requireDappAcknowledgement &&
|
||||
showEducationButton && (
|
||||
<div className="edit-gas-display__education">
|
||||
<button onClick={onEducationClick}>
|
||||
{t('editGasEducationButtonText')}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{supportsEIP1559 && !requireDappAcknowledgement && showEducationButton && (
|
||||
<div className="edit-gas-display__education">
|
||||
<button onClick={onEducationClick}>
|
||||
{t('editGasEducationButtonText')}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<div ref={scrollRef} className="edit-gas-display__scroll-bottom" />
|
||||
</div>
|
||||
);
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
import LoadingHeartBeat from '../../ui/loading-heartbeat';
|
||||
import { checkNetworkAndAccountSupports1559 } from '../../../selectors';
|
||||
import { useIncrementedGasFees } from '../../../hooks/useIncrementedGasFees';
|
||||
import { isLegacyTransaction } from '../../../helpers/utils/transactions.util';
|
||||
|
||||
export default function EditGasPopover({
|
||||
popoverTitle = '',
|
||||
@ -42,9 +43,9 @@ export default function EditGasPopover({
|
||||
}) {
|
||||
const t = useContext(I18nContext);
|
||||
const dispatch = useDispatch();
|
||||
const networkAndAccountSupport1559 = useSelector(
|
||||
checkNetworkAndAccountSupports1559,
|
||||
);
|
||||
const supportsEIP1559 =
|
||||
useSelector(checkNetworkAndAccountSupports1559) &&
|
||||
!isLegacyTransaction(transaction?.txParams);
|
||||
const gasLoadingAnimationIsShowing = useSelector(
|
||||
getGasLoadingAnimationIsShowing,
|
||||
);
|
||||
@ -52,7 +53,7 @@ export default function EditGasPopover({
|
||||
const showEducationButton =
|
||||
(mode === EDIT_GAS_MODES.MODIFY_IN_PLACE ||
|
||||
mode === EDIT_GAS_MODES.SWAPS) &&
|
||||
networkAndAccountSupport1559;
|
||||
supportsEIP1559;
|
||||
const [showEducationContent, setShowEducationContent] = useState(false);
|
||||
|
||||
const [warning] = useState(null);
|
||||
@ -132,7 +133,7 @@ export default function EditGasPopover({
|
||||
closePopover();
|
||||
}
|
||||
|
||||
const newGasSettings = networkAndAccountSupport1559
|
||||
const newGasSettings = supportsEIP1559
|
||||
? {
|
||||
gas: decimalToHex(gasLimit),
|
||||
gasLimit: decimalToHex(gasLimit),
|
||||
@ -149,7 +150,7 @@ export default function EditGasPopover({
|
||||
|
||||
const cleanTransactionParams = { ...updatedTransaction.txParams };
|
||||
|
||||
if (networkAndAccountSupport1559) {
|
||||
if (supportsEIP1559) {
|
||||
delete cleanTransactionParams.gasPrice;
|
||||
}
|
||||
|
||||
@ -182,7 +183,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 (networkAndAccountSupport1559) {
|
||||
if (supportsEIP1559) {
|
||||
dispatch(updateSwapsUserFeeLevel(estimateToUse || 'custom'));
|
||||
dispatch(updateCustomSwapsEIP1559GasParams(newGasSettings));
|
||||
}
|
||||
@ -201,7 +202,7 @@ export default function EditGasPopover({
|
||||
gasPrice,
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
networkAndAccountSupport1559,
|
||||
supportsEIP1559,
|
||||
estimateToUse,
|
||||
estimatedBaseFee,
|
||||
]);
|
||||
|
@ -8,6 +8,7 @@ import {
|
||||
TRANSACTION_TYPES,
|
||||
TRANSACTION_GROUP_STATUSES,
|
||||
TRANSACTION_STATUSES,
|
||||
TRANSACTION_ENVELOPE_TYPES,
|
||||
} from '../../../shared/constants/transaction';
|
||||
import { addCurrencies } from '../../../shared/modules/conversion.utils';
|
||||
import fetchWithCache from './fetch-with-cache';
|
||||
@ -161,6 +162,10 @@ export function sumHexes(...args) {
|
||||
return addHexPrefix(total);
|
||||
}
|
||||
|
||||
export function isLegacyTransaction(txParams) {
|
||||
return txParams.type === TRANSACTION_ENVELOPE_TYPES.LEGACY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a status key for a transaction. Requires parsing the txMeta.txReceipt on top of
|
||||
* txMeta.status because txMeta.status does not reflect on-chain errors.
|
||||
|
@ -2,6 +2,7 @@ import {
|
||||
TRANSACTION_TYPES,
|
||||
TRANSACTION_GROUP_STATUSES,
|
||||
TRANSACTION_STATUSES,
|
||||
TRANSACTION_ENVELOPE_TYPES,
|
||||
} from '../../../shared/constants/transaction';
|
||||
import * as utils from './transactions.util';
|
||||
|
||||
@ -59,4 +60,19 @@ describe('Transactions utils', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isLegacyTransaction', () => {
|
||||
it('should return true if transaction is type-0', () => {
|
||||
expect(
|
||||
utils.isLegacyTransaction({ type: TRANSACTION_ENVELOPE_TYPES.LEGACY }),
|
||||
).toStrictEqual(true);
|
||||
});
|
||||
it('should return false if transaction is not type-0', () => {
|
||||
expect(
|
||||
utils.isLegacyTransaction({
|
||||
type: TRANSACTION_ENVELOPE_TYPES.FEE_MARKET,
|
||||
}),
|
||||
).toStrictEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -37,6 +37,7 @@ import {
|
||||
bnLessThanEqualTo,
|
||||
} from '../helpers/utils/util';
|
||||
import { GAS_FORM_ERRORS } from '../helpers/constants/gas';
|
||||
import { isLegacyTransaction } from '../helpers/utils/transactions.util';
|
||||
|
||||
import { useCurrencyDisplay } from './useCurrencyDisplay';
|
||||
import { useGasFeeEstimates } from './useGasFeeEstimates';
|
||||
@ -155,9 +156,9 @@ export function useGasFeeInputs(
|
||||
editGasMode,
|
||||
) {
|
||||
const { balance: ethBalance } = useSelector(getSelectedAccount);
|
||||
const networkAndAccountSupports1559 = useSelector(
|
||||
checkNetworkAndAccountSupports1559,
|
||||
);
|
||||
const supportsEIP1559 =
|
||||
useSelector(checkNetworkAndAccountSupports1559) &&
|
||||
!isLegacyTransaction(transaction?.txParams);
|
||||
// We need to know whether to show fiat conversions or not, so that we can
|
||||
// default our fiat values to empty strings if showing fiat is not wanted or
|
||||
// possible.
|
||||
@ -188,13 +189,13 @@ export function useGasFeeInputs(
|
||||
} = useGasFeeEstimates();
|
||||
|
||||
const [initialMaxFeePerGas] = useState(
|
||||
networkAndAccountSupports1559 && !transaction?.txParams?.maxFeePerGas
|
||||
supportsEIP1559 && !transaction?.txParams?.maxFeePerGas
|
||||
? Number(hexWEIToDecGWEI(transaction?.txParams?.gasPrice))
|
||||
: Number(hexWEIToDecGWEI(transaction?.txParams?.maxFeePerGas)),
|
||||
);
|
||||
|
||||
const [initialMaxPriorityFeePerGas] = useState(
|
||||
networkAndAccountSupports1559 &&
|
||||
!transaction?.txParams?.maxPriorityFeePerGas
|
||||
supportsEIP1559 && !transaction?.txParams?.maxPriorityFeePerGas
|
||||
? initialMaxFeePerGas
|
||||
: Number(hexWEIToDecGWEI(transaction?.txParams?.maxPriorityFeePerGas)),
|
||||
);
|
||||
@ -277,7 +278,9 @@ export function useGasFeeInputs(
|
||||
);
|
||||
const gasPriceToUse =
|
||||
gasPrice !== null &&
|
||||
(gasPriceHasBeenManuallySet || gasPriceEstimatesHaveNotChanged)
|
||||
(gasPriceHasBeenManuallySet ||
|
||||
gasPriceEstimatesHaveNotChanged ||
|
||||
isLegacyTransaction(transaction?.txParams))
|
||||
? gasPrice
|
||||
: getGasPriceEstimate(
|
||||
gasFeeEstimates,
|
||||
@ -294,7 +297,7 @@ export function useGasFeeInputs(
|
||||
const gasSettings = {
|
||||
gasLimit: decimalToHex(gasLimit),
|
||||
};
|
||||
if (networkAndAccountSupports1559) {
|
||||
if (supportsEIP1559) {
|
||||
gasSettings.maxFeePerGas = maxFeePerGasToUse
|
||||
? decGWEIToHexWEI(maxFeePerGasToUse)
|
||||
: decGWEIToHexWEI(gasPriceToUse || '0');
|
||||
@ -396,7 +399,7 @@ export function useGasFeeInputs(
|
||||
// This ensures these are applied when the api fails to return a fee market type
|
||||
// It is okay if these errors get overwritten below, as those overwrites can only
|
||||
// happen when the estimate api is live.
|
||||
if (networkAndAccountSupports1559) {
|
||||
if (supportsEIP1559) {
|
||||
if (bnLessThanEqualTo(maxPriorityFeePerGasToUse, 0)) {
|
||||
gasErrors.maxPriorityFee = GAS_FORM_ERRORS.MAX_PRIORITY_FEE_BELOW_MINIMUM;
|
||||
} else if (bnGreaterThan(maxPriorityFeePerGasToUse, maxFeePerGasToUse)) {
|
||||
@ -404,67 +407,53 @@ export function useGasFeeInputs(
|
||||
}
|
||||
}
|
||||
|
||||
switch (gasEstimateType) {
|
||||
case GAS_ESTIMATE_TYPES.FEE_MARKET:
|
||||
if (bnLessThanEqualTo(maxPriorityFeePerGasToUse, 0)) {
|
||||
gasErrors.maxPriorityFee =
|
||||
GAS_FORM_ERRORS.MAX_PRIORITY_FEE_BELOW_MINIMUM;
|
||||
} else if (
|
||||
!isGasEstimatesLoading &&
|
||||
bnLessThan(
|
||||
maxPriorityFeePerGasToUse,
|
||||
gasFeeEstimates?.low?.suggestedMaxPriorityFeePerGas,
|
||||
)
|
||||
) {
|
||||
gasWarnings.maxPriorityFee = GAS_FORM_ERRORS.MAX_PRIORITY_FEE_TOO_LOW;
|
||||
} else if (bnGreaterThan(maxPriorityFeePerGasToUse, maxFeePerGasToUse)) {
|
||||
gasErrors.maxFee = GAS_FORM_ERRORS.MAX_FEE_IMBALANCE;
|
||||
} else if (
|
||||
gasFeeEstimates?.high &&
|
||||
bnGreaterThan(
|
||||
maxPriorityFeePerGasToUse,
|
||||
gasFeeEstimates.high.suggestedMaxPriorityFeePerGas *
|
||||
HIGH_FEE_WARNING_MULTIPLIER,
|
||||
)
|
||||
) {
|
||||
gasWarnings.maxPriorityFee =
|
||||
GAS_FORM_ERRORS.MAX_PRIORITY_FEE_HIGH_WARNING;
|
||||
}
|
||||
if (supportsEIP1559 && gasEstimateType === GAS_ESTIMATE_TYPES.FEE_MARKET) {
|
||||
if (bnLessThanEqualTo(maxPriorityFeePerGasToUse, 0)) {
|
||||
gasErrors.maxPriorityFee = GAS_FORM_ERRORS.MAX_PRIORITY_FEE_BELOW_MINIMUM;
|
||||
} else if (
|
||||
!isGasEstimatesLoading &&
|
||||
bnLessThan(
|
||||
maxPriorityFeePerGasToUse,
|
||||
gasFeeEstimates?.low?.suggestedMaxPriorityFeePerGas,
|
||||
)
|
||||
) {
|
||||
gasWarnings.maxPriorityFee = GAS_FORM_ERRORS.MAX_PRIORITY_FEE_TOO_LOW;
|
||||
} else if (bnGreaterThan(maxPriorityFeePerGasToUse, maxFeePerGasToUse)) {
|
||||
gasErrors.maxFee = GAS_FORM_ERRORS.MAX_FEE_IMBALANCE;
|
||||
} else if (
|
||||
gasFeeEstimates?.high &&
|
||||
bnGreaterThan(
|
||||
maxPriorityFeePerGasToUse,
|
||||
gasFeeEstimates.high.suggestedMaxPriorityFeePerGas *
|
||||
HIGH_FEE_WARNING_MULTIPLIER,
|
||||
)
|
||||
) {
|
||||
gasWarnings.maxPriorityFee =
|
||||
GAS_FORM_ERRORS.MAX_PRIORITY_FEE_HIGH_WARNING;
|
||||
}
|
||||
|
||||
if (
|
||||
!isGasEstimatesLoading &&
|
||||
bnLessThan(
|
||||
maxFeePerGasToUse,
|
||||
gasFeeEstimates?.low?.suggestedMaxFeePerGas,
|
||||
)
|
||||
) {
|
||||
gasWarnings.maxFee = GAS_FORM_ERRORS.MAX_FEE_TOO_LOW;
|
||||
} else if (
|
||||
gasFeeEstimates?.high &&
|
||||
bnGreaterThan(
|
||||
maxFeePerGasToUse,
|
||||
gasFeeEstimates.high.suggestedMaxFeePerGas *
|
||||
HIGH_FEE_WARNING_MULTIPLIER,
|
||||
)
|
||||
) {
|
||||
gasWarnings.maxFee = GAS_FORM_ERRORS.MAX_FEE_HIGH_WARNING;
|
||||
}
|
||||
break;
|
||||
case GAS_ESTIMATE_TYPES.LEGACY:
|
||||
case GAS_ESTIMATE_TYPES.ETH_GASPRICE:
|
||||
case GAS_ESTIMATE_TYPES.NONE:
|
||||
if (networkAndAccountSupports1559) {
|
||||
estimatesUnavailableWarning = true;
|
||||
}
|
||||
if (
|
||||
(!networkAndAccountSupports1559 || transaction?.txParams?.gasPrice) &&
|
||||
bnLessThanEqualTo(gasPriceToUse, 0)
|
||||
) {
|
||||
gasErrors.gasPrice = GAS_FORM_ERRORS.GAS_PRICE_TOO_LOW;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (
|
||||
!isGasEstimatesLoading &&
|
||||
bnLessThan(maxFeePerGasToUse, gasFeeEstimates?.low?.suggestedMaxFeePerGas)
|
||||
) {
|
||||
gasWarnings.maxFee = GAS_FORM_ERRORS.MAX_FEE_TOO_LOW;
|
||||
} else if (
|
||||
gasFeeEstimates?.high &&
|
||||
bnGreaterThan(
|
||||
maxFeePerGasToUse,
|
||||
gasFeeEstimates.high.suggestedMaxFeePerGas *
|
||||
HIGH_FEE_WARNING_MULTIPLIER,
|
||||
)
|
||||
) {
|
||||
gasWarnings.maxFee = GAS_FORM_ERRORS.MAX_FEE_HIGH_WARNING;
|
||||
}
|
||||
} else if (supportsEIP1559) {
|
||||
estimatesUnavailableWarning = true;
|
||||
} else if (
|
||||
(!supportsEIP1559 || transaction?.txParams?.gasPrice) &&
|
||||
bnLessThanEqualTo(gasPriceToUse, 0)
|
||||
) {
|
||||
gasErrors.gasPrice = GAS_FORM_ERRORS.GAS_PRICE_TOO_LOW;
|
||||
}
|
||||
|
||||
// Determine if we have any errors which should block submission
|
||||
|
@ -2,6 +2,7 @@ import { act, renderHook } from '@testing-library/react-hooks';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { GAS_ESTIMATE_TYPES } from '../../shared/constants/gas';
|
||||
import { multiplyCurrencies } from '../../shared/modules/conversion.utils';
|
||||
import { TRANSACTION_ENVELOPE_TYPES } from '../../shared/constants/transaction';
|
||||
import {
|
||||
getConversionRate,
|
||||
getNativeCurrency,
|
||||
@ -223,6 +224,31 @@ describe('useGasFeeInputs', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when transaction is type-0', () => {
|
||||
beforeEach(() => {
|
||||
useGasFeeEstimates.mockImplementation(
|
||||
() => FEE_MARKET_ESTIMATE_RETURN_VALUE,
|
||||
);
|
||||
useSelector.mockImplementation(generateUseSelectorRouter());
|
||||
});
|
||||
it('returns gasPrice appropriately, and "0" for EIP1559 fields', () => {
|
||||
const { result } = renderHook(() =>
|
||||
useGasFeeInputs('medium', {
|
||||
txParams: {
|
||||
value: '3782DACE9D90000',
|
||||
gasLimit: '0x5028',
|
||||
gasPrice: '0x5028',
|
||||
type: TRANSACTION_ENVELOPE_TYPES.LEGACY,
|
||||
},
|
||||
}),
|
||||
);
|
||||
expect(result.current.gasPrice).toBe(0.00002052);
|
||||
expect(result.current.maxFeePerGas).toBe('0');
|
||||
expect(result.current.maxPriorityFeePerGas).toBe('0');
|
||||
expect(result.current.hasBlockingGasErrors).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when using EIP 1559 API for estimation', () => {
|
||||
beforeEach(() => {
|
||||
useGasFeeEstimates.mockImplementation(
|
||||
@ -260,7 +286,9 @@ describe('useGasFeeInputs', () => {
|
||||
checkNetworkAndAccountSupports1559Response: true,
|
||||
}),
|
||||
);
|
||||
const { result } = renderHook(() => useGasFeeInputs());
|
||||
const { result } = renderHook(() =>
|
||||
useGasFeeInputs(null, { txParams: {}, userFeeLevel: 'medium' }),
|
||||
);
|
||||
expect(result.current.maxFeePerGas).toBe(
|
||||
FEE_MARKET_ESTIMATE_RETURN_VALUE.gasFeeEstimates.medium
|
||||
.suggestedMaxFeePerGas,
|
||||
|
@ -128,6 +128,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
showLedgerSteps: PropTypes.bool.isRequired,
|
||||
isFirefox: PropTypes.bool.isRequired,
|
||||
nativeCurrency: PropTypes.string,
|
||||
supportsEIP1559: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
@ -309,6 +310,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
isMainnet,
|
||||
showLedgerSteps,
|
||||
isFirefox,
|
||||
supportsEIP1559,
|
||||
} = this.props;
|
||||
const { t } = this.context;
|
||||
|
||||
@ -541,15 +543,17 @@ export default class ConfirmTransactionBase extends Component {
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<GasTiming
|
||||
maxPriorityFeePerGas={hexWEIToDecGWEI(
|
||||
maxPriorityFeePerGas ||
|
||||
txData.txParams.maxPriorityFeePerGas,
|
||||
)}
|
||||
maxFeePerGas={hexWEIToDecGWEI(
|
||||
maxFeePerGas || txData.txParams.maxFeePerGas,
|
||||
)}
|
||||
/>
|
||||
{supportsEIP1559 && (
|
||||
<GasTiming
|
||||
maxPriorityFeePerGas={hexWEIToDecGWEI(
|
||||
maxPriorityFeePerGas ||
|
||||
txData.txParams.maxPriorityFeePerGas,
|
||||
)}
|
||||
maxFeePerGas={hexWEIToDecGWEI(
|
||||
maxFeePerGas || txData.txParams.maxFeePerGas,
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>,
|
||||
|
@ -47,6 +47,7 @@ import {
|
||||
getNativeCurrency,
|
||||
} from '../../ducks/metamask/metamask';
|
||||
import { getGasLoadingAnimationIsShowing } from '../../ducks/app/app';
|
||||
import { isLegacyTransaction } from '../../helpers/utils/transactions.util';
|
||||
import ConfirmTransactionBase from './confirm-transaction-base.component';
|
||||
|
||||
let customNonceValue = '';
|
||||
@ -66,7 +67,6 @@ const mapStateToProps = (state, ownProps) => {
|
||||
} = ownProps;
|
||||
const { id: paramsTransactionId } = params;
|
||||
const isMainnet = getIsMainnet(state);
|
||||
const supportsEIP1599 = checkNetworkAndAccountSupports1559(state);
|
||||
|
||||
const isGasEstimatesLoading = getIsGasEstimatesLoading(state);
|
||||
const gasLoadingAnimationIsShowing = getGasLoadingAnimationIsShowing(state);
|
||||
@ -122,6 +122,8 @@ const mapStateToProps = (state, ownProps) => {
|
||||
const toEns = ensResolutionsByAddress[checksummedAddress] || '';
|
||||
const toNickname = addressBookObject ? addressBookObject.name : '';
|
||||
const transactionStatus = transaction ? transaction.status : '';
|
||||
const supportsEIP1559 =
|
||||
checkNetworkAndAccountSupports1559(state) && !isLegacyTransaction(txParams);
|
||||
|
||||
const {
|
||||
hexTransactionAmount,
|
||||
@ -163,7 +165,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
}
|
||||
customNonceValue = getCustomNonceValue(state);
|
||||
const isEthGasPrice = getIsEthGasPriceFetched(state);
|
||||
const noGasPrice = !supportsEIP1599 && getNoGasPriceFetched(state);
|
||||
const noGasPrice = !supportsEIP1559 && getNoGasPriceFetched(state);
|
||||
const { useNativeCurrencyAsPrimaryCurrency } = getPreferences(state);
|
||||
const gasFeeIsCustom =
|
||||
fullTxData.userFeeLevel === 'custom' ||
|
||||
@ -210,7 +212,7 @@ const mapStateToProps = (state, ownProps) => {
|
||||
isMainnet,
|
||||
isEthGasPrice,
|
||||
noGasPrice,
|
||||
supportsEIP1599,
|
||||
supportsEIP1559,
|
||||
gasIsLoading: isGasEstimatesLoading || gasLoadingAnimationIsShowing,
|
||||
useNativeCurrencyAsPrimaryCurrency,
|
||||
maxFeePerGas: gasEstimationObject.maxFeePerGas,
|
||||
|
Loading…
Reference in New Issue
Block a user