Skip to content

feat(auth): Sign-in with Ethereum for Better Auth (#23) - #100

Merged
Winter-Soren merged 1 commit into
QMeshPy:mainfrom
Arnab-Afk:feat/auth-siwe
Oct 31, 2026
Merged

Winter-Soren merged 1 commit into
QMeshPy:mainfrom
Arnab-Afk:feat/auth-siwe

Conversation

@Arnab-Afk

Copy link
Copy Markdown
Contributor

Summary

Implements wallet-based sign-in (EIP-4361 / Sign-In with Ethereum) alongside the existing email OTP flow in Better Auth, with cryptographic verification, replay protection via single-use nonces, reverse ENS lookup for display names/avatars, and wallet linking/unlinking management.

Closes #23
Part of #1

What is included

1. SIWE Authentication Flow (EIP-4361)

  • Better Auth server configuration with the built-in siwe plugin and siweClient on the frontend.
  • Cryptographic signature verification using @noble/curves (secp256k1) and @noble/hashes (keccak_256), recovering the checksummed Ethereum address from EIP-191 personal_sign signatures without heavyweight external dependencies.
  • Single-use nonce generation and atomic database consumption (consumeVerificationValue), guaranteeing replay attempts fail immediately.
  • Validation of domain, chain ID (> 0), expiration timestamp (expirationTime), and not-before timestamp (notBefore).
  • Reverse ENS lookup to automatically enrich user profiles with ENS names and avatars where available.

2. Wallet Linking & Unlinking

  • Link Wallet (POST /api/auth/siwe/link): Verifies the SIWE signature and single-use nonce, and associates the wallet with the active session's account without creating duplicate accounts. Rejects attempts if the address is already linked to another account (409 Conflict).
  • Unlink Wallet (POST /api/auth/siwe/unlink): Safeguards against lockout by preventing users from unlinking their sole authentication method (if they have no email and only 1 wallet). Automatically promotes the oldest remaining wallet to primary if the primary is unlinked.
  • List Linked Wallets (GET /api/auth/siwe/wallets): Retrieves all linked addresses with chain IDs, primary flags, creation dates, and reverse ENS names.

3. UI Integration

  • Sign In / Sign Up Forms: Added "Sign in with Ethereum" button with seamless Web3 wallet connection, nonce retrieval, and EIP-4361 signing.
  • Settings Page: Added LinkedWalletsPanel to manage linked wallets, copy checksummed addresses, view ENS names, and link/unlink wallets.

4. Tests & Documentation

  • Added comprehensive unit and integration test suite (frontend/tests/siwe-auth.test.mjs) with 16 passing tests covering nonce generation, EIP-4361 parsing, domain normalization, signature verification, address recovery, replay protection, domain/chain/expiration rejection, and linking/unlinking rules.
  • Documented authentication workflows and API contracts in frontend/src/features/auth/README.md.

Acceptance Criteria Checklist

  • Nonces are single-use and expire; replayed signatures are rejected.
  • Domain, chain id and expiry in the SIWE message are validated.
  • A user can link and unlink a wallet; the proxy/session behaviour is unchanged.

- Configure Better Auth with the SIWE plugin and cryptographic signature verification
- Implement EIP-4361 message parsing, domain normalization, and EIP-55 checksumming
- Enforce single-use nonces and expiration with replay protection
- Add wallet linking (POST /api/auth/siwe/link) and unlinking (POST /api/auth/siwe/unlink)
- Protect against account lockouts when unlinking a user's sole authentication method
- Integrate LinkedWalletsPanel into the Settings page and add SIWE to SigninForm and SignupForm
- Add unit and integration tests covering all acceptance criteria (16 passing tests)
- Document authentication architecture and SIWE flows in features/auth/README.md

Closes QMeshPy#23
Copilot AI balanced review requested due to automatic review settings October 28, 2026 18:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@Winter-Soren

Copy link
Copy Markdown
Member

Emergency Merge!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(auth): Sign-in with Ethereum for Better Auth

3 participants