Next.js dashboard + Discord bot: custodial Injective wallets (keys encrypted with ENCRYPTION_KEY, metadata in Supabase), on-chain INJ tips, and guild project points (capped ledger in Postgres).
| Piece | Tech |
|---|---|
| Web | Next.js 14, Tailwind, pnpm |
| Database | Supabase (Postgres) via @supabase/supabase-js + service role on server/bot |
| Chain | Injective SDK (testnet / mainnet via INJECTIVE_NETWORK) |
| Bot | discord.js + shared lib/ |
- Supabase gives you hosted Postgres, dashboard, backups, and optional Auth/Realtime without an ORM.
- When you want Prisma: copy
DATABASE_URLfrom Supabase (Settings → Database → URI), runnpx prisma db pull(or introspect), then replace direct Supabase calls with Prisma - same tables, no vendor lock-in for the schema.
- Node.js LTS, pnpm 9 (
corepack enable) - A Supabase project
- Discord app + bot - see docs/DISCORD_SETUP.md (step-by-step: Client ID, bot token, invite URL,
DISCORD_GUILD_ID)
- Create a project → SQL Editor → paste and run
supabase/migrations/001_initial.sql. - Settings → API: copy Project URL and service_role key into
.env(see below).
cp .env.example .envDiscord: full walkthrough → docs/DISCORD_SETUP.md.
Fill at minimum:
NEXT_PUBLIC_SUPABASE_URL,SUPABASE_SERVICE_ROLE_KEYENCRYPTION_KEY(64 hex chars)DISCORD_BOT_TOKEN,DISCORD_CLIENT_ID,DISCORD_CLIENT_SECRET(OAuth2 secret from the portal - required for real Log in with Discord on the site)NEXTAUTH_SECRET,NEXTAUTH_URL(e.g.http://localhost:3000) - see docs/DISCORD_SETUP.md §7NEXT_PUBLIC_DISCORD_CLIENT_ID- same value asDISCORD_CLIENT_ID; enables the landing page Add to Discord inviteDISCORD_GUILD_ID(recommended for instant slash commands - see Discord guide §4)INJECTIVE_NETWORK=testnetuntil you are ready for mainnet
pnpm install
pnpm dev:all- Web: http://localhost:3000
- Health: http://localhost:3000/api/health (checks Supabase connectivity)
- Marketing page:
/landing- public hero (same content as logged-out home). Logo in the app sidebar/header links here. - In-app routes (query):
/?view=activity→ Activity;/?view=console→ Owner console;/?view=help/settings; noview→ Dashboard. SetNEXT_PUBLIC_APP_URLto the origin only (no/consolepath) unless you intend that screen on every open.
| Command | Description |
|---|---|
pnpm dev |
Next.js only |
pnpm dev:bot |
Bot only (watch) |
pnpm dev:all |
Web + bot |
pnpm build / pnpm start |
Production web |
pnpm start:bot |
Bot (no watch) |
- Invite bot with applications.commands + bot scopes.
/register- creates Injective wallet, stores encrypted private key inusers.- Fund the shown address with INJ on the configured network (testnet faucet for demos).
/balance- reads on-chain INJ via REST./tip @user amount- MsgSend on Injective; row intips./points- guild owner creates capped currencies; mint/send/balance subcommands.
lib/ # Shared: Supabase admin client, crypto, Injective helpers, db accessors
bot/ # Discord entry (tsx)
src/app/ # Next.js App Router
supabase/migrations/ # SQL to apply in Supabase
- Never expose
SUPABASE_SERVICE_ROLE_KEYorENCRYPTION_KEYto the client. - Custodial keys are high risk; use KMS/HSM and key rotation for anything beyond demos.
- Add RLS +
anonpolicies before usingNEXT_PUBLIC_SUPABASE_ANON_KEYin the browser.
- Supabase → Settings → Database → copy connection string (URI).
DATABASE_URL="postgresql://..." npx prisma db pull- Replace
lib/db/*Supabase calls with Prisma queries incrementally.