Skip to content

eth_signTypedData_v4

Defined in EIP-712

Signs EIP-712 typed data. The signing account must be unlocked. This method allows applications to create more user-friendly signing requests by providing structured data with type information, domain separation, and a robust hashing mechanism for the data. This is the most up-to-date version of the EIP-712 signing method.

Parameters

type SignTypedDataV4Params = [string, TypedData]
 
interface TypedData {
  /**
   * The typed data domain
   */
  domain: TypedDataDomain
  /**
   * The primary type of the message
   */
  primaryType: string
  /**
   * Type definitions for all types used in the message
   */
  types: Record<string, TypedDataField[]>
  /**
   * The message to be signed
   */
  message: Record<string, unknown>
}
 
interface TypedDataDomain {
  /**
   * The name of the domain
   */
  name?: string
  /**
   * The version of the domain
   */
  version?: string
  /**
   * The chain ID of the domain
   */
  chainId?: number | string
  /**
   * The verifying contract address
   */
  verifyingContract?: string
  /**
   * A salt used to disambiguate the domain
   */
  salt?: string
}
 
interface TypedDataField {
  /**
   * The name of the field
   */
  name: string
  /**
   * The type of the field
   */
  type: string
}

Returns

string

A signature string in hexadecimal format. The signature conforms to the standard Ethereum signature format: a 65-byte array represented as a hexadecimal string with 0x prefix. The signature can be broken down into:

  • r: The first 32 bytes
  • s: The second 32 bytes
  • v: The final 1 byte (recovery ID)

Example

Request:

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "eth_signTypedData_v4",
  "params": [
    "0x8eeC87D46108b8A3763Dda3A24A0D3e038C6996F",
    {
      "domain": {
        "name": "My Dapp",
        "version": "1",
        "chainId": 1,
        "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
      },
      "message": {
        "from": {
          "name": "Alice",
          "wallets": [
            "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
            "0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF"
          ]
        },
        "to": {
          "name": "Bob",
          "wallets": [
            "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
            "0xB0BdaBea57B0BDABeA57b0bdABEA57b0BDabEa57"
          ]
        },
        "contents": "Hello, Bob!"
      },
      "primaryType": "Mail",
      "types": {
        "EIP712Domain": [
          { "name": "name", "type": "string" },
          { "name": "version", "type": "string" },
          { "name": "chainId", "type": "uint256" },
          { "name": "verifyingContract", "type": "address" }
        ],
        "Mail": [
          { "name": "from", "type": "Person" },
          { "name": "to", "type": "Person" },
          { "name": "contents", "type": "string" }
        ],
        "Person": [
          { "name": "name", "type": "string" },
          { "name": "wallets", "type": "address[]" }
        ]
      }
    }
  ]
}

Response:

{
  "id": 1,
  "jsonrpc": "2.0",
  "result": "0x4355c47d63924e8a72e509b65029052eb6c299d53a04e167c5775fd466751c9d07299936d304c153f6443dfa05f40ff007d72911b6f72307f996231605b915621c"
}

Usage Example

// Request to sign typed data
const signature = await ethereum.request({
  method: 'eth_signTypedData_v4',
  params: [
    '0x8eeC87D46108b8A3763Dda3A24A0D3e038C6996F', // The signer's address
    JSON.stringify({
      domain: {
        name: 'My Dapp',
        version: '1',
        chainId: 1,
        verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
      },
      message: {
        // The data to sign
        value: '100000000000000000', // 0.1 ETH in wei
        recipient: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
        timestamp: 1647032970
      },
      primaryType: 'Transaction',
      types: {
        EIP712Domain: [
          { name: 'name', type: 'string' },
          { name: 'version', type: 'string' },
          { name: 'chainId', type: 'uint256' },
          { name: 'verifyingContract', type: 'address' }
        ],
        Transaction: [
          { name: 'value', type: 'string' },
          { name: 'recipient', type: 'address' },
          { name: 'timestamp', type: 'uint256' }
        ]
      }
    })
  ]
});
console.log('Signature:', signature);

Errors

CodeMessageDescription
4001User denied signature requestThe user rejected the request to sign the data
4100Requested method not supportedThe provider does not support the eth_signTypedData_v4 method
4200Wallet not connectedThe wallet is not connected to the dApp
4300Invalid parametersThe parameters provided are invalid