mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
New reusable gas-display component (#17976)
This commit is contained in:
parent
ca10a1cdb6
commit
fedd6d4970
@ -17,7 +17,7 @@ import {
|
||||
TextVariant,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import GasDetailsItem from '../gas-details-item/gas-details-item';
|
||||
import { ConfirmGasDisplay } from '../confirm-gas-display';
|
||||
import MultiLayerFeeMessage from '../multilayer-fee-message/multi-layer-fee-message';
|
||||
import { formatCurrency } from '../../../helpers/utils/confirm-tx.util';
|
||||
|
||||
@ -111,7 +111,7 @@ export default function ApproveContentCard({
|
||||
(!isMultiLayerFeeNetwork &&
|
||||
supportsEIP1559 &&
|
||||
!renderSimulationFailureWarning ? (
|
||||
<GasDetailsItem
|
||||
<ConfirmGasDisplay
|
||||
userAcknowledgedGasMissing={userAcknowledgedGasMissing}
|
||||
/>
|
||||
) : (
|
||||
|
@ -0,0 +1,157 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ConfirmGasDisplay should match snapshot 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="transaction-detail-item"
|
||||
>
|
||||
<div
|
||||
class="transaction-detail-item__row"
|
||||
>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-row box--flex-wrap-nowrap box--align-items-center typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
||||
>
|
||||
<div
|
||||
class="box box--display-flex box--flex-direction-row"
|
||||
>
|
||||
<div
|
||||
class="box box--margin-right-1 box--flex-direction-row"
|
||||
>
|
||||
Gas
|
||||
</div>
|
||||
<span
|
||||
class="gas-details-item-title__estimate"
|
||||
>
|
||||
(
|
||||
estimated
|
||||
)
|
||||
</span>
|
||||
<div
|
||||
class="info-tooltip"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
aria-describedby="tippy-tooltip-1"
|
||||
class="info-tooltip__tooltip-container"
|
||||
data-original-title="null"
|
||||
data-tooltipped=""
|
||||
style="display: inline;"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 10 10"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M5 0C2.2 0 0 2.2 0 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 2c.4 0 .7.3.7.7s-.3.7-.7.7-.7-.2-.7-.6.3-.8.7-.8zm.7 6H4.3V4.3h1.5V8z"
|
||||
fill="var(--color-icon-alternative)"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
<div
|
||||
class="transaction-detail-item__detail-values"
|
||||
>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
|
||||
>
|
||||
<div
|
||||
class="gas-details-item__currency-container"
|
||||
>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0"
|
||||
>
|
||||
<span
|
||||
class="currency-display-component__prefix"
|
||||
/>
|
||||
<span
|
||||
class="currency-display-component__text"
|
||||
>
|
||||
0
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--margin-left-1 box--flex-direction-row box--text-align-right typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
||||
>
|
||||
<div
|
||||
class="gas-details-item__currency-container"
|
||||
>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0 ETH"
|
||||
>
|
||||
<span
|
||||
class="currency-display-component__prefix"
|
||||
/>
|
||||
<span
|
||||
class="currency-display-component__text"
|
||||
>
|
||||
0
|
||||
</span>
|
||||
<span
|
||||
class="currency-display-component__suffix"
|
||||
>
|
||||
ETH
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="transaction-detail-item__row"
|
||||
>
|
||||
<div>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography gas-timing gas-timing--positive typography--h7 typography--weight-normal typography--style-normal typography--color-text-default"
|
||||
>
|
||||
Maybe in 1 seconds
|
||||
</h6>
|
||||
</div>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography transaction-detail-item__row-subText typography--h7 typography--weight-normal typography--style-normal typography--align-end typography--color-text-alternative"
|
||||
>
|
||||
<div
|
||||
class="box gas-details-item__gasfee-label box--display-inline-flex box--flex-direction-row"
|
||||
>
|
||||
<div
|
||||
class="box box--margin-right-1 box--flex-direction-row"
|
||||
>
|
||||
<strong>
|
||||
Max fee:
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="gas-details-item__currency-container"
|
||||
>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0 ETH"
|
||||
>
|
||||
<span
|
||||
class="currency-display-component__prefix"
|
||||
/>
|
||||
<span
|
||||
class="currency-display-component__text"
|
||||
>
|
||||
0
|
||||
</span>
|
||||
<span
|
||||
class="currency-display-component__suffix"
|
||||
>
|
||||
ETH
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
43
ui/components/app/confirm-gas-display/confirm-gas-display.js
Normal file
43
ui/components/app/confirm-gas-display/confirm-gas-display.js
Normal file
@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import {
|
||||
checkNetworkAndAccountSupports1559,
|
||||
txDataSelector,
|
||||
} from '../../../selectors';
|
||||
import { isLegacyTransaction } from '../../../helpers/utils/transactions.util';
|
||||
import GasDetailsItem from '../gas-details-item';
|
||||
import { getCurrentDraftTransaction } from '../../../ducks/send';
|
||||
import { TransactionEnvelopeType } from '../../../../shared/constants/transaction';
|
||||
import { ConfirmLegacyGasDisplay } from './confirm-legacy-gas-display';
|
||||
|
||||
const ConfirmGasDisplay = ({ userAcknowledgedGasMissing = false }) => {
|
||||
const { txParams } = useSelector((state) => txDataSelector(state));
|
||||
|
||||
const draftTransaction = useSelector(getCurrentDraftTransaction);
|
||||
const transactionType = draftTransaction?.transactionType;
|
||||
let isLegacyTxn;
|
||||
if (transactionType) {
|
||||
isLegacyTxn = transactionType === TransactionEnvelopeType.legacy;
|
||||
} else {
|
||||
isLegacyTxn = isLegacyTransaction(txParams);
|
||||
}
|
||||
|
||||
const networkAndAccountSupports1559 = useSelector(
|
||||
checkNetworkAndAccountSupports1559,
|
||||
);
|
||||
const supportsEIP1559 = networkAndAccountSupports1559 && !isLegacyTxn;
|
||||
|
||||
return supportsEIP1559 ? (
|
||||
<GasDetailsItem userAcknowledgedGasMissing={userAcknowledgedGasMissing} />
|
||||
) : (
|
||||
<ConfirmLegacyGasDisplay />
|
||||
);
|
||||
};
|
||||
|
||||
ConfirmGasDisplay.propTypes = {
|
||||
userAcknowledgedGasMissing: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default ConfirmGasDisplay;
|
@ -0,0 +1,101 @@
|
||||
import React from 'react';
|
||||
import { screen } from '@testing-library/react';
|
||||
|
||||
import { GasEstimateTypes } from '../../../../shared/constants/gas';
|
||||
import mockEstimates from '../../../../test/data/mock-estimates.json';
|
||||
import mockState from '../../../../test/data/mock-state.json';
|
||||
import { renderWithProvider } from '../../../../test/jest';
|
||||
import configureStore from '../../../store/store';
|
||||
|
||||
import { GasFeeContextProvider } from '../../../contexts/gasFee';
|
||||
import ConfirmGasDisplay from './confirm-gas-display';
|
||||
|
||||
jest.mock('../../../store/actions', () => ({
|
||||
disconnectGasFeeEstimatePoller: jest.fn(),
|
||||
getGasFeeEstimatesAndStartPolling: jest
|
||||
.fn()
|
||||
.mockImplementation(() => Promise.resolve()),
|
||||
addPollingTokenToAppState: jest.fn(),
|
||||
getGasFeeTimeEstimate: jest.fn().mockImplementation(() => Promise.resolve()),
|
||||
}));
|
||||
|
||||
const render = ({ transactionProp = {}, contextProps = {} } = {}) => {
|
||||
const store = configureStore({
|
||||
...mockState,
|
||||
...contextProps,
|
||||
metamask: {
|
||||
...mockState.metamask,
|
||||
accounts: {
|
||||
[mockState.metamask.selectedAddress]: {
|
||||
address: mockState.metamask.selectedAddress,
|
||||
balance: '0x1F4',
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
useNativeCurrencyAsPrimaryCurrency: true,
|
||||
},
|
||||
gasFeeEstimates: mockEstimates[GasEstimateTypes.feeMarket],
|
||||
},
|
||||
});
|
||||
|
||||
return renderWithProvider(
|
||||
<GasFeeContextProvider transaction={transactionProp}>
|
||||
<ConfirmGasDisplay />
|
||||
</GasFeeContextProvider>,
|
||||
store,
|
||||
);
|
||||
};
|
||||
|
||||
describe('ConfirmGasDisplay', () => {
|
||||
it('should match snapshot', async () => {
|
||||
const { container } = render();
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
it('should render gas display labels for EIP1559 transcations', () => {
|
||||
render({
|
||||
transactionProp: {
|
||||
txParams: {
|
||||
gas: '0x5208',
|
||||
maxFeePerGas: '0x59682f10',
|
||||
maxPriorityFeePerGas: '0x59682f00',
|
||||
},
|
||||
userFeeLevel: 'medium',
|
||||
},
|
||||
});
|
||||
expect(screen.queryByText('Gas')).toBeInTheDocument();
|
||||
expect(screen.queryByText('(estimated)')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
|
||||
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
|
||||
});
|
||||
it('should render gas display labels for legacy transcations', () => {
|
||||
render({
|
||||
contextProps: {
|
||||
metamask: {
|
||||
networkDetails: {
|
||||
EIPS: {
|
||||
1559: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
confirmTransaction: {
|
||||
txData: {
|
||||
id: 8393540981007587,
|
||||
status: 'unapproved',
|
||||
chainId: '0x5',
|
||||
txParams: {
|
||||
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813',
|
||||
value: '0x0',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
type: '0x0',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(screen.queryByText('Estimated gas fee')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
|
||||
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
@ -0,0 +1,9 @@
|
||||
import { Story, Canvas, ArgsTable } from '@storybook/addon-docs';
|
||||
import { ConfirmLegacyGasDisplay } from '.';
|
||||
|
||||
# Confirm Legacy Gas Display
|
||||
Confirm Legacy Gas Display is used on confirmation screen and send screen to display gas details for legacy transaction.
|
||||
|
||||
<Canvas>
|
||||
<Story id="components-app-ConfirmLegacyGasDisplay--default-story" />
|
||||
</Canvas>
|
@ -0,0 +1,124 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ConfirmLegacyGasDisplay should match snapshot 1`] = `
|
||||
<div>
|
||||
<div
|
||||
class="transaction-detail-item"
|
||||
>
|
||||
<div
|
||||
class="transaction-detail-item__row"
|
||||
>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--display-flex box--flex-direction-row box--flex-wrap-nowrap box--align-items-center typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
||||
>
|
||||
Estimated gas fee
|
||||
<div
|
||||
class="info-tooltip"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
aria-describedby="tippy-tooltip-1"
|
||||
class="info-tooltip__tooltip-container"
|
||||
data-original-title="null"
|
||||
data-tooltipped=""
|
||||
style="display: inline;"
|
||||
tabindex="0"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 10 10"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M5 0C2.2 0 0 2.2 0 5s2.2 5 5 5 5-2.2 5-5-2.2-5-5-5zm0 2c.4 0 .7.3.7.7s-.3.7-.7.7-.7-.2-.7-.6.3-.8.7-.8zm.7 6H4.3V4.3h1.5V8z"
|
||||
fill="var(--color-icon-alternative)"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
<div
|
||||
class="transaction-detail-item__detail-values"
|
||||
>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography typography--h6 typography--weight-normal typography--style-normal typography--color-text-alternative"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0.000021"
|
||||
>
|
||||
<span
|
||||
class="currency-display-component__prefix"
|
||||
/>
|
||||
<span
|
||||
class="currency-display-component__text"
|
||||
>
|
||||
0.000021
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--margin-left-1 box--flex-direction-row box--text-align-right typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0.000021 ETH"
|
||||
>
|
||||
<span
|
||||
class="currency-display-component__prefix"
|
||||
/>
|
||||
<span
|
||||
class="currency-display-component__text"
|
||||
>
|
||||
0.000021
|
||||
</span>
|
||||
<span
|
||||
class="currency-display-component__suffix"
|
||||
>
|
||||
ETH
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="transaction-detail-item__row"
|
||||
>
|
||||
<div />
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography transaction-detail-item__row-subText typography--h7 typography--weight-normal typography--style-normal typography--align-end typography--color-text-alternative"
|
||||
>
|
||||
<strong>
|
||||
Max fee:
|
||||
</strong>
|
||||
<div>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0.000021 ETH"
|
||||
>
|
||||
<span
|
||||
class="currency-display-component__prefix"
|
||||
/>
|
||||
<span
|
||||
class="currency-display-component__text"
|
||||
>
|
||||
0.000021
|
||||
</span>
|
||||
<span
|
||||
class="currency-display-component__suffix"
|
||||
>
|
||||
ETH
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ConfirmLegacyGasDisplay should match snapshot 2`] = `<div />`;
|
@ -0,0 +1,149 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
import { useI18nContext } from '../../../../hooks/useI18nContext';
|
||||
import {
|
||||
getIsMainnet,
|
||||
getPreferences,
|
||||
getUnapprovedTransactions,
|
||||
getUseCurrencyRateCheck,
|
||||
transactionFeeSelector,
|
||||
txDataSelector,
|
||||
} from '../../../../selectors';
|
||||
import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common';
|
||||
|
||||
import TransactionDetailItem from '../../transaction-detail-item';
|
||||
import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display';
|
||||
import InfoTooltip from '../../../ui/info-tooltip';
|
||||
import LoadingHeartBeat from '../../../ui/loading-heartbeat';
|
||||
import { Text } from '../../../component-library/text';
|
||||
import {
|
||||
FONT_STYLE,
|
||||
TextVariant,
|
||||
TextColor,
|
||||
} from '../../../../helpers/constants/design-system';
|
||||
import { useDraftTransactionGasValues } from '../../../../hooks/useDraftTransactionGasValues';
|
||||
|
||||
const renderHeartBeatIfNotInTest = () =>
|
||||
process.env.IN_TEST ? null : <LoadingHeartBeat />;
|
||||
|
||||
const ConfirmLegacyGasDisplay = () => {
|
||||
const t = useI18nContext();
|
||||
|
||||
// state selectors
|
||||
const isMainnet = useSelector(getIsMainnet);
|
||||
const useCurrencyRateCheck = useSelector(getUseCurrencyRateCheck);
|
||||
const { useNativeCurrencyAsPrimaryCurrency } = useSelector(getPreferences);
|
||||
const unapprovedTxs = useSelector(getUnapprovedTransactions);
|
||||
const { transactionData } = useDraftTransactionGasValues();
|
||||
const txData = useSelector((state) => txDataSelector(state));
|
||||
const { id: transactionId, dappSuggestedGasFees } = txData;
|
||||
const transaction = Object.keys(transactionData).length
|
||||
? transactionData
|
||||
: unapprovedTxs[transactionId] || {};
|
||||
const { hexMinimumTransactionFee, hexMaximumTransactionFee } = useSelector(
|
||||
(state) => transactionFeeSelector(state, transaction),
|
||||
);
|
||||
|
||||
return (
|
||||
<TransactionDetailItem
|
||||
key="legacy-gas-details"
|
||||
detailTitle={
|
||||
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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
detailText={
|
||||
useCurrencyRateCheck && (
|
||||
<div>
|
||||
{renderHeartBeatIfNotInTest()}
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={SECONDARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
detailTotal={
|
||||
<div>
|
||||
{renderHeartBeatIfNotInTest()}
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={PRIMARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||
numberOfDecimals={6}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
subText={
|
||||
<>
|
||||
<strong key="editGasSubTextFeeLabel">
|
||||
{t('editGasSubTextFeeLabel')}
|
||||
</strong>
|
||||
<div key="editGasSubTextFeeValue">
|
||||
{renderHeartBeatIfNotInTest()}
|
||||
<UserPreferencedCurrencyDisplay
|
||||
key="editGasSubTextFeeAmount"
|
||||
type={PRIMARY}
|
||||
value={hexMaximumTransactionFee}
|
||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
subTitle={
|
||||
<>
|
||||
{dappSuggestedGasFees && (
|
||||
<Text
|
||||
variant={TextVariant.bodySm}
|
||||
fontStyle={FONT_STYLE.ITALIC}
|
||||
color={TextColor.textAlternative}
|
||||
as="h6"
|
||||
>
|
||||
{t('transactionDetailDappGasMoreInfo')}
|
||||
</Text>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ConfirmLegacyGasDisplay;
|
@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import mockState from '../../../../../test/data/mock-state.json';
|
||||
import configureStore from '../../../../store/store';
|
||||
|
||||
import README from './README.mdx';
|
||||
import ConfirmLegacyGasDisplay from './confirm-legacy-gas-display';
|
||||
|
||||
const store = configureStore(mockState);
|
||||
|
||||
export default {
|
||||
title: 'Components/App/ConfirmLegacyGasDisplay',
|
||||
|
||||
component: ConfirmLegacyGasDisplay,
|
||||
decorators: [(story) => <Provider store={store}>{story()}</Provider>],
|
||||
parameters: {
|
||||
docs: {
|
||||
page: README,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const DefaultStory = () => {
|
||||
return <ConfirmLegacyGasDisplay />;
|
||||
};
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
@ -0,0 +1,110 @@
|
||||
import React from 'react';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
|
||||
import mockState from '../../../../../test/data/mock-state.json';
|
||||
import { renderWithProvider } from '../../../../../test/jest';
|
||||
import configureStore from '../../../../store/store';
|
||||
|
||||
import ConfirmLegacyGasDisplay from './confirm-legacy-gas-display';
|
||||
|
||||
const render = ({ contextProps } = {}) => {
|
||||
const store = configureStore({
|
||||
...mockState,
|
||||
...contextProps,
|
||||
metamask: {
|
||||
...mockState.metamask,
|
||||
accounts: {
|
||||
[mockState.metamask.selectedAddress]: {
|
||||
address: mockState.metamask.selectedAddress,
|
||||
balance: '0x1F4',
|
||||
},
|
||||
},
|
||||
unapprovedTxs: {
|
||||
8393540981007587: {
|
||||
...mockState.metamask.unapprovedTxs[8393540981007587],
|
||||
txParams: {
|
||||
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813',
|
||||
value: '0x0',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
type: '0x0',
|
||||
},
|
||||
},
|
||||
},
|
||||
preferences: {
|
||||
useNativeCurrencyAsPrimaryCurrency: true,
|
||||
},
|
||||
},
|
||||
confirmTransaction: {
|
||||
txData: {
|
||||
id: 8393540981007587,
|
||||
status: 'unapproved',
|
||||
chainId: '0x5',
|
||||
txParams: {
|
||||
from: '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc',
|
||||
to: '0xc42edfcc21ed14dda456aa0756c153f7985d8813',
|
||||
value: '0x0',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
type: '0x0',
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return renderWithProvider(<ConfirmLegacyGasDisplay />, store);
|
||||
};
|
||||
|
||||
describe('ConfirmLegacyGasDisplay', () => {
|
||||
it('should match snapshot', async () => {
|
||||
const { container } = render();
|
||||
await waitFor(() => {
|
||||
expect(container).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
it('should render label', async () => {
|
||||
render();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Estimated gas fee')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
|
||||
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should render gas fee details', async () => {
|
||||
render();
|
||||
await waitFor(() => {
|
||||
expect(screen.queryAllByTitle('0.000021 ETH').length).toBeGreaterThan(0);
|
||||
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
it('should render label and gas details with draftTransaction', async () => {
|
||||
render({
|
||||
send: {
|
||||
currentTransactionUUID: '1d40b578-6184-4607-8513-762c24d0a19b',
|
||||
draftTransactions: {
|
||||
'1d40b578-6184-4607-8513-762c24d0a19b': {
|
||||
gas: {
|
||||
error: null,
|
||||
gasLimit: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
gasTotal: '0x157c9fbb9a000',
|
||||
maxFeePerGas: '0x0',
|
||||
maxPriorityFeePerGas: '0x0',
|
||||
wasManuallyEdited: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByText('Estimated gas fee')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Max fee:')).toBeInTheDocument();
|
||||
expect(screen.queryAllByText('ETH').length).toBeGreaterThan(0);
|
||||
expect(screen.queryAllByTitle('0.000021 ETH').length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1 @@
|
||||
export { default as ConfirmLegacyGasDisplay } from './confirm-legacy-gas-display';
|
1
ui/components/app/confirm-gas-display/index.js
Normal file
1
ui/components/app/confirm-gas-display/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default as ConfirmGasDisplay } from './confirm-gas-display';
|
@ -5,7 +5,12 @@ import { useSelector } from 'react-redux';
|
||||
|
||||
import { TextColor } from '../../../helpers/constants/design-system';
|
||||
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common';
|
||||
import { getPreferences, getUseCurrencyRateCheck } from '../../../selectors';
|
||||
import {
|
||||
getPreferences,
|
||||
getUseCurrencyRateCheck,
|
||||
transactionFeeSelector,
|
||||
} from '../../../selectors';
|
||||
import { getCurrentDraftTransaction } from '../../../ducks/send';
|
||||
import { useGasFeeContext } from '../../../contexts/gasFee';
|
||||
import { useI18nContext } from '../../../hooks/useI18nContext';
|
||||
|
||||
@ -14,10 +19,20 @@ import LoadingHeartBeat from '../../ui/loading-heartbeat';
|
||||
import GasTiming from '../gas-timing/gas-timing.component';
|
||||
import TransactionDetailItem from '../transaction-detail-item/transaction-detail-item.component';
|
||||
import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display';
|
||||
import { hexWEIToDecGWEI } from '../../../../shared/modules/conversion.utils';
|
||||
import { useDraftTransactionGasValues } from '../../../hooks/useDraftTransactionGasValues';
|
||||
import GasDetailsItemTitle from './gas-details-item-title';
|
||||
|
||||
const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => {
|
||||
const t = useI18nContext();
|
||||
const draftTransaction = useSelector(getCurrentDraftTransaction);
|
||||
const { transactionData } = useDraftTransactionGasValues();
|
||||
|
||||
const {
|
||||
hexMinimumTransactionFee: draftHexMinimumTransactionFee,
|
||||
hexMaximumTransactionFee: draftHexMaximumTransactionFee,
|
||||
} = useSelector((state) => transactionFeeSelector(state, transactionData));
|
||||
|
||||
const {
|
||||
estimateUsed,
|
||||
hasSimulationError,
|
||||
@ -41,7 +56,8 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => {
|
||||
detailTitle={<GasDetailsItemTitle />}
|
||||
detailTitleColor={TextColor.textDefault}
|
||||
detailText={
|
||||
useCurrencyRateCheck && (
|
||||
useCurrencyRateCheck &&
|
||||
Object.keys(draftTransaction).length === 0 && (
|
||||
<div className="gas-details-item__currency-container">
|
||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||
<UserPreferencedCurrencyDisplay
|
||||
@ -57,7 +73,7 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => {
|
||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={PRIMARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
value={hexMinimumTransactionFee || draftHexMinimumTransactionFee}
|
||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||
/>
|
||||
</div>
|
||||
@ -86,7 +102,9 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => {
|
||||
<UserPreferencedCurrencyDisplay
|
||||
key="editGasSubTextFeeAmount"
|
||||
type={PRIMARY}
|
||||
value={hexMaximumTransactionFee}
|
||||
value={
|
||||
hexMaximumTransactionFee || draftHexMaximumTransactionFee
|
||||
}
|
||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||
/>
|
||||
</div>
|
||||
@ -95,8 +113,14 @@ const GasDetailsItem = ({ userAcknowledgedGasMissing = false }) => {
|
||||
}
|
||||
subTitle={
|
||||
<GasTiming
|
||||
maxPriorityFeePerGas={maxPriorityFeePerGas.toString()}
|
||||
maxFeePerGas={maxFeePerGas.toString()}
|
||||
maxPriorityFeePerGas={(
|
||||
maxPriorityFeePerGas ||
|
||||
hexWEIToDecGWEI(transactionData.txParams.maxPriorityFeePerGas)
|
||||
).toString()}
|
||||
maxFeePerGas={(
|
||||
maxFeePerGas ||
|
||||
hexWEIToDecGWEI(transactionData.txParams.maxFeePerGas)
|
||||
).toString()}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
40
ui/hooks/useDraftTransactionGasValues.js
Normal file
40
ui/hooks/useDraftTransactionGasValues.js
Normal file
@ -0,0 +1,40 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { getCurrentDraftTransaction } from '../ducks/send';
|
||||
import { getUnapprovedTransactions } from '../selectors';
|
||||
|
||||
/**
|
||||
* Returns an object that resembles the txData.txParams from the Transactions state.
|
||||
* While processing gas details for send transaction and edit transaction,
|
||||
* the gas data from draftTransaction and unapprovedTx has to be reorganized
|
||||
* to mimic the txdata.txParam from a confirmTransaction
|
||||
*
|
||||
* @returns {Object txData.txParams}
|
||||
*/
|
||||
export const useDraftTransactionGasValues = () => {
|
||||
const draftTransaction = useSelector(getCurrentDraftTransaction);
|
||||
const unapprovedTxs = useSelector(getUnapprovedTransactions);
|
||||
|
||||
let transactionData = {};
|
||||
if (Object.keys(draftTransaction).length !== 0) {
|
||||
const editingTransaction = unapprovedTxs[draftTransaction.id];
|
||||
transactionData = {
|
||||
txParams: {
|
||||
gasPrice: draftTransaction.gas?.gasPrice,
|
||||
gas: editingTransaction?.userEditedGasLimit
|
||||
? editingTransaction?.txParams?.gas
|
||||
: draftTransaction.gas?.gasLimit,
|
||||
maxFeePerGas: editingTransaction?.txParams?.maxFeePerGas
|
||||
? editingTransaction?.txParams?.maxFeePerGas
|
||||
: draftTransaction.gas?.maxFeePerGas,
|
||||
maxPriorityFeePerGas: editingTransaction?.txParams?.maxPriorityFeePerGas
|
||||
? editingTransaction?.txParams?.maxPriorityFeePerGas
|
||||
: draftTransaction.gas?.maxPriorityFeePerGas,
|
||||
value: draftTransaction.amount?.value,
|
||||
type: draftTransaction.transactionType,
|
||||
},
|
||||
userFeeLevel: editingTransaction?.userFeeLevel,
|
||||
};
|
||||
}
|
||||
|
||||
return { transactionData };
|
||||
};
|
@ -23,7 +23,6 @@ import {
|
||||
AlignItems,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { ConfirmPageContainerWarning } from '../../../components/app/confirm-page-container/confirm-page-container-content';
|
||||
import GasDetailsItem from '../../../components/app/gas-details-item';
|
||||
import LedgerInstructionField from '../../../components/app/ledger-instruction-field';
|
||||
import { TokenStandard } from '../../../../shared/constants/transaction';
|
||||
import { CHAIN_IDS, TEST_CHAINS } from '../../../../shared/constants/network';
|
||||
@ -34,6 +33,7 @@ import {
|
||||
} from '../../../components/component-library/icon/deprecated';
|
||||
import { ButtonIcon } from '../../../components/component-library/button-icon/deprecated';
|
||||
import { Text } from '../../../components/component-library';
|
||||
import { ConfirmGasDisplay } from '../../../components/app/confirm-gas-display';
|
||||
|
||||
export default class ConfirmApproveContent extends Component {
|
||||
static contextTypes = {
|
||||
@ -170,7 +170,7 @@ export default class ConfirmApproveContent extends Component {
|
||||
!renderSimulationFailureWarning
|
||||
) {
|
||||
return (
|
||||
<GasDetailsItem
|
||||
<ConfirmGasDisplay
|
||||
userAcknowledgedGasMissing={userAcknowledgedGasMissing}
|
||||
/>
|
||||
);
|
||||
|
@ -374,9 +374,7 @@ exports[`Confirm Transaction Base should match snapshot 1`] = `
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--margin-left-1 box--flex-direction-row box--text-align-right typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
||||
>
|
||||
<div
|
||||
class="confirm-page-container-content__currency-container"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0.000021"
|
||||
@ -397,18 +395,14 @@ exports[`Confirm Transaction Base should match snapshot 1`] = `
|
||||
<div
|
||||
class="transaction-detail-item__row"
|
||||
>
|
||||
<div>
|
||||
|
||||
</div>
|
||||
<div />
|
||||
<h6
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography transaction-detail-item__row-subText typography--h7 typography--weight-normal typography--style-normal typography--align-end typography--color-text-alternative"
|
||||
>
|
||||
<strong>
|
||||
Max fee:
|
||||
</strong>
|
||||
<div
|
||||
class="confirm-page-container-content__currency-container"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
title="0.000021"
|
||||
|
@ -28,18 +28,9 @@ import {
|
||||
import { TransactionModalContextProvider } from '../../contexts/transaction-modal';
|
||||
import TransactionDetail from '../../components/app/transaction-detail/transaction-detail.component';
|
||||
import TransactionDetailItem from '../../components/app/transaction-detail-item/transaction-detail-item.component';
|
||||
import InfoTooltip from '../../components/ui/info-tooltip/info-tooltip';
|
||||
import LoadingHeartBeat from '../../components/ui/loading-heartbeat';
|
||||
import GasDetailsItem from '../../components/app/gas-details-item';
|
||||
import GasTiming from '../../components/app/gas-timing/gas-timing.component';
|
||||
import LedgerInstructionField from '../../components/app/ledger-instruction-field';
|
||||
import MultiLayerFeeMessage from '../../components/app/multilayer-fee-message';
|
||||
import Typography from '../../components/ui/typography/typography';
|
||||
import {
|
||||
TextColor,
|
||||
FONT_STYLE,
|
||||
TypographyVariant,
|
||||
} from '../../helpers/constants/design-system';
|
||||
import {
|
||||
disconnectGasFeeEstimatePoller,
|
||||
getGasFeeEstimatesAndStartPolling,
|
||||
@ -53,16 +44,13 @@ import { NETWORK_TO_NAME_MAP } from '../../../shared/constants/network';
|
||||
import {
|
||||
addHexes,
|
||||
hexToDecimal,
|
||||
hexWEIToDecGWEI,
|
||||
} from '../../../shared/modules/conversion.utils';
|
||||
import TransactionAlerts from '../../components/app/transaction-alerts';
|
||||
import { ConfirmHexData } from '../../components/app/confirm-hexdata';
|
||||
import { ConfirmData } from '../../components/app/confirm-data';
|
||||
import { ConfirmTitle } from '../../components/app/confirm-title';
|
||||
import { ConfirmSubTitle } from '../../components/app/confirm-subtitle';
|
||||
|
||||
const renderHeartBeatIfNotInTest = () =>
|
||||
process.env.IN_TEST ? null : <LoadingHeartBeat />;
|
||||
import { ConfirmGasDisplay } from '../../components/app/confirm-gas-display';
|
||||
|
||||
export default class ConfirmTransactionBase extends Component {
|
||||
static contextTypes = {
|
||||
@ -136,7 +124,6 @@ export default class ConfirmTransactionBase extends Component {
|
||||
maxFeePerGas: PropTypes.string,
|
||||
maxPriorityFeePerGas: PropTypes.string,
|
||||
baseFeePerGas: PropTypes.string,
|
||||
isMainnet: PropTypes.bool,
|
||||
gasFeeIsCustom: PropTypes.bool,
|
||||
showLedgerSteps: PropTypes.bool.isRequired,
|
||||
nativeCurrency: PropTypes.string,
|
||||
@ -319,11 +306,7 @@ export default class ConfirmTransactionBase extends Component {
|
||||
txData,
|
||||
useNativeCurrencyAsPrimaryCurrency,
|
||||
primaryTotalTextOverrideMaxAmount,
|
||||
maxFeePerGas,
|
||||
maxPriorityFeePerGas,
|
||||
isMainnet,
|
||||
showLedgerSteps,
|
||||
supportsEIP1559,
|
||||
isMultiLayerFeeNetwork,
|
||||
nativeCurrency,
|
||||
isBuyableChain,
|
||||
@ -439,128 +422,6 @@ export default class ConfirmTransactionBase extends Component {
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
const renderGasDetailsItem = () => {
|
||||
return this.supportsEIP1559 ? (
|
||||
<GasDetailsItem
|
||||
key="gas_details"
|
||||
userAcknowledgedGasMissing={userAcknowledgedGasMissing}
|
||||
/>
|
||||
) : (
|
||||
<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>
|
||||
</>
|
||||
)
|
||||
}
|
||||
detailText={
|
||||
useCurrencyRateCheck && (
|
||||
<div className="confirm-page-container-content__currency-container test">
|
||||
{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}
|
||||
numberOfDecimals={6}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
subText={
|
||||
<>
|
||||
<strong key="editGasSubTextFeeLabel">
|
||||
{t('editGasSubTextFeeLabel')}
|
||||
</strong>
|
||||
<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={TypographyVariant.H7}
|
||||
fontStyle={FONT_STYLE.ITALIC}
|
||||
color={TextColor.textAlternative}
|
||||
>
|
||||
{t('transactionDetailDappGasMoreInfo')}
|
||||
</Typography>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{supportsEIP1559 && (
|
||||
<GasTiming
|
||||
maxPriorityFeePerGas={hexWEIToDecGWEI(
|
||||
maxPriorityFeePerGas ||
|
||||
txData.txParams.maxPriorityFeePerGas,
|
||||
).toString()}
|
||||
maxFeePerGas={hexWEIToDecGWEI(
|
||||
maxFeePerGas || txData.txParams.maxFeePerGas,
|
||||
).toString()}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const simulationFailureWarning = () => (
|
||||
<div className="confirm-page-container-content__error-container">
|
||||
<SimulationErrorMessage
|
||||
@ -594,9 +455,11 @@ export default class ConfirmTransactionBase extends Component {
|
||||
}
|
||||
rows={[
|
||||
renderSimulationFailureWarning && simulationFailureWarning(),
|
||||
!renderSimulationFailureWarning &&
|
||||
!isMultiLayerFeeNetwork &&
|
||||
renderGasDetailsItem(),
|
||||
!renderSimulationFailureWarning && !isMultiLayerFeeNetwork && (
|
||||
<ConfirmGasDisplay
|
||||
userAcknowledgedGasMissing={userAcknowledgedGasMissing}
|
||||
/>
|
||||
),
|
||||
!renderSimulationFailureWarning && isMultiLayerFeeNetwork && (
|
||||
<MultiLayerFeeMessage
|
||||
transaction={txData}
|
||||
|
@ -23,7 +23,11 @@ setBackgroundConnection({
|
||||
});
|
||||
|
||||
const baseStore = {
|
||||
send: INITIAL_SEND_STATE_FOR_EXISTING_DRAFT,
|
||||
send: {
|
||||
...INITIAL_SEND_STATE_FOR_EXISTING_DRAFT,
|
||||
currentTransactionUUID: null,
|
||||
draftTransactions: {},
|
||||
},
|
||||
DNS: domainInitialState,
|
||||
gas: {
|
||||
customData: { limit: null, price: null },
|
||||
|
@ -1,13 +1,10 @@
|
||||
import React, { useContext } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { I18nContext } from '../../../contexts/i18n';
|
||||
import { useGasFeeContext } from '../../../contexts/gasFee';
|
||||
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common';
|
||||
import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display';
|
||||
import GasTiming from '../../../components/app/gas-timing';
|
||||
import InfoTooltip from '../../../components/ui/info-tooltip';
|
||||
import Typography from '../../../components/ui/typography';
|
||||
import Button from '../../../components/ui/button';
|
||||
import Box from '../../../components/ui/box';
|
||||
@ -16,13 +13,11 @@ import {
|
||||
DISPLAY,
|
||||
FLEX_DIRECTION,
|
||||
BLOCK_SIZES,
|
||||
Color,
|
||||
FONT_STYLE,
|
||||
FONT_WEIGHT,
|
||||
} from '../../../helpers/constants/design-system';
|
||||
import { TokenStandard } from '../../../../shared/constants/transaction';
|
||||
import LoadingHeartBeat from '../../../components/ui/loading-heartbeat';
|
||||
import TransactionDetailItem from '../../../components/app/transaction-detail-item';
|
||||
import { ConfirmGasDisplay } from '../../../components/app/confirm-gas-display';
|
||||
import { NETWORK_TO_NAME_MAP } from '../../../../shared/constants/network';
|
||||
import TransactionDetail from '../../../components/app/transaction-detail';
|
||||
import ActionableMessage from '../../../components/ui/actionable-message';
|
||||
@ -31,7 +26,6 @@ import {
|
||||
getPreferences,
|
||||
getIsBuyableChain,
|
||||
transactionFeeSelector,
|
||||
getIsMainnet,
|
||||
getIsTestnet,
|
||||
getUseCurrencyRateCheck,
|
||||
} from '../../../selectors';
|
||||
@ -43,7 +37,6 @@ import { showModal } from '../../../store/actions';
|
||||
import {
|
||||
addHexes,
|
||||
hexWEIToDecETH,
|
||||
hexWEIToDecGWEI,
|
||||
} from '../../../../shared/modules/conversion.utils';
|
||||
import {
|
||||
MetaMetricsEventCategory,
|
||||
@ -61,7 +54,6 @@ export default function GasDisplay({ gasError }) {
|
||||
const { openBuyCryptoInPdapp } = useRamps();
|
||||
|
||||
const currentProvider = useSelector(getProvider);
|
||||
const isMainnet = useSelector(getIsMainnet);
|
||||
const isTestnet = useSelector(getIsTestnet);
|
||||
const isBuyableChain = useSelector(getIsBuyableChain);
|
||||
const draftTransaction = useSelector(getCurrentDraftTransaction);
|
||||
@ -95,11 +87,9 @@ export default function GasDisplay({ gasError }) {
|
||||
userFeeLevel: editingTransaction?.userFeeLevel,
|
||||
};
|
||||
|
||||
const {
|
||||
hexMinimumTransactionFee,
|
||||
hexMaximumTransactionFee,
|
||||
hexTransactionTotal,
|
||||
} = useSelector((state) => transactionFeeSelector(state, transactionData));
|
||||
const { hexMaximumTransactionFee, hexTransactionTotal } = useSelector(
|
||||
(state) => transactionFeeSelector(state, transactionData),
|
||||
);
|
||||
|
||||
let title;
|
||||
if (
|
||||
@ -158,119 +148,13 @@ export default function GasDisplay({ gasError }) {
|
||||
detailTotal = primaryTotalTextOverrideMaxAmount;
|
||||
maxAmount = primaryTotalTextOverrideMaxAmount;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box className="gas-display">
|
||||
<TransactionDetail
|
||||
userAcknowledgedGasMissing={false}
|
||||
rows={[
|
||||
<TransactionDetailItem
|
||||
key="gas-item"
|
||||
detailTitle={
|
||||
<Box display={DISPLAY.FLEX}>
|
||||
<Box marginRight={1}>{t('gas')}</Box>
|
||||
<Typography
|
||||
as="span"
|
||||
marginTop={0}
|
||||
color={Color.textMuted}
|
||||
fontStyle={FONT_STYLE.ITALIC}
|
||||
fontWeight={FONT_WEIGHT.NORMAL}
|
||||
className="gas-display__title__estimate"
|
||||
>
|
||||
({t('transactionDetailGasInfoV2')})
|
||||
</Typography>
|
||||
<InfoTooltip
|
||||
contentText={
|
||||
<>
|
||||
<Typography variant={TypographyVariant.H7}>
|
||||
{t('transactionDetailGasTooltipIntro', [
|
||||
isMainnet ? t('networkNameEthereum') : '',
|
||||
])}
|
||||
</Typography>
|
||||
<Typography variant={TypographyVariant.H7}>
|
||||
{t('transactionDetailGasTooltipExplanation')}
|
||||
</Typography>
|
||||
<Typography variant={TypographyVariant.H7}>
|
||||
<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="right"
|
||||
/>
|
||||
</Box>
|
||||
}
|
||||
detailTitleColor={Color.textDefault}
|
||||
detailText={
|
||||
showCurrencyRateCheck && (
|
||||
<Box className="gas-display__currency-container">
|
||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={SECONDARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel={Boolean(useNativeCurrencyAsPrimaryCurrency)}
|
||||
/>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
detailTotal={
|
||||
<Box className="gas-display__currency-container">
|
||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||
<UserPreferencedCurrencyDisplay
|
||||
type={PRIMARY}
|
||||
value={hexMinimumTransactionFee}
|
||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||
/>
|
||||
</Box>
|
||||
}
|
||||
subText={
|
||||
<>
|
||||
<Box
|
||||
key="editGasSubTextFeeLabel"
|
||||
display={DISPLAY.INLINE_FLEX}
|
||||
className={classNames('gas-display__gas-fee-label', {
|
||||
'gas-display__gas-fee-warning': estimateUsed === 'high',
|
||||
})}
|
||||
>
|
||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||
<Box marginRight={1}>
|
||||
<strong>
|
||||
{estimateUsed === 'high' && '⚠ '}
|
||||
{t('editGasSubTextFeeLabel')}
|
||||
</strong>
|
||||
</Box>
|
||||
<Box
|
||||
key="editGasSubTextFeeValue"
|
||||
className="gas-display__currency-container"
|
||||
>
|
||||
<LoadingHeartBeat estimateUsed={estimateUsed} />
|
||||
<UserPreferencedCurrencyDisplay
|
||||
key="editGasSubTextFeeAmount"
|
||||
type={PRIMARY}
|
||||
value={hexMaximumTransactionFee}
|
||||
hideLabel={!useNativeCurrencyAsPrimaryCurrency}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
}
|
||||
subTitle={
|
||||
<GasTiming
|
||||
maxPriorityFeePerGas={hexWEIToDecGWEI(
|
||||
draftTransaction.gas.maxPriorityFeePerGas,
|
||||
)}
|
||||
maxFeePerGas={hexWEIToDecGWEI(
|
||||
draftTransaction.gas.maxFeePerGas,
|
||||
)}
|
||||
/>
|
||||
}
|
||||
/>,
|
||||
<ConfirmGasDisplay key="gas-display" />,
|
||||
(gasError || isInsufficientTokenError) && (
|
||||
<TransactionDetailItem
|
||||
key="total-item"
|
||||
|
@ -35,7 +35,6 @@
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
&__currency-container,
|
||||
&__total-amount,
|
||||
&__total-value {
|
||||
position: relative;
|
||||
|
@ -197,7 +197,7 @@ exports[`SendContent Component render should match snapshot 1`] = `
|
||||
Gas
|
||||
</div>
|
||||
<span
|
||||
class="box box--margin-bottom-1 box--flex-direction-row typography gas-display__title__estimate typography--p typography--weight-normal typography--style-italic typography--color-text-muted"
|
||||
class="gas-details-item-title__estimate"
|
||||
>
|
||||
(
|
||||
estimated
|
||||
@ -236,7 +236,7 @@ exports[`SendContent Component render should match snapshot 1`] = `
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--margin-left-1 box--flex-direction-row box--text-align-right typography typography--h6 typography--weight-bold typography--style-normal typography--color-text-default"
|
||||
>
|
||||
<div
|
||||
class="box gas-display__currency-container box--flex-direction-row"
|
||||
class="gas-details-item__currency-container"
|
||||
>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
@ -274,7 +274,7 @@ exports[`SendContent Component render should match snapshot 1`] = `
|
||||
class="box box--margin-top-1 box--margin-bottom-1 box--flex-direction-row typography transaction-detail-item__row-subText typography--h7 typography--weight-normal typography--style-normal typography--align-end typography--color-text-alternative"
|
||||
>
|
||||
<div
|
||||
class="box gas-display__gas-fee-label box--display-inline-flex box--flex-direction-row"
|
||||
class="box gas-details-item__gasfee-label box--display-inline-flex box--flex-direction-row"
|
||||
>
|
||||
<div
|
||||
class="box box--margin-right-1 box--flex-direction-row"
|
||||
@ -284,7 +284,7 @@ exports[`SendContent Component render should match snapshot 1`] = `
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="box gas-display__currency-container box--flex-direction-row"
|
||||
class="gas-details-item__currency-container"
|
||||
>
|
||||
<div
|
||||
class="currency-display-component"
|
||||
|
@ -79,6 +79,9 @@ const state = {
|
||||
confirmTransaction: {
|
||||
txData: {},
|
||||
},
|
||||
send: {
|
||||
draftTransactions: {},
|
||||
},
|
||||
};
|
||||
|
||||
jest.mock('../../store/actions', () => ({
|
||||
|
Loading…
Reference in New Issue
Block a user