1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Add Max Fee Per Gas to transaction breakdown (#12042)

This comes through in EIP-1559 transactions and so it is helpful to show
this to users.
This commit is contained in:
Elliot Winkler 2021-09-08 12:06:16 -06:00 committed by GitHub
parent 72617d7036
commit a35f22fcdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 39 deletions

View File

@ -2564,10 +2564,13 @@
"message": "Transaction Fee"
},
"transactionHistoryBaseFee": {
"message": "Base fee (GWEI)"
"message": "Base Fee (GWEI)"
},
"transactionHistoryMaxFeePerGas": {
"message": "Max Fee Per Gas"
},
"transactionHistoryPriorityFee": {
"message": "Priority fee (GWEI)"
"message": "Priority Fee (GWEI)"
},
"transactionHistoryTotalGasFee": {
"message": "Total Gas Fee"

View File

@ -13,9 +13,22 @@ export default class TransactionBreakdownRow extends PureComponent {
const { title, children, className } = this.props;
return (
<div className={classnames('transaction-breakdown-row', className)}>
<div className="transaction-breakdown-row__title">{title}</div>
<div className="transaction-breakdown-row__value">{children}</div>
<div
className={classnames('transaction-breakdown-row', className)}
data-testid="transaction-breakdown-row"
>
<div
className="transaction-breakdown-row__title"
data-testid="transaction-breakdown-row-title"
>
{title}
</div>
<div
className="transaction-breakdown-row__value"
data-testid="transaction-breakdown-row-value"
>
{children}
</div>
</div>
);
}

View File

@ -26,6 +26,7 @@ export default class TransactionBreakdown extends PureComponent {
isTokenApprove: PropTypes.bool,
gas: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
gasPrice: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
maxFeePerGas: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
gasUsed: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
totalInHex: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
baseFee: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
@ -43,6 +44,7 @@ export default class TransactionBreakdown extends PureComponent {
const {
gas,
gasPrice,
maxFeePerGas,
primaryCurrency,
className,
nonce,
@ -169,6 +171,25 @@ export default class TransactionBreakdown extends PureComponent {
)}
</TransactionBreakdownRow>
)}
{isEIP1559Transaction && (
<TransactionBreakdownRow title={t('transactionHistoryMaxFeePerGas')}>
<UserPreferencedCurrencyDisplay
className="transaction-breakdown__value"
currency={nativeCurrency}
denomination={ETH}
numberOfDecimals={9}
value={maxFeePerGas}
type={PRIMARY}
/>
{showFiat && (
<UserPreferencedCurrencyDisplay
className="transaction-breakdown__value"
type={SECONDARY}
value={maxFeePerGas}
/>
)}
</TransactionBreakdownRow>
)}
<TransactionBreakdownRow title={t('total')}>
<UserPreferencedCurrencyDisplay
className="transaction-breakdown__value transaction-breakdown__value--eth-total"

View File

@ -1,31 +0,0 @@
import React from 'react';
import { shallow } from 'enzyme';
import { TRANSACTION_STATUSES } from '../../../../shared/constants/transaction';
import { GAS_LIMITS } from '../../../../shared/constants/gas';
import TransactionBreakdown from './transaction-breakdown.component';
describe('TransactionBreakdown Component', () => {
it('should render properly', () => {
const transaction = {
history: [],
id: 1,
status: TRANSACTION_STATUSES.CONFIRMED,
txParams: {
from: '0x1',
gas: GAS_LIMITS.SIMPLE,
gasPrice: '0x3b9aca00',
nonce: '0xa4',
to: '0x2',
value: '0x2386f26fc10000',
},
};
const wrapper = shallow(
<TransactionBreakdown transaction={transaction} className="test-class" />,
{ context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } },
);
expect(wrapper.hasClass('transaction-breakdown')).toStrictEqual(true);
expect(wrapper.hasClass('test-class')).toStrictEqual(true);
});
});

View File

