Skip to content

Commit

Permalink
Allow TypedDataUtils to be called unbound
Browse files Browse the repository at this point in the history
Previously the functions exposed as `TypedDataUtils` could only be
called from the `TypedDataUtils` object. If they were called unbound,
they would throw errors because of the use of `this`.

They have all been updated to no longer rely upon `this`, so they now
work the same way regardless how they are bound when called.

They are still exported as the `TypedDataUtils` object, so this should
not change the API. This was done to simplify the code, specifically to
make it easier for functions outside of `TypedDataUtils` to reuse code
inside of `TypedDataUtils`.

Some types required adjustments, as type mistakes were brought to light
that TypeScript for some reason wasn't aware of when these were
declared as properties of the `TypedDataUtils` object. These were fixed
by adding two type assertions, making the `types` parameter to
`hashStruct` and `hashType` more strict, and by making the `typedData`
parameter to `eip712Hash` more strict. The type assertions (warranted
or not) preserve the types used previously. We can replace them later
with validation.
  • Loading branch information
Gudahtt committed Aug 2, 2021
1 parent a81d749 commit cf0663c
Show file tree
Hide file tree
Showing 2 changed files with 362 additions and 222 deletions.
123 changes: 123 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1250,3 +1250,126 @@ it('signedTypeMessage V4 with recursive types', function () {
'0xf2ec61e636ff7bb3ac8bc2a4cc2c8b8f635dd1b2ec8094c963128b358e79c85c5ca6dd637ed7e80f0436fe8fce39c0e5f2082c9517fe677cc2917dcd6c84ba881c',
);
});

it('unbound sign typed data utility functions', function () {
const typedData = {
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
{ name: 'verifyingContract', type: 'address' },
],
Person: [
{ name: 'name', type: 'string' },
{ name: 'mother', type: 'Person' },
{ name: 'father', type: 'Person' },
],
},
domain: {
name: 'Family Tree',
version: '1',
chainId: 1,
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
},
primaryType: 'Person' as const,
message: {
name: 'Jon',
mother: {
name: 'Lyanna',
father: {
name: 'Rickard',
},
},
father: {
name: 'Rhaegar',
father: {
name: 'Aeris II',
},
},
},
};

const { encodeData, encodeType, hashStruct, hashType, eip712Hash } =
sigUtil.TypedDataUtils;

expect(encodeType('Person', typedData.types)).toBe(
'Person(string name,Person mother,Person father)',
);

expect(ethUtil.bufferToHex(hashType('Person', typedData.types))).toBe(
'0x7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116',
);

expect(
ethUtil.bufferToHex(
encodeData('Person', typedData.message.mother, typedData.types, 'V4'),
),
).toBe(
`0x${[
'7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116',
'afe4142a2b3e7b0503b44951e6030e0e2c5000ef83c61857e2e6003e7aef8570',
'0000000000000000000000000000000000000000000000000000000000000000',
'88f14be0dd46a8ec608ccbff6d3923a8b4e95cdfc9648f0db6d92a99a264cb36',
].join('')}`,
);
expect(
ethUtil.bufferToHex(
hashStruct('Person', typedData.message.mother, typedData.types, 'V4'),
),
).toBe('0x9ebcfbf94f349de50bcb1e3aa4f1eb38824457c99914fefda27dcf9f99f6178b');

expect(
ethUtil.bufferToHex(
encodeData('Person', typedData.message.father, typedData.types, 'V4'),
),
).toBe(
`0x${[
'7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116',
'b2a7c7faba769181e578a391a6a6811a3e84080c6a3770a0bf8a856dfa79d333',
'0000000000000000000000000000000000000000000000000000000000000000',
'02cc7460f2c9ff107904cff671ec6fee57ba3dd7decf999fe9fe056f3fd4d56e',
].join('')}`,
);
expect(
ethUtil.bufferToHex(
hashStruct('Person', typedData.message.father, typedData.types, 'V4'),
),
).toBe('0xb852e5abfeff916a30cb940c4e24c43cfb5aeb0fa8318bdb10dd2ed15c8c70d8');

expect(
ethUtil.bufferToHex(
encodeData(
typedData.primaryType,
typedData.message,
typedData.types,
'V4',
),
),
).toBe(
`0x${[
'7c5c8e90cb92c8da53b893b24962513be98afcf1b57b00327ae4cc14e3a64116',
'e8d55aa98b6b411f04dbcf9b23f29247bb0e335a6bc5368220032fdcb9e5927f',
'9ebcfbf94f349de50bcb1e3aa4f1eb38824457c99914fefda27dcf9f99f6178b',
'b852e5abfeff916a30cb940c4e24c43cfb5aeb0fa8318bdb10dd2ed15c8c70d8',
].join('')}`,
);
expect(
ethUtil.bufferToHex(
hashStruct(
typedData.primaryType,
typedData.message,
typedData.types,
'V4',
),
),
).toBe('0xfdc7b6d35bbd81f7fa78708604f57569a10edff2ca329c8011373f0667821a45');
expect(
ethUtil.bufferToHex(
hashStruct('EIP712Domain', typedData.domain, typedData.types, 'V4'),
),
).toBe('0xfacb2c1888f63a780c84c216bd9a81b516fc501a19bae1fc81d82df590bbdc60');
expect(ethUtil.bufferToHex(eip712Hash(typedData, 'V4'))).toBe(
'0x807773b9faa9879d4971b43856c4d60c2da15c6f8c062bd9d33afefb756de19c',
);
});
Loading

0 comments on commit cf0663c

Please sign in to comment.