Frontend overview
The frontend is a Next.js 15 app with React 19 and Tailwind. It has one special job that most websites don't: it holds your private key and signs things in the browser.
The stack
App Router framework. Each page is a folder with a page.tsx.
Strict types everywhere; pages are client components.
Utility-first styling with a shadcn-style dark green theme.
Tiny client store for wallet + auth state (persisted to localStorage).
Fetches + polls server data (balances, order book, blocks) every few seconds.
ed25519 + SHA-3/SHA-256 in pure TypeScript. The crypto brain.
The key insight: self-custody
The private key never touches the server. It's generated in the browser and stored in localStorage. Every mutating action — login, sending coins — is signed client-side with that key. This is the "your keys, your coins" model.
Project structure
1app/2├── layout.tsx # root layout: providers, dark theme, fonts3├── globals.css # Tailwind + CSS variables (dark green theme)4├── (marketing)/page.tsx # landing page /5├── (auth)/signin/page.tsx # create/import wallet + sign in6├── (dashboard)/7│ ├── layout.tsx # sidebar + top bar shell8│ ├── dashboard/page.tsx # balances, chain height, faucet, recent txs9│ ├── wallet/page.tsx # send XCH (client-side signing)10│ ├── trade/page.tsx # order book + place orders11│ ├── explorer/page.tsx # block explorer + search12│ ├── staking/page.tsx # stake/unstake, validators13│ ├── multisig/page.tsx # N-of-M wallets14│ └── admin/page.tsx # chain metrics + charts15├── api/health/route.ts # edge function proxying node /health16components/ # layout + UI kit + feature components17lib/18├── api.ts # fetch wrapper + typed endpoints19├── crypto-utils.ts # THE mirror of the node's crypto20└── utils.ts # formatting helpers (shortAddress, etc.)21store/22├── wallet.ts # zustand: wallet + secret key (localStorage)23└── auth.ts # zustand: JWT tokens (localStorage)
Why parentheses around (dashboard)?
(dashboard), (auth) and (marketing) are route groups — they organise code without adding to the URL. app/(dashboard)/dashboard/page.tsx is served at /dashboard. The group also lets the dashboard pages share one layout (the sidebar shell).
Client vs server components
- The root
layout.tsxand landing page are server components (no interactivity needed). - Every dashboard/auth page is
"use client"— they need hooks, state, and crypto. - The only real "server" logic is
app/api/health/route.ts, an edge function that proxies the node's health endpoint.
Where the real work is documented
- Frontend → Pages walkthrough — every screen and what it does.
- Frontend → State & data fetching — Zustand, React Query, the API client.
- Frontend → Client-side crypto — the code that mirrors the Rust node.