@ -10,7 +10,7 @@ import TransactionBreakdown from './transaction-breakdown.component';
const mapStateToProps = (state, ownProps) => {
const { transaction, isTokenApprove } = ownProps;
const {
txParams: { gas, gasPrice, value } = {},
txParams: { gas, gasPrice, maxFeePerGas, value } = {},
txReceipt: { gasUsed, effectiveGasPrice } = {},
baseFeePerGas,
} = transaction;
@ -41,6 +41,7 @@ const mapStateToProps = (state, ownProps) => {
totalInHex,
gas,
gasPrice,
maxFeePerGas,
gasUsed,
isTokenApprove,
hexGasTotal,

View File

@ -0,0 +1,97 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import { within } from '@testing-library/react';
import { renderWithProvider } from '../../../../test/jest/rendering';
import TransactionBreakdown from '.';
function getActualDataFrom(transactionBreakdownRows) {
return transactionBreakdownRows.map((transactionBreakdownRow) => {
const title = within(transactionBreakdownRow).getByTestId(
'transaction-breakdown-row-title',
);
const value = within(transactionBreakdownRow).getByTestId(
'transaction-breakdown-row-value',
);
return [title.textContent, value.textContent];
});
}
describe('TransactionBreakdown', () => {
const store = configureMockStore()({
metamask: {
nativeCurrency: null,
preferences: {},
provider: {
chainId: null,
},
},
});
describe('with a typical non-EIP-1559 transaction', () => {
it('renders properly', () => {
const { getAllByTestId } = renderWithProvider(
<TransactionBreakdown
nonce="0x1d" // 29
transaction={{
txParams: {
gas: '0xb72a', // 46,890
gasPrice: '0x930c19db', // 2,467,043,803
value: '0x2386f26fc10000', // 10,000,000,000,000,000
},
}}
primaryCurrency="-0.01 ETH"
/>,
store,
);
expect(
getActualDataFrom(getAllByTestId('transaction-breakdown-row')),
).toStrictEqual([
['Nonce', '29'],
['Amount', '-0.01 ETH'],
['Gas Limit (units)', '46890'],
['Gas price', '2.467043803'],
['Total', '0.010116ETH'],
]);
});
});
describe('with a typical EIP-1559 transaction', () => {
it('renders properly', () => {
const { getAllByTestId } = renderWithProvider(
<TransactionBreakdown
nonce="0x1d" // 29
transaction={{
txParams: {
gas: '0xb72a', // 46,890
maxFeePerGas: '0xb2d05e00', // 3,000,000,000
maxPriorityFeePerGas: '0x930c19d4', // 2,467,043,796
value: '0x2386f26fc10000', // 10,000,000,000,000,000
},
txReceipt: {
gasUsed: '7a1c', // 31,260
effectiveGasPrice: '0x930c19db', // 2,467,043,803
},
baseFeePerGas: '0x7', // 7
}}
primaryCurrency="-0.01 ETH"
/>,
store,
);
expect(
getActualDataFrom(getAllByTestId('transaction-breakdown-row')),
).toStrictEqual([
['Nonce', '29'],
['Amount', '-0.01 ETH'],
['Gas Limit (units)', '46890'],
['Gas Used (units)', '31260'],
['Base Fee (GWEI)', '0.000000007'],
['Priority Fee (GWEI)', '2.467043796'],
['Total Gas Fee', '0.000077ETH'],
['Max Fee Per Gas', '0.000000003ETH'],
['Total', '0.010077ETH'],
]);
});
});
});

View File

@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { GWEI } from '../../../helpers/constants/common';
import { ETH, GWEI } from '../../../helpers/constants/common';
import { useCurrencyDisplay } from '../../../hooks/useCurrencyDisplay';
export default function CurrencyDisplay({
@ -53,7 +53,7 @@ CurrencyDisplay.propTypes = {
'className': PropTypes.string,
'currency': PropTypes.string,
'data-testid': PropTypes.string,
'denomination': PropTypes.oneOf([GWEI]),
'denomination': PropTypes.oneOf([GWEI, ETH]),
'displayValue': PropTypes.string,
'hideLabel': PropTypes.bool,
'hideTitle': PropTypes.bool,