From d6dbb1bdc80530a7e134df6e4643aed9720e0123 Mon Sep 17 00:00:00 2001 From: Mark Stacey Date: Mon, 9 Aug 2021 14:39:54 -0230 Subject: [PATCH] Add `TypedDataUtils.hashType` tests This function should now be comprehensively tested. These tests mirror the `TypedDataUtils.encodeType` tests. Any uses of `hashType` in the older signature tests have been removed, as they are now redundant. --- src/index.test.ts | 120 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 28 deletions(-) diff --git a/src/index.test.ts b/src/index.test.ts index e2030045..77ef1de2 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -1426,6 +1426,8 @@ describe('TypedDataUtils.encodeData', function () { }); describe('TypedDataUtils.encodeType', () => { + // Note that these tests should mirror the `TypedDataUtils.hashType` tests. The `hashType` + // function just calls `encodeType` and hashes the result. it('should encode simple type', () => { const types = { Person: [{ name: 'name', type: 'string' }], @@ -1510,6 +1512,96 @@ describe('TypedDataUtils.encodeType', () => { }); }); +describe('TypedDataUtils.hashType', () => { + // These tests mirror the `TypedDataUtils.encodeType` tests. The same inputs are expected. + it('should hash simple type', () => { + const types = { + Person: [{ name: 'name', type: 'string' }], + }; + const primaryType = 'Person'; + + expect( + sigUtil.TypedDataUtils.hashType(primaryType, types).toString('hex'), + ).toMatchInlineSnapshot( + `"fcbb73369ebb221abfdc626fdec0be9ca48ad89ef757b9a76eb7b31ddd261338"`, + ); + }); + + it('should hash complex type', () => { + 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'; + + expect( + sigUtil.TypedDataUtils.hashType(primaryType, types).toString('hex'), + ).toMatchInlineSnapshot( + `"dd57d9596af52b430ced3d5b52d4e3d5dccfdf3e0572db1dcf526baad311fbd1"`, + ); + }); + + it('should hash recursive type', () => { + 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'; + + expect( + sigUtil.TypedDataUtils.hashType(primaryType, types).toString('hex'), + ).toMatchInlineSnapshot( + `"66658e9662034bcd21df657297dab8ba47f0ae05dd8aa253cc935d9aacfd9d10"`, + ); + }); + + it('should hash unrecognized types', () => { + const types = { + Mail: [ + { name: 'from', type: 'Person' }, + { name: 'to', type: 'Person' }, + { name: 'contents', type: 'string' }, + ], + }; + const primaryType = 'Mail'; + + expect( + sigUtil.TypedDataUtils.hashType(primaryType, types).toString('hex'), + ).toMatchInlineSnapshot( + `"c0aee50a43b64ca632347f993c5a39cbddcae6ae329a7a111357622dc88dc1fb"`, + ); + }); + + it('should throw if primary type is missing', () => { + const types = { + Person: [ + { name: 'name', type: 'string' }, + { name: 'wallet', type: 'address' }, + ], + }; + const primaryType = 'Mail'; + + expect(() => + sigUtil.TypedDataUtils.hashType(primaryType, types).toString('hex'), + ).toThrow('No type definition specified: Mail'); + }); +}); + it('normalize address lower cases', function () { const initial = '0xA06599BD35921CfB5B71B4BE3869740385b0B306'; const result = sigUtil.normalize(initial); @@ -1977,9 +2069,6 @@ it('signedTypeData', function () { const address = ethUtil.privateToAddress(privateKey); const sig = sigUtil.signTypedData(privateKey, { data: typedData }, 'V3'); - expect(ethUtil.bufferToHex(utils.hashType('Mail', typedData.types))).toBe( - '0xa0cedeb2dc280ba39b857546d74f5549c3a1d7bdc2dd96bf881f76108e23dac2', - ); expect( ethUtil.bufferToHex( utils.hashStruct( @@ -2056,9 +2145,6 @@ it('signedTypeData with bytes', function () { 'V3', ); - expect( - ethUtil.bufferToHex(utils.hashType('Mail', typedDataWithBytes.types)), - ).toBe('0x43999c52db673245777eb64b0330105de064e52179581a340a9856c32372528e'); expect( ethUtil.bufferToHex( utils.hashStruct( @@ -2144,10 +2230,6 @@ it('signedTypeData_v4', function () { const utils = sigUtil.TypedDataUtils; - expect(ethUtil.bufferToHex(utils.hashType('Person', typedData.types))).toBe( - '0xfabfe1ed996349fc6027709802be19d047da1aa5d6894ff5f6486d92db2e6860', - ); - expect( ethUtil.bufferToHex( utils.hashStruct('Person', typedData.message.from, typedData.types, 'V4'), @@ -2165,9 +2247,6 @@ it('signedTypeData_v4', function () { ), ).toBe('0xefa62530c7ae3a290f8a13a5fc20450bdb3a6af19d9d9d2542b5a94e631a9168'); - expect(ethUtil.bufferToHex(utils.hashType('Mail', typedData.types))).toBe( - '0x4bd8a9a2b93427bb184aca81e24beb30ffa3c747e2a33d4225ec08bf12e2e753', - ); expect( ethUtil.bufferToHex( utils.hashStruct( @@ -2255,10 +2334,6 @@ it('signedTypeData_v4', function () { const utils = sigUtil.TypedDataUtils; - expect(ethUtil.bufferToHex(utils.hashType('Person', typedData.types))).toBe( - '0xfabfe1ed996349fc6027709802be19d047da1aa5d6894ff5f6486d92db2e6860', - ); - expect( ethUtil.bufferToHex( utils.hashStruct('Person', typedData.message.from, typedData.types, 'V4'), @@ -2276,9 +2351,6 @@ it('signedTypeData_v4', function () { ), ).toBe('0xefa62530c7ae3a290f8a13a5fc20450bdb3a6af19d9d9d2542b5a94e631a9168'); - expect(ethUtil.bufferToHex(utils.hashType('Mail', typedData.types))).toBe( - '0x4bd8a9a2b93427bb184aca81e24beb30ffa3c747e2a33d4225ec08bf12e2e753', - ); expect( ethUtil.bufferToHex( utils.hashStruct( @@ -2353,10 +2425,6 @@ it('signedTypeData_v4 with recursive types', function () { const utils = sigUtil.TypedDataUtils; - expect(ethUtil.bufferToHex(utils.hashType('Person', typedData.types))).toBe( - '0x7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116', - ); - expect( ethUtil.bufferToHex( utils.hashStruct( @@ -2453,10 +2521,6 @@ it('signedTypeMessage V4 with recursive types', function () { const utils = sigUtil.TypedDataUtils; - expect(ethUtil.bufferToHex(utils.hashType('Person', typedData.types))).toBe( - '0x7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116', - ); - expect( ethUtil.bufferToHex( utils.hashStruct(