diff --git a/test/data/confirmations/typed_sign.ts b/test/data/confirmations/typed_sign.ts index 0a05a6716432..3dd236ca9fa6 100644 --- a/test/data/confirmations/typed_sign.ts +++ b/test/data/confirmations/typed_sign.ts @@ -173,3 +173,41 @@ export const permitSignatureMsg = { origin: 'https://metamask.github.io', }, } as SignatureRequestType; + +export const permitBatchSignatureMsg = { + id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659', + securityAlertResponse: { + reason: 'loading', + result_type: 'validation_in_progress', + securityAlertId: 'ab21395f-2190-472f-8cfa-3d224e7529d8', + }, + status: 'unapproved', + time: 1716826404122, + type: 'eth_signTypedData', + msgParams: { + data: '{"types":{"PermitBatch":[{"name":"details","type":"PermitDetails[]"},{"name":"spender","type":"address"},{"name":"sigDeadline","type":"uint256"}],"PermitDetails":[{"name":"token","type":"address"},{"name":"amount","type":"uint160"},{"name":"expiration","type":"uint48"},{"name":"nonce","type":"uint48"}],"EIP712Domain":[{"name":"name","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}]},"domain":{"name":"Permit2","chainId":"1","verifyingContract":"0x000000000022d473030f116ddee9f6b43ac78ba3"},"primaryType":"PermitBatch","message":{"details":[{"token":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","amount":"1461501637330902918203684832716283019655932542975","expiration":"1722887542","nonce":"5"},{"token":"0xb0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","amount":"2461501637330902918203684832716283019655932542975","expiration":"1722887642","nonce":"6"}],"spender":"0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad","sigDeadline":"1720297342"}}', + from: '0x935e73edb9ff52e23bac7f7e043a1ecd06d05477', + version: 'V4', + signatureMethod: 'eth_signTypedData_v4', + origin: 'https://metamask.github.io', + }, +} as SignatureRequestType; + +export const permitSingleSignatureMsg = { + id: '0b1787a0-1c44-11ef-b70d-e7064bd7b659', + securityAlertResponse: { + reason: 'loading', + result_type: 'validation_in_progress', + securityAlertId: 'ab21395f-2190-472f-8cfa-3d224e7529d8', + }, + status: 'unapproved', + time: 1716826404122, + type: 'eth_signTypedData', + msgParams: { + data: '{"types":{"PermitSingle":[{"name":"details","type":"PermitDetails"},{"name":"spender","type":"address"},{"name":"sigDeadline","type":"uint256"}],"PermitDetails":[{"name":"token","type":"address"},{"name":"amount","type":"uint160"},{"name":"expiration","type":"uint48"},{"name":"nonce","type":"uint48"}],"EIP712Domain":[{"name":"name","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}]},"domain":{"name":"Permit2","chainId":"1","verifyingContract":"0x000000000022d473030f116ddee9f6b43ac78ba3"},"primaryType":"PermitSingle","message":{"details":{"token":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","amount":"1461501637330902918203684832716283019655932542975","expiration":"1722887542","nonce":"5"},"spender":"0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad","sigDeadline":"1720297342"}}', + from: '0x935e73edb9ff52e23bac7f7e043a1ecd06d05477', + version: 'V4', + signatureMethod: 'eth_signTypedData_v4', + origin: 'https://metamask.github.io', + }, +} as SignatureRequestType; diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap index f94ae6dd0b54..6446290ea2b6 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/__snapshots__/permit-simulation.test.tsx.snap @@ -63,51 +63,55 @@ exports[`PermitSimulation renders component correctly 1`] = ` style="margin-left: auto; max-width: 100%;" >
-

- 30 -

+

+ 30 +

+
-
-
-
- -

+

- 0xCcCCc...ccccC -

+ +

+ 0xCcCCc...ccccC +

+
+
-
diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx index daca28ece848..e85ffa28b227 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.test.tsx @@ -1,24 +1,41 @@ import React from 'react'; import configureMockStore from 'redux-mock-store'; +import { act } from 'react-dom/test-utils'; import mockState from '../../../../../../../../test/data/mock-state.json'; +// import { getMockTypedSignConfirmStateForRequest } from '../../../../../../../../test/data/confirmations/helper'; import { renderWithProvider } from '../../../../../../../../test/lib/render-helpers'; +// TODO: readd in 12.4.0 +// import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers'; import { permitSignatureMsg } from '../../../../../../../../test/data/confirmations/typed_sign'; import PermitSimulation from './permit-simulation'; +jest.mock('../../../../../../../store/actions', () => { + return { + getTokenStandardAndDetails: jest.fn().mockResolvedValue({ decimals: 2 }), + }; +}); + describe('PermitSimulation', () => { - it('renders component correctly', () => { + it('renders component correctly', async () => { const state = { ...mockState, confirm: { currentConfirmation: permitSignatureMsg, }, }; + // TODO: readd in 12.4.0 + // const state = getMockTypedSignConfirmStateForRequest(permitSignatureMsg); const mockStore = configureMockStore([])(state); - const { container } = renderWithProvider( - , - mockStore, - ); - expect(container).toMatchSnapshot(); + + await act(async () => { + const { container, findByText } = renderWithProvider( + , + mockStore, + ); + + expect(await findByText('30')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); }); }); diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx index e5e9529a516a..b246c2816d4d 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/permit-simulation.tsx @@ -1,69 +1,61 @@ -import React, { useMemo } from 'react'; +import React from 'react'; import { useSelector } from 'react-redux'; -import { NameType } from '@metamask/name-controller'; -import { calcTokenAmount } from '../../../../../../../../shared/lib/transactions-controller-utils'; +import { PrimaryType } from '../../../../../../../../shared/constants/signatures'; import { parseTypedDataMessage } from '../../../../../../../../shared/modules/transaction.utils'; -import { Numeric } from '../../../../../../../../shared/modules/Numeric'; -import Name from '../../../../../../../components/app/name/name'; import { ConfirmInfoRow, ConfirmInfoRowText, } from '../../../../../../../components/app/confirm/info/row'; -import { shortenString } from '../../../../../../../helpers/utils/util'; import { useI18nContext } from '../../../../../../../hooks/useI18nContext'; import { currentConfirmationSelector } from '../../../../../../../selectors'; -import { Box, Text } from '../../../../../../../components/component-library'; -import Tooltip from '../../../../../../../components/ui/tooltip'; +import { Box } from '../../../../../../../components/component-library'; import { - BackgroundColor, - BlockSize, - BorderRadius, Display, - TextAlign, + FlexDirection, } from '../../../../../../../helpers/constants/design-system'; import { SignatureRequestType } from '../../../../../types/confirm'; -import useTokenExchangeRate from '../../../../../../../components/app/currency-input/hooks/useTokenExchangeRate'; -import { IndividualFiatDisplay } from '../../../../simulation-details/fiat-display'; -import { - formatAmount, - formatAmountMaxPrecision, -} from '../../../../simulation-details/formatAmount'; import { ConfirmInfoSection } from '../../../../../../../components/app/confirm/info/row/section'; +import PermitSimulationValueDisplay from './value-display/value-display'; + +function extractTokenDetailsByPrimaryType( + message: Record, + primaryType: PrimaryType, +): object[] | unknown { + let tokenDetails; + + switch (primaryType) { + case PrimaryType.PermitBatch: + case PrimaryType.PermitSingle: + tokenDetails = message?.details; + break; + case PrimaryType.PermitBatchTransferFrom: + case PrimaryType.PermitTransferFrom: + tokenDetails = message?.permitted; + break; + default: + break; + } + + const isNonArrayObject = tokenDetails && !Array.isArray(tokenDetails); -const PermitSimulation: React.FC<{ - tokenDecimals: number; -}> = ({ tokenDecimals }) => { + return isNonArrayObject ? [tokenDetails] : tokenDetails; +} + +const PermitSimulation: React.FC = () => { const t = useI18nContext(); const currentConfirmation = useSelector( currentConfirmationSelector, ) as SignatureRequestType; + const msgData = currentConfirmation.msgParams?.data; const { domain: { verifyingContract }, - message: { value }, - } = parseTypedDataMessage(currentConfirmation.msgParams?.data as string); - - const exchangeRate = useTokenExchangeRate(verifyingContract); - - const fiatValue = useMemo(() => { - if (exchangeRate && value) { - return exchangeRate.times(new Numeric(value, 10)).toNumber(); - } - return undefined; - }, [exchangeRate, value]); - - const { tokenValue, tokenValueMaxPrecision } = useMemo(() => { - if (!value) { - return { tokenValue: null, tokenValueMaxPrecision: null }; - } - const tokenAmount = calcTokenAmount(value, tokenDecimals); + message, + primaryType, + } = parseTypedDataMessage(msgData as string); - return { - tokenValue: formatAmount('en-US', tokenAmount), - tokenValueMaxPrecision: formatAmountMaxPrecision('en-US', tokenAmount), - }; - }, [tokenDecimals, value]); + const tokenDetails = extractTokenDetailsByPrimaryType(message, primaryType); return ( @@ -75,42 +67,32 @@ const PermitSimulation: React.FC<{ - + {Array.isArray(tokenDetails) ? ( - - - {shortenString(tokenValue || '', { - truncatedCharLimit: 15, - truncatedStartChars: 15, - truncatedEndChars: 0, - skipCharacterInEnd: true, - })} - - + {tokenDetails.map( + ( + { token, amount }: { token: string; amount: string }, + i: number, + ) => ( + + ), + )} - - - - {fiatValue && ( - - )} - + ) : ( + + )} diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/__snapshots__/value-display.test.tsx.snap b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/__snapshots__/value-display.test.tsx.snap new file mode 100644 index 000000000000..022ff8b6dbc2 --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/__snapshots__/value-display.test.tsx.snap @@ -0,0 +1,56 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`PermitSimulationValueDisplay renders component correctly 1`] = ` +
+
+
+
+
+
+

+ 0.432 +

+
+
+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+
+`; diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.test.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.test.tsx new file mode 100644 index 000000000000..f6af7357502d --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.test.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { act } from 'react-dom/test-utils'; +import configureMockStore from 'redux-mock-store'; + +import mockState from '../../../../../../../../../test/data/mock-state.json'; +import { renderWithProvider } from '../../../../../../../../../test/lib/render-helpers'; +import PermitSimulationValueDisplay from './value-display'; + +jest.mock('../../../../../../../../store/actions', () => { + return { + getTokenStandardAndDetails: jest.fn().mockResolvedValue({ decimals: 4 }), + }; +}); + +describe('PermitSimulationValueDisplay', () => { + it('renders component correctly', async () => { + const mockStore = configureMockStore([])(mockState); + + await act(async () => { + const { container, findByText } = renderWithProvider( + , + mockStore, + ); + + expect(await findByText('0.432')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); + }); +}); diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx new file mode 100644 index 000000000000..d0cd9c529d0e --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/permit-simulation/value-display/value-display.tsx @@ -0,0 +1,121 @@ +import React, { useMemo } from 'react'; +import { NameType } from '@metamask/name-controller'; +import { captureException } from '@sentry/browser'; +import { getTokenStandardAndDetails } from '../../../../../../../../store/actions'; +import { shortenString } from '../../../../../../../../helpers/utils/util'; + +import { calcTokenAmount } from '../../../../../../../../../shared/lib/transactions-controller-utils'; +import useTokenExchangeRate from '../../../../../../../../components/app/currency-input/hooks/useTokenExchangeRate'; +import { IndividualFiatDisplay } from '../../../../../simulation-details/fiat-display'; +import { + formatAmount, + formatAmountMaxPrecision, +} from '../../../../../simulation-details/formatAmount'; +import { useAsyncResult } from '../../../../../../../../hooks/useAsyncResult'; + +import { + Box, + Text, +} from '../../../../../../../../components/component-library'; +import Tooltip from '../../../../../../../../components/ui/tooltip'; +import { + BackgroundColor, + BlockSize, + BorderRadius, + Display, + JustifyContent, + TextAlign, +} from '../../../../../../../../helpers/constants/design-system'; +import Name from '../../../../../../../../components/app/name/name'; + +const getTokenDecimals = async (tokenContract: string) => { + const tokenDetails = await getTokenStandardAndDetails(tokenContract); + const tokenDecimals = tokenDetails?.decimals; + + return parseInt(tokenDecimals ?? '0', 10); +}; + +const PermitSimulationValueDisplay: React.FC<{ + primaryType?: string; + tokenContract: string; + value: number | string; +}> = ({ primaryType, tokenContract, value }) => { + const exchangeRate = useTokenExchangeRate(tokenContract); + + const { value: tokenDecimals } = useAsyncResult( + async () => await getTokenDecimals(tokenContract), + [tokenContract], + ); + + const fiatValue = useMemo(() => { + if (exchangeRate && value) { + const tokenAmount = calcTokenAmount(value, tokenDecimals); + return exchangeRate.times(tokenAmount).toNumber(); + } + return undefined; + }, [exchangeRate, tokenDecimals, value]); + + const { tokenValue, tokenValueMaxPrecision } = useMemo(() => { + if (!value) { + return { tokenValue: null, tokenValueMaxPrecision: null }; + } + + const tokenAmount = calcTokenAmount(value, tokenDecimals); + + return { + tokenValue: formatAmount('en-US', tokenAmount), + tokenValueMaxPrecision: formatAmountMaxPrecision('en-US', tokenAmount), + }; + }, [tokenDecimals, value]); + + /** Temporary error capturing as we are building out Permit Simulations */ + if (!tokenContract) { + captureException( + new Error( + `PermitSimulationValueDisplay: Token contract address is missing where primaryType === ${primaryType}`, + ), + ); + return null; + } + + return ( + + + + + + {shortenString(tokenValue || '', { + truncatedCharLimit: 15, + truncatedStartChars: 15, + truncatedEndChars: 0, + skipCharacterInEnd: true, + })} + + + + + + + {fiatValue && } + + + ); +}; + +export default PermitSimulationValueDisplay; diff --git a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx index 48e7f6b64941..ddb56bf82800 100644 --- a/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx +++ b/ui/pages/confirmations/components/confirm/info/typed-sign/typed-sign.tsx @@ -58,9 +58,7 @@ const TypedSignInfo: React.FC = () => { return ( <> - {isPermit && useTransactionSimulations && ( - - )} + {isPermit && useTransactionSimulations && } {isPermit && ( <> diff --git a/ui/pages/confirmations/components/confirm/row/dataTree.tsx b/ui/pages/confirmations/components/confirm/row/dataTree.tsx index 2b38ccee5663..f728b9d5dfa9 100644 --- a/ui/pages/confirmations/components/confirm/row/dataTree.tsx +++ b/ui/pages/confirmations/components/confirm/row/dataTree.tsx @@ -73,12 +73,10 @@ const getTokenDecimalsOfDataTree = async ( return undefined; } - const decimals = parseInt( - (await getTokenStandardAndDetails(tokenContract))?.decimals ?? '0', - 10, - ); + const tokenDetails = await getTokenStandardAndDetails(tokenContract); + const tokenDecimals = tokenDetails?.decimals; - return decimals; + return parseInt(tokenDecimals ?? '0', 10); }; export const DataTree = ({ diff --git a/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap b/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap index ef4508c65552..84bab3847b1e 100644 --- a/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap +++ b/ui/pages/confirmations/confirm/__snapshots__/confirm.test.tsx.snap @@ -225,6 +225,1814 @@ exports[`Confirm matches snapshot for signature - personal sign type 1`] = `
`; +exports[`Confirm should match snapshot for signature - typed sign - V4 - PermitBatch 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ C +
+
+
+

+

+ Chain 5 +

+
+
+
+
+
+
+ +
+
+
+
+
+
+
+

+ Spending cap request +

+

+ This site wants permission to spend your tokens. +

+
+
+
+

+ Estimated changes +

+
+
+ +
+
+
+
+

+ You're giving the spender permission to spend this many tokens from your account. +

+
+
+
+
+

+ Spending cap +

+
+
+
+
+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+
+
+
+
+
+

+ 24,615,016,373,... +

+
+
+
+
+
+ +

+ 0xb0B86...6EB48 +

+
+
+
+
+
+
+
+
+
+
+
+
+

+ Spender +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+
+

+ Request from +

+
+
+ +
+
+
+
+

+ metamask.github.io +

+
+
+
+
+

+ Interacting with +

+
+
+
+ +

+ 0x00000...78BA3 +

+
+
+
+
+
+
+
+

+ Message +

+
+
+
+
+

+ Primary type: +

+
+
+

+ PermitBatch +

+
+
+
+
+
+
+

+ Details: +

+
+
+
+
+

+ 0: +

+
+
+
+
+

+ Token: +

+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+

+ Amount: +

+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+
+

+ Expiration: +

+
+
+

+ 20 January 1970, 22:34 +

+
+
+
+
+

+ Nonce: +

+
+
+

+ 5 +

+
+
+
+
+
+
+

+ 1: +

+
+
+
+
+

+ Token: +

+
+
+
+ +

+ 0xb0B86...6EB48 +

+
+
+
+
+
+

+ Amount: +

+
+
+
+
+

+ 24,615,016,373,... +

+
+
+
+
+
+
+

+ Expiration: +

+
+
+

+ 20 January 1970, 22:34 +

+
+
+
+
+

+ Nonce: +

+
+
+

+ 6 +

+
+
+
+
+
+
+
+
+

+ Spender: +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+

+ SigDeadline: +

+
+
+

+ 20 January 1970, 21:51 +

+
+
+
+
+
+
+
+
+
+ +
+
+
+`; + +exports[`Confirm should match snapshot for signature - typed sign - V4 - PermitSingle 1`] = ` +
+
+
+
+
+
+
+
+
+ + + + + +
+
+
+
+ C +
+
+
+

+

+ Chain 5 +

+
+
+
+
+
+
+ +
+
+
+
+
+
+
+

+ Spending cap request +

+

+ This site wants permission to spend your tokens. +

+
+
+
+

+ Estimated changes +

+
+
+ +
+
+
+
+

+ You're giving the spender permission to spend this many tokens from your account. +

+
+
+
+
+

+ Spending cap +

+
+
+
+
+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+
+
+
+
+
+
+
+

+ Spender +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+
+

+ Request from +

+
+
+ +
+
+
+
+

+ metamask.github.io +

+
+
+
+
+

+ Interacting with +

+
+
+
+ +

+ 0x00000...78BA3 +

+
+
+
+
+
+
+
+

+ Message +

+
+
+
+
+

+ Primary type: +

+
+
+

+ PermitSingle +

+
+
+
+
+
+
+

+ Details: +

+
+
+
+
+

+ Token: +

+
+
+
+ +

+ 0xA0b86...6eB48 +

+
+
+
+
+
+

+ Amount: +

+
+
+
+
+

+ 14,615,016,373,... +

+
+
+
+
+
+
+

+ Expiration: +

+
+
+

+ 20 January 1970, 22:34 +

+
+
+
+
+

+ Nonce: +

+
+
+

+ 5 +

+
+
+
+
+
+
+

+ Spender: +

+
+
+
+ +

+ 0x3fC91...b7FAD +

+
+
+
+
+
+

+ SigDeadline: +

+
+
+

+ 20 January 1970, 21:51 +

+
+
+
+
+
+
+
+
+
+ +
+
+
+`; + exports[`Confirm should match snapshot for signature - typed sign - V4 1`] = `
-
- - - - - -
-
+ />
- C + Chain 5 logo
+ />

+ />

+ />

+ />

+ />

+ />

+ />

{ expect(container).toMatchSnapshot(); }); + // TODO: re-add for 12.4.0 + // it('matches snapshot for signature - personal sign type', async () => { + // const mockStatePersonalSign = getMockPersonalSignConfirmState(); + // const mockStore = configureMockStore(middleware)(mockStatePersonalSign); + + // await act(async () => { + // const { container } = await renderWithConfirmContextProvider( + // , + // mockStore, + // ); + // expect(container).toMatchSnapshot(); + // }); + // }); + it('should match snapshot signature - typed sign - order', async () => { const mockStateTypedSign = { ...mockState, @@ -113,7 +129,85 @@ describe('Confirm', () => { confirm: { currentConfirmation: unapprovedTypedSignMsgV4 }, }; const mockStore = configureMockStore(middleware)(mockStateTypedSign); - const { container } = renderWithProvider(, mockStore); - expect(container).toMatchSnapshot(); + + await act(async () => { + // TODO: re-add for 12.4.0 + // const { container } = await renderWithConfirmContextProvider( + const { container } = renderWithProvider(, mockStore); + + expect(container).toMatchSnapshot(); + }); + }); + + it('should match snapshot for signature - typed sign - V4 - PermitSingle', async () => { + const mockStateTypedSign = { + ...mockState, + metamask: { + ...mockState.metamask, + useTransactionSimulations: true, + }, + confirm: { currentConfirmation: permitSingleSignatureMsg }, + }; + // TODO: re-add for 12.4.0 + // const mockStateTypedSign = getMockTypedSignConfirmStateForRequest( + // permitSingleSignatureMsg, + // { + // metamask: { useTransactionSimulations: true }, + // }, + // ); + const mockStore = configureMockStore(middleware)(mockStateTypedSign); + + jest.spyOn(actions, 'getTokenStandardAndDetails').mockResolvedValue({ + decimals: '2', + standard: 'erc20', + }); + + await act(async () => { + // TODO: re-add for 12.4.0 + // const { container, findByText } = await renderWithConfirmContextProvider( + const { container, findByText } = renderWithProvider( + , + mockStore, + ); + + expect(await findByText('1,461,501,637,3...')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); + }); + + it('should match snapshot for signature - typed sign - V4 - PermitBatch', async () => { + const mockStateTypedSign = { + ...mockState, + metamask: { + ...mockState.metamask, + useTransactionSimulations: true, + }, + confirm: { currentConfirmation: permitBatchSignatureMsg }, + }; + // TODO: re-add for 12.4.0 + // const mockStateTypedSign = getMockTypedSignConfirmStateForRequest( + // permitBatchSignatureMsg, + // { + // metamask: { useTransactionSimulations: true }, + // }, + // ); + const mockStore = configureMockStore(middleware)(mockStateTypedSign); + + jest.spyOn(actions, 'getTokenStandardAndDetails').mockResolvedValue({ + decimals: '2', + standard: 'erc20', + }); + + await act(async () => { + // TODO: re-add for 12.4.0 + // const { container, findByText } = await renderWithConfirmContextProvider( + const { container, findByText } = renderWithProvider( + , + mockStore, + ); + + expect(await findByText('1,461,501,637,3...')).toBeInTheDocument(); + expect(container).toMatchSnapshot(); + }); }); });