TailwindCSS, DaisyUI, Sign-in with Ethereum, NextAuth, wagmi.sh, DrizzleORM and RainbowKit Wallet Integration
Vanilla hardhat example, with simple ERC20 token, and extended to sync the ABI to the client/app/_abi/ directory on compile:
cd hardhat
npx hardhat compile
We're essentailly using SIWE as an Identity Provider, wrapping standard SIWE functionality in the NextAuth suite. This enables us to verify a user and establish a session/JWT token for secure user operations in an off-chain application. Super useful for gaming products or where you might want to token gate a more Web 2.0 style site.
The site is designed to use the built in NextJS and NextAuth SSR flows and validation, allowing you to protect pages and content by skimming the token from cookies to ensure they are logged in. This can be extended to include balance checks, tokens held, etc.
graph
0[Connect Wallet] --> 1[RainbowKit UI]
1 --> 2[RainbowKit SIWE Library]
2 --> 3[User SIWE Message Presented]
3 -- User Declines --> 5[Connection Rejected]
3 -- User Signs--> 4[NextAuth Session Flow]
4 --> 6[Authorize called & SIWE message validated]
6 -- Fails --> 7[Connection Rejected]
6 -- Passes --> 8[JWT & Session Generated]
8 -- Site operations --> 9[NextJS Server-side Validation of Session Token]
8 -- Wallet changes --> 10[Session Dropped]
client (whole app)
- app (NextJS 14.x App Router Structure)
- _components (common use react components)
- _serveractions (server-sde server actions (API-esque))
- _web3 (providers & configs for wagmi, tanstack, rainbow, nextauth)
- api (routes to APIs - only used for nextauth in the boilerplate)
- (routes) (a logical grouping via directory for routes)
- db (DrizzleORM databse definition, operations, and migrations)
- operations (ORM-tied CRUD functions)
- output (migration scripts generated from npm run generate)
- schema (table defintions)
- types (typescript definitions in a single place)
This is designed for Vercel Hosting, with Vercel PostgresDB. You can subsitute the PostgresDB layer to local instances with ease or just rip out the drizzle-ORM and use your own model.
The diagram looks nuts but essentially...
- Clone the repo
- Stand it up on Vercel and attach a PostgresDB database
- Run the client/db/output migration SQL against your db
- Update the environment variables as needed in the App Settings
- Configure the build based on a branch (i.e. main but develop in dev and PR to push changes to Vercel, etc)
- Clone the repo
- Copy the .env.sample to a new .env
- Fill in everything
- Get your Vercel PostgresDB details
- or, use a local instance if you have one (this is better so that vercel and local aren't sharing a schema/data)
- Run the client/db/output migration SQL against your db
- cd client
- npm install
- npm run dev
- Configure the build based on a branch (i.e. main but develop in dev and PR to push changes to Vercel, etc)
graph TB
0[Clone Repo] -- dev only--> 3c[Copy .env.example to new .env file]
3c --> 3
1[Create Vercel Account targeting repo as Source] -- copy .env.example when defining Env Variables in Vercel--> 2[Standup a Vercel PostgresDB]
2b[Use a local PostgresSQL Instance] -- dev --> 3[Update client/.env locally with database details]
2[Standup Vercel PostgresDB] -- dev --> 3[Update client/.env locally with database details]
2[Standup Vercel PostgresDB] -- test/prod--> 4[Connect to Vercel App Auto Add ENV for DB]
3 --> 5[Run database migrations in client/db/output]
4 --> 5[Run database migrations in client/db/output]
5 --> 6[Add WalletConnect & Alchemy API keys to .env]
6 --> 7[Add a NextAuth Secret - suggest using `openssl rand -base64 32`]
7 --> 8[cd ./client]
8 --> 9[npm install]
9 -- dev --> 10[npm run dev]
9 -- test / prod --> 11[Create Pipelines in Vercel]
11 --> 12[Trigger Build]