5

I have a standard typed data object that uses Metamask, according to this scheme(without JSON.stringify):

enter image description here

If you sign such an object like this:

let sig = web3.eth.accounts.sign(JSON.stringify(order), secret_key, true)

then the resulting signature will differ from the signature obtained when signing a similar object in the Metamask by the signTypedData_v4 method. Therefore, I want to get a signature in web3js similar to a Metamask. How can I do this? Thank you in advance!

2 Answers 2

4
let sig = web3.eth.accounts.sign(JSON.stringify(order), secret_key, true)

You are signing a JSON string, which is not correct as per EIP712 specs

You need to sign:

keccak256(
  abi.encodePacked(
    '0x1901', // EIP-712 prefix
    DOMAIN_SEPERATOR // a.k.a hash of domain
    hashStruct // hash of data to sign, definition - https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct
  )
)

Following are a few of the examples:

3
+100

From MetaMask Docs, we find the following JavaScript example of signTypedData_v4. I think this is the only way to implement signTypedData_v4 in web3. Otherwise, you'll need to use MetaMasks's signTypedData(...) method from eth-sig-util.

const msgParams = JSON.stringify({
    types: {
      EIP712Domain: [
        { name: 'name', type: 'string' },
        { name: 'version', type: 'string' },
        { name: 'chainId', type: 'uint256' },
        { name: 'verifyingContract', type: 'address' },
      ],
      // Not an EIP712Domain definition
      Bid: [
        { name: 'name', type: 'string' },

      ],
      // Refer to PrimaryType
      Mail: [
        { name: 'from', type: 'Person' },
        { name: 'to', type: 'Person[]' },
        { name: 'contents', type: 'string' },
      ],
      // Not an EIP712Domain definition
      Person: [
        { name: 'name', type: 'string' },
        { name: 'wallets', type: 'address[]' },
      ],
    },
});

var from = web3.eth.accounts[0];

var params = [from, msgParams];
var method = 'eth_signTypedData_v4';

web3.currentProvider.sendAsync(
    {
      method,
      params,
      from,
    },
    function (err, result) {
      if (err) return console.dir(err);
      if (result.error) {
        alert(result.error.message);
      }
      if (result.error) return console.error('ERROR', result);
      console.log('TYPED SIGNED:' + JSON.stringify(result.result));
    }
)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.