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 7c5553495eb0..f35e2218cbfb 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 @@ -127,3 +127,120 @@ exports[`PermitSimulation renders component correctly 1`] = ` `; + +exports[`PermitSimulation renders correctly for NFT permit 1`] = ` +
+
+
+
+
+

+ Estimated changes +

+
+
+ +
+
+
+
+
+

+ You're giving someone else permission to withdraw NFTs from your account. +

+
+
+
+
+
+

+ Withdraw +

+
+
+
+
+
+
+
+

+ #3606393 +

+
+
+
+
+ +

+ 0xC3644...1FE88 +

+
+
+
+
+
+
+
+
+
+`; 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 1be34109a637..e89efb3c0dc1 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 @@ -4,7 +4,10 @@ import { act } from 'react-dom/test-utils'; import { getMockTypedSignConfirmStateForRequest } from '../../../../../../../../test/data/confirmations/helper'; import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers'; -import { permitSignatureMsg } from '../../../../../../../../test/data/confirmations/typed_sign'; +import { + permitNFTSignatureMsg, + permitSignatureMsg, +} from '../../../../../../../../test/data/confirmations/typed_sign'; import PermitSimulation from './permit-simulation'; jest.mock('../../../../../../../store/actions', () => { @@ -28,4 +31,20 @@ describe('PermitSimulation', () => { expect(container).toMatchSnapshot(); }); }); + + it('renders correctly for NFT permit', async () => { + const state = getMockTypedSignConfirmStateForRequest(permitNFTSignatureMsg); + const mockStore = configureMockStore([])(state); + + await act(async () => { + const { container, findByText } = renderWithConfirmContextProvider( + , + mockStore, + ); + + expect(await findByText('Withdraw')).toBeInTheDocument(); + expect(await findByText('#3606393')).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 231997d18547..44131ec18fbf 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 @@ -45,8 +45,10 @@ const PermitSimulation: React.FC = () => { const { domain: { verifyingContract }, message, + message: { tokenId }, primaryType, } = parseTypedDataMessage(msgData as string); + const isNFT = tokenId !== undefined; const tokenDetails = extractTokenDetailsByPrimaryType(message, primaryType); @@ -68,7 +70,9 @@ const PermitSimulation: React.FC = () => { ); const SpendingCapRow = ( - + {Array.isArray(tokenDetails) ? ( = () => { )} @@ -99,7 +104,9 @@ const PermitSimulation: React.FC = () => { ); 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 index 26def806c6fa..9c4134aa1b2d 100644 --- 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 @@ -56,3 +56,49 @@ exports[`PermitSimulationValueDisplay renders component correctly 1`] = ` `; + +exports[`PermitSimulationValueDisplay renders component correctly for NFT token 1`] = ` +
+
+
+
+
+

+ #4321 +

+
+
+
+
+ +

+ 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 index f6af7357502d..da86d497aac1 100644 --- 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 @@ -29,4 +29,21 @@ describe('PermitSimulationValueDisplay', () => { expect(container).toMatchSnapshot(); }); }); + + it('renders component correctly for NFT token', async () => { + const mockStore = configureMockStore([])(mockState); + + await act(async () => { + const { container, findByText } = renderWithProvider( + , + mockStore, + ); + + expect(await findByText('#4321')).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 index 633191cd2638..360559493596 100644 --- 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 @@ -41,21 +41,26 @@ type PermitSimulationValueDisplayParams = { tokenContract: Hex | string; /** The token amount */ - value: number | string; + value?: number | string; + + /** The tokenId for NFT */ + tokenId?: string; }; const PermitSimulationValueDisplay: React.FC< PermitSimulationValueDisplayParams -> = ({ primaryType, tokenContract, value }) => { +> = ({ primaryType, tokenContract, value, tokenId }) => { const exchangeRate = useTokenExchangeRate(tokenContract); - const { value: tokenDecimals } = useAsyncResult( - async () => await fetchErc20Decimals(tokenContract), - [tokenContract], - ); + const { value: tokenDecimals } = useAsyncResult(async () => { + if (tokenId) { + return undefined; + } + return await fetchErc20Decimals(tokenContract); + }, [tokenContract]); const fiatValue = useMemo(() => { - if (exchangeRate && value) { + if (exchangeRate && value && !tokenId) { const tokenAmount = calcTokenAmount(value, tokenDecimals); return exchangeRate.times(tokenAmount).toNumber(); } @@ -63,7 +68,7 @@ const PermitSimulationValueDisplay: React.FC< }, [exchangeRate, tokenDecimals, value]); const { tokenValue, tokenValueMaxPrecision } = useMemo(() => { - if (!value) { + if (!value || tokenId) { return { tokenValue: null, tokenValueMaxPrecision: null }; } @@ -107,12 +112,14 @@ const PermitSimulationValueDisplay: React.FC< style={{ paddingTop: '1px', paddingBottom: '1px' }} textAlign={TextAlign.Center} > - {shortenString(tokenValue || '', { - truncatedCharLimit: 15, - truncatedStartChars: 15, - truncatedEndChars: 0, - skipCharacterInEnd: true, - })} + {tokenValue !== null && + shortenString(tokenValue || '', { + truncatedCharLimit: 15, + truncatedStartChars: 15, + truncatedEndChars: 0, + skipCharacterInEnd: true, + })} + {tokenId && `#${tokenId}`}