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

Adding GasFee context (#12530)

Adding GasFee context
This commit is contained in:
Jyoti Puri 2021-11-10 07:37:10 +05:30 committed by GitHub
parent 2c410f534d
commit a49a40fbbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 148 additions and 94 deletions

View File

@ -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: {},
}, },
}; };

View File

@ -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
View 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,
};

View File

@ -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,

View File

@ -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