Skip to content
LogoLogo

verifyTypedData

Verify that typed data was signed by the provided address.

Supports verification of:

  • Externally Owned Accounts
  • Smart Contract Accounts:

Usage

// @filename: data.ts
// All properties on a domain are optional
export const domain = {
  name: 'Ether Mail',
  version: '1',
  chainId: 1,
  verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
} as const
 
// The named list of all type definitions
export const types = {
  Person: [
    { name: 'name', type: 'string' },
    { name: 'wallet', type: 'address' },
  ],
  Mail: [
    { name: 'from', type: 'Person' },
    { name: 'to', type: 'Person' },
    { name: 'contents', type: 'string' },
  ],
} as const
// @filename: client.ts
import 'viem/window'
// ---cut---
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { mainnet } from 'viem/chains'
 
export const publicClient = createPublicClient({
  chain: mainnet,
  transport: http()
})
 
export const walletClient = createWalletClient({
  transport: custom(window.ethereum!)
})
 
↓ JSON-RPC Account
export const [account] = await walletClient.getAddresses()
 
↓ Local Account
// export const account = privateKeyToAccount(...)
// @filename: example.ts
// ---cut---
import { account, walletClient, publicClient } from './client'
import { domain, types } from './data'
 
const message = {
  from: {
    name: 'Cow',
    wallet: '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
  },
  to: {
    name: 'Bob',
    wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
  },
  contents: 'Hello, Bob!',
}
 
const signature = await walletClient.signTypedData({
  account,
  domain,
  types,
  primaryType: 'Mail',
  message,
})
const valid = await publicClient.verifyTypedData({
  address: account.address,
  domain,
  types,
  primaryType: 'Mail',
  message,
  signature,
})
// true

Returns

boolean

Whether the signed message is valid for the given address.

Parameters

address

The Ethereum address that signed the original message.

const  = await .({
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266', 
  : {
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : {
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail',
  : {
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...',
})

domain

Type: TypedDataDomain

The typed data domain.

const  = await .({
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
  : { 
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : {
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail',
  : {
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...',
})

types

The type definitions for the typed data.

const  = await .({
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
  : {
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : { 
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail',
  : {
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...',
})

primaryType

Type: Inferred string.

The primary type to extract from types and use in value.

const  = await .({
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
  : { 
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : {
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [ 
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail', 
  : {
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...',
})

message

Type: Inferred from types & primaryType.

const  = await .({
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
  : {
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : {
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail',
  : { 
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...',
})

signature

  • Type: Hex | ByteArray | Signature

The signature of the typed data.

const  = await .({
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
  : {
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : {
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail',
  : {
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...', 
})

blockNumber (optional)

  • Type: bigint

Only used when verifying a typed data that was signed by a Smart Contract Account. The block number to check if the contract was already deployed.

const  = await .({
  : 42069n, 
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
  : {
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : {
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail',
  : {
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...',
})

blockTag (optional)

  • Type: 'latest' | 'earliest' | 'pending' | 'safe' | 'finalized'
  • Default: 'latest'

Only used when verifying a typed data that was signed by a Smart Contract Account. The block tag to check if the contract was already deployed.

const  = await .({
  : 42069n, 
  : '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
  : {
    : 'Ether Mail',
    : '1',
    : 1,
    : '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
  },
  : {
    : [
      { : 'name', : 'string' },
      { : 'wallet', : 'address' },
    ],
    : [
      { : 'from', : 'Person' },
      { : 'to', : 'Person' },
      { : 'contents', : 'string' },
    ],
  },
  : 'Mail',
  : {
    : {
      : 'Cow',
      : '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826',
    },
    : {
      : 'Bob',
      : '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB',
    },
    : 'Hello, Bob!',
  },
  : '0x...',
})