Skip to content

Commit

Permalink
fix: decimal places displayed on token value on permit pages (#25410)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpuri authored Jul 2, 2024
1 parent 05904ca commit 6557b59
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 30 deletions.
2 changes: 1 addition & 1 deletion test/e2e/tests/confirmations/signatures/permit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ async function assertInfoValues(driver: Driver) {
css: '.name__value',
text: '0x5B38D...eddC4',
});
const value = driver.findElement({ text: '3000' });
const value = driver.findElement({ text: '3,000' });
const nonce = driver.findElement({ text: '0' });
const deadline = driver.findElement({ text: '02 August 1971, 16:53' });

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ exports[`TypedSignInfo correctly renders permit sign type 1`] = `
class="mm-box mm-text mm-text--body-md mm-box--color-inherit"
style="white-space: pre-wrap;"
>
3000
3,000
</p>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ exports[`PermitSimulation renders component correctly 1`] = `
<p
class="mm-box mm-text mm-text--body-md mm-text--text-align-center mm-box--padding-inline-2 mm-box--color-text-default mm-box--background-color-background-alternative mm-box--rounded-xl"
>
3000
30.00
</p>
</div>
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ describe('PermitSimulation', () => {
},
};
const mockStore = configureMockStore([])(state);
const { container } = renderWithProvider(<PermitSimulation />, mockStore);
const { container } = renderWithProvider(
<PermitSimulation tokenDecimals={2} />,
mockStore,
);
expect(container).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ import {
import { SignatureRequestType } from '../../../../../types/confirm';
import useTokenExchangeRate from '../../../../../../../components/app/currency-input/hooks/useTokenExchangeRate';
import { IndividualFiatDisplay } from '../../../../simulation-details/fiat-display';
import { formatNumber } from '../../../utils';
import { ConfirmInfoSection } from '../../../../../../../components/app/confirm/info/row/section';

const PermitSimulation: React.FC = () => {
const PermitSimulation: React.FC<{
tokenDecimals: number;
}> = ({ tokenDecimals }) => {
const t = useI18nContext();
const currentConfirmation = useSelector(
currentConfirmationSelector,
Expand Down Expand Up @@ -61,7 +64,10 @@ const PermitSimulation: React.FC = () => {
paddingInline={2}
textAlign={TextAlign.Center}
>
{value}
{formatNumber(
value / Math.pow(10, tokenDecimals),
tokenDecimals,
)}
</Text>
</Box>
<Name value={verifyingContract} type={NameType.ETHEREUM_ADDRESS} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import {
} from '../../../../../../../test/data/confirmations/typed_sign';
import TypedSignInfo from './typed-sign';

jest.mock('../../../../../../store/actions', () => {
return {
getTokenStandardAndDetails: jest.fn().mockResolvedValue({ decimals: 2 }),
};
});

describe('TypedSignInfo', () => {
it('renders origin for typed sign data request', () => {
const state = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { isValidAddress } from 'ethereumjs-util';

Expand All @@ -11,6 +11,7 @@ import {
} from '../../../../../../components/app/confirm/info/row';
import { useI18nContext } from '../../../../../../hooks/useI18nContext';
import { currentConfirmationSelector } from '../../../../../../selectors';
import { getTokenStandardAndDetails } from '../../../../../../store/actions';
import { SignatureRequestType } from '../../../../types/confirm';
import { isPermitSignatureRequest } from '../../../../utils';
import { selectUseTransactionSimulations } from '../../../../selectors/preferences';
Expand All @@ -26,6 +27,7 @@ const TypedSignInfo: React.FC = () => {
const useTransactionSimulations = useSelector(
selectUseTransactionSimulations,
);
const [decimals, setDecimals] = useState<number>(0);

if (!currentConfirmation?.msgParams) {
return null;
Expand All @@ -38,9 +40,23 @@ const TypedSignInfo: React.FC = () => {

const isPermit = isPermitSignatureRequest(currentConfirmation);

useEffect(() => {
(async () => {
if (!isPermit) {
return;
}
const { decimals: tokenDecimals } = await getTokenStandardAndDetails(
verifyingContract,
);
setDecimals(parseInt(tokenDecimals ?? '0', 10));
})();
}, [verifyingContract]);

return (
<>
{isPermit && useTransactionSimulations && <PermitSimulation />}
{isPermit && useTransactionSimulations && (
<PermitSimulation tokenDecimals={decimals} />
)}
<ConfirmInfoSection>
{isPermit && (
<>
Expand All @@ -64,6 +80,7 @@ const TypedSignInfo: React.FC = () => {
<ConfirmInfoRowTypedSignData
data={currentConfirmation.msgParams?.data as string}
isPermit={isPermit}
tokenDecimals={decimals}
/>
</ConfirmInfoRow>
</ConfirmInfoSection>
Expand Down
24 changes: 23 additions & 1 deletion ui/pages/confirmations/components/confirm/row/dataTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ConfirmInfoRowDate,
ConfirmInfoRowText,
} from '../../../../../components/app/confirm/info/row';
import { formatNumber } from '../utils';

type ValueType = string | Record<string, TreeData> | TreeData[];

Expand All @@ -22,9 +23,11 @@ export type TreeData = {
export const DataTree = ({
data,
isPermit = false,
tokenDecimals = 0,
}: {
data: Record<string, TreeData> | TreeData[];
isPermit?: boolean;
tokenDecimals?: number;
}) => (
<Box width={BlockSize.Full}>
{Object.entries(data).map(([label, { value, type }], i) => (
Expand All @@ -42,6 +45,7 @@ export const DataTree = ({
isPermit={isPermit}
value={value}
type={type}
tokenDecimals={tokenDecimals}
/>
}
</ConfirmInfoRow>
Expand All @@ -54,14 +58,32 @@ const DataField = ({
isPermit,
type,
value,
tokenDecimals,
}: {
label: string;
isPermit: boolean;
type: string;
value: ValueType;
tokenDecimals: number;
}) => {
if (typeof value === 'object' && value !== null) {
return <DataTree data={value} isPermit={isPermit} />;
return (
<DataTree
data={value}
isPermit={isPermit}
tokenDecimals={tokenDecimals}
/>
);
}
if (isPermit && label === 'value') {
return (
<ConfirmInfoRowText
text={formatNumber(
parseInt(value, 10) / Math.pow(10, tokenDecimals),
tokenDecimals,
)}
/>
);
}
if (isPermit && label === 'deadline') {
return <ConfirmInfoRowDate date={parseInt(value, 10)} />;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import {
ConfirmInfoRow,
ConfirmInfoRowText,
} from '../../../../../../components/app/confirm/info/row';

import { DataTree } from '../dataTree';
import { parseSanitizeTypedDataMessage } from '../../../../utils';
import { DataTree } from '../dataTree';

export const ConfirmInfoRowTypedSignData = ({
data,
isPermit,
tokenDecimals,
}: {
data: string;
isPermit?: boolean;
tokenDecimals?: number;
}) => {
const t = useI18nContext();

Expand All @@ -35,7 +36,11 @@ export const ConfirmInfoRowTypedSignData = ({
<ConfirmInfoRowText text={primaryType} />
</ConfirmInfoRow>
<Box style={{ marginLeft: -8 }}>
<DataTree data={sanitizedMessage.value} isPermit={isPermit} />
<DataTree
data={sanitizedMessage.value}
isPermit={isPermit}
tokenDecimals={tokenDecimals}
/>
</Box>
</Box>
);
Expand Down
46 changes: 28 additions & 18 deletions ui/pages/confirmations/components/confirm/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,39 @@ import {
unapprovedPersonalSignMsg,
} from '../../../../../test/data/confirmations/personal_sign';
import { SignatureRequestType } from '../../types/confirm';
import { getConfirmationSender } from './utils';
import { formatNumber, getConfirmationSender } from './utils';

describe('getConfirmationSender()', () => {
test("returns the sender address from a signature if it's passed", () => {
const testCurrentConfirmation =
genUnapprovedContractInteractionConfirmation() as TransactionMeta;
const { from } = getConfirmationSender(testCurrentConfirmation);
describe('confirm - utils', () => {
describe('getConfirmationSender()', () => {
test("returns the sender address from a signature if it's passed", () => {
const testCurrentConfirmation =
genUnapprovedContractInteractionConfirmation() as TransactionMeta;
const { from } = getConfirmationSender(testCurrentConfirmation);

expect(from).toEqual(CONTRACT_INTERACTION_SENDER_ADDRESS);
});
expect(from).toEqual(CONTRACT_INTERACTION_SENDER_ADDRESS);
});

test("returns the sender address from a transaction if it's passed", () => {
const { from } = getConfirmationSender(
unapprovedPersonalSignMsg as SignatureRequestType,
);
test("returns the sender address from a transaction if it's passed", () => {
const { from } = getConfirmationSender(
unapprovedPersonalSignMsg as SignatureRequestType,
);

expect(from).toEqual(PERSONAL_SIGN_SENDER_ADDRESS);
});
expect(from).toEqual(PERSONAL_SIGN_SENDER_ADDRESS);
});

test('returns no sender address if no confirmation is passed', () => {
const testCurrentConfirmation = undefined;
const { from } = getConfirmationSender(testCurrentConfirmation);
test('returns no sender address if no confirmation is passed', () => {
const testCurrentConfirmation = undefined;
const { from } = getConfirmationSender(testCurrentConfirmation);

expect(from).toEqual(undefined);
});
});

expect(from).toEqual(undefined);
describe('formatNumber()', () => {
test('formats number according to decimal places passed', () => {
expect(formatNumber(123456, 2)).toEqual('123,456.00');
expect(formatNumber(123456, 0)).toEqual('123,456');
expect(formatNumber(123456, 7)).toEqual('123,456.0000000');
});
});
});
11 changes: 11 additions & 0 deletions ui/pages/confirmations/components/confirm/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ export const getConfirmationSender = (

return { from };
};

export const formatNumber = (value: number, decimals: number) => {
if (value === undefined) {
return value;
}
const formatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: decimals,
maximumFractionDigits: decimals,
});
return formatter.format(value);
};

0 comments on commit 6557b59

Please sign in to comment.