mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 01:39:44 +01:00
parent
2c410f534d
commit
a49a40fbbb
@ -10,6 +10,14 @@ import ConfirmPageContainer, {
|
|||||||
ConfirmPageContainerNavigation,
|
ConfirmPageContainerNavigation,
|
||||||
} from '.';
|
} from '.';
|
||||||
|
|
||||||
|
jest.mock('../../../store/actions', () => ({
|
||||||
|
disconnectGasFeeEstimatePoller: jest.fn(),
|
||||||
|
getGasFeeEstimatesAndStartPolling: jest
|
||||||
|
.fn()
|
||||||
|
.mockImplementation(() => Promise.resolve()),
|
||||||
|
addPollingTokenToAppState: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
describe('Confirm Page Container Container Test', () => {
|
describe('Confirm Page Container Container Test', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
|
||||||
@ -31,6 +39,8 @@ describe('Confirm Page Container Container Test', () => {
|
|||||||
selectedAddress: '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5',
|
selectedAddress: '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5',
|
||||||
addressBook: [],
|
addressBook: [],
|
||||||
chainId: 'test',
|
chainId: 'test',
|
||||||
|
identities: [],
|
||||||
|
featureFlags: {},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import SenderToRecipient from '../../ui/sender-to-recipient';
|
|||||||
import { PageContainerFooter } from '../../ui/page-container';
|
import { PageContainerFooter } from '../../ui/page-container';
|
||||||
import EditGasPopover from '../edit-gas-popover';
|
import EditGasPopover from '../edit-gas-popover';
|
||||||
import { EDIT_GAS_MODES } from '../../../../shared/constants/gas';
|
import { EDIT_GAS_MODES } from '../../../../shared/constants/gas';
|
||||||
|
import { GasFeeContextProvider } from '../../../contexts/gasFee';
|
||||||
import ErrorMessage from '../../ui/error-message';
|
import ErrorMessage from '../../ui/error-message';
|
||||||
import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction';
|
import { TRANSACTION_TYPES } from '../../../../shared/constants/transaction';
|
||||||
import Dialog from '../../ui/dialog';
|
import Dialog from '../../ui/dialog';
|
||||||
@ -135,102 +136,104 @@ export default class ConfirmPageContainer extends Component {
|
|||||||
currentTransaction.txParams?.value === '0x0';
|
currentTransaction.txParams?.value === '0x0';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="page-container">
|
<GasFeeContextProvider transaction={currentTransaction}>
|
||||||
<ConfirmPageContainerNavigation
|
<div className="page-container">
|
||||||
totalTx={totalTx}
|
<ConfirmPageContainerNavigation
|
||||||
positionOfCurrentTx={positionOfCurrentTx}
|
totalTx={totalTx}
|
||||||
nextTxId={nextTxId}
|
positionOfCurrentTx={positionOfCurrentTx}
|
||||||
prevTxId={prevTxId}
|
nextTxId={nextTxId}
|
||||||
showNavigation={showNavigation}
|
prevTxId={prevTxId}
|
||||||
onNextTx={(txId) => onNextTx(txId)}
|
showNavigation={showNavigation}
|
||||||
firstTx={firstTx}
|
onNextTx={(txId) => onNextTx(txId)}
|
||||||
lastTx={lastTx}
|
firstTx={firstTx}
|
||||||
ofText={ofText}
|
lastTx={lastTx}
|
||||||
requestsWaitingText={requestsWaitingText}
|
ofText={ofText}
|
||||||
/>
|
requestsWaitingText={requestsWaitingText}
|
||||||
<ConfirmPageContainerHeader
|
/>
|
||||||
showEdit={showEdit}
|
<ConfirmPageContainerHeader
|
||||||
onEdit={() => onEdit()}
|
showEdit={showEdit}
|
||||||
showAccountInHeader={showAccountInHeader}
|
onEdit={() => onEdit()}
|
||||||
accountAddress={fromAddress}
|
showAccountInHeader={showAccountInHeader}
|
||||||
>
|
accountAddress={fromAddress}
|
||||||
{hideSenderToRecipient ? null : (
|
>
|
||||||
<SenderToRecipient
|
{hideSenderToRecipient ? null : (
|
||||||
senderName={fromName}
|
<SenderToRecipient
|
||||||
senderAddress={fromAddress}
|
senderName={fromName}
|
||||||
recipientName={toName}
|
senderAddress={fromAddress}
|
||||||
recipientAddress={toAddress}
|
recipientName={toName}
|
||||||
recipientEns={toEns}
|
recipientAddress={toAddress}
|
||||||
recipientNickname={toNickname}
|
recipientEns={toEns}
|
||||||
|
recipientNickname={toNickname}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</ConfirmPageContainerHeader>
|
||||||
|
<div>
|
||||||
|
{showAddToAddressDialog && (
|
||||||
|
<Dialog
|
||||||
|
type="message"
|
||||||
|
className="send__dialog"
|
||||||
|
onClick={() => showAddToAddressBookModal()}
|
||||||
|
>
|
||||||
|
{this.context.t('newAccountDetectedDialogMessage')}
|
||||||
|
</Dialog>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{contentComponent || (
|
||||||
|
<ConfirmPageContainerContent
|
||||||
|
action={action}
|
||||||
|
title={title}
|
||||||
|
titleComponent={titleComponent}
|
||||||
|
subtitleComponent={subtitleComponent}
|
||||||
|
hideSubtitle={hideSubtitle}
|
||||||
|
detailsComponent={detailsComponent}
|
||||||
|
dataComponent={dataComponent}
|
||||||
|
errorMessage={errorMessage}
|
||||||
|
errorKey={errorKey}
|
||||||
|
identiconAddress={identiconAddress}
|
||||||
|
nonce={nonce}
|
||||||
|
warning={warning}
|
||||||
|
onCancelAll={onCancelAll}
|
||||||
|
onCancel={onCancel}
|
||||||
|
cancelText={this.context.t('reject')}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
submitText={this.context.t('confirm')}
|
||||||
|
disabled={disabled}
|
||||||
|
unapprovedTxCount={unapprovedTxCount}
|
||||||
|
rejectNText={this.context.t('rejectTxsN', [unapprovedTxCount])}
|
||||||
|
origin={origin}
|
||||||
|
ethGasPriceWarning={ethGasPriceWarning}
|
||||||
|
hideTitle={hideTitle}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</ConfirmPageContainerHeader>
|
{shouldDisplayWarning && (
|
||||||
<div>
|
<div className="confirm-approve-content__warning">
|
||||||
{showAddToAddressDialog && (
|
<ErrorMessage errorKey={errorKey} />
|
||||||
<Dialog
|
</div>
|
||||||
type="message"
|
)}
|
||||||
className="send__dialog"
|
{contentComponent && (
|
||||||
onClick={() => showAddToAddressBookModal()}
|
<PageContainerFooter
|
||||||
|
onCancel={onCancel}
|
||||||
|
cancelText={this.context.t('reject')}
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
submitText={this.context.t('confirm')}
|
||||||
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
{this.context.t('newAccountDetectedDialogMessage')}
|
{unapprovedTxCount > 1 && (
|
||||||
</Dialog>
|
<a onClick={onCancelAll}>
|
||||||
|
{this.context.t('rejectTxsN', [unapprovedTxCount])}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</PageContainerFooter>
|
||||||
|
)}
|
||||||
|
{editingGas && (
|
||||||
|
<EditGasPopover
|
||||||
|
mode={EDIT_GAS_MODES.MODIFY_IN_PLACE}
|
||||||
|
onClose={handleCloseEditGas}
|
||||||
|
transaction={currentTransaction}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{contentComponent || (
|
</GasFeeContextProvider>
|
||||||
<ConfirmPageContainerContent
|
|
||||||
action={action}
|
|
||||||
title={title}
|
|
||||||
titleComponent={titleComponent}
|
|
||||||
subtitleComponent={subtitleComponent}
|
|
||||||
hideSubtitle={hideSubtitle}
|
|
||||||
detailsComponent={detailsComponent}
|
|
||||||
dataComponent={dataComponent}
|
|
||||||
errorMessage={errorMessage}
|
|
||||||
errorKey={errorKey}
|
|
||||||
identiconAddress={identiconAddress}
|
|
||||||
nonce={nonce}
|
|
||||||
warning={warning}
|
|
||||||
onCancelAll={onCancelAll}
|
|
||||||
onCancel={onCancel}
|
|
||||||
cancelText={this.context.t('reject')}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
submitText={this.context.t('confirm')}
|
|
||||||
disabled={disabled}
|
|
||||||
unapprovedTxCount={unapprovedTxCount}
|
|
||||||
rejectNText={this.context.t('rejectTxsN', [unapprovedTxCount])}
|
|
||||||
origin={origin}
|
|
||||||
ethGasPriceWarning={ethGasPriceWarning}
|
|
||||||
hideTitle={hideTitle}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{shouldDisplayWarning && (
|
|
||||||
<div className="confirm-approve-content__warning">
|
|
||||||
<ErrorMessage errorKey={errorKey} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{contentComponent && (
|
|
||||||
<PageContainerFooter
|
|
||||||
onCancel={onCancel}
|
|
||||||
cancelText={this.context.t('reject')}
|
|
||||||
onSubmit={onSubmit}
|
|
||||||
submitText={this.context.t('confirm')}
|
|
||||||
disabled={disabled}
|
|
||||||
>
|
|
||||||
{unapprovedTxCount > 1 && (
|
|
||||||
<a onClick={onCancelAll}>
|
|
||||||
{this.context.t('rejectTxsN', [unapprovedTxCount])}
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</PageContainerFooter>
|
|
||||||
)}
|
|
||||||
{editingGas && (
|
|
||||||
<EditGasPopover
|
|
||||||
mode={EDIT_GAS_MODES.MODIFY_IN_PLACE}
|
|
||||||
onClose={handleCloseEditGas}
|
|
||||||
transaction={currentTransaction}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
ui/contexts/gasFee.js
Normal file
37
ui/contexts/gasFee.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import React, { createContext, useContext } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useGasFeeInputs } from '../hooks/gasFeeInput/useGasFeeInputs';
|
||||||
|
|
||||||
|
export const GasFeeContext = createContext({});
|
||||||
|
|
||||||
|
export const GasFeeContextProvider = ({
|
||||||
|
children,
|
||||||
|
defaultEstimateToUse,
|
||||||
|
transaction,
|
||||||
|
minimumGasLimit,
|
||||||
|
editGasMode,
|
||||||
|
}) => {
|
||||||
|
const gasFeeDetails = useGasFeeInputs(
|
||||||
|
defaultEstimateToUse,
|
||||||
|
transaction,
|
||||||
|
minimumGasLimit,
|
||||||
|
editGasMode,
|
||||||
|
);
|
||||||
|
return (
|
||||||
|
<GasFeeContext.Provider value={gasFeeDetails}>
|
||||||
|
{children}
|
||||||
|
</GasFeeContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useGasFeeContext() {
|
||||||
|
return useContext(GasFeeContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
GasFeeContextProvider.propTypes = {
|
||||||
|
children: PropTypes.node.isRequired,
|
||||||
|
defaultEstimateToUse: PropTypes.string,
|
||||||
|
transaction: PropTypes.object.isRequired,
|
||||||
|
minimumGasLimit: PropTypes.string,
|
||||||
|
editGasMode: PropTypes.string,
|
||||||
|
};
|
@ -130,7 +130,10 @@ const getMaxFeeWarning = (
|
|||||||
return undefined;
|
return undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getBalanceError = (minimumCostInHexWei, transaction, ethBalance) => {
|
const hasBalanceError = (minimumCostInHexWei, transaction, ethBalance) => {
|
||||||
|
if (minimumCostInHexWei === undefined || ethBalance === undefined) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const minimumTxCostInHexWei = addHexes(
|
const minimumTxCostInHexWei = addHexes(
|
||||||
minimumCostInHexWei,
|
minimumCostInHexWei,
|
||||||
transaction?.txParams?.value || '0x0',
|
transaction?.txParams?.value || '0x0',
|
||||||
@ -247,7 +250,7 @@ export function useGasFeeErrors({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { balance: ethBalance } = useSelector(getSelectedAccount);
|
const { balance: ethBalance } = useSelector(getSelectedAccount);
|
||||||
const balanceError = getBalanceError(
|
const balanceError = hasBalanceError(
|
||||||
minimumCostInHexWei,
|
minimumCostInHexWei,
|
||||||
transaction,
|
transaction,
|
||||||
ethBalance,
|
ethBalance,
|
||||||
|
@ -3,6 +3,7 @@ import { useSelector } from 'react-redux';
|
|||||||
|
|
||||||
import { getAdvancedInlineGasShown } from '../../selectors';
|
import { getAdvancedInlineGasShown } from '../../selectors';
|
||||||
import { hexToDecimal } from '../../helpers/utils/conversions.util';
|
import { hexToDecimal } from '../../helpers/utils/conversions.util';
|
||||||
|
import { EDIT_GAS_MODES } from '../../../shared/constants/gas';
|
||||||
import { GAS_FORM_ERRORS } from '../../helpers/constants/gas';
|
import { GAS_FORM_ERRORS } from '../../helpers/constants/gas';
|
||||||
import {
|
import {
|
||||||
GAS_RECOMMENDATIONS,
|
GAS_RECOMMENDATIONS,
|
||||||
@ -65,7 +66,7 @@ export function useGasFeeInputs(
|
|||||||
defaultEstimateToUse = GAS_RECOMMENDATIONS.MEDIUM,
|
defaultEstimateToUse = GAS_RECOMMENDATIONS.MEDIUM,
|
||||||
transaction,
|
transaction,
|
||||||
minimumGasLimit = '0x5208',
|
minimumGasLimit = '0x5208',
|
||||||
editGasMode,
|
editGasMode = EDIT_GAS_MODES.MODIFY_IN_PLACE,
|
||||||
) {
|
) {
|
||||||
// We need the gas estimates from the GasFeeController in the background.
|
// We need the gas estimates from the GasFeeController in the background.
|
||||||
// Calling this hooks initiates polling for new gas estimates and returns the
|
// Calling this hooks initiates polling for new gas estimates and returns the
|
||||||
|
Loading…
Reference in New Issue
Block a user