# `Ethers.Signature`
[🔗](https://github.com/ExWeb3/elixir_ethers/blob/v0.8.0/lib/ethers/signature.ex#L1)

Universal signature verification: EOA (`ecrecover`), smart-contract wallets
([ERC-1271](https://eips.ethereum.org/EIPS/eip-1271)) and counterfactual —
not-yet-deployed — wallets ([ERC-6492](https://eips.ethereum.org/EIPS/eip-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:

```elixir
{: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"]
)
```

# `verify_hash`

```elixir
@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`

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

Verifies a signature over an [EIP-191](https://eips.ethereum.org/EIPS/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`

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

Verifies a signature over [EIP-712](https://eips.ethereum.org/EIPS/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.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
