I am trying to compute the hash to be signed for EIP-712 typed data using the ethers.js(v5.7.2) library in TypeScript. I'm using _TypedDataEncoder.hash()
to hash the typed data, but I am encountering the following error:
Error: ambiguous primary types or unused types: "PermitSingle", "EIP712Domain" (argument="types", value= {... }, code=INVALID_ARGUMENT, version=hash/5.7.0)
Here is the TypeScript code I am using:
import { arrayify, BytesLike, concat, hexlify } from '@ethersproject/bytes'
import { _TypedDataEncoder } from '@ethersproject/hash'
import { keccak256 } from '@ethersproject/keccak256'
import { TypedDataDomain, TypedDataField } from 'ethers'
function hashTypedDataV4(params: any) {
// Destructure the params
const [from, jsonData]: [string, string] = params;
const { types, domain, primaryType, message } = JSON.parse(jsonData);
// Hash the EIP-712 Domain
const domainSeparator = _TypedDataEncoder.hashDomain(domain);
// Hash the message (EIP-712 typed data)
const messageHash = structHash(domain, types, message);
// Compute the final hash to sign (according to EIP-712)
const hashToSign = arrayify(keccak256(concat(['0x1901', domainSeparator, messageHash])));
return hashToSign;
}
function structHash(domain: TypedDataDomain, types: Record<string, TypedDataField[]>, data: Record<string, any>) {
return _TypedDataEncoder.hash(domain, types, data); // ERROR OCCURS HERE!
}
The error seems to occur on the return _TypedDataEncoder.hash(domain, types, data) line in the structHash
method. From the error message, it seems like there is some ambiguity regarding the primary types, but I am not sure how to resolve it.
Below is an example of the params I am passing to hashTypedDataV4 (please note that the function expects the second element of params to be a JSON string, but I'm showing it as a JSON object for readability - you can use JSON.stringify() to convert it back to the expected format):
[
"0xfdb267dc5e340647aab9372fc5a8e406d4e71c8d",
{
"types": {
"PermitSingle": [
{ "name": "details", "type": "PermitDetails" },
{ "name": "spender", "type": "address" },
{ "name": "sigDeadline", "type": "uint256" }
],
"PermitDetails": [
{ "name": "token", "type": "address" },
{ "name": "amount", "type": "uint160" },
{ "name": "expiration", "type": "uint48" },
{ "name": "nonce", "type": "uint48" }
],
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "chainId", "type": "uint256"
},
{ "name": "verifyingContract", "type": "address" }
]
},
"domain": { "name": "Permit2", "chainId": "1", "verifyingContract": "0x14a5698aeab8aa3f472c6d0a0061730f45467bd9"
},
"primaryType": "PermitSingle",
"message": {
"details": {
"token": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"amount": "1461501637330902918203684832716283019655932542975",
"expiration": "1690127209",
"nonce": "0"
},
"spender": "0x49c4f688ade58ad80de1ddd932db3b804fef5cef",
"sigDeadline": "1687537009"
}
}
]
Could anyone please help me understand what might be causing this error and how to resolve it?