The Chaoslab user-facing application — React + TypeScript + Vite, talking to the real
chaoslab-backend API.
Status: Phases 1–4 — architecture/product foundation, design system & application shell, authentication & onboarding, and wallet & home. Routing, auth, the typed API client, state management, CI, design tokens, reusable UI components, i18n, the responsive sidebar/bottom-nav shell, real login/register/KYC-status screens, and a real balance/recent-activity Home and Wallet are in place; payments, vaults, and activity history still ship in later phases — those routes still render a Phase 1 placeholder inside the Phase 2 shell. See
docs/ARCHITECTURE.mdfor the full architecture writeup.
chaoslab-App(this repo) — the user-facing application.chaoslab-backend— the financial/API engine (transactions, fees, KYC, vaults, Stellar SEP integrations). This app is a client of it and never becomes authoritative for financial state.chaoslab-frontend— developer documentation site. Unrelated codebase, not touched by this app.
- Node.js 24.x
- A running
chaoslab-backendinstance (for anything beyond routing/UI — see that repo's own README for setup)
npm install(npm ci in CI — see .npmrc for why legacy-peer-deps is set: openapi-typescript's
peer range hasn't caught up to the TypeScript version this project uses yet.)
cp .env.example .env.localThen point VITE_API_BASE_URL / VITE_WS_URL at your chaoslab-backend instance. The
app validates these at startup (src/config/env.ts) and fails fast — with a clear
error, not a silent misconfiguration — if they're missing or malformed.
npm run devnpm run test # vitest run
npm run test:watch # vitest, watch mode
npm run test:coverage # with coverage reportTests never hit a real network — MSW (src/test/mocks/) intercepts every request.
npm run lint # eslint .
npm run lint:fix
npm run format # prettier --write .
npm run format:check # prettier --check .
npm run typecheck # tsc -b --noEmitnpm run buildFeature-oriented structure under src/:
src/
app/ bootstrap: App.tsx, RootLayout, ErrorBoundary, QueryClient
api/ typed backend API client, error normalization, session/refresh
routes/ router, route guards (ProtectedRoute/PublicOnlyRoute), 404
features/ auth, home, wallet, payments, vaults, activity, notifications,
settings, plus domain modules shared across routes: account/
(balance), transactions/ (recent-activity list)
components/
ui/ design-system primitives (Button, Dialog, StatusBadge, ...)
shell/ AppShell, Sidebar, BottomNav, Header, SkipLink
styles/ design tokens (tokens.css) and breakpoints (breakpoints.ts)
i18n/ typed message catalog, I18nProvider, useTranslation()
hooks/ shared hooks
lib/ idempotency, request correlation, token storage, WebSocket client,
cx(), formatMoney()
stores/ Zustand client/UI state (never server data — see below)
types/ generated API types + domain types (e.g. transaction status)
config/ validated environment config
test/ MSW mocks, test utilities, setup
The API client is typed directly against chaoslab-backend's real OpenAPI contract
(openapi/openapi.json, snapshotted from that repo's own schema-driven generator — not
hand-written). Server state (balances, transactions, KYC, ...) lives in TanStack Query;
client/UI state (theme, nav) lives in Zustand — these are never mixed. Every reusable
component in src/components/ui/ is token-driven (src/styles/tokens.css) and
string-driven (src/i18n/) — no hardcoded colors, spacing, or user-facing text.
Full detail — API integration, auth/session lifecycle, state management, financial
safety primitives (idempotency keys, transaction status), the WebSocket foundation,
the design system, i18n, the application shell, environment config, testing
conventions, CI, and security principles — is in
docs/ARCHITECTURE.md.