Conversation
alisinabh
force-pushed
the
feat/universal-sig-verification
branch
from
July 19, 2026 04:29
ebe1cac to
6997141
Compare
alisinabh
force-pushed
the
feat/universal-sig-verification
branch
from
July 19, 2026 04:37
6997141 to
63c965c
Compare
Implement Ethers.Siwe and Ethers.Siwe.Message covering the SIWE message lifecycle: new/new! construction with field validation, crypto-random nonce generation, EIP-4361 rendering (with String.Chars), strict parsing per the spec grammar (verified against the spruceid/siwe reference test vectors with byte-for-byte round-tripping), and stateless validation of the validity window and domain/scheme/nonce/address binding. Timestamps are stored as RFC 3339 strings exactly as parsed so that a parsed message always re-renders identical to its source, which is required for signature verification. Signature verification (Ethers.Siwe.verify/3) lands separately on top of the ERC-6492 universal signature verification work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The one-call backend flow: parse the raw EIP-4361 message (or accept an already-parsed struct), run stateless field validation, then check the signature via Ethers.Signature.verify_message/4 — EOA signatures verify locally with zero RPC round-trips while ERC-1271 and ERC-6492 smart-contract wallets are verified with a single eth_call. When given a string, the signature is verified over the exact original input. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds first-class Sign-In with Ethereum (SIWE, EIP-4361) support to the Ethers library, including message construction/parsing/validation and an end-to-end verification helper that leverages the universal signature verification stack (EOA + ERC-1271/6492). It also introduces a dedicated guide and comprehensive fixtures/tests for reference vectors and verification flows.
Changes:
- Add
Ethers.SiweandEthers.Siwe.Messageimplementing EIP-4361 creation, rendering, strict parsing, stateless validation, and signature verification. - Add SIWE documentation guide and wire it into ExDoc.
- Add reference fixtures and ExUnit coverage for parsing/validation and EOA + ERC-1271 verification paths.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
lib/ethers/siwe.ex |
Core SIWE implementation: build/parse/render/validate/verify. |
lib/ethers/siwe/message.ex |
Defines the SIWE message struct, types, and String.Chars impl. |
guides/siwe.md |
Phoenix integration guide and security notes for SIWE usage. |
mix.exs |
Adds the SIWE guide/modules to generated docs navigation/groups. |
CHANGELOG.md |
Documents new SIWE feature in the changelog. |
test/ethers/siwe_test.exs |
Unit tests for message lifecycle: new/render/parse/validate and vectors. |
test/ethers/siwe_verify_test.exs |
End-to-end verify/3 tests for EOA and ERC-1271 paths. |
test/support/fixtures/siwe/parsing_positive.json |
Official/reference positive parsing vectors for round-trip tests. |
test/support/fixtures/siwe/parsing_negative.json |
Reference negative raw-message vectors for strict parsing tests. |
test/support/fixtures/siwe/parsing_negative_objects.json |
Reference negative object vectors for new/1 validation tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
An authority with a port delimiter but no digits (example.com:) is now rejected as a SIWE domain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third PR of the v0.7 "Auth" tier. Stacked on #266 (base is
feat/universal-sig-verification; retarget after #266 merges).What
Ethers.Siwe+Ethers.Siwe.Messageimplementing EIP-4361:new/1/new!/1(field validation, EIP-55 address normalization, nonce rules),generate_nonce/0(crypto-random, ≥8 alphanumeric)to_message/1(exact EIP-4361 rendering +String.Chars), strictparse/1(byte-for-byte round-trip)validate/2— stateless checks with injectabletime:: domain/scheme/nonce/address binding, expiration (exclusive) / not-before (inclusive), versionverify/3— the one-call backend flow: parse → validate → signature check viaEthers.Signature.verify_message/4, so smart-wallet (ERC-1271/6492) sign-ins work out of the box; EOA sign-ins verify with zero RPC calls.{:ok, false}maps to{:error, :invalid_signature}.guides/siwe.mdwith the Phoenix controller recipe (nonce in session → verify endpoint).Design notes
DateTime) so non-UTC offsets and sub-second precision round-trip exactly, matching spruceid's JS/Rust libraries;new/1acceptsDateTimeandvalidate/2parses on demand.schemefield from the current EIP-4361 ABNF.Testing
verify/3covered end-to-end: EOA happy path under a raising RPC stub (proving no network use), wrong signer/message, every validation error short-circuiting before the signature check, and a deployed ERC-1271 wallet on anvil accepting its owner's signature.mix format,mix credo --strict,mix dialyzerclean.🤖 Generated with Claude Code