1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 01:47:00 +01:00

Allow sending up to 15 decimals on the send screen (#12707)

This commit is contained in:
Dan J Miller 2022-02-10 19:05:41 -03:30 committed by GitHub
parent 8f2144fdb0
commit 8597cd1401
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 48 additions and 8 deletions

View File

@ -0,0 +1,5 @@
/**
* MAX_DECIMAL represensts the maximum number of decimal values allow for the input,
* the limitation in javascript <input/> retstricts us to keep it as 15 and below.
*/
export const MAX_DECIMAL = 15;

View File

@ -14,6 +14,7 @@ import {
getNativeCurrency,
} from '../../../ducks/metamask/metamask';
import { getCurrentCurrency, getShouldShowFiat } from '../../../selectors';
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
/**
* Component that allows user to enter currency values as a number, and props receive a converted
@ -25,12 +26,14 @@ import { getCurrentCurrency, getShouldShowFiat } from '../../../selectors';
* @param options0.featureSecondary
* @param options0.onChange
* @param options0.onPreferenceToggle
* @param options0.primaryNumberOfDecimals
*/
export default function CurrencyInput({
hexValue,
featureSecondary,
onChange,
onPreferenceToggle,
primaryNumberOfDecimals = 8,
}) {
const t = useContext(I18nContext);
@ -64,7 +67,10 @@ export default function CurrencyInput({
: getValueFromWeiHex({
value: hexValue,
toCurrency: ETH,
numberOfDecimals: 8,
numberOfDecimals:
primaryNumberOfDecimals <= MAX_DECIMAL
? primaryNumberOfDecimals
: MAX_DECIMAL,
});
return Number(decimalValueString) || 0;
@ -127,7 +133,10 @@ export default function CurrencyInput({
if (shouldUseFiat()) {
// Display ETH
currency = preferredCurrency || ETH;
numberOfDecimals = 8;
numberOfDecimals =
primaryNumberOfDecimals <= MAX_DECIMAL
? primaryNumberOfDecimals
: MAX_DECIMAL;
} else {
// Display Fiat
currency = secondaryCurrency;
@ -143,7 +152,6 @@ export default function CurrencyInput({
/>
);
};
return (
<UnitInput
{...{
@ -173,4 +181,5 @@ CurrencyInput.propTypes = {
featureSecondary: PropTypes.bool,
onChange: PropTypes.func,
onPreferenceToggle: PropTypes.func,
primaryNumberOfDecimals: PropTypes.number,
};

View File

@ -6,6 +6,7 @@ import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import UnitInput from '../../ui/unit-input';
import CurrencyDisplay from '../../ui/currency-display';
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
import CurrencyInput from './currency-input';
describe('CurrencyInput Component', () => {
@ -145,7 +146,11 @@ describe('CurrencyInput Component', () => {
const wrapper = mount(
<Provider store={store}>
<CurrencyInput hexValue="f602f2234d0ea" featureSecondary />
<CurrencyInput
hexValue="f602f2234d0ea"
featureSecondary
primaryNumberOfDecimals={MAX_DECIMAL}
/>
</Provider>,
{
context: { t: (str) => `${str}_t` },
@ -157,7 +162,7 @@ describe('CurrencyInput Component', () => {
expect(wrapper.find('.unit-input__suffix')).toHaveLength(1);
expect(wrapper.find('.unit-input__suffix').text()).toStrictEqual('ETH');
expect(wrapper.find('.unit-input__input').props().value).toStrictEqual(
0.00432788,
0.004327880204276,
);
expect(
wrapper.find('.currency-input__conversion-component').text(),
@ -193,7 +198,11 @@ describe('CurrencyInput Component', () => {
const store = configureMockStore()(mockStore);
const wrapper = mount(
<Provider store={store}>
<CurrencyInput onChange={handleChangeSpy} hexValue="f602f2234d0ea" />
<CurrencyInput
onChange={handleChangeSpy}
hexValue="f602f2234d0ea"
primaryNumberOfDecimals={MAX_DECIMAL}
/>
</Provider>,
);
@ -202,7 +211,7 @@ describe('CurrencyInput Component', () => {
expect(handleBlurSpy.callCount).toStrictEqual(0);
const input = wrapper.find('input');
expect(input.props().value).toStrictEqual(0.00432788);
expect(input.props().value).toStrictEqual(0.004327880204276);
input.simulate('change', { target: { value: 1 } });
expect(handleChangeSpy.callCount).toStrictEqual(2);

View File

@ -11,6 +11,7 @@ import {
import { ETH } from '../../../helpers/constants/common';
import { addHexPrefix } from '../../../../app/scripts/lib/util';
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
/**
* Component that allows user to enter token values as a number, and props receive a converted
@ -34,6 +35,7 @@ export default class TokenInput extends PureComponent {
symbol: PropTypes.string,
}).isRequired,
tokenExchangeRates: PropTypes.object,
primaryNumberOfDecimals: PropTypes.number,
};
constructor(props) {
@ -108,6 +110,7 @@ export default class TokenInput extends PureComponent {
currentCurrency,
hideConversion,
token,
primaryNumberOfDecimals = 8,
} = this.props;
const { decimalValue } = this.state;
@ -129,7 +132,10 @@ export default class TokenInput extends PureComponent {
} else {
// Display ETH
currency = ETH;
numberOfDecimals = 6;
numberOfDecimals =
primaryNumberOfDecimals <= MAX_DECIMAL
? primaryNumberOfDecimals
: MAX_DECIMAL;
}
const decimalEthValue = decimalValue * tokenExchangeRate || 0;

View File

@ -1,6 +1,9 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { MAX_DECIMAL } from '../../../../shared/constants/decimal';
const DECIMAL_REGEX = /\.(\d*)/u;
function removeLeadingZeroes(str) {
return str.replace(/^0*(?=\d)/u, '');
@ -62,6 +65,11 @@ export default class UnitInput extends PureComponent {
handleChange = (event) => {
const { value: userInput } = event.target;
const match = DECIMAL_REGEX.exec(userInput);
if (match?.[1]?.length > MAX_DECIMAL) {
return;
}
let value = userInput;
if (userInput.length && userInput.length > 1) {

View File

@ -4,6 +4,7 @@ import SendRowWrapper from '../send-row-wrapper';
import UserPreferencedCurrencyInput from '../../../../components/app/user-preferenced-currency-input';
import UserPreferencedTokenInput from '../../../../components/app/user-preferenced-token-input';
import { ASSET_TYPES } from '../../../../ducks/send';
import { MAX_DECIMAL } from '../../../../../shared/constants/decimal';
import AmountMaxButton from './amount-max-button';
export default class SendAmountRow extends Component {
@ -31,12 +32,14 @@ export default class SendAmountRow extends Component {
onChange={this.handleChange}
token={asset.details}
value={amount}
primaryNumberOfDecimals={asset.decimals}
/>
) : (
<UserPreferencedCurrencyInput
error={inError}
onChange={this.handleChange}
hexValue={amount}
primaryNumberOfDecimals={MAX_DECIMAL}
/>
);
}