diff --git a/src/__snapshots__/sign-typed-data-gggg.test.ts.snap b/src/__snapshots__/sign-typed-data-gggg.test.ts.snap deleted file mode 100644 index 4e177088..00000000 --- a/src/__snapshots__/sign-typed-data-gggg.test.ts.snap +++ /dev/null @@ -1,215 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0x10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d50967f2a2c7f3d22f9278175c1e6aa39cf9171db91dceacd5ee0f37c2e507b5abe"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0x101" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d504535a04e923af75e64a9f6cdfb922004b40beec0649d36cf6ea095b7c4975cae"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "10" (type "Buffer") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "10" (type "number") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d500ef9d8f8804d174666011a394cab7901679a8944d24249fd148a6a36071151f8"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V3 should encode data when called unbound 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; - -exports[`TypedDataUtils.encodeData V3 should encode data when given extraneous types 1`] = `"cddf41b07426e1a761f3da57e35474ae3deaa5b596306531f651c6dc1321e4fd6cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a custom type property set to undefined 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a dynamic property set to null 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a dynamic property set to undefined 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a recursive data type 1`] = `"66658e9662034bcd21df657297dab8ba47f0ae05dd8aa253cc935d9aacfd9d10fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8585a30736f22452235ee25aabb6e4c2a6a22c8cf007855687a076a95d15f00c0"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with an atomic property set to undefined 1`] = `"2445b23f0dc0a35bae9b7bd2bd12c89a2db0f66a4a73c8e8b95df6729c227c43fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d16cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with custom type 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "0x10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d50967f2a2c7f3d22f9278175c1e6aa39cf9171db91dceacd5ee0f37c2e507b5abe"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "0x101" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d504535a04e923af75e64a9f6cdfb922004b40beec0649d36cf6ea095b7c4975cae"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "10" (type "Buffer") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "10" (type "number") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d500ef9d8f8804d174666011a394cab7901679a8944d24249fd148a6a36071151f8"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode array of all bytes example data 1`] = `"93f286650d21b73fafa0cf1f6da3997b287c960d06b6f072958b05a5502e54febac16bf09382afca2698a9b7c71eb0d570d3267fcdc6cbc891688a4defd1cab4"`; - -exports[`TypedDataUtils.encodeData V4 should encode data when called unbound 1`] = `"cddf41b07426e1a761f3da57e35474ae3deaa5b596306531f651c6dc1321e4fd6cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V4 should encode data when given extraneous types 1`] = `"cddf41b07426e1a761f3da57e35474ae3deaa5b596306531f651c6dc1321e4fd6cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a custom data type array 1`] = `"077b2e5169bfc57ed1b6acf858d27ae9b8311db1ccf71df99dfcf9efe8eec43856cacfdc07c6f697bc1bc978cf38559d5c729ed1cd1177e047df929e19dc2a2e8548546251a0cc6d0005e1a792e00f85feed5056e580102ed1afa615f87bb130b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a custom type property set to null 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c80000000000000000000000000000000000000000000000000000000000000000b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a custom type property set to undefined 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c80000000000000000000000000000000000000000000000000000000000000000b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a dynamic property set to null 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a recursive data type 1`] = `"66658e9662034bcd21df657297dab8ba47f0ae05dd8aa253cc935d9aacfd9d10fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8161abe35f76debc1e0496baa54308eb1f1331218276bf01c4af34ee637780b25"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with custom type 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -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 "0x101" (type "string") 1`] = `"9ec9530996ac7e6e69e8451f8ce9b3b76292a29f8b63af77c328bc95d921a044"`; - -exports[`TypedDataUtils.hashStruct V3 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; - -exports[`TypedDataUtils.hashStruct V3 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; - -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 should hash data when called unbound 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; - -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 "bytes" should hash "0x10" (type "string") 1`] = `"724dca4470f2d466424cc9f6ee09f55034659518ef5426fde3af846aa6fefcd6"`; - -exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0x101" (type "string") 1`] = `"9ec9530996ac7e6e69e8451f8ce9b3b76292a29f8b63af77c328bc95d921a044"`; - -exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; - -exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; - -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`] = `"fc59b9fa24a676115c57754d0e7e18c515e78386aea5dd143d7248348008664e"`; - -exports[`TypedDataUtils.hashStruct V4 should hash data when called unbound 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; - -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[`signTypedData V1 example data type "bytes" should sign "0x10" (type "string") 1`] = `"0xa110741a43ecb6b47993f5b821d7352b11b3c683995ac0f75818ee8aaec46f711008c6396607b1b48d137dfff943c1e2d3f75adc8bb37648841a49b4c164913e1c"`; - -exports[`signTypedData V1 example data type "bytes" should sign "10" (type "Buffer") 1`] = `"0xa7d8de4864a3a08645fb5e46797de200d93e8af90607a5716b562f9d04ea0447077bcb7216c8836ee33a05f699a051584b209634bd2ac728f47f49b84955af2c1b"`; - -exports[`signTypedData V1 example data type "bytes" should sign "10" (type "number") 1`] = `"0x783accdc2cf6914d8c2d92550a177a437665becc2b5d6339f7e3142df73473f31d7fde79e11636dded8ecee29b54eb7b4f1cc5bb25a7187183cfebe76ad6b6151c"`; - -exports[`signTypedData V1 example data type "bytes" should sign "10" (type "string") 1`] = `"0xa7d8de4864a3a08645fb5e46797de200d93e8af90607a5716b562f9d04ea0447077bcb7216c8836ee33a05f699a051584b209634bd2ac728f47f49b84955af2c1b"`; - -exports[`signTypedData V1 should sign data with a dynamic property set to undefined 1`] = `[Function]`; - -exports[`signTypedData V1 should sign data with an atomic property set to undefined 1`] = `[Function]`; - -exports[`signTypedData V3 example data type "bytes" should sign "0x10" (type "string") 1`] = `"0x3de701e25bff8626c535c0b630b5d5cce8230965ef5cd21b894daef9c3fe15b7042ea68ebbe272a50d1d69dc1df1a3e5a5a16ca570cee8df43d251d4835b808f1b"`; - -exports[`signTypedData V3 example data type "bytes" should sign "0x101" (type "string") 1`] = `"0x821516d637520e4fc33b1493648fba6e90966cc0831f2a5b388d4772e76b8c1c47d0f0346a42c153a56d3144087de5933e10d2c3a1c458a48dd1343d05b03e4b1b"`; - -exports[`signTypedData V3 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; - -exports[`signTypedData V3 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; - -exports[`signTypedData V3 example data type "bytes" should sign "10" (type "Buffer") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V3 example data type "bytes" should sign "10" (type "number") 1`] = `"0x3d21aa6434df45520cd508b0a5ebbf237cce369518fa6c2b7d18919af55f2d67328ac8634cd92f8530422e47f6feaa7310eb8b661160c3123f224ce981b05eff1b"`; - -exports[`signTypedData V3 example data type "bytes" should sign "10" (type "string") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V3 should sign a minimal valid typed message 1`] = `"0x24367b495e5d9f1fabc6e66abaaf0f3e5fe6fd984d5870a72523a1add3f3efdd41005bceba75e7c3ee96c233a5c7b4fe5642a58966eb46de25f111f541b272b31b"`; - -exports[`signTypedData V3 should sign a typed message with a domain separator that uses all fields 1`] = `"0xf040a7c2d6af769217af11d4344329079314b55cfb7f449f946adf6706a9c57a4b88b2b50565d41f5b288e10de4547924210e3096b5eec8fa7573933cb068f0b1b"`; - -exports[`signTypedData V3 should sign a typed message with data 1`] = `"0x6d670a14c801041d1e54e0565df65327c462aef1083766b93b9a523f8fff449c114bc223ff59eba0c8cddfa7396008c1291096cf39e494ef041af1e43b382d1a1b"`; - -exports[`signTypedData V3 should sign a typed message with extra domain seperator fields 1`] = `"0x8ee10dccf694bce51a20752181940f12686da8ec8fa8eba0aac2ea7cc31ad5024be6bfe9ac492ae75bc594e3925c0e7de33509daf4ed3725278a3180b526313c1c"`; - -exports[`signTypedData V3 should sign a typed message with only custom domain seperator fields 1`] = `"0x3b863232a4522d03c07ad317001becca5e39dad8adcc2562b34423ac914cdad2162c59c848c45a59b00028143c4524365f382b8565d83363cde52c2b448d9c591c"`; - -exports[`signTypedData V3 should sign data when given extraneous types 1`] = `"0x9809571f17ee150687932fb7b993f4437b05caf9c8e64818ab4356b33992f3796636c18e88ba9c6dc140f39f95d8ae5770ad2f17070af208690c82d33f3bc8701c"`; - -exports[`signTypedData V3 should sign data with a custom type property set to undefined 1`] = `"0x9ba34db2c5428567823481e8f0c2c5413af6be8b516fc2d29615f84f225184c402659b49887adf9ae09ba8e76fce7835c8604dcab40720851456027797457ab81c"`; - -exports[`signTypedData V3 should sign data with a dynamic property set to null 1`] = `"0xe18d18885acf2acf1af426a60c4d8d1345de64c741900d6c6c47a5ad434c1d9b357d1480f1ecf152f88bd3f4f5226720b2636e39059166d1fbdb568ab5211ed81c"`; - -exports[`signTypedData V3 should sign data with a dynamic property set to undefined 1`] = `"0x07eb3eef41f303c119d3f4be1ee1f26a49d031c2bec9809a65546e3acf2147303d39f08995413d9f786f4e8a367b113dae9f5bf36ec61709d2ed1e79130329901b"`; - -exports[`signTypedData V3 should sign data with a recursive data type 1`] = `"0xa8817c10be86cf9097f3d9da56c6eb22c4a9c34963071545b34b499beb758f49470b3cc4911833ad8d296eca48e18c23c97725abee34161f09a0658efd1daec71b"`; - -exports[`signTypedData V3 should sign data with an atomic property set to undefined 1`] = `"0x698f3018e9facd6772bbe069df16454d141376336ef04e87df1618bb4e17c43a0a46b6cbdd97ebdce5933014b2a6038ba00fde5375d96fd53393fe723362d4af1b"`; - -exports[`signTypedData V3 should sign data with custom type 1`] = `"0x22ee0cb3a379f3a122f7b59456ebcf404ca139320a0723560abde49cc95f4a2f69774bf94c4e776f1a9c8c8a67e9e2bdda131e04bde935f73fae376ee788920d1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign "0x10" (type "string") 1`] = `"0x3de701e25bff8626c535c0b630b5d5cce8230965ef5cd21b894daef9c3fe15b7042ea68ebbe272a50d1d69dc1df1a3e5a5a16ca570cee8df43d251d4835b808f1b"`; - -exports[`signTypedData V4 example data type "bytes" should sign "0x101" (type "string") 1`] = `"0x821516d637520e4fc33b1493648fba6e90966cc0831f2a5b388d4772e76b8c1c47d0f0346a42c153a56d3144087de5933e10d2c3a1c458a48dd1343d05b03e4b1b"`; - -exports[`signTypedData V4 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign "10" (type "Buffer") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign "10" (type "number") 1`] = `"0x3d21aa6434df45520cd508b0a5ebbf237cce369518fa6c2b7d18919af55f2d67328ac8634cd92f8530422e47f6feaa7310eb8b661160c3123f224ce981b05eff1b"`; - -exports[`signTypedData V4 example data type "bytes" should sign "10" (type "string") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign array of all bytes example data 1`] = `"0x4b33cc27656a85e41328ef2f72c2a86c612075e977e29523cced5b3f7f7686fd3b75b624b04bf9add8b2f036e0de5979d3bb01d94b1944069e233a40d49d966e1c"`; - -exports[`signTypedData V4 should sign a minimal valid typed message 1`] = `"0x24367b495e5d9f1fabc6e66abaaf0f3e5fe6fd984d5870a72523a1add3f3efdd41005bceba75e7c3ee96c233a5c7b4fe5642a58966eb46de25f111f541b272b31b"`; - -exports[`signTypedData V4 should sign a typed message with a domain separator that uses all fields 1`] = `"0xf040a7c2d6af769217af11d4344329079314b55cfb7f449f946adf6706a9c57a4b88b2b50565d41f5b288e10de4547924210e3096b5eec8fa7573933cb068f0b1b"`; - -exports[`signTypedData V4 should sign a typed message with data 1`] = `"0x6d670a14c801041d1e54e0565df65327c462aef1083766b93b9a523f8fff449c114bc223ff59eba0c8cddfa7396008c1291096cf39e494ef041af1e43b382d1a1b"`; - -exports[`signTypedData V4 should sign a typed message with extra domain seperator fields 1`] = `"0x8ee10dccf694bce51a20752181940f12686da8ec8fa8eba0aac2ea7cc31ad5024be6bfe9ac492ae75bc594e3925c0e7de33509daf4ed3725278a3180b526313c1c"`; - -exports[`signTypedData V4 should sign a typed message with only custom domain seperator fields 1`] = `"0x3b863232a4522d03c07ad317001becca5e39dad8adcc2562b34423ac914cdad2162c59c848c45a59b00028143c4524365f382b8565d83363cde52c2b448d9c591c"`; - -exports[`signTypedData V4 should sign data when given extraneous types 1`] = `"0x9809571f17ee150687932fb7b993f4437b05caf9c8e64818ab4356b33992f3796636c18e88ba9c6dc140f39f95d8ae5770ad2f17070af208690c82d33f3bc8701c"`; - -exports[`signTypedData V4 should sign data with a custom data type array 1`] = `"0x17c484deba479e3e9f821a6d5defc0179ddf52195c0cd75895c936b3ab4d217c6ba7f1f164a3ac9701e1694a04a13f421fb67ec44cd316846326a98b0d5838a01c"`; - -exports[`signTypedData V4 should sign data with a custom type property set to null 1`] = `"0xc24daccba3391e6f6c3c07c8d62b8c83f7bb4e370613cb2d9ece63a4897d2d044e77e613091a496d8f337854c09ee139e4bca87839d3562ba16a850daa60185a1c"`; - -exports[`signTypedData V4 should sign data with a custom type property set to undefined 1`] = `"0xc24daccba3391e6f6c3c07c8d62b8c83f7bb4e370613cb2d9ece63a4897d2d044e77e613091a496d8f337854c09ee139e4bca87839d3562ba16a850daa60185a1c"`; - -exports[`signTypedData V4 should sign data with a dynamic property set to null 1`] = `"0xe18d18885acf2acf1af426a60c4d8d1345de64c741900d6c6c47a5ad434c1d9b357d1480f1ecf152f88bd3f4f5226720b2636e39059166d1fbdb568ab5211ed81c"`; - -exports[`signTypedData V4 should sign data with a recursive data type 1`] = `"0x8f549ddc5ce19505b8ae0d262db4640c7b1410dec5ee037d65c2225d53c845bd38265565378b7e7a53e08499dcfdb70e885ed9207f67d7bc34278b81b39b93d11b"`; - -exports[`signTypedData V4 should sign data with custom type 1`] = `"0x22ee0cb3a379f3a122f7b59456ebcf404ca139320a0723560abde49cc95f4a2f69774bf94c4e776f1a9c8c8a67e9e2bdda131e04bde935f73fae376ee788920d1c"`; diff --git a/src/__snapshots__/sign-typed-data-narrowed.test.ts.snap b/src/__snapshots__/sign-typed-data-narrowed.test.ts.snap new file mode 100644 index 00000000..1e96a157 --- /dev/null +++ b/src/__snapshots__/sign-typed-data-narrowed.test.ts.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TypedDataUtils.encodeData TypedDataUtils.hashStruct V3 example data type "bytes" should hash "0x101" (type "string") 1`] = `"9ec9530996ac7e6e69e8451f8ce9b3b76292a29f8b63af77c328bc95d921a044"`; + +exports[`TypedDataUtils.encodeData TypedDataUtils.hashStruct V3 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; + +exports[`TypedDataUtils.encodeData TypedDataUtils.hashStruct V3 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"700c3e0cc9d6f0ba10b117c03ca22a8934a51cc2a00cd0359c1c856e5eb814ae"`; + +exports[`TypedDataUtils.encodeData TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0x101" (type "string") 1`] = `"9ec9530996ac7e6e69e8451f8ce9b3b76292a29f8b63af77c328bc95d921a044"`; + +exports[`TypedDataUtils.encodeData TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; + +exports[`TypedDataUtils.encodeData TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"700c3e0cc9d6f0ba10b117c03ca22a8934a51cc2a00cd0359c1c856e5eb814ae"`; + +exports[`TypedDataUtils.encodeData TypedDataUtils.hashStruct V4 example data type "bytes" should hash array of all bytes example data 1`] = `"234c1c4aff47de355ae7d9555f024f2cd5a29959b69e2fad482146efcf983452"`; + +exports[`TypedDataUtils.encodeData V3 V4 example data type "bytes" should encode "0x101" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d504535a04e923af75e64a9f6cdfb922004b40beec0649d36cf6ea095b7c4975cae"`; + +exports[`TypedDataUtils.encodeData V3 V4 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; + +exports[`TypedDataUtils.encodeData V3 V4 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d5079e359f9f8dd862458d27e6f821489aabacad92fedc4fb7117a53cb15cec6756"`; + +exports[`TypedDataUtils.encodeData V3 V4 example data type "bytes" should encode array of all bytes example data 1`] = `"93f286650d21b73fafa0cf1f6da3997b287c960d06b6f072958b05a5502e54fef56a97ca3a3d71042b307a9e33372ec8d2828dbfa0b7025a7503b218f22fba90"`; + +exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0x101" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d504535a04e923af75e64a9f6cdfb922004b40beec0649d36cf6ea095b7c4975cae"`; + +exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; + +exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d5079e359f9f8dd862458d27e6f821489aabacad92fedc4fb7117a53cb15cec6756"`; + +exports[`TypedDataUtils.encodeData signTypedData V3 example data type "bytes" should sign "0x101" (type "string") 1`] = `"0x821516d637520e4fc33b1493648fba6e90966cc0831f2a5b388d4772e76b8c1c47d0f0346a42c153a56d3144087de5933e10d2c3a1c458a48dd1343d05b03e4b1b"`; + +exports[`TypedDataUtils.encodeData signTypedData V3 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; + +exports[`TypedDataUtils.encodeData signTypedData V3 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"0x55cbf0cc598373784e1c2cecec99668f491852ecf9f7f37b6e1203d06867764b598b4e5556807ce8f32f422c395b52a66c789439db7a1efe0ff7c682f4bf7b421b"`; + +exports[`TypedDataUtils.encodeData signTypedData V4 example data type "bytes" should sign "0x101" (type "string") 1`] = `"0x821516d637520e4fc33b1493648fba6e90966cc0831f2a5b388d4772e76b8c1c47d0f0346a42c153a56d3144087de5933e10d2c3a1c458a48dd1343d05b03e4b1b"`; + +exports[`TypedDataUtils.encodeData signTypedData V4 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; + +exports[`TypedDataUtils.encodeData signTypedData V4 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012" (type "string") 1`] = `"0x55cbf0cc598373784e1c2cecec99668f491852ecf9f7f37b6e1203d06867764b598b4e5556807ce8f32f422c395b52a66c789439db7a1efe0ff7c682f4bf7b421b"`; + +exports[`TypedDataUtils.encodeData signTypedData V4 example data type "bytes" should sign array of all bytes example data 1`] = `"0x87a5eb254e39bfbec5d058c3e2eef14dcfada0c3edd4a3bf61e6bd5f3773f1231da7dde4ccf3239651f48b460fd16fb6d0ff422f340fbd9f313849776e09294e1c"`; diff --git a/src/__snapshots__/sign-typed-data-old.test.ts.snap b/src/__snapshots__/sign-typed-data-old.test.ts.snap deleted file mode 100644 index eaf376f6..00000000 --- a/src/__snapshots__/sign-typed-data-old.test.ts.snap +++ /dev/null @@ -1,203 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0x10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d50967f2a2c7f3d22f9278175c1e6aa39cf9171db91dceacd5ee0f37c2e507b5abe"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0x101" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d504535a04e923af75e64a9f6cdfb922004b40beec0649d36cf6ea095b7c4975cae"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "10" (type "Buffer") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "10" (type "number") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d500ef9d8f8804d174666011a394cab7901679a8944d24249fd148a6a36071151f8"`; - -exports[`TypedDataUtils.encodeData V3 example data type "bytes" should encode "10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V3 should encode data when called unbound 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; - -exports[`TypedDataUtils.encodeData V3 should encode data when given extraneous types 1`] = `"cddf41b07426e1a761f3da57e35474ae3deaa5b596306531f651c6dc1321e4fd6cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a custom type property set to undefined 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a dynamic property set to null 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a dynamic property set to undefined 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with a recursive data type 1`] = `"66658e9662034bcd21df657297dab8ba47f0ae05dd8aa253cc935d9aacfd9d10fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8585a30736f22452235ee25aabb6e4c2a6a22c8cf007855687a076a95d15f00c0"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with an atomic property set to undefined 1`] = `"2445b23f0dc0a35bae9b7bd2bd12c89a2db0f66a4a73c8e8b95df6729c227c43fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d16cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V3 should encode data with custom type 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "0x10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d50967f2a2c7f3d22f9278175c1e6aa39cf9171db91dceacd5ee0f37c2e507b5abe"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "0x101" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d504535a04e923af75e64a9f6cdfb922004b40beec0649d36cf6ea095b7c4975cae"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d503c69557ff216b14e1d6882d6397d50cfc71f2cfc4151763c37e657cd8fb6eb5d"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "10" (type "Buffer") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "10" (type "number") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d500ef9d8f8804d174666011a394cab7901679a8944d24249fd148a6a36071151f8"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode "10" (type "string") 1`] = `"fe4e90aeb2dead25fb44e8b67b2f9cdb3cabea1f7555b81fcc61f7103acf5d501a192fabce13988b84994d4296e6cdc418d55e2f1d7f942188d4040b94fc57ac"`; - -exports[`TypedDataUtils.encodeData V4 example data type "bytes" should encode array of all bytes example data 1`] = `"93f286650d21b73fafa0cf1f6da3997b287c960d06b6f072958b05a5502e54febac16bf09382afca2698a9b7c71eb0d570d3267fcdc6cbc891688a4defd1cab4"`; - -exports[`TypedDataUtils.encodeData V4 should encode data when called unbound 1`] = `"cddf41b07426e1a761f3da57e35474ae3deaa5b596306531f651c6dc1321e4fd6cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V4 should encode data when given extraneous types 1`] = `"cddf41b07426e1a761f3da57e35474ae3deaa5b596306531f651c6dc1321e4fd6cdba77591a790691c694fa0be937f835b8a589095e427022aa1035e579ee596"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a custom data type array 1`] = `"077b2e5169bfc57ed1b6acf858d27ae9b8311db1ccf71df99dfcf9efe8eec43856cacfdc07c6f697bc1bc978cf38559d5c729ed1cd1177e047df929e19dc2a2e8548546251a0cc6d0005e1a792e00f85feed5056e580102ed1afa615f87bb130b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a custom type property set to null 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c80000000000000000000000000000000000000000000000000000000000000000b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a custom type property set to undefined 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c80000000000000000000000000000000000000000000000000000000000000000b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a dynamic property set to null 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with a recursive data type 1`] = `"66658e9662034bcd21df657297dab8ba47f0ae05dd8aa253cc935d9aacfd9d10fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8161abe35f76debc1e0496baa54308eb1f1331218276bf01c4af34ee637780b25"`; - -exports[`TypedDataUtils.encodeData V4 should encode data with custom type 1`] = `"a0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2fc71e5fa27ff56c350aa531bc129ebdf613b772b6604664f5d8dbe21b85eb0c8cd54f074a4af31b4411ff6a60c9719dbd559c221c8ac3492d9d872b041d703d1b5aadf3154a261abdd9086fc627b61efca26ae5702701d05cd2305f7c52a2fc8"`; - -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 "0x101" (type "string") 1`] = `"9ec9530996ac7e6e69e8451f8ce9b3b76292a29f8b63af77c328bc95d921a044"`; - -exports[`TypedDataUtils.hashStruct V3 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; - -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 should hash data when called unbound 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; - -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 "bytes" should hash "0x10" (type "string") 1`] = `"724dca4470f2d466424cc9f6ee09f55034659518ef5426fde3af846aa6fefcd6"`; - -exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0x101" (type "string") 1`] = `"9ec9530996ac7e6e69e8451f8ce9b3b76292a29f8b63af77c328bc95d921a044"`; - -exports[`TypedDataUtils.hashStruct V4 example data type "bytes" should hash "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"262fae6268b3ee84a3870ced869fddd7b881ea50983994601c1dfdb2f61d9dce"`; - -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`] = `"fc59b9fa24a676115c57754d0e7e18c515e78386aea5dd143d7248348008664e"`; - -exports[`TypedDataUtils.hashStruct V4 should hash data when called unbound 1`] = `"15d2c54cdaa22a6a3a8dbd89086b2ffcf0853857db9bcf1541765a8f769a63ba"`; - -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[`signTypedData V1 example data type "bytes" should sign "0x10" (type "string") 1`] = `"0xa110741a43ecb6b47993f5b821d7352b11b3c683995ac0f75818ee8aaec46f711008c6396607b1b48d137dfff943c1e2d3f75adc8bb37648841a49b4c164913e1c"`; - -exports[`signTypedData V1 example data type "bytes" should sign "10" (type "Buffer") 1`] = `"0xa7d8de4864a3a08645fb5e46797de200d93e8af90607a5716b562f9d04ea0447077bcb7216c8836ee33a05f699a051584b209634bd2ac728f47f49b84955af2c1b"`; - -exports[`signTypedData V1 example data type "bytes" should sign "10" (type "number") 1`] = `"0x783accdc2cf6914d8c2d92550a177a437665becc2b5d6339f7e3142df73473f31d7fde79e11636dded8ecee29b54eb7b4f1cc5bb25a7187183cfebe76ad6b6151c"`; - -exports[`signTypedData V1 example data type "bytes" should sign "10" (type "string") 1`] = `"0xa7d8de4864a3a08645fb5e46797de200d93e8af90607a5716b562f9d04ea0447077bcb7216c8836ee33a05f699a051584b209634bd2ac728f47f49b84955af2c1b"`; - -exports[`signTypedData V1 should sign data with a dynamic property set to undefined 1`] = `[Function]`; - -exports[`signTypedData V1 should sign data with an atomic property set to undefined 1`] = `[Function]`; - -exports[`signTypedData V3 example data type "bytes" should sign "0x10" (type "string") 1`] = `"0x3de701e25bff8626c535c0b630b5d5cce8230965ef5cd21b894daef9c3fe15b7042ea68ebbe272a50d1d69dc1df1a3e5a5a16ca570cee8df43d251d4835b808f1b"`; - -exports[`signTypedData V3 example data type "bytes" should sign "0x101" (type "string") 1`] = `"0x821516d637520e4fc33b1493648fba6e90966cc0831f2a5b388d4772e76b8c1c47d0f0346a42c153a56d3144087de5933e10d2c3a1c458a48dd1343d05b03e4b1b"`; - -exports[`signTypedData V3 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; - -exports[`signTypedData V3 example data type "bytes" should sign "10" (type "Buffer") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V3 example data type "bytes" should sign "10" (type "number") 1`] = `"0x3d21aa6434df45520cd508b0a5ebbf237cce369518fa6c2b7d18919af55f2d67328ac8634cd92f8530422e47f6feaa7310eb8b661160c3123f224ce981b05eff1b"`; - -exports[`signTypedData V3 example data type "bytes" should sign "10" (type "string") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V3 should sign a minimal valid typed message 1`] = `"0x24367b495e5d9f1fabc6e66abaaf0f3e5fe6fd984d5870a72523a1add3f3efdd41005bceba75e7c3ee96c233a5c7b4fe5642a58966eb46de25f111f541b272b31b"`; - -exports[`signTypedData V3 should sign a typed message with a domain separator that uses all fields 1`] = `"0xf040a7c2d6af769217af11d4344329079314b55cfb7f449f946adf6706a9c57a4b88b2b50565d41f5b288e10de4547924210e3096b5eec8fa7573933cb068f0b1b"`; - -exports[`signTypedData V3 should sign a typed message with data 1`] = `"0x6d670a14c801041d1e54e0565df65327c462aef1083766b93b9a523f8fff449c114bc223ff59eba0c8cddfa7396008c1291096cf39e494ef041af1e43b382d1a1b"`; - -exports[`signTypedData V3 should sign a typed message with extra domain seperator fields 1`] = `"0x8ee10dccf694bce51a20752181940f12686da8ec8fa8eba0aac2ea7cc31ad5024be6bfe9ac492ae75bc594e3925c0e7de33509daf4ed3725278a3180b526313c1c"`; - -exports[`signTypedData V3 should sign a typed message with only custom domain seperator fields 1`] = `"0x3b863232a4522d03c07ad317001becca5e39dad8adcc2562b34423ac914cdad2162c59c848c45a59b00028143c4524365f382b8565d83363cde52c2b448d9c591c"`; - -exports[`signTypedData V3 should sign data when given extraneous types 1`] = `"0x9809571f17ee150687932fb7b993f4437b05caf9c8e64818ab4356b33992f3796636c18e88ba9c6dc140f39f95d8ae5770ad2f17070af208690c82d33f3bc8701c"`; - -exports[`signTypedData V3 should sign data with a custom type property set to undefined 1`] = `"0x9ba34db2c5428567823481e8f0c2c5413af6be8b516fc2d29615f84f225184c402659b49887adf9ae09ba8e76fce7835c8604dcab40720851456027797457ab81c"`; - -exports[`signTypedData V3 should sign data with a dynamic property set to null 1`] = `"0xe18d18885acf2acf1af426a60c4d8d1345de64c741900d6c6c47a5ad434c1d9b357d1480f1ecf152f88bd3f4f5226720b2636e39059166d1fbdb568ab5211ed81c"`; - -exports[`signTypedData V3 should sign data with a dynamic property set to undefined 1`] = `"0x07eb3eef41f303c119d3f4be1ee1f26a49d031c2bec9809a65546e3acf2147303d39f08995413d9f786f4e8a367b113dae9f5bf36ec61709d2ed1e79130329901b"`; - -exports[`signTypedData V3 should sign data with a recursive data type 1`] = `"0xa8817c10be86cf9097f3d9da56c6eb22c4a9c34963071545b34b499beb758f49470b3cc4911833ad8d296eca48e18c23c97725abee34161f09a0658efd1daec71b"`; - -exports[`signTypedData V3 should sign data with an atomic property set to undefined 1`] = `"0x698f3018e9facd6772bbe069df16454d141376336ef04e87df1618bb4e17c43a0a46b6cbdd97ebdce5933014b2a6038ba00fde5375d96fd53393fe723362d4af1b"`; - -exports[`signTypedData V3 should sign data with custom type 1`] = `"0x22ee0cb3a379f3a122f7b59456ebcf404ca139320a0723560abde49cc95f4a2f69774bf94c4e776f1a9c8c8a67e9e2bdda131e04bde935f73fae376ee788920d1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign "0x10" (type "string") 1`] = `"0x3de701e25bff8626c535c0b630b5d5cce8230965ef5cd21b894daef9c3fe15b7042ea68ebbe272a50d1d69dc1df1a3e5a5a16ca570cee8df43d251d4835b808f1b"`; - -exports[`signTypedData V4 example data type "bytes" should sign "0x101" (type "string") 1`] = `"0x821516d637520e4fc33b1493648fba6e90966cc0831f2a5b388d4772e76b8c1c47d0f0346a42c153a56d3144087de5933e10d2c3a1c458a48dd1343d05b03e4b1b"`; - -exports[`signTypedData V4 example data type "bytes" should sign "0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001" (type "string") 1`] = `"0x82533d24d72d06740288f8276a45cd67271a2cf48e0a48bf4782467edabaa3b726aa6e912ccbbe808dd7cd17f4aa018edcc655f0b639661178a823c9869cf1de1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign "10" (type "Buffer") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign "10" (type "number") 1`] = `"0x3d21aa6434df45520cd508b0a5ebbf237cce369518fa6c2b7d18919af55f2d67328ac8634cd92f8530422e47f6feaa7310eb8b661160c3123f224ce981b05eff1b"`; - -exports[`signTypedData V4 example data type "bytes" should sign "10" (type "string") 1`] = `"0xb1db198b7d92bf4cf766276d7a7998a770cb16f8adeaae5f0ac4a0c3372ec75b27d8e5514fcf3ea8cf7b57041792a018dcc31b02f5696500d742618b48bb7f8f1c"`; - -exports[`signTypedData V4 example data type "bytes" should sign array of all bytes example data 1`] = `"0x4b33cc27656a85e41328ef2f72c2a86c612075e977e29523cced5b3f7f7686fd3b75b624b04bf9add8b2f036e0de5979d3bb01d94b1944069e233a40d49d966e1c"`; - -exports[`signTypedData V4 should sign a minimal valid typed message 1`] = `"0x24367b495e5d9f1fabc6e66abaaf0f3e5fe6fd984d5870a72523a1add3f3efdd41005bceba75e7c3ee96c233a5c7b4fe5642a58966eb46de25f111f541b272b31b"`; - -exports[`signTypedData V4 should sign a typed message with a domain separator that uses all fields 1`] = `"0xf040a7c2d6af769217af11d4344329079314b55cfb7f449f946adf6706a9c57a4b88b2b50565d41f5b288e10de4547924210e3096b5eec8fa7573933cb068f0b1b"`; - -exports[`signTypedData V4 should sign a typed message with data 1`] = `"0x6d670a14c801041d1e54e0565df65327c462aef1083766b93b9a523f8fff449c114bc223ff59eba0c8cddfa7396008c1291096cf39e494ef041af1e43b382d1a1b"`; - -exports[`signTypedData V4 should sign a typed message with extra domain seperator fields 1`] = `"0x8ee10dccf694bce51a20752181940f12686da8ec8fa8eba0aac2ea7cc31ad5024be6bfe9ac492ae75bc594e3925c0e7de33509daf4ed3725278a3180b526313c1c"`; - -exports[`signTypedData V4 should sign a typed message with only custom domain seperator fields 1`] = `"0x3b863232a4522d03c07ad317001becca5e39dad8adcc2562b34423ac914cdad2162c59c848c45a59b00028143c4524365f382b8565d83363cde52c2b448d9c591c"`; - -exports[`signTypedData V4 should sign data when given extraneous types 1`] = `"0x9809571f17ee150687932fb7b993f4437b05caf9c8e64818ab4356b33992f3796636c18e88ba9c6dc140f39f95d8ae5770ad2f17070af208690c82d33f3bc8701c"`; - -exports[`signTypedData V4 should sign data with a custom data type array 1`] = `"0x17c484deba479e3e9f821a6d5defc0179ddf52195c0cd75895c936b3ab4d217c6ba7f1f164a3ac9701e1694a04a13f421fb67ec44cd316846326a98b0d5838a01c"`; - -exports[`signTypedData V4 should sign data with a custom type property set to null 1`] = `"0xc24daccba3391e6f6c3c07c8d62b8c83f7bb4e370613cb2d9ece63a4897d2d044e77e613091a496d8f337854c09ee139e4bca87839d3562ba16a850daa60185a1c"`; - -exports[`signTypedData V4 should sign data with a custom type property set to undefined 1`] = `"0xc24daccba3391e6f6c3c07c8d62b8c83f7bb4e370613cb2d9ece63a4897d2d044e77e613091a496d8f337854c09ee139e4bca87839d3562ba16a850daa60185a1c"`; - -exports[`signTypedData V4 should sign data with a dynamic property set to null 1`] = `"0xe18d18885acf2acf1af426a60c4d8d1345de64c741900d6c6c47a5ad434c1d9b357d1480f1ecf152f88bd3f4f5226720b2636e39059166d1fbdb568ab5211ed81c"`; - -exports[`signTypedData V4 should sign data with a recursive data type 1`] = `"0x8f549ddc5ce19505b8ae0d262db4640c7b1410dec5ee037d65c2225d53c845bd38265565378b7e7a53e08499dcfdb70e885ed9207f67d7bc34278b81b39b93d11b"`; - -exports[`signTypedData V4 should sign data with custom type 1`] = `"0x22ee0cb3a379f3a122f7b59456ebcf404ca139320a0723560abde49cc95f4a2f69774bf94c4e776f1a9c8c8a67e9e2bdda131e04bde935f73fae376ee788920d1c"`; diff --git a/src/sign-typed-data-gggg.test.ts b/src/sign-typed-data-gggg.test.ts deleted file mode 100644 index 928cdad4..00000000 --- a/src/sign-typed-data-gggg.test.ts +++ /dev/null @@ -1,4894 +0,0 @@ -// Allow using snapshots in this file. -/* -eslint jest/no-restricted-matchers: [ - 'error', - { - resolves: 'Use `expect(await promise)` instead.', - toBeFalsy: 'Avoid `toBeFalsy`', - toBeTruthy: 'Avoid `toBeTruthy`', - } -] -*/ - -import * as ethUtil from '@ethereumjs/util'; -import Ajv from 'ajv'; -import { - recoverTypedSignature, - signTypedData, - TypedDataUtils, - typedSignatureHash, - SignTypedDataVersion, - TYPED_MESSAGE_SCHEMA, -} from './sign-typed-data'; - -const privateKey = Buffer.from( - '4af1bceebf7f3634ec3cff8a2c38e51178d5d4ce585c52d6043e5e2cc3418bb0', - 'hex', -); - -/** - * Get a list of all Solidity types supported by EIP-712. - * - * @returns A list of all supported Solidity types. - */ -function getEip712SolidityTypes() { - const types = ['bool', 'address', 'string', 'bytes']; - const ints = Array.from(new Array(32)).map( - (_, index) => `int${(index + 1) * 8}`, - ); - const uints = Array.from(new Array(32)).map( - (_, index) => `uint${(index + 1) * 8}`, - ); - const bytes = Array.from(new Array(32)).map( - (_, index) => `bytes${index + 1}`, - ); - - return [...types, ...ints, ...uints, ...bytes]; -} - -const eip712SolidityTypes = getEip712SolidityTypes(); - - -// const MAX_SAFE_INTEGER_AS_HEX = `0x${Number.MAX_SAFE_INTEGER.toString(16)}`; -// const MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX = `0x${( -// Number.MAX_SAFE_INTEGER + 1 -// ).toString(16)}`; - -// we test both even and odd length hex values because Node's Buffer.from() method does not buffer hex numbers correctly -// so we made a helper function numberToBuffer, which includes a conditional on whether the hex is even or odd - -const encodeDataExamples = { - // dynamic types supported by EIP-712: - bytes: [ - // 10, - // '10', - // '0x10', // even - '0x101', // odd - // Buffer.from('10', 'utf8'), - '0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001', // even - '0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012', // odd - ], - // string: [ - // 'Hello!', - // '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - // '0xabcd', // even - // '0xabcde', // odd - // '😁', - // 10, - // MAX_SAFE_INTEGER_AS_HEX, - // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, - // ], - // // atomic types supported by EIP-712: - // address: [ - // '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - // '0x0', // odd - // '0x10', // even - // 10, - // 'bBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - // Number.MAX_SAFE_INTEGER, - // MAX_SAFE_INTEGER_AS_HEX, - // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, - // ], - // bool: [true, false, 'true', 'false', 0, 1, -1, Number.MAX_SAFE_INTEGER], - // bytes1: [ - // '0x10', // even - // '0x101', // odd - // 10, - // 0, - // 1, - // -1, - // Number.MAX_SAFE_INTEGER, - // Buffer.from('10', 'utf8'), - // MAX_SAFE_INTEGER_AS_HEX, - // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, - // ], - // bytes32: [ - // '0x10', // even - // '0x101', // odd - // 10, - // 0, - // 1, - // -1, - // Number.MAX_SAFE_INTEGER, - // Buffer.from('10', 'utf8'), - // MAX_SAFE_INTEGER_AS_HEX, - // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, - // ], - // int8: [0, '0', '0x0', 255, -255], - // int256: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], - // uint8: [0, '0', '0x0', 255], - // uint256: [0, '0', '0x0', Number.MAX_SAFE_INTEGER], - // // atomic types not supported by EIP-712: - // int: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], // interpreted as `int256` by `ethereumjs-abi` - // uint: [0, '0', '0x0', Number.MAX_SAFE_INTEGER], // interpreted as `uint256` by `ethereumjs-abi` - // // `fixed` and `ufixed` types omitted because their encoding in `ethereumjs-abi` is very broken at the moment. - // // `function` type omitted because it is not supported by `ethereumjs-abi`. -}; - -const encodeDataErrorExamples = { - // address: [ - // { - // input: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB0', - // errorMessage: 'Supplied uint exceeds width: 160 vs 164', - // }, - // ], - // int8: [{ input: '256', errorMessage: 'Supplied int exceeds width: 8 vs 9' }], - // uint: [{ input: -1, errorMessage: 'Supplied uint is negative' }], - // uint8: [{ input: -1, errorMessage: 'Supplied uint is negative' }], - // uint256: [{ input: -1, errorMessage: 'Supplied uint is negative' }], - // bytes1: [ - // { input: 'a', errorMessage: 'Cannot convert string to buffer' }, - // { input: 'test', errorMessage: 'Cannot convert string to buffer' }, - // ], - // bytes32: [ - // { input: 'a', errorMessage: 'Cannot convert string to buffer' }, - // { input: 'test', errorMessage: 'Cannot convert string to buffer' }, - // ], -}; - -// Union of all types from both sets of examples -const allExampleTypes = [ - ...new Set( - Object.keys(encodeDataExamples).concat( - Object.keys(encodeDataErrorExamples), - ), - ), -]; - -describe('TypedDataUtils.encodeData', function () { - // The `TypedDataUtils.encodeData` function accepts most Solidity data types, as well as custom - // data types defined by the types provided. The supported Solidity data types are divided into - // two types: atomic and dynamic. Atomic types are of a fixed size (e.g. `int8`), whereas dynamic - // types can vary in size (e.g. strings, bytes). We also test arrays of each of these types. - // - // The tests below test all boundary conditions of each Solidity type. These tests are - // automatically constructed using the example data above ("encodeDataExamples" and - // "encodeDataErrorExamples"). The behaviour for `null` and `undefined` inputs does vary between - // atomic, dynamic, and custom types though, so each of these three categories is tested - // separately with `null` and `undefined` input. Lastly, there are more tests for various other - // edge cases. - // - // The behavior differs between V3 and V4, so each test has been run for each version. We also - // have a block of tests to verify that signatures that match between V3 and V4 remain identical, - // and that signatures that differ between V3 and V4 remain different. - // - // To make reading and maintaining these tests easier, the order will be the same throughout all - // 4 of these test suites. Here is a table showing that order, as well as the compatibility of - // each input type with V3 and V4 `encodeData`. The table also shows whether the signature is - // identical between versions in the cases where the input can be encoded in both versions. - // - // | Input type | V3 | V4 | Matching Signatures | - // | ---------------------------------------------------- | -- | -- | ------------------- | - // | Auto-generated tests from the example data | Y | Y | Y | - // | Arrays using the example data | N | Y | | - // | Custom type | Y | Y | Y | - // | Recursive custom type | Y | Y | N | - // | Custom type array | N | Y | | - // | Custom type with extra properties | Y | Y | Y | - // | Atomic type with `null` input | N | N | | - // | Atomic type with `undefined` input | Y | N | | - // | Dynamic type with `null` input | Y | Y | Y | - // | Dynamic type with `undefined` input | Y | N | | - // | Custom type with `null` input | N | Y | | - // | Custom type with `undefined` input | Y | Y | N | - // | Functions | N | N | | - // | 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 () { - 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( - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = TypedDataUtils.encodeData( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - 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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - 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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should encode data when called unbound', function () { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - const primaryType = 'Message'; - const { hashStruct } = TypedDataUtils; - - expect( - hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - }); - - describe('V4', function () { - describe('example data', function () { - 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( - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = TypedDataUtils.encodeData( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - 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(() => - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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( - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should encode data when called unbound', function () { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - const primaryType = 'Message'; - const { encodeData } = TypedDataUtils; - - expect( - encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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 () { - 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 = TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const originalV4Signature = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const v3signatureWithExtraProperties = TypedDataUtils.encodeData( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4signatureWithExtraProperties = TypedDataUtils.encodeData( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.encodeData( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - - expect(v3Signature).not.toBe(v4Signature); - }); - }); - - it('should throw if passed an invalid version', () => { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - expect(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - 'V0' as any, - ).toString('hex'), - ).toThrow('Invalid version'); - }); - - it('should throw if passed a version that is not allowed', () => { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - expect(() => - TypedDataUtils.encodeData( - 'Message', - message, - types, - SignTypedDataVersion.V1 as any, - ).toString('hex'), - ).toThrow('SignTypedDataVersion not allowed'); - }); -}); - -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 () { - 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 hash "${input}" (type "${inputType}")`, function () { - const types = { - Message: [{ name: 'data', type }], - }; - const message = { data: input }; - - expect( - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.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 hash "${input}" (type "${inputType}")`, function () { - const types = { - Message: [{ name: 'data', type }], - }; - const message = { data: input }; - - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow(errorMessage); - }); - } - - it(`should fail to hash array of all ${type} example data`, function () { - const types = { - Message: [{ name: 'data', type: `${type}[]` }], - }; - const message = { data: inputs }; - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow( - 'Arrays are unimplemented in encodeData; use V4 extension', - ); - }); - }); - } - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - 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(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = TypedDataUtils.hashStruct( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should throw an error when trying to hash a function', function () { - const types = { - Message: [{ name: 'data', type: 'function' }], - }; - const message = { data: 'test' }; - - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow('Unsupported or invalid type: function'); - }); - - it('should throw an error when trying to hash with a missing primary type definition', function () { - const types = {}; - const message = { data: 'test' }; - - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow('No type definition specified: Message'); - }); - - 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(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toThrow('Unsupported or invalid type: foo'); - }); - - 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!' }; - - expect( - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash data when called unbound', function () { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - const primaryType = 'Message'; - const { hashStruct } = TypedDataUtils; - - expect( - hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'), - ).toMatchSnapshot(); - }); - }); - - describe('V4', function () { - describe('example data', function () { - 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 hash "${input}" (type "${inputType}")`, function () { - const types = { - Message: [{ name: 'data', type }], - }; - const message = { data: input }; - - expect( - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.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 hash "${input}" (type "${inputType}")`, function () { - const types = { - Message: [{ name: 'data', type }], - }; - const message = { data: input }; - - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow(errorMessage); - }); - } - - it(`should hash array of all ${type} example data`, function () { - const types = { - Message: [{ name: 'data', type: `${type}[]` }], - }; - const message = { data: inputs }; - expect( - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toMatchSnapshot(); - }); - }); - } - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = TypedDataUtils.hashStruct( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - 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(() => - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow('missing value for field length of type int32'); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.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(() => - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow('missing value for field contents of type string'); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash 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( - TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should throw an error when trying to hash a function', function () { - const types = { - Message: [{ name: 'data', type: 'function' }], - }; - const message = { data: 'test' }; - - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow('Unsupported or invalid type: function'); - }); - - it('should throw an error when trying to hash with a missing primary type definition', function () { - const types = {}; - const message = { data: 'test' }; - - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow('No type definition specified: Message'); - }); - - 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(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toThrow('Unsupported or invalid type: foo'); - }); - - 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!' }; - - expect( - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'), - ).toMatchSnapshot(); - }); - - it('should hash data when called unbound', function () { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - const primaryType = 'Message'; - const { hashStruct } = TypedDataUtils; - - expect( - hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.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 () { - 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 hash "${input}" (type "${inputType}")`, function () { - const types = { - Message: [{ name: 'data', type }], - }; - const message = { data: input }; - - const v3Signature = TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - - expect(v3Signature).toBe(v4Signature); - }); - } - }); - } - }); - - it('should hash 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 = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.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 = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const originalV4Signature = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const v3signatureWithExtraProperties = TypedDataUtils.hashStruct( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4signatureWithExtraProperties = TypedDataUtils.hashStruct( - primaryType, - messageWithExtraProperties, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - - expect(originalV3Signature).toBe(originalV4Signature); - expect(v3signatureWithExtraProperties).toBe( - v4signatureWithExtraProperties, - ); - }); - - it('should hash 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 = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - - expect(v3Signature).toBe(v4Signature); - }); - - 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 = TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.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 hash 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 = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.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 hash 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 = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V3, - ).toString('hex'); - const v4Signature = TypedDataUtils.hashStruct( - primaryType, - message, - types, - SignTypedDataVersion.V4, - ).toString('hex'); - - expect(v3Signature).not.toBe(v4Signature); - }); - }); - - it('should throw if passed an invalid version', () => { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - 'V0' as any, - ).toString('hex'), - ).toThrow('Invalid version'); - }); - - it('should throw if passed a version that is not allowed', () => { - const types = { - Message: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - expect(() => - TypedDataUtils.hashStruct( - 'Message', - message, - types, - SignTypedDataVersion.V1 as any, - ).toString('hex'), - ).toThrow('SignTypedDataVersion not allowed'); - }); -}); - - -// Comments starting with "V1:" highlight differences relative to V3 and 4. -const signTypedDataV1Examples = { - // dynamic types supported by EIP-712: - bytes: [10, '10', '0x10', Buffer.from('10', 'utf8')], - string: [ - 'Hello!', - '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - '0xabcd', - '😁', - ], - // atomic types supported by EIP-712: - address: [ - '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - // V1: No apparent maximum address length - '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbBbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - '0x0', - 10, - Number.MAX_SAFE_INTEGER, - ], - bool: [true, false, 'true', 'false', 0, 1, -1, Number.MAX_SAFE_INTEGER], - bytes1: [ - '0x10', - 10, - 0, - 1, - -1, - Number.MAX_SAFE_INTEGER, - Buffer.from('10', 'utf8'), - ], - bytes32: [ - '0x10', - 10, - 0, - 1, - -1, - Number.MAX_SAFE_INTEGER, - Buffer.from('10', 'utf8'), - ], - int8: [0, '0', '0x0', 255, -255], - int256: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], - uint8: [0, '0', '0x0', 255, -255], - uint256: [ - 0, - '0', - '0x0', - Number.MAX_SAFE_INTEGER, - // V1: Negative unsigned integers - Number.MIN_SAFE_INTEGER, - ], - // atomic types not supported by EIP-712: - int: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], // interpreted as `int256` by `ethereumjs-abi` - uint: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], // interpreted as `uint256` by `ethereumjs-abi` - // `fixed` and `ufixed` types omitted because their encoding in `ethereumjs-abi` is very broken at the moment. - // `function` type omitted because it is not supported by `ethereumjs-abi`. -}; - -const signTypedDataV1ErrorExamples = { - string: [ - { - // V1: Does not accept numbers as strings (arguably correctly). - input: 10, - errorMessage: - 'The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received type number (10)', - }, - ], - address: [ - { - // V1: Unprefixed addresses are not accepted. - input: 'bBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', - errorMessage: - 'Cannot convert string to buffer. toBuffer only supports 0x-prefixed hex strings and this string was given:', - }, - ], - int8: [{ input: '256', errorMessage: 'Supplied int exceeds width: 8 vs 9' }], - bytes1: [ - { input: 'a', errorMessage: 'Cannot convert string to buffer' }, - { input: 'test', errorMessage: 'Cannot convert string to buffer' }, - ], - bytes32: [ - { input: 'a', errorMessage: 'Cannot convert string to buffer' }, - { input: 'test', errorMessage: 'Cannot convert string to buffer' }, - ], -}; - -// // Union of all types from both sets of examples -const allSignTypedDataV1ExampleTypes = [ - ...new Set( - Object.keys(encodeDataExamples).concat( - Object.keys(encodeDataErrorExamples), - ), - ), -]; - -describe('signTypedData', function () { - describe('V1', function () { - it('should throw when given an empty array', function () { - expect(() => - signTypedData({ - privateKey, - data: [], - version: SignTypedDataVersion.V1, - }), - ).toThrow('Expect argument to be non-empty array'); - }); - - describe('example data', function () { - for (const type of allSignTypedDataV1ExampleTypes) { - describe(`type "${type}"`, function () { - // Test all examples that do not crash - const inputs = signTypedDataV1Examples[type] || []; - for (const input of inputs) { - const inputType = input instanceof Buffer ? 'Buffer' : typeof input; - it(`should sign "${input}" (type "${inputType}")`, function () { - expect( - signTypedData({ - privateKey, - data: [{ name: 'data', type, value: input }], - version: SignTypedDataVersion.V1, - }), - ).toMatchSnapshot(); - }); - } - - // Test all examples that crash - const errorInputs = signTypedDataV1ErrorExamples[type] || []; - for (const { input, errorMessage } of errorInputs) { - const inputType = input instanceof Buffer ? 'Buffer' : typeof input; - it(`should fail to sign "${input}" (type "${inputType}")`, function () { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type, value: input }], - version: SignTypedDataVersion.V1, - }), - ).toThrow(errorMessage); - }); - } - - if (type === 'bytes') { - it(`should fail to sign array of all ${type} example data`, function () { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type: `${type}[]`, value: inputs }], - version: SignTypedDataVersion.V1, - }), - ).toThrow( - 'The "list[0]" argument must be an instance of Buffer or Uint8Array. Received type number (10)', - ); - }); - } else { - it(`should sign array of all ${type} example data`, function () { - expect( - signTypedData({ - privateKey, - data: [{ name: 'data', type: `${type}[]`, value: inputs }], - version: SignTypedDataVersion.V1, - }), - ).toMatchSnapshot(); - }); - } - }); - } - }); - - it('should throw an error when an atomic property is set to null', function () { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type: 'int32', value: null }], - version: SignTypedDataVersion.V1, - }), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - it('should sign data with an atomic property set to undefined', function () { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type: 'int32', value: undefined }], - version: SignTypedDataVersion.V1, - }), - ).toMatchSnapshot(); - }); - - it('should sign data with a dynamic property set to null', function () { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type: 'string', value: null }], - version: SignTypedDataVersion.V1, - }), - ).toThrow( - 'The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received null', - ); - }); - - it('should sign data with a dynamic property set to undefined', function () { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type: 'string', value: undefined }], - version: SignTypedDataVersion.V1, - }), - ).toMatchSnapshot(); - }); - - it('should throw an error when trying to sign a function', function () { - expect(() => - signTypedData({ - privateKey, - data: [ - { - name: 'data', - type: 'function', - value: () => console.log(test), - }, - ], - version: SignTypedDataVersion.V1, - }), - ).toThrow('Unsupported or invalid type: function'); - }); - - it('should throw an error when trying to sign an unrecognized type', function () { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type: 'foo', value: 'test' }], - version: SignTypedDataVersion.V1, - }), - ).toThrow('Unsupported or invalid type: foo'); - }); - }); - - describe('V3', function () { - // This first group of tests mirrors the `TypedDataUtils.eip712Hash` tests, because all of - // those test cases are relevant here as well. - - it('should sign a minimal valid typed message', function () { - const signature = signTypedData({ - privateKey, - // This represents the most basic "typed message" that is valid according to our types. - // It's not a very useful message (it's totally empty), but it's complete according to the - // spec. - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - }, - version: SignTypedDataVersion.V3, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('minimal typed message signature should be identical to minimal valid typed message signature', function () { - const minimalSignature = signTypedData({ - privateKey, - // This tests that when the mandatory fields `domain`, `message`, and `types.EIP712Domain` - // are omitted, the result is the same as if they were included but empty. - data: { - types: {}, - primaryType: 'EIP712Domain', - } as any, - version: SignTypedDataVersion.V3, - }); - const minimalValidSignature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - }, - version: SignTypedDataVersion.V3, - }); - - expect(minimalSignature).toBe(minimalValidSignature); - }); - - it('should ignore extra data properties', function () { - const minimalValidSignature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - }, - version: SignTypedDataVersion.V3, - }); - const extraPropertiesSignature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - extra: 'stuff', - moreExtra: 1, - } as any, - version: SignTypedDataVersion.V3, - }); - - expect(minimalValidSignature).toBe(extraPropertiesSignature); - }); - - it('should sign a typed message with a domain separator that uses all fields', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'verifyingContract', - type: 'address', - }, - { - name: 'salt', - type: 'bytes32', - }, - ], - }, - primaryType: 'EIP712Domain', - domain: { - name: 'example.metamask.io', - version: '1', - chainId: 1, - verifyingContract: '0x0000000000000000000000000000000000000000', - salt: Buffer.from(new Int32Array([1, 2, 3])), - }, - message: {}, - }, - version: SignTypedDataVersion.V3, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('should sign a typed message with extra domain seperator fields', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'verifyingContract', - type: 'address', - }, - { - name: 'salt', - type: 'bytes32', - }, - { - name: 'extraField', - type: 'string', - }, - ], - }, - primaryType: 'EIP712Domain', - domain: { - name: 'example.metamask.io', - version: '1', - chainId: 1, - verifyingContract: '0x0000000000000000000000000000000000000000', - salt: Buffer.from(new Int32Array([1, 2, 3])), - extraField: 'stuff', - }, - message: {}, - } as any, - version: SignTypedDataVersion.V3, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('should sign a typed message with only custom domain seperator fields', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'customName', - type: 'string', - }, - { - name: 'customVersion', - type: 'string', - }, - { - name: 'customChainId', - type: 'uint256', - }, - { - name: 'customVerifyingContract', - type: 'address', - }, - { - name: 'customSalt', - type: 'bytes32', - }, - { - name: 'extraField', - type: 'string', - }, - ], - }, - primaryType: 'EIP712Domain', - domain: { - customName: 'example.metamask.io', - customVersion: '1', - customChainId: 1, - customVerifyingContract: - '0x0000000000000000000000000000000000000000', - customSalt: Buffer.from(new Int32Array([1, 2, 3])), - extraField: 'stuff', - }, - message: {}, - } as any, - version: SignTypedDataVersion.V3, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('should sign a typed message with data', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'verifyingContract', - type: 'address', - }, - { - name: 'salt', - type: 'bytes32', - }, - ], - Message: [{ name: 'data', type: 'string' }], - }, - primaryType: 'Message', - domain: { - name: 'example.metamask.io', - version: '1', - chainId: 1, - verifyingContract: '0x0000000000000000000000000000000000000000', - salt: Buffer.from(new Int32Array([1, 2, 3])), - }, - message: { - data: 'Hello!', - }, - }, - version: SignTypedDataVersion.V3, - }); - - expect(signature).toMatchSnapshot(); - }); - - // This second group of tests mirrors the `TypedDataUtils.encodeData` tests, because all of - // those test cases are relevant here as well. - - describe('example data', function () { - 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 sign "${input}" (type "${inputType}")`, function () { - expect( - signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - Message: [{ name: 'data', type }], - }, - primaryType: 'Message', - domain: {}, - message: { - data: input, - }, - }, - version: SignTypedDataVersion.V3, - }), - ).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 sign "${input}" (type "${inputType}")`, function () { - expect(() => - signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - Message: [{ name: 'data', type }], - }, - primaryType: 'Message', - domain: {}, - message: { - data: input, - }, - }, - version: SignTypedDataVersion.V3, - }), - ).toThrow(errorMessage); - }); - } - - it(`should fail to sign array of all ${type} example data`, function () { - expect(() => - signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - Message: [{ name: 'data', type: `${type}[]` }], - }, - primaryType: 'Message', - domain: {}, - message: { - data: inputs, - }, - }, - version: SignTypedDataVersion.V3, - }), - ).toThrow( - 'Arrays are unimplemented in encodeData; use V4 extension', - ); - }); - }); - } - }); - - it('should sign data with custom type', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toMatchSnapshot(); - }); - - it('should sign data with a recursive data type', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toMatchSnapshot(); - }); - - it('should throw an error when trying to sign a custom type array', function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: 'string[]' }], - }; - const message = { data: ['1', '2', '3'] }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toThrow('Arrays are unimplemented in encodeData; use V4 extension'); - }); - - it('should ignore extra unspecified message properties', function () { - const types = { - EIP712Domain: [], - 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 = signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message: messageWithExtraProperties, - }, - version: SignTypedDataVersion.V3, - }); - - expect(originalSignature).toBe(signatureWithExtraProperties); - }); - - it('should throw an error when an atomic property is set to null', function () { - const types = { - EIP712Domain: [], - 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(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - it('should sign data with an atomic property set to undefined', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toMatchSnapshot(); - }); - - it('should sign data with a dynamic property set to null', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toMatchSnapshot(); - }); - - it('should sign data with a dynamic property set to undefined', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toMatchSnapshot(); - }); - - it('should throw an error when a custom type property is set to null', function () { - const types = { - EIP712Domain: [], - 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(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - it('should sign data with a custom type property set to undefined', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toMatchSnapshot(); - }); - - it('should throw an error when trying to sign a function', function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: 'function' }], - }; - const message = { data: 'test' }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toThrow('Unsupported or invalid type: function'); - }); - - it('should throw an error when trying to sign with a missing primary type definition', function () { - const types = { - EIP712Domain: [], - }; - const message = { data: 'test' }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - } as any, - version: SignTypedDataVersion.V3, - }), - ).toThrow('No type definition specified: Message'); - }); - - it('should throw an error when trying to sign an unrecognized type', function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: 'foo' }], - }; - const message = { data: 'test' }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toThrow('Unsupported or invalid type: foo'); - }); - - it('should sign data when given extraneous types', function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: 'string' }], - Extra: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - const primaryType = 'Message'; - - expect( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V3, - }), - ).toMatchSnapshot(); - }); - }); - - describe('V4', function () { - // This first group of tests mirrors the `TypedDataUtils.eip712Hash` tests, because all of - // those test cases are relevant here as well. - - it('should sign a minimal valid typed message', function () { - const signature = signTypedData({ - privateKey, - // This represents the most basic "typed message" that is valid according to our types. - // It's not a very useful message (it's totally empty), but it's complete according to the - // spec. - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - }, - version: SignTypedDataVersion.V4, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('minimal typed message signature should be identical to minimal valid typed message signature', function () { - const minimalSignature = signTypedData({ - privateKey, - // This tests that when the mandatory fields `domain`, `message`, and `types.EIP712Domain` - // are omitted, the result is the same as if they were included but empty. - data: { - types: {}, - primaryType: 'EIP712Domain', - } as any, - version: SignTypedDataVersion.V4, - }); - const minimalValidSignature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - }, - version: SignTypedDataVersion.V4, - }); - - expect(minimalSignature).toBe(minimalValidSignature); - }); - - it('should ignore extra data properties', function () { - const minimalValidSignature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - }, - version: SignTypedDataVersion.V4, - }); - const extraPropertiesSignature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [], - }, - primaryType: 'EIP712Domain', - domain: {}, - message: {}, - extra: 'stuff', - moreExtra: 1, - } as any, - version: SignTypedDataVersion.V4, - }); - - expect(minimalValidSignature).toBe(extraPropertiesSignature); - }); - - it('should sign a typed message with a domain separator that uses all fields', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'verifyingContract', - type: 'address', - }, - { - name: 'salt', - type: 'bytes32', - }, - ], - }, - primaryType: 'EIP712Domain', - domain: { - name: 'example.metamask.io', - version: '1', - chainId: 1, - verifyingContract: '0x0000000000000000000000000000000000000000', - salt: Buffer.from(new Int32Array([1, 2, 3])), - }, - message: {}, - }, - version: SignTypedDataVersion.V4, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('should sign a typed message with extra domain seperator fields', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'verifyingContract', - type: 'address', - }, - { - name: 'salt', - type: 'bytes32', - }, - { - name: 'extraField', - type: 'string', - }, - ], - }, - primaryType: 'EIP712Domain', - domain: { - name: 'example.metamask.io', - version: '1', - chainId: 1, - verifyingContract: '0x0000000000000000000000000000000000000000', - salt: Buffer.from(new Int32Array([1, 2, 3])), - extraField: 'stuff', - }, - message: {}, - } as any, - version: SignTypedDataVersion.V4, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('should sign a typed message with only custom domain seperator fields', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'customName', - type: 'string', - }, - { - name: 'customVersion', - type: 'string', - }, - { - name: 'customChainId', - type: 'uint256', - }, - { - name: 'customVerifyingContract', - type: 'address', - }, - { - name: 'customSalt', - type: 'bytes32', - }, - { - name: 'extraField', - type: 'string', - }, - ], - }, - primaryType: 'EIP712Domain', - domain: { - customName: 'example.metamask.io', - customVersion: '1', - customChainId: 1, - customVerifyingContract: - '0x0000000000000000000000000000000000000000', - customSalt: Buffer.from(new Int32Array([1, 2, 3])), - extraField: 'stuff', - }, - message: {}, - } as any, - version: SignTypedDataVersion.V4, - }); - - expect(signature).toMatchSnapshot(); - }); - - it('should sign a typed message with data', function () { - const signature = signTypedData({ - privateKey, - data: { - types: { - EIP712Domain: [ - { - name: 'name', - type: 'string', - }, - { - name: 'version', - type: 'string', - }, - { - name: 'chainId', - type: 'uint256', - }, - { - name: 'verifyingContract', - type: 'address', - }, - { - name: 'salt', - type: 'bytes32', - }, - ], - Message: [{ name: 'data', type: 'string' }], - }, - primaryType: 'Message', - domain: { - name: 'example.metamask.io', - version: '1', - chainId: 1, - verifyingContract: '0x0000000000000000000000000000000000000000', - salt: Buffer.from(new Int32Array([1, 2, 3])), - }, - message: { - data: 'Hello!', - }, - }, - version: SignTypedDataVersion.V4, - }); - - expect(signature).toMatchSnapshot(); - }); - - // This second group of tests mirrors the `TypedDataUtils.encodeData` tests, because all of - // those test cases are relevant here as well. - describe('example data', function () { - 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 sign "${input}" (type "${inputType}")`, function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type }], - }; - const message = { data: input }; - const primaryType = 'Message'; - - expect( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).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 sign "${input}" (type "${inputType}")`, function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type }], - }; - const message = { data: input }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toThrow(errorMessage); - }); - } - - it(`should sign array of all ${type} example data`, function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: `${type}[]` }], - }; - const message = { data: inputs }; - const primaryType = 'Message'; - expect( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - }); - } - }); - - it('should sign data with custom type', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - - it('should sign data with a recursive data type', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - - it('should sign data with a custom data type array', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - - it('should ignore extra unspecified message properties', function () { - const types = { - EIP712Domain: [], - 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 = signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }); - const messageWithExtraProperties = { ...message, foo: 'bar' }; - const signatureWithExtraProperties = signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message: messageWithExtraProperties, - }, - version: SignTypedDataVersion.V4, - }); - - expect(originalSignature).toBe(signatureWithExtraProperties); - }); - - it('should throw an error when an atomic property is set to null', function () { - const types = { - EIP712Domain: [], - 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(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toThrow(/^Cannot read prop.+ null/u); - }); - - it('should throw an error when an atomic property is set to undefined', function () { - const types = { - EIP712Domain: [], - 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(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toThrow('missing value for field length of type int32'); - }); - - it('should sign data with a dynamic property set to null', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - - it('should throw an error when a dynamic property is set to undefined', function () { - const types = { - EIP712Domain: [], - 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(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toThrow('missing value for field contents of type string'); - }); - - it('should sign data with a custom type property set to null', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - - it('should sign data with a custom type property set to undefined', function () { - const types = { - EIP712Domain: [], - 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( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - - it('should throw an error when trying to encode a function', function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: 'function' }], - }; - const message = { data: 'test' }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toThrow('Unsupported or invalid type: function'); - }); - - it('should throw an error when trying to sign with a missing primary type definition', function () { - const types = { - EIP712Domain: [], - }; - const message = { data: 'test' }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - } as any, - version: SignTypedDataVersion.V4, - }), - ).toThrow('No type definition specified: Message'); - }); - - it('should throw an error when trying to sign an unrecognized type', function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: 'foo' }], - }; - const message = { data: 'test' }; - const primaryType = 'Message'; - - expect(() => - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toThrow('Unsupported or invalid type: foo'); - }); - - it('should sign data when given extraneous types', function () { - const types = { - EIP712Domain: [], - Message: [{ name: 'data', type: 'string' }], - Extra: [{ name: 'data', type: 'string' }], - }; - const message = { data: 'Hello!' }; - const primaryType = 'Message'; - - expect( - signTypedData({ - privateKey, - data: { - types, - primaryType, - domain: {}, - message, - }, - version: SignTypedDataVersion.V4, - }), - ).toMatchSnapshot(); - }); - }); - - describe('validation', () => { - it('should throw if passed an invalid version', () => { - expect(() => - signTypedData({ - privateKey, - data: [{ name: 'data', type: 'string', value: 'Hello!' }], - version: 'V0' as any, - }), - ).toThrow('Invalid version'); - }); - - it('should throw if passed null data', () => { - expect(() => - signTypedData({ - privateKey, - data: null, - version: SignTypedDataVersion.V1, - }), - ).toThrow('Missing data parameter'); - }); - - it('should throw if passed undefined data', () => { - expect(() => - signTypedData({ - privateKey, - data: undefined, - version: SignTypedDataVersion.V1, - }), - ).toThrow('Missing data parameter'); - }); - - it('should throw if passed a null private key', () => { - expect(() => - signTypedData({ - privateKey: null, - data: [{ name: 'data', type: 'string', value: 'Hello!' }], - version: SignTypedDataVersion.V1, - }), - ).toThrow('Missing private key parameter'); - }); - - it('should throw if passed an undefined private key', () => { - expect(() => - signTypedData({ - privateKey: undefined, - data: [{ name: 'data', type: 'string', value: 'Hello!' }], - version: SignTypedDataVersion.V1, - }), - ).toThrow('Missing private key parameter'); - }); - }); -}); diff --git a/src/sign-typed-data-narrowed.test.ts b/src/sign-typed-data-narrowed.test.ts new file mode 100644 index 00000000..5c432735 --- /dev/null +++ b/src/sign-typed-data-narrowed.test.ts @@ -0,0 +1,833 @@ +// Allow using snapshots in this file. +/* +eslint jest/no-restricted-matchers: [ + 'error', + { + resolves: 'Use `expect(await promise)` instead.', + toBeFalsy: 'Avoid `toBeFalsy`', + toBeTruthy: 'Avoid `toBeTruthy`', + } +] +*/ + +import Ajv from 'ajv'; +import { + recoverTypedSignature, + signTypedData, + TypedDataUtils, + typedSignatureHash, + SignTypedDataVersion, + TYPED_MESSAGE_SCHEMA, +} from './sign-typed-data'; + +const privateKey = Buffer.from( + '4af1bceebf7f3634ec3cff8a2c38e51178d5d4ce585c52d6043e5e2cc3418bb0', + 'hex', +); + +/** + * Get a list of all Solidity types supported by EIP-712. + * + * @returns A list of all supported Solidity types. + */ +function getEip712SolidityTypes() { + const types = ['bool', 'address', 'string', 'bytes']; + const ints = Array.from(new Array(32)).map( + (_, index) => `int${(index + 1) * 8}`, + ); + const uints = Array.from(new Array(32)).map( + (_, index) => `uint${(index + 1) * 8}`, + ); + const bytes = Array.from(new Array(32)).map( + (_, index) => `bytes${index + 1}`, + ); + + return [...types, ...ints, ...uints, ...bytes]; +} + +const eip712SolidityTypes = getEip712SolidityTypes(); + +// const MAX_SAFE_INTEGER_AS_HEX = `0x${Number.MAX_SAFE_INTEGER.toString(16)}`; +// const MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX = `0x${( +// Number.MAX_SAFE_INTEGER + 1 +// ).toString(16)}`; + +// we test both even and odd length hex values because Node's Buffer.from() method does not buffer hex numbers correctly +// so we made a helper function numberToBuffer, which includes a conditional on whether the hex is even or odd + +const encodeDataExamples = { + // dynamic types supported by EIP-712: + bytes: [ + // 10, + // '10', + // '0x10', // even + '0x101', // odd + // Buffer.from('10', 'utf8'), + '0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001', // even + '0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012', // odd + ], + // string: [ + // 'Hello!', + // '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + // '0xabcd', // even + // '0xabcde', // odd + // '😁', + // 10, + // MAX_SAFE_INTEGER_AS_HEX, + // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, + // ], + // // atomic types supported by EIP-712: + // address: [ + // '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + // '0x0', // odd + // '0x10', // even + // 10, + // 'bBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + // Number.MAX_SAFE_INTEGER, + // MAX_SAFE_INTEGER_AS_HEX, + // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, + // ], + // bool: [true, false, 'true', 'false', 0, 1, -1, Number.MAX_SAFE_INTEGER], + // bytes1: [ + // '0x10', // even + // '0x101', // odd + // 10, + // 0, + // 1, + // -1, + // Number.MAX_SAFE_INTEGER, + // Buffer.from('10', 'utf8'), + // MAX_SAFE_INTEGER_AS_HEX, + // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, + // ], + // bytes32: [ + // '0x10', // even + // '0x101', // odd + // 10, + // 0, + // 1, + // -1, + // Number.MAX_SAFE_INTEGER, + // Buffer.from('10', 'utf8'), + // MAX_SAFE_INTEGER_AS_HEX, + // MAX_SAFE_INTEGER_PLUS_ONE_AS_HEX, + // ], + // int8: [0, '0', '0x0', 255, -255], + // int256: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], + // uint8: [0, '0', '0x0', 255], + // uint256: [0, '0', '0x0', Number.MAX_SAFE_INTEGER], + // // atomic types not supported by EIP-712: + // int: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], // interpreted as `int256` by `ethereumjs-abi` + // uint: [0, '0', '0x0', Number.MAX_SAFE_INTEGER], // interpreted as `uint256` by `ethereumjs-abi` + // // `fixed` and `ufixed` types omitted because their encoding in `ethereumjs-abi` is very broken at the moment. + // // `function` type omitted because it is not supported by `ethereumjs-abi`. +}; + +const encodeDataErrorExamples = { + // address: [ + // { + // input: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB0', + // errorMessage: 'Supplied uint exceeds width: 160 vs 164', + // }, + // ], + // int8: [{ input: '256', errorMessage: 'Supplied int exceeds width: 8 vs 9' }], + // uint: [{ input: -1, errorMessage: 'Supplied uint is negative' }], + // uint8: [{ input: -1, errorMessage: 'Supplied uint is negative' }], + // uint256: [{ input: -1, errorMessage: 'Supplied uint is negative' }], + // bytes1: [ + // { input: 'a', errorMessage: 'Cannot convert string to buffer' }, + // { input: 'test', errorMessage: 'Cannot convert string to buffer' }, + // ], + // bytes32: [ + // { input: 'a', errorMessage: 'Cannot convert string to buffer' }, + // { input: 'test', errorMessage: 'Cannot convert string to buffer' }, + // ], +}; + +// Union of all types from both sets of examples +const allExampleTypes = [ + ...new Set( + Object.keys(encodeDataExamples).concat( + Object.keys(encodeDataErrorExamples), + ), + ), +]; + +describe('TypedDataUtils.encodeData', function () { + // The `TypedDataUtils.encodeData` function accepts most Solidity data types, as well as custom + // data types defined by the types provided. The supported Solidity data types are divided into + // two types: atomic and dynamic. Atomic types are of a fixed size (e.g. `int8`), whereas dynamic + // types can vary in size (e.g. strings, bytes). We also test arrays of each of these types. + // + // The tests below test all boundary conditions of each Solidity type. These tests are + // automatically constructed using the example data above ("encodeDataExamples" and + // "encodeDataErrorExamples"). The behaviour for `null` and `undefined` inputs does vary between + // atomic, dynamic, and custom types though, so each of these three categories is tested + // separately with `null` and `undefined` input. Lastly, there are more tests for various other + // edge cases. + // + // The behavior differs between V3 and V4, so each test has been run for each version. We also + // have a block of tests to verify that signatures that match between V3 and V4 remain identical, + // and that signatures that differ between V3 and V4 remain different. + // + // To make reading and maintaining these tests easier, the order will be the same throughout all + // 4 of these test suites. Here is a table showing that order, as well as the compatibility of + // each input type with V3 and V4 `encodeData`. The table also shows whether the signature is + // identical between versions in the cases where the input can be encoded in both versions. + // + // | Input type | V3 | V4 | Matching Signatures | + // | ---------------------------------------------------- | -- | -- | ------------------- | + // | Auto-generated tests from the example data | Y | Y | Y | + // | Arrays using the example data | N | Y | | + // | Custom type | Y | Y | Y | + // | Recursive custom type | Y | Y | N | + // | Custom type array | N | Y | | + // | Custom type with extra properties | Y | Y | Y | + // | Atomic type with `null` input | N | N | | + // | Atomic type with `undefined` input | Y | N | | + // | Dynamic type with `null` input | Y | Y | Y | + // | Dynamic type with `undefined` input | Y | N | | + // | Custom type with `null` input | N | Y | | + // | Custom type with `undefined` input | Y | Y | N | + // | Functions | N | N | | + // | 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 () { + 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( + TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.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(() => + TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.V3, + ).toString('hex'), + ).toThrow(errorMessage); + }); + } + }); + } + }); + + describe('V4', function () { + describe('example data', function () { + 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( + TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.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(() => + TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.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( + TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.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 () { + 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 = TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.V3, + ).toString('hex'); + const v4Signature = TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.V4, + ).toString('hex'); + + expect(v3Signature).toBe(v4Signature); + }); + } + }); + } + }); + }); + + it('should throw if passed an invalid version', () => { + const types = { + Message: [{ name: 'data', type: 'string' }], + }; + const message = { data: 'Hello!' }; + expect(() => + TypedDataUtils.encodeData( + 'Message', + message, + types, + 'V0' as any, + ).toString('hex'), + ).toThrow('Invalid version'); + }); + + it('should throw if passed a version that is not allowed', () => { + const types = { + Message: [{ name: 'data', type: 'string' }], + }; + const message = { data: 'Hello!' }; + expect(() => + TypedDataUtils.encodeData( + 'Message', + message, + types, + SignTypedDataVersion.V1 as any, + ).toString('hex'), + ).toThrow('SignTypedDataVersion not allowed'); + }); + }); + + 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 () { + 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 hash "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + expect( + TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.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 hash "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + expect(() => + TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.V3, + ).toString('hex'), + ).toThrow(errorMessage); + }); + } + + it(`should fail to hash array of all ${type} example data`, function () { + const types = { + Message: [{ name: 'data', type: `${type}[]` }], + }; + const message = { data: inputs }; + expect(() => + TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.V3, + ).toString('hex'), + ).toThrow( + 'Arrays are unimplemented in encodeData; use V4 extension', + ); + }); + }); + } + }); + }); + + describe('V4', function () { + describe('example data', function () { + 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 hash "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + expect( + TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.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 hash "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + expect(() => + TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.V4, + ).toString('hex'), + ).toThrow(errorMessage); + }); + } + + it(`should hash array of all ${type} example data`, function () { + const types = { + Message: [{ name: 'data', type: `${type}[]` }], + }; + const message = { data: inputs }; + expect( + TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.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 () { + 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 hash "${input}" (type "${inputType}")`, function () { + const types = { + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + + const v3Signature = TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.V3, + ).toString('hex'); + const v4Signature = TypedDataUtils.hashStruct( + 'Message', + message, + types, + SignTypedDataVersion.V4, + ).toString('hex'); + + expect(v3Signature).toBe(v4Signature); + }); + } + }); + } + }); + }); + }); + // Comments starting with "V1:" highlight differences relative to V3 and 4. + const signTypedDataV1Examples = { + // dynamic types supported by EIP-712: + bytes: [10, '10', '0x10', Buffer.from('10', 'utf8')], + string: [ + 'Hello!', + '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + '0xabcd', + '😁', + ], + // atomic types supported by EIP-712: + address: [ + '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + // V1: No apparent maximum address length + '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbBbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + '0x0', + 10, + Number.MAX_SAFE_INTEGER, + ], + bool: [true, false, 'true', 'false', 0, 1, -1, Number.MAX_SAFE_INTEGER], + bytes1: [ + '0x10', + 10, + 0, + 1, + -1, + Number.MAX_SAFE_INTEGER, + Buffer.from('10', 'utf8'), + ], + bytes32: [ + '0x10', + 10, + 0, + 1, + -1, + Number.MAX_SAFE_INTEGER, + Buffer.from('10', 'utf8'), + ], + int8: [0, '0', '0x0', 255, -255], + int256: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], + uint8: [0, '0', '0x0', 255, -255], + uint256: [ + 0, + '0', + '0x0', + Number.MAX_SAFE_INTEGER, + // V1: Negative unsigned integers + Number.MIN_SAFE_INTEGER, + ], + // atomic types not supported by EIP-712: + int: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], // interpreted as `int256` by `ethereumjs-abi` + uint: [0, '0', '0x0', Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER], // interpreted as `uint256` by `ethereumjs-abi` + // `fixed` and `ufixed` types omitted because their encoding in `ethereumjs-abi` is very broken at the moment. + // `function` type omitted because it is not supported by `ethereumjs-abi`. + }; + + const signTypedDataV1ErrorExamples = { + string: [ + { + // V1: Does not accept numbers as strings (arguably correctly). + input: 10, + errorMessage: + 'The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received type number (10)', + }, + ], + address: [ + { + // V1: Unprefixed addresses are not accepted. + input: 'bBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', + errorMessage: + 'Cannot convert string to buffer. toBuffer only supports 0x-prefixed hex strings and this string was given:', + }, + ], + int8: [ + { input: '256', errorMessage: 'Supplied int exceeds width: 8 vs 9' }, + ], + bytes1: [ + { input: 'a', errorMessage: 'Cannot convert string to buffer' }, + { input: 'test', errorMessage: 'Cannot convert string to buffer' }, + ], + bytes32: [ + { input: 'a', errorMessage: 'Cannot convert string to buffer' }, + { input: 'test', errorMessage: 'Cannot convert string to buffer' }, + ], + }; + + // // Union of all types from both sets of examples + const allSignTypedDataV1ExampleTypes = [ + ...new Set( + Object.keys(encodeDataExamples).concat( + Object.keys(encodeDataErrorExamples), + ), + ), + ]; + + describe('signTypedData', function () { + describe('V3', function () { + // This second group of tests mirrors the `TypedDataUtils.encodeData` tests, because all of + // those test cases are relevant here as well. + + describe('example data', function () { + 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 sign "${input}" (type "${inputType}")`, function () { + expect( + signTypedData({ + privateKey, + data: { + types: { + EIP712Domain: [], + Message: [{ name: 'data', type }], + }, + primaryType: 'Message', + domain: {}, + message: { + data: input, + }, + }, + version: SignTypedDataVersion.V3, + }), + ).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 sign "${input}" (type "${inputType}")`, function () { + expect(() => + signTypedData({ + privateKey, + data: { + types: { + EIP712Domain: [], + Message: [{ name: 'data', type }], + }, + primaryType: 'Message', + domain: {}, + message: { + data: input, + }, + }, + version: SignTypedDataVersion.V3, + }), + ).toThrow(errorMessage); + }); + } + + it(`should fail to sign array of all ${type} example data`, function () { + expect(() => + signTypedData({ + privateKey, + data: { + types: { + EIP712Domain: [], + Message: [{ name: 'data', type: `${type}[]` }], + }, + primaryType: 'Message', + domain: {}, + message: { + data: inputs, + }, + }, + version: SignTypedDataVersion.V3, + }), + ).toThrow( + 'Arrays are unimplemented in encodeData; use V4 extension', + ); + }); + }); + } + }); + }); + + describe('V4', function () { + // This first group of tests mirrors the `TypedDataUtils.eip712Hash` tests, because all of + // those test cases are relevant here as well. + + // This second group of tests mirrors the `TypedDataUtils.encodeData` tests, because all of + // those test cases are relevant here as well. + describe('example data', function () { + 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 sign "${input}" (type "${inputType}")`, function () { + const types = { + EIP712Domain: [], + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + const primaryType = 'Message'; + + expect( + signTypedData({ + privateKey, + data: { + types, + primaryType, + domain: {}, + message, + }, + version: SignTypedDataVersion.V4, + }), + ).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 sign "${input}" (type "${inputType}")`, function () { + const types = { + EIP712Domain: [], + Message: [{ name: 'data', type }], + }; + const message = { data: input }; + const primaryType = 'Message'; + + expect(() => + signTypedData({ + privateKey, + data: { + types, + primaryType, + domain: {}, + message, + }, + version: SignTypedDataVersion.V4, + }), + ).toThrow(errorMessage); + }); + } + + it(`should sign array of all ${type} example data`, function () { + const types = { + EIP712Domain: [], + Message: [{ name: 'data', type: `${type}[]` }], + }; + const message = { data: inputs }; + const primaryType = 'Message'; + expect( + signTypedData({ + privateKey, + data: { + types, + primaryType, + domain: {}, + message, + }, + version: SignTypedDataVersion.V4, + }), + ).toMatchSnapshot(); + }); + }); + } + }); + }); + }); +}); diff --git a/src/sign-typed-data.test.ts b/src/sign-typed-data.test.ts index b0a930b3..bbb7921f 100644 --- a/src/sign-typed-data.test.ts +++ b/src/sign-typed-data.test.ts @@ -245,7 +245,8 @@ const encodeDataExamples = { '0x10', // even '0x101', // odd Buffer.from('10', 'utf8'), - '0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001', + '0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b70000000000000000000000000000000000000000000000000000000000000001', // even + '0xa22cb465000000000000000000000000a9079d872d10185b54c5db2c36cc978cbd3f72b700000000000000000000000000000000000000000000000000000000000000012', // odd ], string: [ 'Hello!',