Admin dashboard for managing ENS name categories on Grails.
Cat Admin is an internal tool for managing "categories" (also known as "clubs") — curated collections of ENS names grouped by shared characteristics like digit count, patterns, or themes.
Features:
- Create new categories
- Add/remove ENS names to categories (bulk operations supported)
- View category membership details
- Look up any ENS name and see its category memberships
- Full audit log of all changes
- Next.js 15 with App Router
- React 19 with TanStack Query
- Tailwind CSS v4
- PostgreSQL (direct connection to Grails database)
- SIWE (Sign-In With Ethereum) authentication
- RainbowKit + Wagmi for wallet connection
- Node.js 18+
- Access to the Grails PostgreSQL database
- An authorized admin wallet address
Copy env.example to .env.local and fill in:
# Database connection (get from Railway)
DATABASE_URL=postgresql://grails_cat_admin:<password>@<host>:<port>/railway
# Grails API for authentication
GRAILS_API_URL=https://grails-api.ethid.org/api/v1
# Comma-separated list of admin wallet addresses
ADMIN_ADDRESSES=0x123...,0x456...
# WalletConnect project ID (required)
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your_project_idnpm install
npm run devOpen http://localhost:3000 and connect your wallet.
- Connect your Ethereum wallet
- Sign a message to prove ownership
- Your address is checked against
ADMIN_ADDRESSES - If authorized, you get a session cookie
Only wallets in the ADMIN_ADDRESSES list can access the admin panel.
This app is designed to be public-facing and open source. Security measures include:
- httpOnly cookies for session tokens
- SIWE authentication (cryptographic wallet verification)
- Rate limiting on all API endpoints
- CSP headers and security headers
- Input validation and length limits
- Audit logging of all database changes
- Parameterized SQL queries
The app connects directly to the Grails PostgreSQL database using a restricted user (grails_cat_admin) with minimal permissions:
clubstable: SELECT, INSERT, UPDATEclub_membershipstable: SELECT, INSERT, DELETEens_namestable: SELECT onlyclubs_audit_logtable: SELECT only
All changes are automatically logged via database triggers.
MIT