EIP-1559 V2: Adding default settings to advanced gas modal (#12911)

feature/default_network_editable
Niranjana Binoy 3 years ago committed by GitHub
parent 3a11800cb1
commit 8c77e37d2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      app/_locales/en/messages.json
  2. 80
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.js
  3. 132
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/advanced-gas-fee-defaults.test.js
  4. 1
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/index.js
  5. 6
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-defaults/index.scss
  6. 1
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-gas-limit/advanced-gas-fee-gas-limit.js
  7. 2
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/advanced-gas-fee-inputs.js
  8. 8
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/base-fee-input.js
  9. 2
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/index.scss
  10. 5
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-inputs/priority-fee-input/priority-fee-input.js
  11. 5
      ui/components/app/advanced-gas-fee-popover/advanced-gas-fee-popover.js
  12. 3
      ui/components/app/advanced-gas-fee-popover/context/advancedGasFeePopover.js
  13. 17
      ui/components/app/advanced-gas-fee-popover/index.scss
  14. 3
      ui/components/app/app-components.scss

@ -170,6 +170,12 @@
"advancedBaseGasFeeToolTip": { "advancedBaseGasFeeToolTip": {
"message": "When your transaction gets included in the block, any difference between your max base fee and the actual base fee will be refunded. Total amount is calculated as max base fee (in GWEI) * gas limit." "message": "When your transaction gets included in the block, any difference between your max base fee and the actual base fee will be refunded. Total amount is calculated as max base fee (in GWEI) * gas limit."
}, },
"advancedGasFeeDefaultOptIn": {
"message": "Save these $1 as my default for \"Advanced\""
},
"advancedGasFeeDefaultOptOut": {
"message": "Always use these values and advanced setting as default."
},
"advancedGasFeeModalTitle": { "advancedGasFeeModalTitle": {
"message": "Advanced gas fee" "message": "Advanced gas fee"
}, },
@ -1851,6 +1857,9 @@
"newTransactionFee": { "newTransactionFee": {
"message": "New Transaction Fee" "message": "New Transaction Fee"
}, },
"newValues": {
"message": "new values"
},
"next": { "next": {
"message": "Next" "message": "Next"
}, },

@ -0,0 +1,80 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import Box from '../../../ui/box';
import Typography from '../../../ui/typography';
import CheckBox from '../../../ui/check-box';
import I18nValue from '../../../ui/i18n-value';
import {
COLORS,
DISPLAY,
FLEX_DIRECTION,
TYPOGRAPHY,
} from '../../../../helpers/constants/design-system';
import { getAdvancedGasFeeValues } from '../../../../selectors';
import { setAdvancedGasFee } from '../../../../store/actions';
import { useAdvancedGasFeePopoverContext } from '../context';
import { useI18nContext } from '../../../../hooks/useI18nContext';
const AdvancedGasFeeDefaults = () => {
const t = useI18nContext();
const dispatch = useDispatch();
const {
hasErrors,
baseFeeMultiplier,
maxPriorityFeePerGas,
} = useAdvancedGasFeePopoverContext();
const advancedGasFeeValues = useSelector(getAdvancedGasFeeValues);
const updateDefaultSettings = (value) => {
if (value) {
dispatch(
setAdvancedGasFee({
maxBaseFee: baseFeeMultiplier,
priorityFee: maxPriorityFeePerGas,
}),
);
} else {
dispatch(setAdvancedGasFee(null));
}
};
const isDefaultSettingsSelected =
Boolean(advancedGasFeeValues) &&
advancedGasFeeValues.maxBaseFee === baseFeeMultiplier &&
advancedGasFeeValues.priorityFee === maxPriorityFeePerGas;
const handleUpdateDefaultSettings = () =>
updateDefaultSettings(!isDefaultSettingsSelected);
return (
<Box
display={DISPLAY.FLEX}
flexDirection={FLEX_DIRECTION.ROW}
marginRight={4}
className="advanced-gas-fee-defaults"
>
<CheckBox
checked={isDefaultSettingsSelected}
className="advanced-gas-fee-defaults__checkbox"
onClick={handleUpdateDefaultSettings}
disabled={hasErrors}
/>
<Typography variant={TYPOGRAPHY.H7} color={COLORS.UI4} margin={0}>
{!isDefaultSettingsSelected && Boolean(advancedGasFeeValues) ? (
<I18nValue
messageKey="advancedGasFeeDefaultOptIn"
options={[
<strong key="default-value-change">{t('newValues')}</strong>,
]}
/>
) : (
<I18nValue messageKey="advancedGasFeeDefaultOptOut" />
)}
</Typography>
</Box>
);
};
export default AdvancedGasFeeDefaults;

@ -0,0 +1,132 @@
import React from 'react';
import { fireEvent, screen } from '@testing-library/react';
import { GAS_ESTIMATE_TYPES } from '../../../../../shared/constants/gas';
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
import mockEstimates from '../../../../../test/data/mock-estimates.json';
import mockState from '../../../../../test/data/mock-state.json';
import { AdvancedGasFeePopoverContextProvider } from '../context';
import { GasFeeContextProvider } from '../../../../contexts/gasFee';
import configureStore from '../../../../store/store';
import AdvancedGasFeeInputs from '../advanced-gas-fee-inputs';
import AdvancedGasFeeDefaults from './advanced-gas-fee-defaults';
jest.mock('../../../../store/actions', () => ({
disconnectGasFeeEstimatePoller: jest.fn(),
getGasFeeEstimatesAndStartPolling: jest
.fn()
.mockImplementation(() => Promise.resolve()),
addPollingTokenToAppState: jest.fn(),
removePollingTokenFromAppState: jest.fn(),
}));
const render = (defaultGasParams) => {
const store = configureStore({
metamask: {
...mockState.metamask,
...defaultGasParams,
accounts: {
[mockState.metamask.selectedAddress]: {
address: mockState.metamask.selectedAddress,
balance: '0x1F4',
},
},
featureFlags: { advancedInlineGas: true },
gasFeeEstimates:
mockEstimates[GAS_ESTIMATE_TYPES.FEE_MARKET].gasFeeEstimates,
},
});
return renderWithProvider(
<GasFeeContextProvider
transaction={{
userFeeLevel: 'custom',
txParams: {
maxFeePerGas: '0x174876E800',
maxPriorityFeePerGas: '0x77359400',
},
}}
>
<AdvancedGasFeePopoverContextProvider>
<AdvancedGasFeeInputs />
<AdvancedGasFeeDefaults />
</AdvancedGasFeePopoverContextProvider>
</GasFeeContextProvider>,
store,
);
};
describe('AdvancedGasFeeDefaults', () => {
it('should renders correct message when the default is not set', () => {
render({ advancedGasFee: null });
expect(
screen.queryByText(
'Always use these values and advanced setting as default.',
),
).toBeInTheDocument();
});
it('should renders correct message when the default values are set', () => {
render({
advancedGasFee: { maxBaseFee: 2, priorityFee: 2 },
});
expect(
screen.queryByText(
'Always use these values and advanced setting as default.',
),
).toBeInTheDocument();
});
it('should renders correct message when checkbox is selected and default values are saved', () => {
render({
advancedGasFee: null,
});
expect(
screen.queryByText(
'Always use these values and advanced setting as default.',
),
).toBeInTheDocument();
fireEvent.change(document.getElementsByTagName('input')[0], {
target: { value: 3 },
});
fireEvent.change(document.getElementsByTagName('input')[1], {
target: { value: 4 },
});
});
it('should renders correct message when the default values are set and the maxBaseFee values are updated', () => {
render({
advancedGasFee: { maxBaseFee: 2, priorityFee: 2 },
});
expect(document.getElementsByTagName('input')[2]).toBeChecked();
expect(
screen.queryByText(
'Always use these values and advanced setting as default.',
),
).toBeInTheDocument();
fireEvent.change(document.getElementsByTagName('input')[0], {
target: { value: 4 },
});
expect(document.getElementsByTagName('input')[0]).toHaveValue(4);
expect(screen.queryByText('new values')).toBeInTheDocument();
expect(
screen.queryByText('Save these as my default for "Advanced"'),
).toBeInTheDocument();
});
it('should renders correct message when the default values are set and the priorityFee values are updated', () => {
render({
advancedGasFee: { maxBaseFee: 2, priorityFee: 2 },
});
expect(document.getElementsByTagName('input')[2]).toBeChecked();
expect(
screen.queryByText(
'Always use these values and advanced setting as default.',
),
).toBeInTheDocument();
fireEvent.change(document.getElementsByTagName('input')[1], {
target: { value: 4 },
});
expect(document.getElementsByTagName('input')[1]).toHaveValue(4);
expect(screen.queryByText('new values')).toBeInTheDocument();
expect(
screen.queryByText('Save these as my default for "Advanced"'),
).toBeInTheDocument();
});
});

@ -0,0 +1 @@
export { default } from './advanced-gas-fee-defaults';

@ -0,0 +1,6 @@
.advanced-gas-fee-defaults {
& &__checkbox {
font-size: $font-size-h4;
margin: 0 8px 0 8px;
}
}

@ -63,6 +63,7 @@ const AdvancedGasFeeGasLimit = () => {
tag={TYPOGRAPHY.Paragraph} tag={TYPOGRAPHY.Paragraph}
variant={TYPOGRAPHY.H7} variant={TYPOGRAPHY.H7}
className="advanced-gas-fee-gas-limit" className="advanced-gas-fee-gas-limit"
margin={[0, 2]}
> >
<strong> <strong>
<I18nValue messageKey="gasLimitV2" /> <I18nValue messageKey="gasLimitV2" />

@ -6,7 +6,7 @@ import PriorityFeeInput from './priority-fee-input';
const AdvancedGasFeeInputs = () => { const AdvancedGasFeeInputs = () => {
return ( return (
<Box className="advanced-gas-fee-inputs" margin={[4, 0]}> <Box className="advanced-gas-fee-inputs">
<BaseFeeInput /> <BaseFeeInput />
<div className="advanced-gas-fee-inputs__separator" /> <div className="advanced-gas-fee-inputs__separator" />
<PriorityFeeInput /> <PriorityFeeInput />

@ -10,7 +10,6 @@ import {
import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common'; import { PRIMARY, SECONDARY } from '../../../../../helpers/constants/common';
import { bnGreaterThan, bnLessThan } from '../../../../../helpers/utils/util'; import { bnGreaterThan, bnLessThan } from '../../../../../helpers/utils/util';
import { decGWEIToHexWEI } from '../../../../../helpers/utils/conversions.util'; import { decGWEIToHexWEI } from '../../../../../helpers/utils/conversions.util';
import { getAdvancedGasFeeValues } from '../../../../../selectors'; import { getAdvancedGasFeeValues } from '../../../../../selectors';
import { useGasFeeContext } from '../../../../../contexts/gasFee'; import { useGasFeeContext } from '../../../../../contexts/gasFee';
import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { useI18nContext } from '../../../../../hooks/useI18nContext';
@ -77,11 +76,13 @@ const validateBaseFee = (
const BaseFeeInput = () => { const BaseFeeInput = () => {
const t = useI18nContext(); const t = useI18nContext();
const { gasFeeEstimates, estimateUsed, maxFeePerGas } = useGasFeeContext(); const { gasFeeEstimates, estimateUsed, maxFeePerGas } = useGasFeeContext();
const { const {
maxPriorityFeePerGas, maxPriorityFeePerGas,
setErrorValue, setErrorValue,
setMaxFeePerGas, setMaxFeePerGas,
setBaseFeeMultiplier,
} = useAdvancedGasFeePopoverContext(); } = useAdvancedGasFeePopoverContext();
const { const {
@ -177,6 +178,7 @@ const BaseFeeInput = () => {
if (baseFeeTrend !== 'level' && baseFeeTrend !== feeTrend) { if (baseFeeTrend !== 'level' && baseFeeTrend !== feeTrend) {
setFeeTrend(baseFeeTrend); setFeeTrend(baseFeeTrend);
} }
setBaseFeeMultiplier(maxBaseFeeMultiplier);
}, [ }, [
feeTrend, feeTrend,
editingInGwei, editingInGwei,
@ -184,14 +186,16 @@ const BaseFeeInput = () => {
gasFeeEstimates, gasFeeEstimates,
maxBaseFeeGWEI, maxBaseFeeGWEI,
maxPriorityFeePerGas, maxPriorityFeePerGas,
maxBaseFeeMultiplier,
setBaseFeeError, setBaseFeeError,
setErrorValue, setErrorValue,
setMaxFeePerGas, setMaxFeePerGas,
setFeeTrend, setFeeTrend,
setBaseFeeMultiplier,
]); ]);
return ( return (
<Box className="base-fee-input"> <Box className="base-fee-input" margin={[0, 2]}>
<FormField <FormField
error={baseFeeError ? t(baseFeeError) : ''} error={baseFeeError ? t(baseFeeError) : ''}
onChange={updateBaseFee} onChange={updateBaseFee}

@ -9,6 +9,6 @@
&__separator { &__separator {
border-top: 1px solid $ui-grey; border-top: 1px solid $ui-grey;
margin: 24px 0 16px 0; margin: 16px 0;
} }
} }

@ -11,6 +11,7 @@ import { useGasFeeContext } from '../../../../../contexts/gasFee';
import { useI18nContext } from '../../../../../hooks/useI18nContext'; import { useI18nContext } from '../../../../../hooks/useI18nContext';
import { useUserPreferencedCurrency } from '../../../../../hooks/useUserPreferencedCurrency'; import { useUserPreferencedCurrency } from '../../../../../hooks/useUserPreferencedCurrency';
import FormField from '../../../../ui/form-field'; import FormField from '../../../../ui/form-field';
import Box from '../../../../ui/box';
import { bnGreaterThan, bnLessThan } from '../../../../../helpers/utils/util'; import { bnGreaterThan, bnLessThan } from '../../../../../helpers/utils/util';
import { useAdvancedGasFeePopoverContext } from '../../context'; import { useAdvancedGasFeePopoverContext } from '../../context';
@ -103,7 +104,7 @@ const PriorityFeeInput = () => {
]); ]);
return ( return (
<> <Box margin={[0, 2]}>
<FormField <FormField
error={priorityFeeError ? t(priorityFeeError) : ''} error={priorityFeeError ? t(priorityFeeError) : ''}
onChange={updatePriorityFee} onChange={updatePriorityFee}
@ -119,7 +120,7 @@ const PriorityFeeInput = () => {
historical={renderFeeRange(historicalPriorityFeeRange)} historical={renderFeeRange(historicalPriorityFeeRange)}
feeTrend={feeTrend} feeTrend={feeTrend}
/> />
</> </Box>
); );
}; };

@ -9,6 +9,7 @@ import { AdvancedGasFeePopoverContextProvider } from './context';
import AdvancedGasFeeInputs from './advanced-gas-fee-inputs'; import AdvancedGasFeeInputs from './advanced-gas-fee-inputs';
import AdvancedGasFeeGasLimit from './advanced-gas-fee-gas-limit'; import AdvancedGasFeeGasLimit from './advanced-gas-fee-gas-limit';
import AdvancedGasFeeSaveButton from './advanced-gas-fee-save'; import AdvancedGasFeeSaveButton from './advanced-gas-fee-save';
import AdvancedGasFeeDefaults from './advanced-gas-fee-defaults';
const AdvancedGasFeePopover = () => { const AdvancedGasFeePopover = () => {
const t = useI18nContext(); const t = useI18nContext();
@ -29,9 +30,11 @@ const AdvancedGasFeePopover = () => {
onClose={closeAllModals} onClose={closeAllModals}
footer={<AdvancedGasFeeSaveButton />} footer={<AdvancedGasFeeSaveButton />}
> >
<Box className="advanced-gas-fee-popover__wrapper" margin={4}> <Box margin={4}>
<AdvancedGasFeeInputs /> <AdvancedGasFeeInputs />
<div className="advanced-gas-fee-popover__separator" /> <div className="advanced-gas-fee-popover__separator" />
<AdvancedGasFeeDefaults />
<div className="advanced-gas-fee-popover__separator" />
<AdvancedGasFeeGasLimit /> <AdvancedGasFeeGasLimit />
</Box> </Box>
</Popover> </Popover>

@ -20,6 +20,7 @@ export const AdvancedGasFeePopoverContextProvider = ({ children }) => {
}, },
[errors, setErrors], [errors, setErrors],
); );
const [baseFeeMultiplier, setBaseFeeMultiplier] = useState();
return ( return (
<AdvancedGasFeePopoverContext.Provider <AdvancedGasFeePopoverContext.Provider
@ -29,9 +30,11 @@ export const AdvancedGasFeePopoverContextProvider = ({ children }) => {
maxFeePerGas, maxFeePerGas,
maxPriorityFeePerGas, maxPriorityFeePerGas,
setErrorValue, setErrorValue,
baseFeeMultiplier,
setGasLimit, setGasLimit,
setMaxPriorityFeePerGas, setMaxPriorityFeePerGas,
setMaxFeePerGas, setMaxFeePerGas,
setBaseFeeMultiplier,
}} }}
> >
{children} {children}

@ -1,14 +1,21 @@
.advanced-gas-fee-popover { .advanced-gas-fee-popover {
&__wrapper {
border-top: 1px solid $ui-grey;
}
&__separator { &__separator {
border-top: 1px solid $ui-grey; border-top: 1px solid $ui-grey;
margin: 24px 0 16px 0; margin: 16px 0;
} }
.form-field__heading-title > h6 { .form-field__heading-title > h6 {
font-size: $font-size-h7; font-size: $font-size-h7;
} }
.popover-header {
border-radius: 0;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
border-bottom: 1px solid $ui-grey;
}
.popover-footer {
border-top: none;
}
} }

@ -62,9 +62,10 @@
@import 'whats-new-popup/index'; @import 'whats-new-popup/index';
@import 'loading-network-screen/index'; @import 'loading-network-screen/index';
@import 'flask/experimental-area/index'; @import 'flask/experimental-area/index';
@import 'transaction-decoding/index';
@import 'advanced-gas-fee-popover/index'; @import 'advanced-gas-fee-popover/index';
@import 'advanced-gas-fee-popover/advanced-gas-fee-gas-limit/index'; @import 'advanced-gas-fee-popover/advanced-gas-fee-gas-limit/index';
@import 'advanced-gas-fee-popover/advanced-gas-fee-inputs/index'; @import 'advanced-gas-fee-popover/advanced-gas-fee-inputs/index';
@import 'advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/index'; @import 'advanced-gas-fee-popover/advanced-gas-fee-inputs/base-fee-input/index';
@import 'advanced-gas-fee-popover/advanced-gas-fee-input-subtext/index'; @import 'advanced-gas-fee-popover/advanced-gas-fee-input-subtext/index';
@import 'transaction-decoding/index'; @import 'advanced-gas-fee-popover/advanced-gas-fee-defaults/index';

Loading…
Cancel
Save