Edit transaction screen changes for EIP-1559 V2 (#12493)

Edit transaction screen changes for EIP-1559 V2
feature/default_network_editable
Jyoti Puri 3 years ago committed by GitHub
parent e6ae6e09b8
commit 3dfc1cc5f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      app/_locales/en/messages.json
  2. 2
      development/build/scripts.js
  3. 8
      ui/components/app/gas-timing/gas-timing.component.js
  4. 19
      ui/components/app/transaction-detail-item/index.scss
  5. 18
      ui/components/app/transaction-detail/index.scss
  6. 15
      ui/components/ui/i18n-value/i18n-value.component.js
  7. 1
      ui/components/ui/i18n-value/index.js
  8. 3
      ui/components/ui/typography/typography.js
  9. 6
      ui/components/ui/typography/typography.scss
  10. 1
      ui/css/design-system/attributes.scss
  11. 233
      ui/pages/confirm-transaction-base/confirm-transaction-base.component.js
  12. 136
      ui/pages/confirm-transaction-base/gas-details-item/gas-details-item.js
  13. 17
      ui/pages/confirm-transaction-base/gas-details-item/gas-details-item.scss
  14. 41
      ui/pages/confirm-transaction-base/gas-details-item/gas-details-item.test.js
  15. 1
      ui/pages/confirm-transaction-base/gas-details-item/index.js
  16. 1
      ui/pages/pages.scss

@ -2800,6 +2800,12 @@
"transactionDetailGasHeading": {
"message": "Estimated gas fee"
},
"transactionDetailGasHeadingV2": {
"message": "Gas"
},
"transactionDetailGasInfoV2": {
"message": "estimated"
},
"transactionDetailGasTooltipConversion": {
"message": "Learn more about gas fees"
},

@ -34,6 +34,7 @@ const metamaskrc = require('rc')('metamask', {
INFURA_PROD_PROJECT_ID: process.env.INFURA_PROD_PROJECT_ID,
ONBOARDING_V2: process.env.ONBOARDING_V2,
COLLECTIBLES_V1: process.env.COLLECTIBLES_V1,
EIP_1559_V2: process.env.EIP_1559_V2,
SEGMENT_HOST: process.env.SEGMENT_HOST,
SEGMENT_WRITE_KEY: process.env.SEGMENT_WRITE_KEY,
SEGMENT_BETA_WRITE_KEY: process.env.SEGMENT_BETA_WRITE_KEY,
@ -758,6 +759,7 @@ function getEnvironmentVariables({ buildType, devMode, testing }) {
SWAPS_USE_DEV_APIS: process.env.SWAPS_USE_DEV_APIS === '1',
ONBOARDING_V2: metamaskrc.ONBOARDING_V2 === '1',
COLLECTIBLES_V1: metamaskrc.COLLECTIBLES_V1 === '1',
EIP_1559_V2: metamaskrc.EIP_1559_V2 === '1',
};
}

@ -27,6 +27,8 @@ import { GAS_FORM_ERRORS } from '../../../helpers/constants/gas';
// Once we reach this second threshold, we switch to minutes as a unit
const SECOND_CUTOFF = 90;
// eslint-disable-next-line prefer-destructuring
const EIP_1559_V2 = process.env.EIP_1559_V2;
// Shows "seconds" as unit of time if under SECOND_CUTOFF, otherwise "minutes"
const toHumanReadableTime = (milliseconds = 1, t) => {
@ -164,6 +166,12 @@ export default function GasTiming({
toHumanReadableTime(Number(customEstimatedTime?.upperTimeBound), t),
]);
}
}
// code below needs to cleaned-up once EIP_1559_V2 flag is removed
else if (EIP_1559_V2) {
text = t('gasTimingNegative', [
toHumanReadableTime(low.maxWaitTimeEstimate, t),
]);
} else {
text = (
<>

@ -1,5 +1,7 @@
.transaction-detail-item {
color: $ui-4;
padding: 20px 0;
border-bottom: 1px solid $ui-3;
&__row {
display: flex;
@ -36,4 +38,21 @@
.currency-display-component {
display: inline;
}
&:first-of-type {
padding-top: 0;
}
&:last-of-type {
margin-bottom: 20px;
}
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
border-bottom: 0;
}
}

@ -15,22 +15,4 @@
text-transform: uppercase;
}
}
&-rows &-item:first-child {
padding-top: 0;
}
&-item {
padding: 20px 0;
border-bottom: 1px solid $ui-3;
&:first-child {
padding-top: 0;
}
&:last-child {
padding-bottom: 0;
border-bottom: 0;
}
}
}

