Decision
Every signature verification site uses OpenZeppelin’sSignatureChecker.isValidSignatureNow rather than ECDSA.recover. This transparently supports both EOAs (ecrecover, ~5.6k gas) and smart accounts (ERC-1271 isValidSignature, ~12–15k gas for Safe).
Safe is the recommended wallet for nodes and high-value clients. Session keys via ERC-7579 smartsessions handle the hot signing paths (per-MB vouchers, per-probe/stream slash_sig).
What SignatureChecker changes
ECDSA.recover(hash, sig) → address reverses a signature into an address. This doesn’t work for ERC-1271 contracts, which reply “yes/no” given (hash, sig, address).
SignatureChecker.isValidSignatureNow(signer, hash, sig):
- For an EOA address, falls through to
ecrecover— same cost, same semantics. - For a contract address, calls
signer.isValidSignature(hash, sig)— the standard ERC-1271 path.
Unchanged
- EIP-712 domains and typed data hashes — unchanged. Safe’s ERC-1271 implementation validates the same EIP-712 payloads.
- Voucher format — unchanged. The
Vouchercarries the signer’s address already; no schema migration. - EOA flow — fully supported. Clients and nodes that prefer EOAs stay on EOAs.
Hot path: Safe-7579 + session keys
The hot signing path runs on Safe-7579 +erc7579/smartsessions. Session keys give:
- ERC-1271 validation (Safe signs)
- Time windows (expire at X)
- Selector- and domain-scoped action policies (only sign vouchers for channel Y)
- Per-session spending caps
- First-class revocation
SlashJudge implications
SlashJudge verifies slash_sig against a provided Ethereum address rather than recovering it. The offender’s address comes from the on-chain NodeId binding in StakingRegistry — the challenger supplies the NodeId, the contract looks up the bound address, and SignatureChecker verifies the signature against that address. Works for both EOA-owned nodes and Safe-owned nodes uniformly.
Source ADR: 024-account-abstraction.md