EIPs

EIP-712 — Typed structured data hashing and signing

eips.ethereum.org/EIPS/eip-712

EIP-712 lets a dapp ask the user to sign structured data — domain-bound, schema-defined, human-readable in the wallet popup. Where personal_sign (EIP-191) signs an opaque byte string, EIP-712 signs a typed object whose hash is computed from declared field types.

import { hash_typed_data, type TypedData } from "@ethernauta/eip/712";

const typed: TypedData = {
  types: {
    Permit: [
      { name: "owner", type: "address" },
      { name: "spender", type: "address" },
      { name: "value", type: "uint256" },
      { name: "nonce", type: "uint256" },
      { name: "deadline", type: "uint256" },
    ],
  },
  primary_type: "Permit",
  domain: {
    name: "USD Coin",
    version: "2",
    chain_id: 1,
    verifying_contract: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  },
  message: { owner, spender, value, nonce, deadline },
};

const digest = hash_typed_data(typed);

Surface

ExportTypePurpose
typedDataSchemaValibot schemaValidate a typed-data payload.
TypedData, TypedDataDomain, TypedDataFieldtypesInferred shapes.
hash_typed_data(td: TypedData) => Hash32EIP-712 digest.
sign_typed_dataSignable<Bytes65>Method binding for eth_signTypedData_v4.

Signing via the wallet

import { sign_typed_data } from "@ethernauta/eip/712";

const signature = await sign_typed_data({ account, typed_data })(
  signer({ chain_id: eip155_1.chain_id }),
);

The signer wraps a 1193 provider; the wallet opens its sign-typed-data view, displays the field-by-field breakdown, and returns the 65-byte signature.

Verification

import { verify_typed_data } from "@ethernauta/crypto";

const ok = await verify_typed_data({
  address,
  typed_data,
  signature,
})(reader({ chain_id: eip155_1.chain_id }));

Same EOA → 1271 fallback as verify_message. Add _universal for counterfactual.

Common consumers

  • ERC-2612 permit — gasless ERC-20 approvals.
  • EIP-4361 SIWE — sign-in with Ethereum.
  • ERC-7683 — cross-chain order signing.
  • EIP-7702 authorizations — set-code delegations.

Each of those packages composes the hash_typed_data primitive rather than reimplementing the digest.

See also