Skip to content
This repository was archived by the owner on Oct 7, 2024. It is now read-only.

Commit ec8b5da

Browse files
authored
Fix signTypedMessage parameter types (#250)
The `signTypedMessage` parameter types accepted the data to sign as an array. This works with `signTypedData_v1`, but is incompatible with later versions. The signature has been updated to accept data as either an array or an object. Additionally, tests have been added to cover all three supported versions of `signTypedData`.
1 parent 3e102b5 commit ec8b5da

File tree

2 files changed

+154
-20
lines changed

2 files changed

+154
-20
lines changed

src/KeyringController.test.ts

Lines changed: 153 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -950,27 +950,161 @@ describe('KeyringController', () => {
950950
expect(result).toBe('SR6bQ1m3OTHvI1FLwcGzm+Uk6hffoFPxsQ0DTOeKMEc=');
951951
});
952952

953-
it('signTypedMessage', async () => {
954-
const inputParams = {
955-
from: mockAddress,
956-
data: [
957-
{
958-
type: 'string',
959-
name: 'Message',
960-
value: 'Hi, Alice!',
953+
describe('signTypedMessage', () => {
954+
it('signs a v1 typed message if no version is provided', async () => {
955+
const inputParams = {
956+
from: mockAddress,
957+
data: [
958+
{
959+
type: 'string',
960+
name: 'Message',
961+
value: 'Hi, Alice!',
962+
},
963+
{
964+
type: 'uint32',
965+
name: 'A number',
966+
value: '1337',
967+
},
968+
],
969+
origin: 'https://metamask.github.io',
970+
};
971+
const result = await keyringController.signTypedMessage(inputParams);
972+
expect(result).toMatchInlineSnapshot(
973+
`"0x089bb031f5bf2b2cbdf49eb2bb37d6071ab71f950b9dc49e398ca2ba984aca3c189b3b8de6c14c56461460dd9f59443340f1b144aeeff73275ace41ac184e54f1c"`,
974+
);
975+
});
976+
977+
it('signs a v1 typed message', async () => {
978+
const inputParams = {
979+
from: mockAddress,
980+
data: [
981+
{
982+
type: 'string',
983+
name: 'Message',
984+
value: 'Hi, Alice!',
985+
},
986+
{
987+
type: 'uint32',
988+
name: 'A number',
989+
value: '1337',
990+
},
991+
],
992+
origin: 'https://metamask.github.io',
993+
};
994+
const result = await keyringController.signTypedMessage(inputParams, {
995+
version: 'V1',
996+
});
997+
expect(result).toMatchInlineSnapshot(
998+
`"0x089bb031f5bf2b2cbdf49eb2bb37d6071ab71f950b9dc49e398ca2ba984aca3c189b3b8de6c14c56461460dd9f59443340f1b144aeeff73275ace41ac184e54f1c"`,
999+
);
1000+
});
1001+
1002+
it('signs a v3 typed message', async () => {
1003+
const typedData = {
1004+
types: {
1005+
EIP712Domain: [
1006+
{ name: 'name', type: 'string' },
1007+
{ name: 'version', type: 'string' },
1008+
{ name: 'chainId', type: 'uint256' },
1009+
{ name: 'verifyingContract', type: 'address' },
1010+
],
1011+
Person: [
1012+
{ name: 'name', type: 'string' },
1013+
{ name: 'wallet', type: 'address' },
1014+
],
1015+
Mail: [
1016+
{ name: 'from', type: 'Person' },
1017+
{ name: 'to', type: 'Person' },
1018+
{ name: 'contents', type: 'string' },
1019+
],
9611020
},
962-
{
963-
type: 'uint32',
964-
name: 'A number',
965-
value: '1337',
1021+
primaryType: 'Mail' as const,
1022+
domain: {
1023+
name: 'Ether Mail',
1024+
version: '1',
1025+
chainId: 1,
1026+
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
9661027
},
967-
],
968-
origin: 'https://metamask.github.io',
969-
};
970-
const result = await keyringController.signTypedMessage(inputParams);
971-
expect(result).toBe(
972-
'0x089bb031f5bf2b2cbdf49eb2bb37d6071ab71f950b9dc49e398ca2ba984aca3c189b3b8de6c14c56461460dd9f59443340f1b144aeeff73275ace41ac184e54f1c',
973-
);
1028+
message: {
1029+
from: {
1030+
name: 'Cow',
1031+
wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
1032+
},
1033+
to: {
1034+
name: 'Bob',
1035+
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
1036+
},
1037+
contents: 'Hello, Bob!',
1038+
},
1039+
};
1040+
const inputParams = {
1041+
from: mockAddress,
1042+
data: typedData,
1043+
origin: 'https://metamask.github.io',
1044+
};
1045+
const result = await keyringController.signTypedMessage(inputParams, {
1046+
version: 'V3',
1047+
});
1048+
expect(result).toMatchInlineSnapshot(
1049+
`"0x1c496cc9f42fc8f8a30bef731b20a1b8722569473643c0cd92e3e494be9c62725043275475ca81d9691c6c31e188dfbd5884b4352ba21bd99f38e6d357c738b81b"`,
1050+
);
1051+
});
1052+
1053+
it('signs a v4 typed message', async () => {
1054+
const typedData = {
1055+
types: {
1056+
EIP712Domain: [
1057+
{ name: 'name', type: 'string' },
1058+
{ name: 'version', type: 'string' },
1059+
{ name: 'chainId', type: 'uint256' },
1060+
{ name: 'verifyingContract', type: 'address' },
1061+
],
1062+
Person: [
1063+
{ name: 'name', type: 'string' },
1064+
{ name: 'wallet', type: 'address[]' },
1065+
],
1066+
Mail: [
1067+
{ name: 'from', type: 'Person' },
1068+
{ name: 'to', type: 'Person[]' },
1069+
{ name: 'contents', type: 'string' },
1070+
],
1071+
},
1072+
primaryType: 'Mail' as const,
1073+
domain: {
1074+
name: 'Ether Mail',
1075+
version: '1',
1076+
chainId: 1,
1077+
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
1078+
},
1079+
message: {
1080+
from: {
1081+
name: 'Cow',
1082+
wallet: [
1083+
'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
1084+
'0xDD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
1085+
],
1086+
},
1087+
to: [
1088+
{
1089+
name: 'Bob',
1090+
wallet: ['0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'],
1091+
},
1092+
],
1093+
contents: 'Hello, Bob!',
1094+
},
1095+
};
1096+
const inputParams = {
1097+
from: mockAddress,
1098+
data: typedData,
1099+
origin: 'https://metamask.github.io',
1100+
};
1101+
const result = await keyringController.signTypedMessage(inputParams, {
1102+
version: 'V4',
1103+
});
1104+
expect(result).toMatchInlineSnapshot(
1105+
`"0xe8d6baed58a611bbe247aecf2a8cbe0e3877bf1828c6bd9402749ce9e16f557a5669102bd05f0c3e33c200ff965abf07dab9299cb4bcdc504c9a695205240b321c"`,
1106+
);
1107+
});
9741108
});
9751109
});
9761110
});

src/KeyringController.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ class KeyringController extends EventEmitter {
512512
async signTypedMessage(
513513
msgParams: {
514514
from: string;
515-
data: Record<string, unknown>[];
515+
data: Record<string, unknown> | Record<string, unknown>[];
516516
},
517517
opts: Record<string, unknown> = { version: 'V1' },
518518
): Promise<string> {

0 commit comments

Comments
 (0)