mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Fix a bug where non-address types would be rendered as addresses in EIP-712 (#17846)
* Fix EIP-712 rendering logic * Fix tests * Fix tests and story * Fix lint * Fix import * Fix stories
This commit is contained in:
parent
932282e638
commit
64bfe6f307
@ -26,7 +26,7 @@ function SignatureRequestData({ data }) {
|
||||
|
||||
return (
|
||||
<Box className="signature-request-data__node">
|
||||
{Object.entries(data).map(([label, value], i) => (
|
||||
{Object.entries(data).map(([label, { value, type }], i) => (
|
||||
<Box
|
||||
className="signature-request-data__node"
|
||||
key={`${label}-${i}`}
|
||||
@ -54,7 +54,8 @@ function SignatureRequestData({ data }) {
|
||||
marginLeft={4}
|
||||
className="signature-request-data__node__value"
|
||||
>
|
||||
{isValidHexAddress(value, {
|
||||
{type === 'address' &&
|
||||
isValidHexAddress(value, {
|
||||
mixedCaseUseChecksum: true,
|
||||
}) ? (
|
||||
<Typography
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { sanitizeMessage } from '../../../../helpers/utils/util';
|
||||
import SignatureRequestData from './signature-request-data';
|
||||
|
||||
export default {
|
||||
@ -16,38 +17,58 @@ export const DefaultStory = (args) => {
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
||||
|
||||
DefaultStory.args = {
|
||||
data: JSON.parse(
|
||||
JSON.stringify({
|
||||
domain: {
|
||||
name: 'happydapp.website',
|
||||
},
|
||||
message: {
|
||||
string: 'haay wuurl',
|
||||
number: 42,
|
||||
},
|
||||
primaryType: 'Mail',
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
{ name: 'chainId', type: 'uint256' },
|
||||
{ name: 'verifyingContract', type: 'address' },
|
||||
],
|
||||
Group: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'members', type: 'Person[]' },
|
||||
],
|
||||
Mail: [
|
||||
{ name: 'from', type: 'Person' },
|
||||
{ name: 'to', type: 'Person[]' },
|
||||
{ name: 'contents', type: 'string' },
|
||||
],
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallets', type: 'address[]' },
|
||||
const rawMessage = {
|
||||
domain: {
|
||||
chainId: 97,
|
||||
name: 'Ether Mail',
|
||||
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
|
||||
version: '1',
|
||||
},
|
||||
message: {
|
||||
contents: 'Hello, Bob!',
|
||||
from: {
|
||||
name: 'Cow',
|
||||
wallets: [
|
||||
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
||||
'0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
|
||||
'0x06195827297c7A80a443b6894d3BDB8824b43896',
|
||||
],
|
||||
},
|
||||
to: [
|
||||
{
|
||||
name: 'Bob',
|
||||
wallets: [
|
||||
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
'0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
],
|
||||
},
|
||||
}),
|
||||
),
|
||||
],
|
||||
},
|
||||
primaryType: 'Mail',
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
{ name: 'chainId', type: 'uint256' },
|
||||
{ name: 'verifyingContract', type: 'address' },
|
||||
],
|
||||
Mail: [
|
||||
{ name: 'from', type: 'Person' },
|
||||
{ name: 'to', type: 'Person[]' },
|
||||
{ name: 'contents', type: 'string' },
|
||||
],
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallets', type: 'address[]' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
DefaultStory.args = {
|
||||
data: sanitizeMessage(
|
||||
rawMessage.message,
|
||||
rawMessage.primaryType,
|
||||
rawMessage.types,
|
||||
).value,
|
||||
};
|
||||
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import configureMockStore from 'redux-mock-store';
|
||||
import { renderWithProvider } from '../../../../../test/lib/render-helpers';
|
||||
import { sanitizeMessage } from '../../../../helpers/utils/util';
|
||||
import Identicon from '../../../ui/identicon';
|
||||
import SignatureRequestData from './signature-request-data';
|
||||
|
||||
@ -59,124 +60,65 @@ describe('Signature Request Data', () => {
|
||||
},
|
||||
};
|
||||
|
||||
let messageData;
|
||||
const store = configureMockStore()(mockStore);
|
||||
|
||||
beforeEach(() => {
|
||||
messageData = {
|
||||
domain: {
|
||||
chainId: 97,
|
||||
name: 'Ether Mail',
|
||||
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
|
||||
version: '1',
|
||||
const rawMessage = {
|
||||
domain: {
|
||||
chainId: 97,
|
||||
name: 'Ether Mail',
|
||||
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
|
||||
version: '1',
|
||||
},
|
||||
message: {
|
||||
contents: 'Hello, Bob!',
|
||||
from: {
|
||||
name: 'Cow',
|
||||
wallets: [
|
||||
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
||||
'0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
|
||||
'0x06195827297c7A80a443b6894d3BDB8824b43896',
|
||||
],
|
||||
},
|
||||
message: {
|
||||
contents: 'Hello, Bob!',
|
||||
from: {
|
||||
name: 'Cow',
|
||||
to: [
|
||||
{
|
||||
name: 'Bob',
|
||||
wallets: [
|
||||
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
||||
'0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
|
||||
'0x06195827297c7A80a443b6894d3BDB8824b43896',
|
||||
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
'0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
],
|
||||
},
|
||||
to: [
|
||||
{
|
||||
name: 'Bob',
|
||||
wallets: [
|
||||
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
'0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
primaryType: 'Mail',
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
{ name: 'chainId', type: 'uint256' },
|
||||
{ name: 'verifyingContract', type: 'address' },
|
||||
],
|
||||
Mail: [
|
||||
{ name: 'from', type: 'Person' },
|
||||
{ name: 'to', type: 'Person[]' },
|
||||
{ name: 'contents', type: 'string' },
|
||||
],
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallets', type: 'address[]' },
|
||||
],
|
||||
},
|
||||
};
|
||||
});
|
||||
],
|
||||
},
|
||||
primaryType: 'Mail',
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
{ name: 'chainId', type: 'uint256' },
|
||||
{ name: 'verifyingContract', type: 'address' },
|
||||
],
|
||||
Mail: [
|
||||
{ name: 'from', type: 'Person' },
|
||||
{ name: 'to', type: 'Person[]' },
|
||||
{ name: 'contents', type: 'string' },
|
||||
],
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallets', type: 'address[]' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
it('should render domain chainId', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText('97')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render domain name', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText('Ether Mail')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render Identicon for domain verifying contract', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const iconImage = (
|
||||
<Identicon
|
||||
diameter={32}
|
||||
address={msgParams.data.domain.verifyingContract}
|
||||
/>
|
||||
);
|
||||
expect(iconImage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render domain verifying contract shorten address', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
store,
|
||||
);
|
||||
|
||||
expect(getByText('0xCcC...cccC')).toBeInTheDocument();
|
||||
});
|
||||
const messageData = sanitizeMessage(
|
||||
rawMessage.message,
|
||||
rawMessage.primaryType,
|
||||
rawMessage.types,
|
||||
);
|
||||
|
||||
it('should render contents title', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -184,13 +126,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render contants text', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -198,13 +135,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render from title', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -212,13 +144,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render name title in "from" object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams.data.message.from} />,
|
||||
<SignatureRequestData data={messageData.value.from.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -226,13 +153,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render name text in "from" object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -240,13 +162,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render wallets title in "from" object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams.data.message.from} />,
|
||||
<SignatureRequestData data={messageData.value.from.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -254,28 +171,18 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render Identicon for first wallet in "from" object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const iconImage = (
|
||||
<Identicon
|
||||
diameter={32}
|
||||
address={msgParams.data.message.from.wallets[0]}
|
||||
address={messageData.value.from.value.wallets.value[0].value}
|
||||
/>
|
||||
);
|
||||
expect(iconImage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render first account name from wallets array if address exists in identities object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -283,28 +190,18 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render Identicon for second wallet in "from" object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const iconImage = (
|
||||
<Identicon
|
||||
diameter={32}
|
||||
address={msgParams.data.message.from.wallets[1]}
|
||||
address={messageData.value.from.value.wallets.value[1].value}
|
||||
/>
|
||||
);
|
||||
expect(iconImage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render second account name from wallets array if address exists in identities object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -312,28 +209,18 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render Identicon for third wallet in "from" object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const iconImage = (
|
||||
<Identicon
|
||||
diameter={32}
|
||||
address={msgParams.data.message.from.wallets[2]}
|
||||
address={messageData.value.from.value.wallets.value[2].value}
|
||||
/>
|
||||
);
|
||||
expect(iconImage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render third account name from wallets array if address exists in address book object', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -341,13 +228,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render name title in "to" array of objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams.data.message.to[0]} />,
|
||||
<SignatureRequestData data={messageData.value.to.value[0].value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -355,13 +237,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render name text in "to" array of objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams.data.message.to[0]} />,
|
||||
<SignatureRequestData data={messageData.value.to.value[0].value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -369,13 +246,8 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render wallets title in "to" array of objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams.data.message.to[0]} />,
|
||||
<SignatureRequestData data={messageData.value.to.value[0].value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -383,28 +255,18 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render Identicon for first wallet in "to" array of objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const iconImage = (
|
||||
<Identicon
|
||||
diameter={32}
|
||||
address={msgParams.data.message.to[0].wallets[0]}
|
||||
address={messageData.value.to.value[0].value.wallets.value[0].value}
|
||||
/>
|
||||
);
|
||||
expect(iconImage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render first shorten address from wallets array if address does not exists in identities and address book objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -412,28 +274,18 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render Identicon for second wallet in "to" array of objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const iconImage = (
|
||||
<Identicon
|
||||
diameter={32}
|
||||
address={msgParams.data.message.to[0].wallets[1]}
|
||||
address={messageData.value.to.value[0].value.wallets.value[1].value}
|
||||
/>
|
||||
);
|
||||
expect(iconImage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render second shorten address from wallets array if address does not exists in identities and address book objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -441,28 +293,18 @@ describe('Signature Request Data', () => {
|
||||
});
|
||||
|
||||
it('should render Identicon for third wallet in "to" array of objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const iconImage = (
|
||||
<Identicon
|
||||
diameter={32}
|
||||
address={msgParams.data.message.to[0].wallets[2]}
|
||||
address={messageData.value.to.value[0].value.wallets.value[2].value}
|
||||
/>
|
||||
);
|
||||
expect(iconImage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should render third shorten address from wallets array if address does not exists in identities and address book objects', () => {
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageData)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const { getByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={messageData.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
@ -471,9 +313,9 @@ describe('Signature Request Data', () => {
|
||||
|
||||
it('should escape RTL character in label or value', () => {
|
||||
const messageDataWithRTLCharacters = {
|
||||
...messageData,
|
||||
...rawMessage,
|
||||
message: {
|
||||
...messageData.message,
|
||||
...rawMessage.message,
|
||||
contents: 'Hello, \u202E Bob!',
|
||||
from: {
|
||||
'name\u202Ename': 'Cow \u202E Cow',
|
||||
@ -495,20 +337,20 @@ describe('Signature Request Data', () => {
|
||||
],
|
||||
},
|
||||
types: {
|
||||
...messageData.message.types,
|
||||
...rawMessage.types,
|
||||
Person: [
|
||||
{ name: 'name\u202Ename', type: 'string' },
|
||||
{ name: 'wallets\u202Ewallets', type: 'address[]' },
|
||||
],
|
||||
},
|
||||
};
|
||||
const msgParams = {
|
||||
data: JSON.parse(JSON.stringify(messageDataWithRTLCharacters)),
|
||||
version: 'V4',
|
||||
origin: 'test',
|
||||
};
|
||||
const data = sanitizeMessage(
|
||||
messageDataWithRTLCharacters.message,
|
||||
messageDataWithRTLCharacters.primaryType,
|
||||
messageDataWithRTLCharacters.types,
|
||||
);
|
||||
const { getByText, getAllByText } = renderWithProvider(
|
||||
<SignatureRequestData data={msgParams} />,
|
||||
<SignatureRequestData data={data.value} />,
|
||||
store,
|
||||
);
|
||||
|
||||
|
@ -87,7 +87,7 @@ export default function SignatureRequestMessage({
|
||||
>
|
||||
{primaryType}
|
||||
</Typography>
|
||||
<SignatureRequestData data={data} />
|
||||
<SignatureRequestData data={data.value} />
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import { sanitizeMessage } from '../../../../helpers/utils/util';
|
||||
import SignatureRequestMessage from './signature-request-message';
|
||||
|
||||
export default {
|
||||
@ -20,39 +21,59 @@ export const DefaultStory = (args) => {
|
||||
|
||||
DefaultStory.storyName = 'Default';
|
||||
|
||||
const rawMessage = {
|
||||
domain: {
|
||||
chainId: 97,
|
||||
name: 'Ether Mail',
|
||||
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
|
||||
version: '1',
|
||||
},
|
||||
message: {
|
||||
contents: 'Hello, Bob!',
|
||||
from: {
|
||||
name: 'Cow',
|
||||
wallets: [
|
||||
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
||||
'0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
|
||||
'0x06195827297c7A80a443b6894d3BDB8824b43896',
|
||||
],
|
||||
},
|
||||
to: [
|
||||
{
|
||||
name: 'Bob',
|
||||
wallets: [
|
||||
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
'0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
'0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
primaryType: 'Mail',
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
{ name: 'chainId', type: 'uint256' },
|
||||
{ name: 'verifyingContract', type: 'address' },
|
||||
],
|
||||
Mail: [
|
||||
{ name: 'from', type: 'Person' },
|
||||
{ name: 'to', type: 'Person[]' },
|
||||
{ name: 'contents', type: 'string' },
|
||||
],
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallets', type: 'address[]' },
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
DefaultStory.args = {
|
||||
data: JSON.parse(
|
||||
JSON.stringify({
|
||||
domain: {
|
||||
name: 'happydapp.website',
|
||||
},
|
||||
message: {
|
||||
string: 'haay wuurl',
|
||||
number: 42,
|
||||
},
|
||||
primaryType: 'Mail',
|
||||
types: {
|
||||
EIP712Domain: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'version', type: 'string' },
|
||||
{ name: 'chainId', type: 'uint256' },
|
||||
{ name: 'verifyingContract', type: 'address' },
|
||||
],
|
||||
Group: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'members', type: 'Person[]' },
|
||||
],
|
||||
Mail: [
|
||||
{ name: 'from', type: 'Person' },
|
||||
{ name: 'to', type: 'Person[]' },
|
||||
{ name: 'contents', type: 'string' },
|
||||
],
|
||||
Person: [
|
||||
{ name: 'name', type: 'string' },
|
||||
{ name: 'wallets', type: 'address[]' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
data: sanitizeMessage(
|
||||
rawMessage.message,
|
||||
rawMessage.primaryType,
|
||||
rawMessage.types,
|
||||
),
|
||||
messageIsScrollable: true,
|
||||
};
|
||||
|
@ -444,11 +444,14 @@ export const sanitizeMessage = (msg, primaryType, types) => {
|
||||
// Primary type can be an array.
|
||||
const isArray = primaryType && isArrayType(primaryType);
|
||||
if (isArray) {
|
||||
return msg.map((value) =>
|
||||
sanitizeMessage(value, stripOneLayerofNesting(primaryType), types),
|
||||
);
|
||||
return {
|
||||
value: msg.map((value) =>
|
||||
sanitizeMessage(value, stripOneLayerofNesting(primaryType), types),
|
||||
),
|
||||
type: primaryType,
|
||||
};
|
||||
} else if (isSolidityType(primaryType)) {
|
||||
return msg;
|
||||
return { value: msg, type: primaryType };
|
||||
}
|
||||
|
||||
// If not, assume to be struct
|
||||
@ -459,7 +462,7 @@ export const sanitizeMessage = (msg, primaryType, types) => {
|
||||
throw new Error(`Invalid primary type definition`);
|
||||
}
|
||||
|
||||
const sanitizedMessage = {};
|
||||
const sanitizedStruct = {};
|
||||
const msgKeys = Object.keys(msg);
|
||||
msgKeys.forEach((msgKey) => {
|
||||
const definedType = Object.values(baseTypeDefinitions).find(
|
||||
@ -470,13 +473,13 @@ export const sanitizeMessage = (msg, primaryType, types) => {
|
||||
return;
|
||||
}
|
||||
|
||||
sanitizedMessage[msgKey] = sanitizeMessage(
|
||||
sanitizedStruct[msgKey] = sanitizeMessage(
|
||||
msg[msgKey],
|
||||
definedType.type,
|
||||
types,
|
||||
);
|
||||
});
|
||||
return sanitizedMessage;
|
||||
return { value: sanitizedStruct, type: primaryType };
|
||||
};
|
||||
|
||||
export function getAssetImageURL(image, ipfsGateway) {
|
||||
|
@ -478,12 +478,107 @@ describe('util', () => {
|
||||
|
||||
it('should return parsed message if types is defined', () => {
|
||||
const result = util.sanitizeMessage(message, primaryType, types);
|
||||
expect(result.contents).toStrictEqual('Hello, Bob!');
|
||||
expect(result.from.name).toStrictEqual('Cow');
|
||||
expect(result.from.wallets).toHaveLength(2);
|
||||
expect(result.to).toHaveLength(1);
|
||||
expect(result.to[0].name).toStrictEqual('Bob');
|
||||
expect(result.to[0].wallets).toHaveLength(3);
|
||||
expect(result).toStrictEqual({
|
||||
type: 'Mail',
|
||||
value: {
|
||||
contents: {
|
||||
type: 'string',
|
||||
value: 'Hello, Bob!',
|
||||
},
|
||||
from: {
|
||||
type: 'Person',
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
value: 'Cow',
|
||||
},
|
||||
wallets: {
|
||||
type: 'address[]',
|
||||
value: [
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
nestArray: {
|
||||
type: 'uint256[2][2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256[2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 12,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 34,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 56,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'uint256[2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 56,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 78,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 89,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
to: {
|
||||
type: 'Person[]',
|
||||
value: [
|
||||
{
|
||||
type: 'Person',
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
value: 'Bob',
|
||||
},
|
||||
wallets: {
|
||||
type: 'address[]',
|
||||
value: [
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return parsed nested array if defined', () => {
|
||||
@ -497,10 +592,50 @@ describe('util', () => {
|
||||
primaryType,
|
||||
types,
|
||||
);
|
||||
expect(result.nestArray).toHaveLength(2);
|
||||
expect(result.nestArray[0]).toHaveLength(3);
|
||||
expect(result.nestArray[0][0]).toStrictEqual(12);
|
||||
expect(result.nestArray[0][2]).toStrictEqual(56);
|
||||
expect(result).toStrictEqual({
|
||||
type: 'Mail',
|
||||
value: {
|
||||
nestArray: {
|
||||
type: 'uint256[2][2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256[2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 12,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 34,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 56,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'uint256[2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 56,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 78,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 89,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return parsed nested array with struct if defined', () => {
|
||||
@ -537,14 +672,104 @@ describe('util', () => {
|
||||
],
|
||||
};
|
||||
const result = util.sanitizeMessage(msg, primaryType, types);
|
||||
expect(result.nestedPeople).toHaveLength(2);
|
||||
expect(result.nestedPeople[0]).toHaveLength(1);
|
||||
expect(result.nestedPeople[0][0].name).toStrictEqual('Bob');
|
||||
expect(result.nestedPeople[0][0].wallets).toHaveLength(3);
|
||||
expect(result.nestedPeople[0][0].wallets[0]).toStrictEqual(
|
||||
'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
);
|
||||
expect(result.nestedPeople[1][1].name).toStrictEqual('Brandon');
|
||||
expect(result).toStrictEqual({
|
||||
type: 'Mail',
|
||||
value: {
|
||||
nestedPeople: {
|
||||
type: 'Person[][]',
|
||||
value: [
|
||||
{
|
||||
type: 'Person[]',
|
||||
value: [
|
||||
{
|
||||
type: 'Person',
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
value: 'Bob',
|
||||
},
|
||||
wallets: {
|
||||
type: 'address[]',
|
||||
value: [
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'Person[]',
|
||||
value: [
|
||||
{
|
||||
type: 'Person',
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
value: 'Ben',
|
||||
},
|
||||
wallets: {
|
||||
type: 'address[]',
|
||||
value: [
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'Person',
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
value: 'Brandon',
|
||||
},
|
||||
wallets: {
|
||||
type: 'address[]',
|
||||
value: [
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should return ignore message data with unknown types', () => {
|
||||
@ -555,14 +780,107 @@ describe('util', () => {
|
||||
|
||||
// result will NOT contain the do_not_displays because type definition
|
||||
const result = util.sanitizeMessage(message, primaryType, types);
|
||||
expect(result.contents).toStrictEqual('Hello, Bob!');
|
||||
expect(result.from.name).toStrictEqual('Cow');
|
||||
expect(result.from.wallets).toHaveLength(2);
|
||||
expect(result.to).toHaveLength(1);
|
||||
expect(result.to[0].name).toStrictEqual('Bob');
|
||||
expect(result.to[0].wallets).toHaveLength(3);
|
||||
expect(result.do_not_display).toBeUndefined();
|
||||
expect(result.do_not_display_2).toBeUndefined();
|
||||
expect(result).toStrictEqual({
|
||||
type: 'Mail',
|
||||
value: {
|
||||
contents: {
|
||||
type: 'string',
|
||||
value: 'Hello, Bob!',
|
||||
},
|
||||
from: {
|
||||
type: 'Person',
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
value: 'Cow',
|
||||
},
|
||||
wallets: {
|
||||
type: 'address[]',
|
||||
value: [
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
nestArray: {
|
||||
type: 'uint256[2][2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256[2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 12,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 34,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 56,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'uint256[2]',
|
||||
value: [
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 56,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 78,
|
||||
},
|
||||
{
|
||||
type: 'uint256',
|
||||
value: 89,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
to: {
|
||||
type: 'Person[]',
|
||||
value: [
|
||||
{
|
||||
type: 'Person',
|
||||
value: {
|
||||
name: {
|
||||
type: 'string',
|
||||
value: 'Bob',
|
||||
},
|
||||
wallets: {
|
||||
type: 'address[]',
|
||||
value: [
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57',
|
||||
},
|
||||
{
|
||||
type: 'address',
|
||||
value: '0xB0B0b0b0b0b0B000000000000000000000000000',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user