Skip to content

Latest commit

 

History

477 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mux Dashboard

The developer console for Mux Protocol — manage API keys, track wallet creation, and monitor account activity on Stellar.

Mux Dashboard is the interface for developers building on Mux. It provides visibility into the Invisible Wallet system while abstracting away all blockchain complexity.


Overview

Mux Dashboard allows developers to:

  • Create and manage API keys for SDK access
  • Track Stellar account creation on Testnet and Mainnet
  • Monitor wallet activity and balances
  • View usage metrics such as transaction counts and account status
  • Configure basic project-level settings

End users do not interact with this dashboard — it is purely for developers integrating Mux into their applications.


Core Principles

  • Developer-first UX: designed for fast onboarding and management
  • Invisible Wallet visibility: see accounts and activity without exposing keys or blockchain jargon
  • Safe and clear: all actions are explicit; sensitive operations are handled by the backend

Key Features

  • API Key Management: generate, rotate, and revoke keys
  • Wallet/Account Tracking: monitor accounts created via the SDK
  • Activity Metrics: view transaction volumes and status
  • Requests over time: visualize API request traffic trends
  • Wallet creation analytics: monitor daily wallet creation volume
  • Network Switching: testnet vs mainnet tracking
  • Usage Monitoring: see platform-sponsored actions and account health

Getting Started

Prerequisites

  • Node.js >= 18
  • Access to Mux Backend API

Installation

git clone https://github.com/mux-labs/mux-frontend.git
cd mux-frontend
pnpm install
pnpm run dev

Environment variables

All variables are optional in local development — sensible mock/default behavior kicks in when they're unset (see src/lib/env.ts for the validation schema). Copy .env.example to .env.local and fill in real values for testnet/mainnet-connected work.

