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