@ -0,0 +1,15 @@
import PropTypes from 'prop-types';
import { useI18nContext } from '../../../hooks/useI18nContext';
const I18nValue = ({ messageKey, options }) => {
const t = useI18nContext();
return t(messageKey, options);
};
I18nValue.propTypes = {
messageKey: PropTypes.string.isRequired,
options: PropTypes.array,
};
export default I18nValue;

@ -0,0 +1 @@
export { default } from './i18n-value.component';

@ -20,6 +20,7 @@ export default function Typography({
children,
fontWeight = 'normal',
fontStyle = 'normal',
fontSize,
align,
boxProps = {},
margin = [1, 0],
@ -33,6 +34,7 @@ export default function Typography({
{
[`typography--align-${align}`]: Boolean(align),
[`typography--color-${color}`]: Boolean(color),
[`typography--size-${fontSize}`]: Boolean(fontSize),
},
);
@ -67,6 +69,7 @@ Typography.propTypes = {
margin: MultipleSizes,
fontWeight: PropTypes.oneOf(Object.values(FONT_WEIGHT)),
fontStyle: PropTypes.oneOf(Object.values(FONT_STYLE)),
fontSize: PropTypes.string,
tag: PropTypes.oneOf([
'p',
'h1',

@ -32,6 +32,12 @@
}
}
@each $size in design-system.$font-size {
&--size-#{$size} {
font-size: $size;
}
}
@each $alignment in design-system.$text-align {
&--align-#{$alignment} {
text-align: $alignment;

@ -82,3 +82,4 @@ $display: block, grid, flex, inline-block, inline-grid, inline-flex, list-item;
$text-align: left, right, center, justify, end;
$font-weight: bold, normal, 100, 200, 300, 400, 500, 600, 700, 800, 900;
$font-style: normal, italic, oblique;
$font-size: 12px;

@ -52,6 +52,11 @@ import {
import Typography from '../../components/ui/typography/typography';
import { MIN_GAS_LIMIT_DEC } from '../send/send.constants';
import GasDetailsItem from './gas-details-item';
// eslint-disable-next-line prefer-destructuring
const EIP_1559_V2 = process.env.EIP_1559_V2;
const renderHeartBeatIfNotInTest = () =>
process.env.IN_TEST === 'true' ? null : <LoadingHeartBeat />;
@ -408,114 +413,130 @@ export default class ConfirmTransactionBase extends Component {
<TransactionDetail
onEdit={() => this.handleEditGas()}
rows={[
<TransactionDetailItem
key="gas-item"
detailTitle={
txData.dappSuggestedGasFees ? (
<>
{t('transactionDetailGasHeading')}
<InfoTooltip
contentText={t('transactionDetailDappGasTooltip')}
position="top"
>
<i className="fa fa-info-circle" />
</InfoTooltip>
</>
) : (
<>
{t('transactionDetailGasHeading')}
<InfoTooltip
contentText={
<>
<p>
{t('transactionDetailGasTooltipIntro', [
isMainnet ? t('networkNameEthereum') : '',
])}
</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={COLORS.BLACK}
detailText={
<div className="confirm-page-container-content__currency-container">
{renderHeartBeatIfNotInTest()}
<UserPreferencedCurrencyDisplay
type={SECONDARY}
value={hexMinimumTransactionFee}
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
/>
</div>
}
detailTotal={
<div className="confirm-page-container-content__currency-container">
{renderHeartBeatIfNotInTest()}
<UserPreferencedCurrencyDisplay
type={PRIMARY}
value={hexMinimumTransactionFee}
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
/>
</div>
}
subText={t('editGasSubTextFee', [
<b key="editGasSubTextFeeLabel">
{t('editGasSubTextFeeLabel')}
</b>,
<div
key="editGasSubTextFeeValue"
className="confirm-page-container-content__currency-container"
>
{renderHeartBeatIfNotInTest()}
<UserPreferencedCurrencyDisplay
key="editGasSubTextFeeAmount"
type={PRIMARY}
value={hexMaximumTransactionFee}
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
/>
</div>,
])}
subTitle={
<>
{txData.dappSuggestedGasFees ? (
<Typography
variant={TYPOGRAPHY.H7}
fontStyle={FONT_STYLE.ITALIC}
color={COLORS.UI4}
>
{t('transactionDetailDappGasMoreInfo')}
</Typography>
EIP_1559_V2 ? (
<GasDetailsItem
key="gas_details"
hexMaximumTransactionFee={hexMaximumTransactionFee}
hexMinimumTransactionFee={hexMinimumTransactionFee}
isMainnet={isMainnet}
maxFeePerGas={maxFeePerGas}
maxPriorityFeePerGas={maxPriorityFeePerGas}
supportsEIP1559={supportsEIP1559}
txData={txData}
useNativeCurrencyAsPrimaryCurrency={
useNativeCurrencyAsPrimaryCurrency
}
/>
) : (
<TransactionDetailItem
key="gas-item"
detailTitle={
txData.dappSuggestedGasFees ? (
<>
{t('transactionDetailGasHeading')}
<InfoTooltip
contentText={t('transactionDetailDappGasTooltip')}
position="top"
>
<i className="fa fa-info-circle" />
</InfoTooltip>
</>
) : (
''
)}
{supportsEIP1559 && (
<GasTiming
maxPriorityFeePerGas={hexWEIToDecGWEI(
maxPriorityFeePerGas ||
txData.txParams.maxPriorityFeePerGas,
)}
maxFeePerGas={hexWEIToDecGWEI(
maxFeePerGas || txData.txParams.maxFeePerGas,
)}
<>
{t('transactionDetailGasHeading')}
<InfoTooltip
contentText={
<>
<p>
{t('transactionDetailGasTooltipIntro', [
isMainnet ? t('networkNameEthereum') : '',
])}
</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={COLORS.BLACK}
detailText={
<div className="confirm-page-container-content__currency-container">
{renderHeartBeatIfNotInTest()}
<UserPreferencedCurrencyDisplay
type={SECONDARY}
value={hexMinimumTransactionFee}
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
/>
)}
</>
}
/>,
</div>
}
detailTotal={
<div className="confirm-page-container-content__currency-container">
{renderHeartBeatIfNotInTest()}
<UserPreferencedCurrencyDisplay
type={PRIMARY}
value={hexMinimumTransactionFee}
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
/>
</div>
}
subText={t('editGasSubTextFee', [
<b key="editGasSubTextFeeLabel">
{t('editGasSubTextFeeLabel')}
</b>,
<div
key="editGasSubTextFeeValue"
className="confirm-page-container-content__currency-container"
>
{renderHeartBeatIfNotInTest()}
<UserPreferencedCurrencyDisplay
key="editGasSubTextFeeAmount"
type={PRIMARY}
value={hexMaximumTransactionFee}
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
/>
</div>,
])}
subTitle={
<>
{txData.dappSuggestedGasFees ? (
<Typography
variant={TYPOGRAPHY.H7}
fontStyle={FONT_STYLE.ITALIC}
color={COLORS.UI4}
>
{t('transactionDetailDappGasMoreInfo')}
</Typography>
) : (
''
)}
{supportsEIP1559 && (
<GasTiming
maxPriorityFeePerGas={hexWEIToDecGWEI(
maxPriorityFeePerGas ||
txData.txParams.maxPriorityFeePerGas,
)}
maxFeePerGas={hexWEIToDecGWEI(
maxFeePerGas || txData.txParams.maxFeePerGas,
)}
/>
)}
</>
}
/>
),
<TransactionDetailItem
key="total-item"
detailTitle={t('total')}

@ -0,0 +1,136 @@
import React from 'react';
import PropTypes from 'prop-types';
import { COLORS } from '../../../helpers/constants/design-system';
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common';
import { hexWEIToDecGWEI } from '../../../helpers/utils/conversions.util';
import { useI18nContext } from '../../../hooks/useI18nContext';
import Box from '../../../components/ui/box';
import Typography from '../../../components/ui/typography/typography';
import GasTiming from '../../../components/app/gas-timing/gas-timing.component';
import I18nValue from '../../../components/ui/i18n-value';
import InfoTooltip from '../../../components/ui/info-tooltip/info-tooltip';
import LoadingHeartBeat from '../../../components/ui/loading-heartbeat';
import TransactionDetailItem from '../../../components/app/transaction-detail-item/transaction-detail-item.component';
import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display';
const HeartBeat = () =>
process.env.IN_TEST === 'true' ? null : <LoadingHeartBeat />;
const GasDetailItem = ({
hexMaximumTransactionFee,
hexMinimumTransactionFee,
isMainnet,
maxFeePerGas,
maxPriorityFeePerGas,
supportsEIP1559,
txData,
useNativeCurrencyAsPrimaryCurrency,
}) => {
const t = useI18nContext();
return (
<TransactionDetailItem
key="gas-item"
detailTitle={
<Box display="flex">
<Box marginRight={1}>
<I18nValue messageKey="transactionDetailGasHeadingV2" />
</Box>
<span className="gas-details-item__estimate">
(<I18nValue messageKey="transactionDetailGasInfoV2" />)
</span>
<InfoTooltip
contentText={
<>
<Typography fontSize="12px">
{t('transactionDetailGasTooltipIntro', [
isMainnet ? t('networkNameEthereum') : '',
])}
</Typography>
<Typography fontSize="12px">
{t('transactionDetailGasTooltipExplanation')}
</Typography>
<Typography fontSize="12px">
<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>
</Typography>
</>
}
position="top"
/>
</Box>
}
detailTitleColor={COLORS.BLACK}
detailText={
<div className="gas-details-item__currency-container">
<HeartBeat />
<UserPreferencedCurrencyDisplay
type={SECONDARY}
value={hexMinimumTransactionFee}
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
/>
</div>
}
detailTotal={
<div className="gas-details-item__currency-container">
<HeartBeat />
<UserPreferencedCurrencyDisplay
type={PRIMARY}
value={hexMinimumTransactionFee}
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
/>
</div>
}
subText={t('editGasSubTextFee', [
<Box key="editGasSubTextFeeLabel" display="inline-flex">
<Box marginRight={1} className="gas-details-item__gasfee-label">
<I18nValue messageKey="editGasSubTextFeeLabel" />
</Box>
<div
key="editGasSubTextFeeValue"
className="gas-details-item__currency-container"
>
<HeartBeat />
<UserPreferencedCurrencyDisplay
key="editGasSubTextFeeAmount"
type={PRIMARY}
value={hexMaximumTransactionFee}
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
/>
</div>
</Box>,
])}
subTitle={
supportsEIP1559 && (
<GasTiming
maxPriorityFeePerGas={hexWEIToDecGWEI(
maxPriorityFeePerGas || txData.txParams.maxPriorityFeePerGas,
)}
maxFeePerGas={hexWEIToDecGWEI(
maxFeePerGas || txData.txParams.maxFeePerGas,
)}
/>
)
}
/>
);
};
GasDetailItem.propTypes = {
hexMaximumTransactionFee: PropTypes.string,
hexMinimumTransactionFee: PropTypes.string,
isMainnet: PropTypes.bool,
maxFeePerGas: PropTypes.string,
maxPriorityFeePerGas: PropTypes.string,
supportsEIP1559: PropTypes.bool,
txData: PropTypes.object,
useNativeCurrencyAsPrimaryCurrency: PropTypes.bool,
};
export default GasDetailItem;

@ -0,0 +1,17 @@
.gas-details-item {
&__estimate {
font-weight: 400;
font-style: italic;
font-size: 12px;
color: $Grey-500;
line-height: inherit;
}
&__gasfee-label {
font-weight: bold;
}
&__currency-container {
position: relative;
}
}

@ -0,0 +1,41 @@
import React from 'react';
import { screen } from '@testing-library/react';
import { ETH } from '../../../helpers/constants/common';
import { renderWithProvider } from '../../../../test/jest';
import configureStore from '../../../store/store';
import GasDetailsItem from './gas-details-item';
const render = (props) => {
const store = configureStore({
metamask: {
nativeCurrency: ETH,
preferences: {
useNativeCurrencyAsPrimaryCurrency: true,
},
provider: {},
},
});
return renderWithProvider(<GasDetailsItem txData={{}} {...props} />, store);
};
describe('GasDetailsItem', () => {
it('should render label', () => {
render();
expect(screen.queryByText('Gas')).toBeInTheDocument();
expect(screen.queryByText('(estimated)')).toBeInTheDocument();
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
});
it('should render gas fee details', () => {
render({
hexMinimumTransactionFee: '0x1ca62a4f7800',
hexMaximumTransactionFee: '0x290ee75e3d900',
});
expect(screen.queryAllByText('0.000031')).toHaveLength(2);
expect(screen.queryByText('ETH')).toBeInTheDocument();
expect(screen.queryByText('0.000722')).toBeInTheDocument();
});
});

@ -0,0 +1 @@
export { default } from './gas-details-item';

@ -5,6 +5,7 @@
@import 'confirm-approve/index';
@import 'confirm-decrypt-message/confirm-decrypt-message';
@import 'confirm-encryption-public-key/confirm-encryption-public-key';
@import 'confirm-transaction-base/gas-details-item/gas-details-item';
@import 'confirmation/confirmation';
@import 'connected-sites/index';
@import 'connected-accounts/index';

Loading…
Cancel
Save