Variable Required Default Description
NEXT_PUBLIC_API_URL No (none) Base URL for the Mux backend API used by client-side requests, e.g. https://api.muxprotocol.com for mainnet or a testnet-specific URL. When unset, API routes such as /api/auth/login and /api/wallets fall back to an in-repo mock so pnpm run dev and CI work without a live backend — but only when NODE_ENV is not production (see the production note below). Set this in new deploys; use the aliases below only for backward compatibility. An alias set to an empty string (e.g. NEXT_PUBLIC_API_URL=) is treated as unset and the next alias in the chain is tried (see API_URL_CANDIDATES in src/lib/api/config.ts).
NEXT_PUBLIC_MUX_API_URL No https://api.muxprotocol.com Legacy alias for the API base URL, checked after NEXT_PUBLIC_API_URL (see src/lib/api/config.ts). Kept for backward compatibility with older deploys.
NEXT_PUBLIC_API_BASE No (none) Third fallback in the API base URL resolution chain, checked after the two vars above.
NEXT_PUBLIC_APP_URL No http://localhost:3000 Public-facing URL of this application, used for building absolute links (e.g. callback URLs).
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID No (none) WalletConnect project ID, needed only if wallet-connect based flows are enabled.
MUX_API_KEY No (none) Server-only Mux Protocol API key. Used exclusively by Next.js API routes (src/app/api/**) to authenticate upstream requests to the backend. Never exposed to the browser — do not prefix it with NEXT_PUBLIC_.
MUX_API_SECRET No (none) Server-only Mux Protocol API secret, paired with MUX_API_KEY and sent alongside it on every upstream request.
MUX_BACKEND_URL No (none) Server-only base URL of mux-backend. Used by /api/spending-limits to proxy GET/PUT (spending limits and the real todayUsage). When unset the route returns 503 rather than fabricating usage — the frontend never persists spending limits itself (see getBackendApiBaseUrl() in src/lib/api/config.ts).

There is no client-visible Mux API key. Project credentials only ever live in MUX_API_KEY/MUX_API_SECRET and are attached server-side, in Next.js API routes, to requests made to the backend — the browser talks only to this app's own same-origin /api/* routes and never holds a Mux credential.

Testnet vs. mainnet: which backend this frontend talks to is driven entirely by NEXT_PUBLIC_API_URL (or its aliases above) — point it at a testnet-configured Mux backend for staging/testnet work, and at the production backend for mainnet. Separately, the dashboard has an in-app Testnet/Mainnet switcher (NetworkContext, in the top nav) that scopes which network's wallets are fetched within that backend — useWallets sends it as a ?network= query param on /api/wallets, so wallets are never double-filtered by both a server-side scope and an independent client-side one. The env var picks the backend; the in-app switcher picks the network within it. The CI workflow (.github/workflows/ci.yml) sets a placeholder NEXT_PUBLIC_API_URL only so next build can run without secrets; it does not reflect a real environment.

Production defaults: when NODE_ENV=production, unset vars with a documented default (e.g. NEXT_PUBLIC_MUX_API_URLhttps://api.muxprotocol.com) are applied automatically by getEnv(), so a production deploy with a forgotten env var talks to the real backend instead of silently serving mock data. Local dev and tests are unaffected — leaving everything unset there still uses the in-repo mocks.

NODE_ENV (standard Next.js variable, not defined in .env.example) also gates some behavior: analytics/tracking hooks (useAnalytics.ts, useAnalyticsMetrics.ts, useAnalyticsTracking.ts, recoveryAnalyticsTracking.ts, spendingLimitsTracking.ts) log to the console outside of production; src/lib/env.ts throws on missing required vars only when NODE_ENV=production; and the mock/demo fallbacks in API routes and data hooks (src/lib/api/runtimeMode.ts, useNotifications.ts, useRecovery.ts) are disabled when NODE_ENV=production so mock data is never served in a production build.

Production never silently falls back to mock data. /api/auth/login, /api/auth/refresh, /api/wallets, /api/wallets/[id], GET /api/transactions, /api/notifications, /api/overview, and /api/api-keys (GET/POST/PATCH) all fall back to in-repo mock data (fake wallets, dashboard stats, API keys, a hardcoded mock bearer/refresh token) when no backend URL is configured — that's what makes pnpm run dev, CI, and the /demo routes work with no live backend. In a production build (NODE_ENV=production) that fallback is disabled: if NEXT_PUBLIC_API_URL (or its aliases) is missing, those routes return 503 backend_unavailable instead of serving fabricated wallets/analytics/ API keys or accepting the mock token as valid auth. See isMockFallbackAllowed() in src/lib/api/config.ts.

APIKeyModal's standalone (no-onCreateKey) key generator follows the same rule client-side, and the wallets sidebar prefetch (src/lib/walletsPrefetchCache.ts) attaches the caller's session token and keys its cache entry by it, so a prefetch from one session is never served to a different session that signs in afterward on the same device.

See docs/frontend-env-vars.md for the full reference, including which file reads each variable and a manual verification checklist.

Auth and API client behavior

  • src/lib/api.js adds request header support with x-request-id and automatic session refresh on 401
  • src/utils/fetchWithAuth.ts (used by useWallets / useWallet / the Send flow) mirrors that behaviour: on a 401 it calls POST /api/auth/refresh once and retries the original request with the rotated token, only clearing the session and redirecting to /login if the refresh itself fails (#630)
  • src/lib/session.js persists auth state and clears stale sessions gracefully
  • src/hooks/useSessionGuard.ts is the documented client-side stale-session guard; AuthGuard (wrapped around every real /dashboard/* route by DashboardLayout) delegates its redirect to it, so a middleware-cookie pass with a missing in-memory session still bounces to /login (#624)
  • src/hooks/useWallets.ts adds a wallet query hook that loads wallets from /api/wallets
  • src/app/api/auth/refresh/route.ts, /api/wallets/route.ts, and /api/wallets/[id]/route.ts simulate auth-protected backend behavior for local testing
  • src/app/api/requests/today/route.ts and src/app/api/transactions/route.ts (list via GET, the wallet "Send" flow via POST) follow the same pattern as the routes above: they proxy to NEXT_PUBLIC_API_URL (or its aliases) when configured, and fall back to mock data / an in-memory mock transaction otherwise. GET /api/transactions filters the mock list by ?address= (sender or recipient) and ?network=, and returns 503 backend_unavailable in a production build with no backend rather than serving mock history
  • The analytics CSV / JSON export (/dashboard/analytics) is backed by real, date-scoped transaction records via useAnalyticsTransactions (GET /analytics/transactions-list), not synthetic objects derived from the aggregated top-assets table. Same production/mock split: in a production build with no backend it surfaces an error instead of silently exporting mock rows. See src/docs/Analytics_Data_Sources.md.
  • Receive-address QR codes (src/components/wallet/QrCode.tsx) and the QR download action (src/components/wallet/QRDownloadButton.tsx) encode the real wallet address client-side via the qrcode package; no backend call is involved

Server-verified sessions (#621–#628). When NEXT_PUBLIC_API_URL is set:

  • POST /api/auth/login proxies to {backend}/auth/login and writes the backend-issued session token to an HttpOnly, SameSite=Lax, Secure (in production) mux_auth_token cookie set from the route's Set-Cookie response — never document.cookie (#627).
  • POST /api/auth/refresh proxies to {backend}/auth/refresh, forwarding the caller's Authorization header / session cookie, and rotates the mux_auth_token cookie from the response (#626). Without a backend it only mints the mock token outside production.
  • The Next.js middleware verifies the token against GET {backend}/auth/session on every /dashboard request — the client-set mux_auth_session marker cookie is only trusted in mock mode (no backend), and now carries ; Secure on HTTPS.
  • Any bearer-token block in the login response is persisted to sessionStorage (never localStorage) via src/lib/session.js so src/lib/api.js and src/utils/fetchWithAuth.ts can attach Authorization headers and refresh on 401 (#628, #630). Both read the same mux-auth-session key, so useWallets sends the token AuthContext actually stored (#629).
  • signOut() calls POST /api/auth/logout to clear the HttpOnly cookie and the stored bearer session.

A production build with no backend refuses mock sign-in / refresh with 503 backend_unavailable (#625). See docs/auth-local-setup.md.

No silent mock success in production. API routes that fall back to in-repo mock data (/api/auth/login, /api/notifications, …) do so only outside production. A production build with no backend configured returns 503 instead of mock data, so a misconfiguration is visible rather than masked. The shared rule lives in src/lib/api/runtimeMode.ts.

Smoke tests

Run unit/component smoke tests with:

pnpm test

Run Playwright end-to-end smoke tests (login, wallet monitoring, and wallet send/receive, desktop and mobile viewports) with:

pnpm exec playwright install --with-deps chromium
pnpm run test:e2e

CI runs this same suite on every push and PR (the e2e-tests job in .github/workflows/ci.yml), alongside typecheck, Vitest, and build.

See tests/e2e/README.md for what's covered and a manual verification checklist.

Documentation

Root-level .md files are kept to just this README.md. Deeper reference docs (env vars, auth setup, analytics data sources, CI typecheck/build verification, etc.) live under docs/ so they stay easy to find and don't clutter the repo root as features evolve.


Design Philosophy

  • The dashboard is developer-focused, not end-user focused
  • Backend handles wallets and transactions; the dashboard is a monitoring and management tool
  • Makes it simple to observe, control, and integrate Mux-powered wallets

Roadmap

  • Per-key usage analytics
  • Webhooks and notifications for SDK events
  • Team access management — basic admin/developer member management is in at /dashboard/settings/team (/api/team); see docs/team-access-and-audit-log.md
  • Audit logs for all wallet and API activity/api/activity now follows the same production/mock split as the rest of the app instead of always serving mock data; see docs/team-access-and-audit-log.md

About

Web interface for Mux — manage accounts, automate transactions, and interact with dApps.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages