Metamask Error: Verifying Signed Data with Ether.js SignTypedData
When using the Ethers.js library to sign and encode data as a signed TypedData, Solidity’s Metamask may encounter an error that prevents it from verifying the signed data. In this article, we’ll explore the issue and provide a possible solution.
The Issue:
The error typically occurs when attempting to verify the signed data using MetaMask’s verify
function on the signTypedData
property returned by Ethers.js. The problem lies in how Solidity’s signTypedData
function interacts with the Ethers.js library and the verify
method.
Sign TypedData Functionality
When you call signTypedData
on your data, it creates a signature of the input data using the signer’s private key. However, when verifying this signed data in Metamask using verify
, the library expects to receive the original unaltered input data as an argument.
Ethers.js Sign TypedData
The signTypedData
function is designed to create and verify a signature of the input data without altering it. To use signTypedData
with Ethers.js, you need to create a signed version of your input data that can be verified by the library.
For example:
const domain = {
name: 'og-nft',
version: '1'
};
const types = {
// ...
};
// Create a signed version of the data using Ethers.js SignTypedData
const signature = await ethers.signTypedData(
{
type,
value: {
og_nft: { ... } // Replace with your actual input data
}
},
'0x...' // Replace with your private key
);
// Create a signed TypedData from the signed data
const sigTypedData = ethers.Signer.signTypedData(signature, domain);
In this example, we first create a signature
object using Ethers.js’s signTypedData
function. We then use this signature to create a typed data object, which is used for verification.
Metamask Verification Issue
Now that you have the signed TypedData object in place, you can attempt to verify it in Metamask. However, as mentioned earlier, Metamask’s verify
function expects the original unaltered input data as an argument.
To fix this issue, you need to create a new typed data object with the same properties and value as your original input data. In other words, you need to recreate the original input data using Ethers.js.
// Create a new typed data object from the signed TypedData
const verification = ethers.Signer.verifyTyped(
sigTypedData,
domain,
{ type: 'unverify' } // Replace with your private key
);
// Verify the typed data using Metamask's verify function
await metamask.verify(verification);
In this example, we create a new verification
object by calling Ethers.js’s verifyTyped
function on the signed TypedData. We then pass the original input data (domain
) and a verification key (which can be obtained using Ethers.js).
By recreating the original input data using Ethers.js, you should now be able to verify the signed data in Metamask.
Conclusion
In this article, we’ve explored the issue of verifying signed TypedData using MetaMask with Ethers.js. By understanding how Solidity’s signTypedData
function interacts with Ethers.js and creating a new typed data object from the signed data, you should be able to resolve the error and verify your signed data in Metamask.