Quickstart
Clone the siwe-quickstart repo and run it locally to see Sign in with Ethereum in action — wallet connection, message signing, server-side verification, and session management in a single Next.js app.
Get Started
git clone https://github.com/signinwithethereum/siwe-quickstart
cd siwe-quickstart
cp .env.local.example .env.local
npm install
npm run dev
Open http://localhost:3000, connect a wallet, and sign in.
Environment Variables
The only required variable is SESSION_SECRET (at least 32 characters). The defaults work out of the box for local development:
| Variable | Required | Purpose |
|---|---|---|
SESSION_SECRET | Yes | Encrypts session cookies |
NEXT_PUBLIC_WC_PROJECT_ID | No | Enables WalletConnect (get one free at cloud.walletconnect.com) |
ETH_RPC_URL | No | Server-side RPC for signature verification and ENS resolution (defaults to a public RPC) |
NEXT_PUBLIC_DOMAIN | No | Explicit domain for SIWE verification when behind a reverse proxy |
How It Works
The app follows a standard SIWE authentication flow:
- User connects their wallet (MetaMask, WalletConnect, etc.)
- Frontend requests a nonce from the server
- Frontend constructs a EIP-4361 message and asks the wallet to sign it
- Frontend sends the message + signature to the server
- Server verifies the signature, checks the nonce, and creates an encrypted session
- User is authenticated — their Ethereum address is the identity
The next two pages walk through how this is implemented:
- Frontend — wagmi setup, the authentication context, and the sign-in flow
- Backend — API routes for nonce, verification, sessions, and how
verify()works under the hood
Stack
| Layer | Library |
|---|---|
| SIWE | @signinwithethereum/siwe v4 |
| Framework | Next.js (App Router) |
| Wallet hooks | wagmi + viem |
| Wallet connectors | Injected (MetaMask, etc.) + WalletConnect |
| Sessions | iron-session |
Getting Help
- Documentation: TypeScript Library
- Issues: GitHub
- Integrations: Auth0, Discourse