Ethers.Signature (Ethers v0.7.0)

Copy Markdown View Source

Universal signature verification: EOA (ecrecover), smart-contract wallets (ERC-1271) and counterfactual — not-yet-deployed — wallets (ERC-6492).

Smart-contract wallets (Safe, Coinbase Smart Wallet, ERC-4337/EIP-7702 accounts, ...) cannot produce signatures that ecrecover validates. Backends which only use ecrecover-based verification (Ethers.PersonalMessage.verify/3, Ethers.TypedData.valid_signature?/3) silently reject all smart-wallet users. The functions in this module verify any signature:

  1. Fast path — for plain 65-byte ECDSA signatures, ecrecover runs locally first. A match verifies without any RPC round-trip.
  2. Universal path — otherwise, one eth_call executes the Ethers.Contracts.UniversalSigValidator contract deploylessly (no to address, nothing gets deployed on chain). The validator unwraps ERC-6492 signatures (counterfactually deploying the wallet inside the call), performs the ERC-1271 isValidSignature/2 check for contract accounts, and falls back to ecrecover.

Verification outcome is a boolean inside an ok-tuple: {:ok, false} means the signature is invalid, while {:error, reason} is reserved for transport/RPC failures. There are deliberately no bang variants — raising would conflate an invalid signature with an RPC failure.

Example

A backend verifying a wallet login message:

{:ok, true} = Ethers.Signature.verify_message("Sign in to Example", signature, address)

# With explicit RPC options
Ethers.Signature.verify_message("Sign in to Example", signature, address,
  rpc_opts: [url: "https://eth.example.com"]
)

Summary

Functions

Verifies a signature over a 32-byte digest against an address.

Verifies a signature over an EIP-191 personal message (the personal_sign scheme) against an address.

Verifies a signature over EIP-712 typed structured data against an address.

Functions

verify_hash(hash, signature, address, opts \\ [])

@spec verify_hash(binary(), binary(), Ethers.Types.t_address(), Keyword.t()) ::
  {:ok, boolean()} | {:error, term()}

Verifies a signature over a 32-byte digest against an address.

Accepts any signature kind: plain 65-byte ECDSA (EOA), ERC-1271 (verified on-chain via the account contract) and ERC-6492-wrapped (counterfactual wallets). Plain EOA signatures that recover to address are verified locally without any RPC call.

Parameters

  • hash: The 32-byte digest that was signed — either a raw binary or a 0x-prefixed hex string. (e.g. Ethers.PersonalMessage.hash/1 or Ethers.TypedData.hash/1)
  • signature: The signature as a 0x-prefixed hex string or raw binary. ERC-6492-wrapped signatures (longer than 65 bytes) are passed to the validator untouched.
  • address: The address to verify against (EOA or smart-contract account).
  • opts: Options.

Options

  • :block: The block number (integer) or block tag for the validation eth_call. Defaults to "latest".
  • :rpc_client: The RPC Client to use. It should implement ethereum jsonRPC API. default: Ethereumex.HttpClient
  • :rpc_opts: Extra options to pass to rpc_client. (Like timeout, Server URL, etc.)

Returns

  • {:ok, true} if the signature is valid for address.
  • {:ok, false} if the signature is invalid.
  • {:error, reason} on malformed input or RPC transport failure.

verify_message(message, signature, address, opts \\ [])

@spec verify_message(binary(), binary(), Ethers.Types.t_address(), Keyword.t()) ::
  {:ok, boolean()} | {:error, term()}

Verifies a signature over an EIP-191 personal message (the personal_sign scheme) against an address.

Hashes message with Ethers.PersonalMessage.hash/1 and delegates to verify_hash/4 — see it for accepted signature kinds, options and return values.

verify_typed_data(typed_data, signature, address, opts \\ [])

@spec verify_typed_data(
  Ethers.TypedData.t(),
  binary(),
  Ethers.Types.t_address(),
  Keyword.t()
) ::
  {:ok, boolean()} | {:error, term()}

Verifies a signature over EIP-712 typed structured data against an address.

Hashes typed_data with Ethers.TypedData.hash/1 and delegates to verify_hash/4 — see it for accepted signature kinds, options and return values.