From 00493259a16a9d8238005e7bcf7f784d6c86c979 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Mon, 9 Aug 2021 14:34:21 -0230 Subject: [PATCH] Add `TypedDataUtils.hashStruct` tests This function should now be comprehensively tested. The tests mirror the `TypedDataUtils.encodeData` tests exactly. Any uses of `hashStruct` in the older signature tests have been removed, as they are now redundant. --- src/__snapshots__/index.test.ts.snap | 304 +++++ src/index.test.ts | 1654 ++++++++++++++++++++++---- 2 files changed, 1700 insertions(+), 258 deletions(-) diff --git a/src/__snapshots__/index.test.ts.snap b/src/__snapshots__/index.test.ts.snap index 4273cf04..16898866 100644 --- a/src/__snapshots__/index.test.ts.snap +++ b/src/__snapshots__/index.test.ts.snap @@ -304,6 +304,310 @@ exports[`TypedDataUtils.encodeData V4 should encode data with a recursive data t exports[`TypedDataUtils.encodeData V4 should encode data with custom type 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; +exports[`TypedDataUtils.hashStruct V3 example data type "address" should hash "0x0" (type "string") 1`] = `"c93aa5d5f1b1efece209c34fceee0aeb33da38ea34dbdd4df854e9708a636fea"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "address" should hash "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" (type "string") 1`] = `"ab14541443c6f456616e472ecca6d4fc887f862760d3a056b348441a9e0fd1c6"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "address" should hash "10" (type "number") 1`] = `"ce14e365ba45aa306d169b4cd22bd4a4dd45b07f68948757788cd974302272b9"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "address" should hash "9007199254740991" (type "number") 1`] = `"edb736a49622b7860bcec9c56c2b0346870f5bf02b7e516722c51be85c740bd3"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "address" should hash "bBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" (type "string") 1`] = `"4d9b02d96f7647b8d3acfafc97b2faa65ef7b442ea647f8c8f6f606d4d794d34"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "-1" (type "number") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "0" (type "number") 1`] = `"8015e06ae558f4ef85aa3a10a88e0530c81d4c6437ea005773d0ae01fa87e98f"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "1" (type "number") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "9007199254740991" (type "number") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "false" (type "boolean") 1`] = `"8015e06ae558f4ef85aa3a10a88e0530c81d4c6437ea005773d0ae01fa87e98f"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "false" (type "string") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "true" (type "boolean") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bool" should hash "true" (type "string") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes" should hash "0x10" (type "string") 1`] = `"724dca4470f2d466424cc9f6ee09f55034659518ef5426fde3af846aa6fefcd6"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes" should hash "10" (type "Buffer") 1`] = `"7223320363eca5bb181c12017960acf7bdbb70a05b684bf42bb31f422a19ed0c"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes" should hash "10" (type "number") 1`] = `"b6976a8d3ca85d894db066bed9dd1eac9a3ac6b0e87155e28e958215cd078f1b"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes" should hash "10" (type "string") 1`] = `"7223320363eca5bb181c12017960acf7bdbb70a05b684bf42bb31f422a19ed0c"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes1" should hash "-1" (type "number") 1`] = `"7ac24420f34ed860bcaeeeaa671447f3d4830177fa06022e6f7424ca2a482041"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes1" should hash "0" (type "number") 1`] = `"7ac24420f34ed860bcaeeeaa671447f3d4830177fa06022e6f7424ca2a482041"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes1" should hash "0x10" (type "string") 1`] = `"e900d48fde06ac14ab54c8c9246180736dffaafbd702b4448d95266e515c698f"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes1" should hash "1" (type "number") 1`] = `"c84c962fe80560aae67c8b46cc1d901abf65728d1fccce809a93435e1ff053dc"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes1" should hash "10" (type "Buffer") 1`] = `"7a9f9769fc28b3d34a1acabdbac6aad4c227c30d7ec06da6ea98986a2402d61e"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes1" should hash "10" (type "number") 1`] = `"042571d85305b5304f1ec048ee522d52f7750cd802c2a56783abdb1d4dbfa207"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes1" should hash "9007199254740991" (type "number") 1`] = `"224aa7830e89b97cde54f24a6e6f189ae53303bc371a9937e78437b172ca1b45"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes32" should hash "-1" (type "number") 1`] = `"724c93ad5b90d8174128477a263c7409b5e04b404e41f29f2ab4ec85706a8adf"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes32" should hash "0" (type "number") 1`] = `"724c93ad5b90d8174128477a263c7409b5e04b404e41f29f2ab4ec85706a8adf"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes32" should hash "0x10" (type "string") 1`] = `"e12c668b2a048da24f2cbefcaebf992a22406fc4fb16e93881c41ec30760077a"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes32" should hash "1" (type "number") 1`] = `"c1e60a5b178f07e19a88d6ba804fd66454da16b0ef30544efaf05e9166a5ce77"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes32" should hash "10" (type "Buffer") 1`] = `"f0954c59ac57c9bc45fb997ef895fce917cfcaca6c452b0678bc3a89a4ca0e32"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes32" should hash "10" (type "number") 1`] = `"88f9527b959d7651b65276b40513cd46e3f41d791b727a44278721a2a36809b4"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "bytes32" should hash "9007199254740991" (type "number") 1`] = `"df80d4e7982c6aae5b1f697b9da4811ae768d198aba8aea8470d4658d0dc5625"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int" should hash "-9007199254740991" (type "number") 1`] = `"828639b34ed68e48e9c6938edb70f9bbe9aaf716df431a47cfef19e66959c6b0"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int" should hash "0" (type "number") 1`] = `"7152867e6c08ec6c73e80791694b4c9c29630ce5203d52d4a2a00e551f8fd673"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int" should hash "0" (type "string") 1`] = `"7152867e6c08ec6c73e80791694b4c9c29630ce5203d52d4a2a00e551f8fd673"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int" should hash "0x0" (type "string") 1`] = `"7152867e6c08ec6c73e80791694b4c9c29630ce5203d52d4a2a00e551f8fd673"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int" should hash "9007199254740991" (type "number") 1`] = `"58688562012b128b5b702e46276e9ee8815955345556708ae7d25e49a9717eb5"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int8" should hash "-255" (type "number") 1`] = `"5176307b3ebcc216e0c74964fab1ffc6aea9af022f5e1ff5218e8c8f271308a5"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int8" should hash "0" (type "number") 1`] = `"7e41c54c3c21ff362622f9159b9b1566b4d9d883fe397da923f8415f1f2d1b89"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int8" should hash "0" (type "string") 1`] = `"7e41c54c3c21ff362622f9159b9b1566b4d9d883fe397da923f8415f1f2d1b89"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int8" should hash "0x0" (type "string") 1`] = `"7e41c54c3c21ff362622f9159b9b1566b4d9d883fe397da923f8415f1f2d1b89"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int8" should hash "255" (type "number") 1`] = `"6af1c0206f5eca44c09a657cc0e5b0492c3c50fdac13b4d0f9230629cb4a5524"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int256" should hash "-9007199254740991" (type "number") 1`] = `"ca8549280a9bd8667b6bdbf0d0eba01c9088d221db3836601e47d90351cba5ec"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int256" should hash "0" (type "number") 1`] = `"ccf20a1de5e96bc817d94d9d27528918348beb21127fd4b077789d4ba83aaf18"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int256" should hash "0" (type "string") 1`] = `"ccf20a1de5e96bc817d94d9d27528918348beb21127fd4b077789d4ba83aaf18"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int256" should hash "0x0" (type "string") 1`] = `"ccf20a1de5e96bc817d94d9d27528918348beb21127fd4b077789d4ba83aaf18"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "int256" should hash "9007199254740991" (type "number") 1`] = `"bab9169a0079a42c1cd2d180095cf08a1dd0429496b1aeb69fced72472812876"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "string" should hash "0xabcd" (type "string") 1`] = `"4560af2575aabbf895509b931fce6f2d9699df2aff56c44f768cd887c755a826"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "string" should hash "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" (type "string") 1`] = `"214632528de591d75e17abdeb0ccae3dab34a3be73b696af781a227af8070309"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "string" should hash "10" (type "number") 1`] = `"df09ff353f47aae6eb9a7c188daaa88a55d3469a603a1c35e86793f248b59958"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "string" should hash "Hello!" (type "string") 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "string" should hash "😁" (type "string") 1`] = `"ca0bd988509ebbefdabd88aba786ff9825dbdaf2532339957ca3ea4e44fc183a"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint" should hash "0" (type "number") 1`] = `"865464863c9a46afbad30a6c25cabcba74a7f1b80b7e48ab1b00206d2c074caf"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint" should hash "0" (type "string") 1`] = `"865464863c9a46afbad30a6c25cabcba74a7f1b80b7e48ab1b00206d2c074caf"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint" should hash "0x0" (type "string") 1`] = `"865464863c9a46afbad30a6c25cabcba74a7f1b80b7e48ab1b00206d2c074caf"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint" should hash "9007199254740991" (type "number") 1`] = `"a9213a44af227656d5a7d16228d7082862c94eb0ae84491f42e74cee35a5e202"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint8" should hash "0" (type "number") 1`] = `"73ee3fc1fa9dc8c99c59fcb1d9d8c9fe181510086128e4763618d7c6b2208361"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint8" should hash "0" (type "string") 1`] = `"73ee3fc1fa9dc8c99c59fcb1d9d8c9fe181510086128e4763618d7c6b2208361"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint8" should hash "0x0" (type "string") 1`] = `"73ee3fc1fa9dc8c99c59fcb1d9d8c9fe181510086128e4763618d7c6b2208361"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint8" should hash "255" (type "number") 1`] = `"30b2c001d2daa96e91576d1019a1842f75d983de5f89934671dc02074971b850"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint256" should hash "0" (type "number") 1`] = `"c4adc42f66c4586eb979042b897a75bc2bd4c8fb866531c44100a22168cdcdbc"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint256" should hash "0" (type "string") 1`] = `"c4adc42f66c4586eb979042b897a75bc2bd4c8fb866531c44100a22168cdcdbc"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint256" should hash "0x0" (type "string") 1`] = `"c4adc42f66c4586eb979042b897a75bc2bd4c8fb866531c44100a22168cdcdbc"`; + +exports[`TypedDataUtils.hashStruct V3 example data type "uint256" should hash "9007199254740991" (type "number") 1`] = `"3cfc99947ae18942816da1e3a94b479043b95f4de5851660ce9d53fe5f29b686"`; + +exports[`TypedDataUtils.hashStruct V3 should hash data when given extraneous types 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; + +exports[`TypedDataUtils.hashStruct V3 should hash data with a custom type property set to undefined 1`] = `"adb6678488e67a64751a5e102fb22d40eae1eaa02809c52458562c9158bcf2c9"`; + +exports[`TypedDataUtils.hashStruct V3 should hash data with a dynamic property set to null 1`] = `"d2a1810699ec28c0c42814956e9f333a82abe619c42a5610e568c2c4c21af66e"`; + +exports[`TypedDataUtils.hashStruct V3 should hash data with a dynamic property set to undefined 1`] = `"8c6273864d5942235f90965f11c0a66344a02be03ae4961c4bdc9b9db849463e"`; + +exports[`TypedDataUtils.hashStruct V3 should hash data with a recursive data type 1`] = `"08fafba26ad35ef7eb49050d251805e1e6b873bd4a096bfd11ad0d3a276161c0"`; + +exports[`TypedDataUtils.hashStruct V3 should hash data with an atomic property set to undefined 1`] = `"b95cd7bb59592ce59cdba3b1c9c42c8dcd68fc8a59bd26f12f9a13805e34af16"`; + +exports[`TypedDataUtils.hashStruct V3 should hash data with custom type 1`] = `"c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "address" should hash "0x0" (type "string") 1`] = `"c93aa5d5f1b1efece209c34fceee0aeb33da38ea34dbdd4df854e9708a636fea"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "address" should hash "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" (type "string") 1`] = `"ab14541443c6f456616e472ecca6d4fc887f862760d3a056b348441a9e0fd1c6"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "address" should hash "10" (type "number") 1`] = `"ce14e365ba45aa306d169b4cd22bd4a4dd45b07f68948757788cd974302272b9"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "address" should hash "9007199254740991" (type "number") 1`] = `"edb736a49622b7860bcec9c56c2b0346870f5bf02b7e516722c51be85c740bd3"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "address" should hash "bBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" (type "string") 1`] = `"4d9b02d96f7647b8d3acfafc97b2faa65ef7b442ea647f8c8f6f606d4d794d34"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "address" should hash array of all address example data 1`] = `"fee33414e29960601d222dc4ac9695a24e631218ff4bab72376686b7a867d644"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "-1" (type "number") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "0" (type "number") 1`] = `"8015e06ae558f4ef85aa3a10a88e0530c81d4c6437ea005773d0ae01fa87e98f"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "1" (type "number") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "9007199254740991" (type "number") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "false" (type "boolean") 1`] = `"8015e06ae558f4ef85aa3a10a88e0530c81d4c6437ea005773d0ae01fa87e98f"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "false" (type "string") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "true" (type "boolean") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash "true" (type "string") 1`] = `"df410941012cfe7070ec9abfdb367531856dda97faaa5134e46c313058e8415e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bool" should hash array of all bool example data 1`] = `"6f00436587cd0a7f731ee48fd94e198edb2139db837718bb8fc49016083f3e57"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0x10" (type "string") 1`] = `"724dca4470f2d466424cc9f6ee09f55034659518ef5426fde3af846aa6fefcd6"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "10" (type "Buffer") 1`] = `"7223320363eca5bb181c12017960acf7bdbb70a05b684bf42bb31f422a19ed0c"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "10" (type "number") 1`] = `"b6976a8d3ca85d894db066bed9dd1eac9a3ac6b0e87155e28e958215cd078f1b"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "10" (type "string") 1`] = `"7223320363eca5bb181c12017960acf7bdbb70a05b684bf42bb31f422a19ed0c"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash array of all bytes example data 1`] = `"229b923e2aca4d65c347bec3235d7514bd107762bff4b891cfd1bc02e8636aeb"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash "-1" (type "number") 1`] = `"7ac24420f34ed860bcaeeeaa671447f3d4830177fa06022e6f7424ca2a482041"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash "0" (type "number") 1`] = `"7ac24420f34ed860bcaeeeaa671447f3d4830177fa06022e6f7424ca2a482041"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash "0x10" (type "string") 1`] = `"e900d48fde06ac14ab54c8c9246180736dffaafbd702b4448d95266e515c698f"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash "1" (type "number") 1`] = `"c84c962fe80560aae67c8b46cc1d901abf65728d1fccce809a93435e1ff053dc"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash "10" (type "Buffer") 1`] = `"7a9f9769fc28b3d34a1acabdbac6aad4c227c30d7ec06da6ea98986a2402d61e"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash "10" (type "number") 1`] = `"042571d85305b5304f1ec048ee522d52f7750cd802c2a56783abdb1d4dbfa207"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash "9007199254740991" (type "number") 1`] = `"224aa7830e89b97cde54f24a6e6f189ae53303bc371a9937e78437b172ca1b45"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes1" should hash array of all bytes1 example data 1`] = `"921fdc86bdfa6ebce66ad328c5fc7083d0d5e55aa485fe852951d64dfcb35a97"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash "-1" (type "number") 1`] = `"724c93ad5b90d8174128477a263c7409b5e04b404e41f29f2ab4ec85706a8adf"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash "0" (type "number") 1`] = `"724c93ad5b90d8174128477a263c7409b5e04b404e41f29f2ab4ec85706a8adf"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash "0x10" (type "string") 1`] = `"e12c668b2a048da24f2cbefcaebf992a22406fc4fb16e93881c41ec30760077a"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash "1" (type "number") 1`] = `"c1e60a5b178f07e19a88d6ba804fd66454da16b0ef30544efaf05e9166a5ce77"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash "10" (type "Buffer") 1`] = `"f0954c59ac57c9bc45fb997ef895fce917cfcaca6c452b0678bc3a89a4ca0e32"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash "10" (type "number") 1`] = `"88f9527b959d7651b65276b40513cd46e3f41d791b727a44278721a2a36809b4"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash "9007199254740991" (type "number") 1`] = `"df80d4e7982c6aae5b1f697b9da4811ae768d198aba8aea8470d4658d0dc5625"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "bytes32" should hash array of all bytes32 example data 1`] = `"18c1d960af1aa842eaf29de0f1516b42b88b1ce877e1eafc960bab55bbe5e304"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int" should hash "-9007199254740991" (type "number") 1`] = `"828639b34ed68e48e9c6938edb70f9bbe9aaf716df431a47cfef19e66959c6b0"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int" should hash "0" (type "number") 1`] = `"7152867e6c08ec6c73e80791694b4c9c29630ce5203d52d4a2a00e551f8fd673"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int" should hash "0" (type "string") 1`] = `"7152867e6c08ec6c73e80791694b4c9c29630ce5203d52d4a2a00e551f8fd673"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int" should hash "0x0" (type "string") 1`] = `"7152867e6c08ec6c73e80791694b4c9c29630ce5203d52d4a2a00e551f8fd673"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int" should hash "9007199254740991" (type "number") 1`] = `"58688562012b128b5b702e46276e9ee8815955345556708ae7d25e49a9717eb5"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int" should hash array of all int example data 1`] = `"d16177fae6110a0f8b8f527d47c595bbb7174f8b7eaef8f1867bb87827834f5c"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int8" should hash "-255" (type "number") 1`] = `"5176307b3ebcc216e0c74964fab1ffc6aea9af022f5e1ff5218e8c8f271308a5"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int8" should hash "0" (type "number") 1`] = `"7e41c54c3c21ff362622f9159b9b1566b4d9d883fe397da923f8415f1f2d1b89"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int8" should hash "0" (type "string") 1`] = `"7e41c54c3c21ff362622f9159b9b1566b4d9d883fe397da923f8415f1f2d1b89"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int8" should hash "0x0" (type "string") 1`] = `"7e41c54c3c21ff362622f9159b9b1566b4d9d883fe397da923f8415f1f2d1b89"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int8" should hash "255" (type "number") 1`] = `"6af1c0206f5eca44c09a657cc0e5b0492c3c50fdac13b4d0f9230629cb4a5524"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int8" should hash array of all int8 example data 1`] = `"526b53feebd1ecdce33c443de5f84c56fa0a1b9c449906c922375307fc038014"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int256" should hash "-9007199254740991" (type "number") 1`] = `"ca8549280a9bd8667b6bdbf0d0eba01c9088d221db3836601e47d90351cba5ec"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int256" should hash "0" (type "number") 1`] = `"ccf20a1de5e96bc817d94d9d27528918348beb21127fd4b077789d4ba83aaf18"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int256" should hash "0" (type "string") 1`] = `"ccf20a1de5e96bc817d94d9d27528918348beb21127fd4b077789d4ba83aaf18"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int256" should hash "0x0" (type "string") 1`] = `"ccf20a1de5e96bc817d94d9d27528918348beb21127fd4b077789d4ba83aaf18"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int256" should hash "9007199254740991" (type "number") 1`] = `"bab9169a0079a42c1cd2d180095cf08a1dd0429496b1aeb69fced72472812876"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "int256" should hash array of all int256 example data 1`] = `"85f9609b0fa0359c908f0d1effd2ca69a1bd1a983f473c142e26acdef6eb7ff1"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "string" should hash "0xabcd" (type "string") 1`] = `"4560af2575aabbf895509b931fce6f2d9699df2aff56c44f768cd887c755a826"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "string" should hash "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" (type "string") 1`] = `"214632528de591d75e17abdeb0ccae3dab34a3be73b696af781a227af8070309"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "string" should hash "10" (type "number") 1`] = `"df09ff353f47aae6eb9a7c188daaa88a55d3469a603a1c35e86793f248b59958"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "string" should hash "Hello!" (type "string") 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "string" should hash "😁" (type "string") 1`] = `"ca0bd988509ebbefdabd88aba786ff9825dbdaf2532339957ca3ea4e44fc183a"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "string" should hash array of all string example data 1`] = `"8a06ba7853752159aad26061592e1cabd0d2bff33391fe48a20aceeb686d1edc"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint" should hash "0" (type "number") 1`] = `"865464863c9a46afbad30a6c25cabcba74a7f1b80b7e48ab1b00206d2c074caf"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint" should hash "0" (type "string") 1`] = `"865464863c9a46afbad30a6c25cabcba74a7f1b80b7e48ab1b00206d2c074caf"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint" should hash "0x0" (type "string") 1`] = `"865464863c9a46afbad30a6c25cabcba74a7f1b80b7e48ab1b00206d2c074caf"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint" should hash "9007199254740991" (type "number") 1`] = `"a9213a44af227656d5a7d16228d7082862c94eb0ae84491f42e74cee35a5e202"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint" should hash array of all uint example data 1`] = `"420e09236f286bb5a68736a7848e26108542d57c2b0030693eea99f41ef92125"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint8" should hash "0" (type "number") 1`] = `"73ee3fc1fa9dc8c99c59fcb1d9d8c9fe181510086128e4763618d7c6b2208361"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint8" should hash "0" (type "string") 1`] = `"73ee3fc1fa9dc8c99c59fcb1d9d8c9fe181510086128e4763618d7c6b2208361"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint8" should hash "0x0" (type "string") 1`] = `"73ee3fc1fa9dc8c99c59fcb1d9d8c9fe181510086128e4763618d7c6b2208361"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint8" should hash "255" (type "number") 1`] = `"30b2c001d2daa96e91576d1019a1842f75d983de5f89934671dc02074971b850"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint8" should hash array of all uint8 example data 1`] = `"66db87ae5c12bcea050f54891a0ceb924753764a4b1ead83ae8692d752a2a26a"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint256" should hash "0" (type "number") 1`] = `"c4adc42f66c4586eb979042b897a75bc2bd4c8fb866531c44100a22168cdcdbc"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint256" should hash "0" (type "string") 1`] = `"c4adc42f66c4586eb979042b897a75bc2bd4c8fb866531c44100a22168cdcdbc"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint256" should hash "0x0" (type "string") 1`] = `"c4adc42f66c4586eb979042b897a75bc2bd4c8fb866531c44100a22168cdcdbc"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint256" should hash "9007199254740991" (type "number") 1`] = `"3cfc99947ae18942816da1e3a94b479043b95f4de5851660ce9d53fe5f29b686"`; + +exports[`TypedDataUtils.hashStruct V4 example data type "uint256" should hash array of all uint256 example data 1`] = `"f44a78e7f58e62916b00244626970fb046c4e6495bd453c83298686c00d8e9f0"`; + +exports[`TypedDataUtils.hashStruct V4 should hash data when given extraneous types 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; + +exports[`TypedDataUtils.hashStruct V4 should hash data with a custom data type array 1`] = `"ac26cc7aa2cb9a8a445fae4e48b33f978b558da9b16e26381c53814d3317f541"`; + +exports[`TypedDataUtils.hashStruct V4 should hash data with a custom type property set to null 1`] = `"fdecfae63c304f6fc7795188607e3838f5bf6798e47f147efdb2c71fcec1335e"`; + +exports[`TypedDataUtils.hashStruct V4 should hash data with a custom type property set to undefined 1`] = `"fdecfae63c304f6fc7795188607e3838f5bf6798e47f147efdb2c71fcec1335e"`; + +exports[`TypedDataUtils.hashStruct V4 should hash data with a dynamic property set to null 1`] = `"d2a1810699ec28c0c42814956e9f333a82abe619c42a5610e568c2c4c21af66e"`; + +exports[`TypedDataUtils.hashStruct V4 should hash data with a recursive data type 1`] = `"098a3fdba6dae9a89a220b7adbe1f38cf5d2aeabd94657aea65bb8aeef44f02e"`; + +exports[`TypedDataUtils.hashStruct V4 should hash data with custom type 1`] = `"c52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e"`; + exports[`concatSig should concatenate an all-zero extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`; exports[`concatSig should concatenate an extended ECDSA signature 1`] = `"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"`; diff --git a/src/index.test.ts b/src/index.test.ts index 82b204ca..2321985c 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -119,7 +119,1318 @@ describe('TypedDataUtils.encodeData', function () { // | Unrecognized primary type | N | N | | // | Unrecognized non-primary type | N | N | | // | Extra type specified that isn't used by primary type | Y | Y | Y | + // + // Note that these tests should mirror the `TypedDataUtils.hashStruct` tests. The `hashStruct` + // function just calls `encodeData` and hashes the result. + + describe('V3', function () { + describe('example data', function () { + // Reassigned to silence "no-loop-func" ESLint rule + // It was complaining because it saw that `it` and `expect` as "modified variables from the outer scope" + // which can be dangerous to reference in a loop. But they aren't modified in this case, just invoked. + const _expect = expect; + const _it = it; + + for (const type of allExampleTypes) { + describe(`type "${type}"`, function () { + // Test all examples that do not crash + const inputs = encodeDataExamples[type] || []; + for (const input of inputs) { + const inputType = input instanceof Buffer ? 'Buffer' : typeof input; + _it(`should encode "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + _expect( + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + } + + // Test all examples that crash + const errorInputs = encodeDataErrorExamples[type] || []; + for (const { input, errorMessage } of errorInputs) { + const inputType = input instanceof Buffer ? 'Buffer' : typeof input; + _it( + `should fail to encode "${input}" (type "${inputType}")`, + function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + _expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toThrow(errorMessage); + }, + ); + } + + _it( + `should fail to encode array of all ${type} example data`, + function () { + const types = { + Message: [{ name: 'data', type: `${type}[]` }], + }; + const message = { data: inputs }; + _expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toThrow( + 'Arrays are unimplemented in encodeData; use V4 extension', + ); + }, + ); + }); + } + }); + + it('should encode data with custom type', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should encode data with a recursive data type', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'replyTo', type: 'Mail' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + replyTo: { + to: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + from: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello!', + }, + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should throw an error when trying to encode a custom type array', function () { + const types = { + Message: [{ name: 'data', type: 'string[]' }], + }; + const message = { data: ['1', '2', '3'] }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toThrow('Arrays are unimplemented in encodeData; use V4 extension'); + }); + + it('should ignore extra unspecified message properties', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }; + + const originalSignature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'); + const messageWithExtraProperties = { ...message, foo: 'bar' }; + const signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + primaryType, + messageWithExtraProperties, + types, + 'V3', + ).toString('hex'); + + expect(originalSignature).toBe(signatureWithExtraProperties); + }); + + it('should throw an error when an atomic property is set to null', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'length', type: 'int32' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello!', + length: null, + }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toThrow(`Cannot read property 'toArray' of null`); + }); + + it('should encode data with an atomic property set to undefined', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'length', type: 'int32' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello!', + length: undefined, + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should encode data with a dynamic property set to null', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: null, + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should encode data with a dynamic property set to undefined', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: undefined, + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should throw an error when a custom type property is set to null', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + to: null, + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + contents: 'Hello, Bob!', + }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toThrow(`Cannot read property 'name' of null`); + }); + + it('should encode data with a custom type property set to undefined', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: undefined, + contents: 'Hello, Bob!', + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should throw an error when trying to encode a function', function () { + const types = { + Message: [{ name: 'data', type: 'function' }], + }; + const message = { data: 'test' }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toThrow('Unsupported or invalid type: function'); + }); + + it('should throw an error when trying to encode with a missing primary type definition', function () { + const types = {}; + const message = { data: 'test' }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toThrow('No type definition specified: Message'); + }); + + it('should throw an error when trying to encode an unrecognized type', function () { + const types = { + Message: [{ name: 'data', type: 'foo' }], + }; + const message = { data: 'test' }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toThrow('Unsupported or invalid type: foo'); + }); + + it('should encode data when given extraneous types', function () { + const types = { + Message: [{ name: 'data', type: 'string' }], + Extra: [{ name: 'data', type: 'string' }], + }; + const message = { data: 'Hello!' }; + + expect( + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'), + ).toMatchSnapshot(); + }); + }); + + describe('V4', function () { + describe('example data', function () { + // Reassigned to silence "no-loop-func" ESLint rule + // It was complaining because it saw that `it` and `expect` as "modified variables from the outer scope" + // which can be dangerous to reference in a loop. But they aren't modified in this case, just invoked. + const _expect = expect; + const _it = it; + + for (const type of allExampleTypes) { + describe(`type "${type}"`, function () { + // Test all examples that do not crash + const inputs = encodeDataExamples[type] || []; + for (const input of inputs) { + const inputType = input instanceof Buffer ? 'Buffer' : typeof input; + _it(`should encode "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + _expect( + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + } + + // Test all examples that crash + const errorInputs = encodeDataErrorExamples[type] || []; + for (const { input, errorMessage } of errorInputs) { + const inputType = input instanceof Buffer ? 'Buffer' : typeof input; + _it( + `should fail to encode "${input}" (type "${inputType}")`, + function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + _expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'), + ).toThrow(errorMessage); + }, + ); + } + + _it(`should encode array of all ${type} example data`, function () { + const types = { + Message: [{ name: 'data', type: `${type}[]` }], + }; + const message = { data: inputs }; + _expect( + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + }); + } + }); + + it('should encode data with custom type', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should encode data with a recursive data type', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'replyTo', type: 'Mail' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + replyTo: { + to: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + from: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello!', + }, + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should encode data with a custom data type array', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address[]' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person[]' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: [ + '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + '0xDD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + ], + }, + to: [ + { + name: 'Bob', + wallet: ['0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'], + }, + ], + contents: 'Hello, Bob!', + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should ignore extra unspecified message properties', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }; + + const originalSignature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'); + const messageWithExtraProperties = { ...message, foo: 'bar' }; + const signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + primaryType, + messageWithExtraProperties, + types, + 'V4', + ).toString('hex'); + + expect(originalSignature).toBe(signatureWithExtraProperties); + }); + + it('should throw an error when an atomic property is set to null', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'length', type: 'int32' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello!', + length: null, + }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toThrow(`Cannot read property 'toArray' of null`); + }); + + it('should throw an error when an atomic property is set to undefined', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'length', type: 'int32' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello!', + length: undefined, + }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toThrow('missing value for field length of type int32'); + }); + + it('should encode data with a dynamic property set to null', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: null, + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should throw an error when a dynamic property is set to undefined', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: undefined, + }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toThrow('missing value for field contents of type string'); + }); + + it('should encode data with a custom type property set to null', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + to: null, + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + contents: 'Hello, Bob!', + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should encode data with a custom type property set to undefined', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: undefined, + contents: 'Hello, Bob!', + }; + + expect( + sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + + it('should throw an error when trying to encode a function', function () { + const types = { + Message: [{ name: 'data', type: 'function' }], + }; + const message = { data: 'test' }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'), + ).toThrow('Unsupported or invalid type: function'); + }); + + it('should throw an error when trying to encode with a missing primary type definition', function () { + const types = {}; + const message = { data: 'test' }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'), + ).toThrow('No type definition specified: Message'); + }); + + it('should throw an error when trying to encode an unrecognized type', function () { + const types = { + Message: [{ name: 'data', type: 'foo' }], + }; + const message = { data: 'test' }; + + expect(() => + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'), + ).toThrow('Unsupported or invalid type: foo'); + }); + + it('should encode data when given extraneous types', function () { + const types = { + Message: [{ name: 'data', type: 'string' }], + Extra: [{ name: 'data', type: 'string' }], + }; + const message = { data: 'Hello!' }; + + expect( + sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'), + ).toMatchSnapshot(); + }); + }); + + // This test suite covers all cases where data should be encoded identically + // on V3 and V4 + describe('V3/V4 identical encodings', function () { + describe('example data', function () { + // Reassigned to silence "no-loop-func" ESLint rule + // It was complaining because it saw that `it` and `expect` as "modified variables from the outer scope" + // which can be dangerous to reference in a loop. But they aren't modified in this case, just invoked. + const _expect = expect; + const _it = it; + + for (const type of allExampleTypes) { + describe(`type "${type}"`, function () { + // Test all examples that do not crash + const inputs = encodeDataExamples[type] || []; + for (const input of inputs) { + const inputType = input instanceof Buffer ? 'Buffer' : typeof input; + _it(`should encode "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + const v3Signature = sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'); + const v4Signature = sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'); + + _expect(v3Signature).toBe(v4Signature); + }); + } + }); + } + }); + + it('should encode data with custom type', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }; + + const v3Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'); + const v4Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'); + + expect(v3Signature).toBe(v4Signature); + }); + + it('should ignore extra unspecified message properties', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + }; + + const originalV3Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'); + const originalV4Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'); + const messageWithExtraProperties = { ...message, foo: 'bar' }; + const v3signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + primaryType, + messageWithExtraProperties, + types, + 'V3', + ).toString('hex'); + const v4signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + primaryType, + messageWithExtraProperties, + types, + 'V4', + ).toString('hex'); + + expect(originalV3Signature).toBe(originalV4Signature); + expect(v3signatureWithExtraProperties).toBe( + v4signatureWithExtraProperties, + ); + }); + + it('should encode data with a dynamic property set to null', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: null, + }; + + const v3Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'); + const v4Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'); + + expect(v3Signature).toBe(v4Signature); + }); + + it('should encode data when given extraneous types', function () { + const types = { + Message: [{ name: 'data', type: 'string' }], + Extra: [{ name: 'data', type: 'string' }], + }; + const message = { data: 'Hello!' }; + + const v3Signature = sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V3', + ).toString('hex'); + const v4Signature = sigUtil.TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V4', + ).toString('hex'); + + expect(v3Signature).toBe(v4Signature); + }); + }); + + // This test suite covers all cases where data should be encoded differently + // on V3 and V4 + describe('V3/V4 encoding differences', () => { + // Recursive data structures are encoded differently because V4 encodes + // missing custom typed properties as 0 byte32 rather than omitting it, + // and all recursive data structures must include a missing custom typed + // property (the recursive one), or they'd be infinitely large or cyclic. + // And cyclic data structures are not supported. + it('should encode data with recursive data differently', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + { name: 'replyTo', type: 'Mail' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + to: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello, Bob!', + replyTo: { + to: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + from: { + name: 'Bob', + wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + }, + contents: 'Hello!', + }, + }; + + const v3Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'); + const v4Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'); + + expect(v3Signature).not.toBe(v4Signature); + }); + + // Missing custom type properties are omitted in V3, but encoded as 0 (bytes32) in V4 + it('should encode missing custom type properties differently', function () { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + const message = { + from: { + name: 'Cow', + wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', + }, + contents: 'Hello, Bob!', + }; + + const v3Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V3', + ).toString('hex'); + const v4Signature = sigUtil.TypedDataUtils.encodeData( + primaryType, + message, + types, + 'V4', + ).toString('hex'); + + expect(v3Signature).not.toBe(v4Signature); + }); + }); +}); +describe('TypedDataUtils.hashStruct', function () { + // These tests mirror the `TypedDataUtils.encodeData` tests. The same inputs are expected. + // See the `encodeData` test comments for more information about these test cases. describe('V3', function () { describe('example data', function () { // Reassigned to silence "no-loop-func" ESLint rule @@ -134,14 +1445,14 @@ describe('TypedDataUtils.encodeData', function () { const inputs = encodeDataExamples[type] || []; for (const input of inputs) { const inputType = input instanceof Buffer ? 'Buffer' : typeof input; - _it(`should encode "${input}" (type "${inputType}")`, function () { + _it(`should hash "${input}" (type "${inputType}")`, function () { const types = { Message: [{ name: 'data', type }], }; const message = { data: input }; _expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -156,7 +1467,7 @@ describe('TypedDataUtils.encodeData', function () { for (const { input, errorMessage } of errorInputs) { const inputType = input instanceof Buffer ? 'Buffer' : typeof input; _it( - `should fail to encode "${input}" (type "${inputType}")`, + `should fail to hash "${input}" (type "${inputType}")`, function () { const types = { Message: [{ name: 'data', type }], @@ -164,7 +1475,7 @@ describe('TypedDataUtils.encodeData', function () { const message = { data: input }; _expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -176,14 +1487,14 @@ describe('TypedDataUtils.encodeData', function () { } _it( - `should fail to encode array of all ${type} example data`, + `should fail to hash array of all ${type} example data`, function () { const types = { Message: [{ name: 'data', type: `${type}[]` }], }; const message = { data: inputs }; _expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -198,7 +1509,7 @@ describe('TypedDataUtils.encodeData', function () { } }); - it('should encode data with custom type', function () { + it('should hash data with custom type', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -224,7 +1535,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -233,7 +1544,7 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should encode data with a recursive data type', function () { + it('should hash data with a recursive data type', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -271,7 +1582,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -280,14 +1591,14 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should throw an error when trying to encode a custom type array', function () { + it('should throw an error when trying to hash a custom type array', function () { const types = { Message: [{ name: 'data', type: 'string[]' }], }; const message = { data: ['1', '2', '3'] }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -321,14 +1632,14 @@ describe('TypedDataUtils.encodeData', function () { contents: 'Hello, Bob!', }; - const originalSignature = sigUtil.TypedDataUtils.encodeData( + const originalSignature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V3', ).toString('hex'); const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + const signatureWithExtraProperties = sigUtil.TypedDataUtils.hashStruct( primaryType, messageWithExtraProperties, types, @@ -366,7 +1677,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -375,7 +1686,7 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow(`Cannot read property 'toArray' of null`); }); - it('should encode data with an atomic property set to undefined', function () { + it('should hash data with an atomic property set to undefined', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -403,7 +1714,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -412,7 +1723,7 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should encode data with a dynamic property set to null', function () { + it('should hash data with a dynamic property set to null', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -438,7 +1749,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -447,7 +1758,7 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should encode data with a dynamic property set to undefined', function () { + it('should hash data with a dynamic property set to undefined', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -473,7 +1784,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -505,7 +1816,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -514,7 +1825,7 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow(`Cannot read property 'name' of null`); }); - it('should encode data with a custom type property set to undefined', function () { + it('should hash data with a custom type property set to undefined', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -537,7 +1848,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -546,14 +1857,14 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should throw an error when trying to encode a function', function () { + it('should throw an error when trying to hash a function', function () { const types = { Message: [{ name: 'data', type: 'function' }], }; const message = { data: 'test' }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -562,12 +1873,12 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('Unsupported or invalid type: function'); }); - it('should throw an error when trying to encode with a missing primary type definition', function () { + it('should throw an error when trying to hash with a missing primary type definition', function () { const types = {}; const message = { data: 'test' }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -576,14 +1887,14 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('No type definition specified: Message'); }); - it('should throw an error when trying to encode an unrecognized type', function () { + it('should throw an error when trying to hash an unrecognized type', function () { const types = { Message: [{ name: 'data', type: 'foo' }], }; const message = { data: 'test' }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -592,7 +1903,7 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('Unsupported or invalid type: foo'); }); - it('should encode data when given extraneous types', function () { + it('should hash data when given extraneous types', function () { const types = { Message: [{ name: 'data', type: 'string' }], Extra: [{ name: 'data', type: 'string' }], @@ -600,7 +1911,7 @@ describe('TypedDataUtils.encodeData', function () { const message = { data: 'Hello!' }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -624,14 +1935,14 @@ describe('TypedDataUtils.encodeData', function () { const inputs = encodeDataExamples[type] || []; for (const input of inputs) { const inputType = input instanceof Buffer ? 'Buffer' : typeof input; - _it(`should encode "${input}" (type "${inputType}")`, function () { + _it(`should hash "${input}" (type "${inputType}")`, function () { const types = { Message: [{ name: 'data', type }], }; const message = { data: input }; _expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -646,7 +1957,7 @@ describe('TypedDataUtils.encodeData', function () { for (const { input, errorMessage } of errorInputs) { const inputType = input instanceof Buffer ? 'Buffer' : typeof input; _it( - `should fail to encode "${input}" (type "${inputType}")`, + `should fail to hash "${input}" (type "${inputType}")`, function () { const types = { Message: [{ name: 'data', type }], @@ -654,7 +1965,7 @@ describe('TypedDataUtils.encodeData', function () { const message = { data: input }; _expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -665,13 +1976,13 @@ describe('TypedDataUtils.encodeData', function () { ); } - _it(`should encode array of all ${type} example data`, function () { + _it(`should hash array of all ${type} example data`, function () { const types = { Message: [{ name: 'data', type: `${type}[]` }], }; const message = { data: inputs }; _expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -683,7 +1994,7 @@ describe('TypedDataUtils.encodeData', function () { } }); - it('should encode data with custom type', function () { + it('should hash data with custom type', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -709,7 +2020,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -718,7 +2029,7 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should encode data with a recursive data type', function () { + it('should hash data with a recursive data type', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -756,7 +2067,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -765,7 +2076,7 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should encode data with a custom data type array', function () { + it('should hash data with a custom data type array', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -796,7 +2107,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -830,14 +2141,14 @@ describe('TypedDataUtils.encodeData', function () { contents: 'Hello, Bob!', }; - const originalSignature = sigUtil.TypedDataUtils.encodeData( + const originalSignature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V4', ).toString('hex'); const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + const signatureWithExtraProperties = sigUtil.TypedDataUtils.hashStruct( primaryType, messageWithExtraProperties, types, @@ -875,7 +2186,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -912,7 +2223,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -921,7 +2232,7 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('missing value for field length of type int32'); }); - it('should encode data with a dynamic property set to null', function () { + it('should hash data with a dynamic property set to null', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -947,7 +2258,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -982,7 +2293,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -991,7 +2302,7 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('missing value for field contents of type string'); }); - it('should encode data with a custom type property set to null', function () { + it('should hash data with a custom type property set to null', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -1014,7 +2325,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -1023,7 +2334,7 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should encode data with a custom type property set to undefined', function () { + it('should hash data with a custom type property set to undefined', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -1046,7 +2357,7 @@ describe('TypedDataUtils.encodeData', function () { }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -1055,14 +2366,14 @@ describe('TypedDataUtils.encodeData', function () { ).toMatchSnapshot(); }); - it('should throw an error when trying to encode a function', function () { + it('should throw an error when trying to hash a function', function () { const types = { Message: [{ name: 'data', type: 'function' }], }; const message = { data: 'test' }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -1071,12 +2382,12 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('Unsupported or invalid type: function'); }); - it('should throw an error when trying to encode with a missing primary type definition', function () { + it('should throw an error when trying to hash with a missing primary type definition', function () { const types = {}; const message = { data: 'test' }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -1085,14 +2396,14 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('No type definition specified: Message'); }); - it('should throw an error when trying to encode an unrecognized type', function () { + it('should throw an error when trying to hash an unrecognized type', function () { const types = { Message: [{ name: 'data', type: 'foo' }], }; const message = { data: 'test' }; expect(() => - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -1101,7 +2412,7 @@ describe('TypedDataUtils.encodeData', function () { ).toThrow('Unsupported or invalid type: foo'); }); - it('should encode data when given extraneous types', function () { + it('should hash data when given extraneous types', function () { const types = { Message: [{ name: 'data', type: 'string' }], Extra: [{ name: 'data', type: 'string' }], @@ -1109,7 +2420,7 @@ describe('TypedDataUtils.encodeData', function () { const message = { data: 'Hello!' }; expect( - sigUtil.TypedDataUtils.encodeData( + sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -1135,19 +2446,19 @@ describe('TypedDataUtils.encodeData', function () { const inputs = encodeDataExamples[type] || []; for (const input of inputs) { const inputType = input instanceof Buffer ? 'Buffer' : typeof input; - _it(`should encode "${input}" (type "${inputType}")`, function () { + _it(`should hash "${input}" (type "${inputType}")`, function () { const types = { Message: [{ name: 'data', type }], }; const message = { data: input }; - const v3Signature = sigUtil.TypedDataUtils.encodeData( + const v3Signature = sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, 'V3', ).toString('hex'); - const v4Signature = sigUtil.TypedDataUtils.encodeData( + const v4Signature = sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -1161,7 +2472,7 @@ describe('TypedDataUtils.encodeData', function () { } }); - it('should encode data with custom type', function () { + it('should hash data with custom type', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -1186,13 +2497,13 @@ describe('TypedDataUtils.encodeData', function () { contents: 'Hello, Bob!', }; - const v3Signature = sigUtil.TypedDataUtils.encodeData( + const v3Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V3', ).toString('hex'); - const v4Signature = sigUtil.TypedDataUtils.encodeData( + const v4Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -1227,26 +2538,26 @@ describe('TypedDataUtils.encodeData', function () { contents: 'Hello, Bob!', }; - const originalV3Signature = sigUtil.TypedDataUtils.encodeData( + const originalV3Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V3', ).toString('hex'); - const originalV4Signature = sigUtil.TypedDataUtils.encodeData( + const originalV4Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V4', ).toString('hex'); const messageWithExtraProperties = { ...message, foo: 'bar' }; - const v3signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + const v3signatureWithExtraProperties = sigUtil.TypedDataUtils.hashStruct( primaryType, messageWithExtraProperties, types, 'V3', ).toString('hex'); - const v4signatureWithExtraProperties = sigUtil.TypedDataUtils.encodeData( + const v4signatureWithExtraProperties = sigUtil.TypedDataUtils.hashStruct( primaryType, messageWithExtraProperties, types, @@ -1259,7 +2570,7 @@ describe('TypedDataUtils.encodeData', function () { ); }); - it('should encode data with a dynamic property set to null', function () { + it('should hash data with a dynamic property set to null', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -1284,13 +2595,13 @@ describe('TypedDataUtils.encodeData', function () { contents: null, }; - const v3Signature = sigUtil.TypedDataUtils.encodeData( + const v3Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V3', ).toString('hex'); - const v4Signature = sigUtil.TypedDataUtils.encodeData( + const v4Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -1300,20 +2611,20 @@ describe('TypedDataUtils.encodeData', function () { expect(v3Signature).toBe(v4Signature); }); - it('should encode data when given extraneous types', function () { + it('should hash data when given extraneous types', function () { const types = { Message: [{ name: 'data', type: 'string' }], Extra: [{ name: 'data', type: 'string' }], }; const message = { data: 'Hello!' }; - const v3Signature = sigUtil.TypedDataUtils.encodeData( + const v3Signature = sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, 'V3', ).toString('hex'); - const v4Signature = sigUtil.TypedDataUtils.encodeData( + const v4Signature = sigUtil.TypedDataUtils.hashStruct( 'Message', message, types, @@ -1332,7 +2643,7 @@ describe('TypedDataUtils.encodeData', function () { // and all recursive data structures must include a missing custom typed // property (the recursive one), or they'd be infinitely large or cyclic. // And cyclic data structures are not supported. - it('should encode data with recursive data differently', function () { + it('should hash data with recursive data differently', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -1369,13 +2680,13 @@ describe('TypedDataUtils.encodeData', function () { }, }; - const v3Signature = sigUtil.TypedDataUtils.encodeData( + const v3Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V3', ).toString('hex'); - const v4Signature = sigUtil.TypedDataUtils.encodeData( + const v4Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -1386,7 +2697,7 @@ describe('TypedDataUtils.encodeData', function () { }); // Missing custom type properties are omitted in V3, but encoded as 0 (bytes32) in V4 - it('should encode missing custom type properties differently', function () { + it('should hash missing custom type properties differently', function () { const types = { Person: [ { name: 'name', type: 'string' }, @@ -1407,13 +2718,13 @@ describe('TypedDataUtils.encodeData', function () { contents: 'Hello, Bob!', }; - const v3Signature = sigUtil.TypedDataUtils.encodeData( + const v3Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, 'V3', ).toString('hex'); - const v4Signature = sigUtil.TypedDataUtils.encodeData( + const v4Signature = sigUtil.TypedDataUtils.hashStruct( primaryType, message, types, @@ -2182,21 +3493,6 @@ it('signedTypeData', function () { expect(ethUtil.bufferToHex(utils.hashType('Mail', typedData.types))).toBe( '0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2', ); - expect( - ethUtil.bufferToHex( - utils.hashStruct( - typedData.primaryType, - typedData.message, - typedData.types, - 'V3', - ), - ), - ).toBe('0xc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e'); - expect( - ethUtil.bufferToHex( - utils.hashStruct('EIP712Domain', typedData.domain, typedData.types, 'V3'), - ), - ).toBe('0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f'); expect(ethUtil.bufferToHex(utils.eip712Hash(typedData, 'V3'))).toBe( '0xbe609aee343fb3c4b28e1df9e632fca64fcfaede20f02e86244efddf30957bd2', ); @@ -2261,26 +3557,6 @@ it('signedTypeData with bytes', function () { expect( ethUtil.bufferToHex(utils.hashType('Mail', typedDataWithBytes.types)), ).toBe('0x43999c52db673245777eb64b0330105de064e52179581a340a9856c32372528e'); - expect( - ethUtil.bufferToHex( - utils.hashStruct( - typedDataWithBytes.primaryType, - typedDataWithBytes.message, - typedDataWithBytes.types, - 'V3', - ), - ), - ).toBe('0xe004bdc1ca57ba9ad5ea8c81e54dcbdb3bfce2d1d5ad92113f0871fb2a6eb052'); - expect( - ethUtil.bufferToHex( - utils.hashStruct( - 'EIP712Domain', - typedDataWithBytes.domain, - typedDataWithBytes.types, - 'V3', - ), - ), - ).toBe('0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f'); expect(ethUtil.bufferToHex(utils.eip712Hash(typedDataWithBytes, 'V3'))).toBe( '0xb4aaf457227fec401db772ec22d2095d1235ee5d0833f56f59108c9ffc90fb4b', ); @@ -2350,41 +3626,9 @@ it('signedTypeData_v4', function () { '0xfabfe1ed996349fc6027709802be19d047da1aa5d6894ff5f6486d92db2e6860', ); - expect( - ethUtil.bufferToHex( - utils.hashStruct('Person', typedData.message.from, typedData.types, 'V4'), - ), - ).toBe('0x9b4846dd48b866f0ac54d61b9b21a9e746f921cefa4ee94c4c0a1c49c774f67f'); - - expect( - ethUtil.bufferToHex( - utils.hashStruct( - 'Person', - typedData.message.to[0], - typedData.types, - 'V4', - ), - ), - ).toBe('0xefa62530c7ae3a290f8a13a5fc20450bdb3a6af19d9d9d2542b5a94e631a9168'); - expect(ethUtil.bufferToHex(utils.hashType('Mail', typedData.types))).toBe( '0x4bd8a9a2b93427bb184aca81e24beb30ffa3c747e2a33d4225ec08bf12e2e753', ); - expect( - ethUtil.bufferToHex( - utils.hashStruct( - typedData.primaryType, - typedData.message, - typedData.types, - 'V4', - ), - ), - ).toBe('0xeb4221181ff3f1a83ea7313993ca9218496e424604ba9492bb4052c03d5c3df8'); - expect( - ethUtil.bufferToHex( - utils.hashStruct('EIP712Domain', typedData.domain, typedData.types, 'V4'), - ), - ).toBe('0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f'); expect(ethUtil.bufferToHex(utils.eip712Hash(typedData, 'V4'))).toBe( '0xa85c2e2b118698e88db68a8105b794a8cc7cec074e89ef991cb4f5f533819cc2', ); @@ -2461,41 +3705,9 @@ it('signedTypeData_v4', function () { '0xfabfe1ed996349fc6027709802be19d047da1aa5d6894ff5f6486d92db2e6860', ); - expect( - ethUtil.bufferToHex( - utils.hashStruct('Person', typedData.message.from, typedData.types, 'V4'), - ), - ).toBe('0x9b4846dd48b866f0ac54d61b9b21a9e746f921cefa4ee94c4c0a1c49c774f67f'); - - expect( - ethUtil.bufferToHex( - utils.hashStruct( - 'Person', - typedData.message.to[0], - typedData.types, - 'V4', - ), - ), - ).toBe('0xefa62530c7ae3a290f8a13a5fc20450bdb3a6af19d9d9d2542b5a94e631a9168'); - expect(ethUtil.bufferToHex(utils.hashType('Mail', typedData.types))).toBe( '0x4bd8a9a2b93427bb184aca81e24beb30ffa3c747e2a33d4225ec08bf12e2e753', ); - expect( - ethUtil.bufferToHex( - utils.hashStruct( - typedData.primaryType, - typedData.message, - typedData.types, - 'V4', - ), - ), - ).toBe('0xeb4221181ff3f1a83ea7313993ca9218496e424604ba9492bb4052c03d5c3df8'); - expect( - ethUtil.bufferToHex( - utils.hashStruct('EIP712Domain', typedData.domain, typedData.types, 'V4'), - ), - ).toBe('0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f'); expect(ethUtil.bufferToHex(utils.eip712Hash(typedData, 'V4'))).toBe( '0xa85c2e2b118698e88db68a8105b794a8cc7cec074e89ef991cb4f5f533819cc2', ); @@ -2559,43 +3771,6 @@ it('signedTypeData_v4 with recursive types', function () { '0x7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116', ); - expect( - ethUtil.bufferToHex( - utils.hashStruct( - 'Person', - typedData.message.mother, - typedData.types, - 'V4', - ), - ), - ).toBe('0x9ebcfbf94f349de50bcb1e3aa4f1eb38824457c99914fefda27dcf9f99f6178b'); - - expect( - ethUtil.bufferToHex( - utils.hashStruct( - 'Person', - typedData.message.father, - typedData.types, - 'V4', - ), - ), - ).toBe('0xb852e5abfeff916a30cb940c4e24c43cfb5aeb0fa8318bdb10dd2ed15c8c70d8'); - - expect( - ethUtil.bufferToHex( - utils.hashStruct( - typedData.primaryType, - typedData.message, - typedData.types, - 'V4', - ), - ), - ).toBe('0xfdc7b6d35bbd81f7fa78708604f57569a10edff2ca329c8011373f0667821a45'); - expect( - ethUtil.bufferToHex( - utils.hashStruct('EIP712Domain', typedData.domain, typedData.types, 'V4'), - ), - ).toBe('0xfacb2c1888f63a780c84c216bd9a81b516fc501a19bae1fc81d82df590bbdc60'); expect(ethUtil.bufferToHex(utils.eip712Hash(typedData, 'V4'))).toBe( '0x807773b9faa9879d4971b43856c4d60c2da15c6f8c062bd9d33afefb756de19c', ); @@ -2659,43 +3834,6 @@ it('signedTypeMessage V4 with recursive types', function () { '0x7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116', ); - expect( - ethUtil.bufferToHex( - utils.hashStruct( - 'Person', - typedData.message.mother, - typedData.types, - 'V4', - ), - ), - ).toBe('0x9ebcfbf94f349de50bcb1e3aa4f1eb38824457c99914fefda27dcf9f99f6178b'); - - expect( - ethUtil.bufferToHex( - utils.hashStruct( - 'Person', - typedData.message.father, - typedData.types, - 'V4', - ), - ), - ).toBe('0xb852e5abfeff916a30cb940c4e24c43cfb5aeb0fa8318bdb10dd2ed15c8c70d8'); - - expect( - ethUtil.bufferToHex( - utils.hashStruct( - typedData.primaryType, - typedData.message, - typedData.types, - 'V4', - ), - ), - ).toBe('0xfdc7b6d35bbd81f7fa78708604f57569a10edff2ca329c8011373f0667821a45'); - expect( - ethUtil.bufferToHex( - utils.hashStruct('EIP712Domain', typedData.domain, typedData.types, 'V4'), - ), - ).toBe('0xfacb2c1888f63a780c84c216bd9a81b516fc501a19bae1fc81d82df590bbdc60'); expect(ethUtil.bufferToHex(utils.eip712Hash(typedData, 'V4'))).toBe( '0x807773b9faa9879d4971b43856c4d60c2da15c6f8c062bd9d33afefb756de19c', );