BaseToolbox LogoBaseToolbox
Blog

© 2025 BaseToolbox. All rights reserved.

Privacy PolicyAboutContact Us

How to Read EIP-712 Typed Data Before You Sign

Published on August 12, 2026

EIP-712 typed data can be easier to read than an opaque hex message, but readable fields are not automatically harmless. Before signing, identify the signing domain, the primary message type, the addresses receiving authority, the amounts involved, and any time or replay controls.

The fastest local workflow is to paste the complete JSON into the EIP-712 Inspector. It reproduces the domain separator, message struct hash, final digest, and optional signer recovery without connecting a wallet or making an RPC request. Use those results as evidence about the supplied bytes, not as a global safety rating.

The four parts of EIP-712 typed data

A typical request contains four top-level sections:

  • domain identifies the signing context, commonly with a name, version, chain ID, and verifying contract.
  • types defines named structures and the type of each field.
  • primaryType names the root structure being signed.
  • message contains the actual values for that structure.

The EIP-712 specification defines how the domain separator and message struct hash become the final digest. It also states an important boundary: the standard itself does not provide replay protection.

Start with the domain

Read chainId and verifyingContract before studying the message. A chain ID helps bind the domain to a chain. A verifying contract helps bind it to the contract expected to consume the signature. Their absence is a concrete fact worth noticing, although presence alone does not establish trust.

Compare the verifying contract with the address you expected. The Crypto Address Validator can check its EVM syntax and EIP-55 checksum state locally. That check does not confirm contract ownership, code, reputation, or deployment state.

The domain name and version are useful labels, but they are supplied data. Do not rely on a familiar name while ignoring an unfamiliar contract address or chain.

Trace the primary type and nested fields

Next, find primaryType, then follow its fields through types. Structures can contain other structures and arrays, so the important value may be nested several levels below the top-level message.

Use this review table as a practical checklist:

Field pattern What to verify
owner, from, signer The account whose authority is being used
spender, operator, to The address receiving permission or value
value, amount, allowance-like fields The exact integer and its token-decimal interpretation
deadline, expiry, expiration Whether the Unix time has passed or is unexpectedly distant
nonce Whether the application describes how it prevents reuse

Large integers should usually be represented as JSON strings so JavaScript does not lose precision. If an amount is in raw token units, use the Ethereum Unit Converter with the token's known decimals. The converter does not fetch token metadata, so the decimal setting remains your responsibility.

Treat Permit-shaped messages as authorizations

Types named Permit, PermitSingle, or similar often authorize a spender without sending a normal approval transaction first. The exact meaning comes from the verifying application and contract, not the type name alone.

When a Permit-shaped message contains a spender, check that address and the authorized amount together. Also inspect expiration and signature deadline fields. Uniswap Permit2, for example, includes both allowance-transfer and signature-transfer interfaces, but seeing a Permit2-shaped structure does not prove which deployed contract or call path will use it.

If you also have transaction input data, inspect it separately with the EVM Calldata and ABI Decoder. Typed data describes a signed digest; calldata describes encoded function input. They are related in some flows but are not interchangeable.

What hashes and signer recovery prove

The canonical type string determines a type hash. The domain produces a domain separator. The primary message produces a struct hash. EIP-712 combines the last two into the final digest that is signed.

If a 65-byte signature recovers to an address, that proves the corresponding key authorized this calculated digest, assuming the supplied typed data is the intended input. It does not prove that the contract is trustworthy, the amount is reasonable, the signature is unused, or the resulting action will be safe.

An expected-signer mismatch is decisive for that comparison. A match is narrower: it confirms identity for the digest, not the wisdom of the authorization.

Final pre-sign checklist

Before approving a wallet prompt, verify all of the following:

  1. The chain ID and verifying contract match the intended application context.
  2. The primary type and every nested spender, operator, recipient, and amount are understood.
  3. Token units are interpreted with the correct decimals.
  4. Deadlines and expirations are acceptable, and replay handling is explained by the application.
  5. Any recovered signer matches the account you expected.

If one of those facts is missing, pause and get the missing context from an independent official source. A decoder can make the supplied data legible; it cannot supply absent contract semantics or chain state.

Primary references

  • EIP-712: Typed structured data hashing and signing
  • Uniswap Permit2 repository and interface source

Ready to try it yourself?

Put what you have learned into practice with our free online tool.

Inspect EIP-712 Typed Data Locally