Skip to content

geovgy/eip712-noir

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EIP712-Noir

A Noir library for EIP-712 typed structured data hashing. Compute domain separators, struct hashes, and full signTypedData-compatible message hashes inside Noir circuits.

Installation

Add eip712 as a dependency in your Nargo.toml:

[dependencies]
eip712 = { tag = "v0.1.0", git = "https://github.com/geovgy/eip712-noir" }

Usage

use eip712::{build_domain_separator, to_struct_hash, hash_typed_data_v4};
use keccak256::keccak256;

fn main(expected_hash: pub [u8; 32]) {
    // 1. Build the EIP-712 domain separator
    let domain_separator = build_domain_separator(
        "MyDapp".as_bytes(),   // name
        "1".as_bytes(),        // version
        1,                     // chainId
        0xYourContractAddress, // verifyingContract
    );

    // 2. Encode your struct fields and compute the struct hash.
    //    Concatenate the ABI-encoded field values (each 32 bytes) into a
    //    byte array, then pass it with your primary type hash.
    let primary_type_hash: [u8; 32] = /* keccak256 of your type string */;
    let encoded_fields: [u8; N] = /* your ABI-encoded fields */;
    let struct_hash = to_struct_hash(primary_type_hash, encoded_fields);

    // 3. Compute the final EIP-712 hash: keccak256("\x19\x01" || domainSeparator || structHash)
    let typed_data_hash = hash_typed_data_v4(domain_separator, struct_hash);

    assert(typed_data_hash == expected_hash);
}

Functions

build_domain_separator(name, version, chain_id, verifying_contract) -> [u8; 32]

Computes the EIP-712 domain separator by hashing:

keccak256(typeHash || keccak256(name) || keccak256(version) || chainId || verifyingContract)
  • name: domain name as a byte array (e.g. "MyDapp".as_bytes())
  • version: domain version as a byte array (e.g. "1".as_bytes())
  • chain_id: chain ID as a Field
  • verifying_contract: contract address as a Field

to_struct_hash(primary_type_hash, message) -> [u8; 32]

Computes the hash of a struct by prepending its type hash:

keccak256(primaryTypeHash || encodedMessage)
  • primary_type_hash: the keccak256 of the EIP-712 type string
  • message: ABI-encoded struct fields concatenated as a byte array

hash_typed_data_v4(domain_separator, struct_hash) -> [u8; 32]

Computes the final EIP-712 message hash:

keccak256("\x19\x01" || domainSeparator || structHash)

This is the hash that gets signed by eth_signTypedData_v4.

Development

Prerequisites

  • Nargo (Noir package manager)
  • Bun (for the TypeScript test helper)

Run Noir tests

nargo test

Run the TypeScript reference script

The included index.ts uses viem to compute the same EIP-712 hashes off-chain, useful for generating expected values and verifying correctness.

bun install
bun run index.ts

About

A Noir library for EIP-712 typed structured data hashing

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors