Customising the frontend¶
The explorer frontend is a React 19 + Vite + Tailwind app. Layout in packages/frontend/src/:
src/
├── App.tsx
├── main.tsx
├── api.ts centralised API client
├── utils.ts
├── layout/ header, footer, shell
├── pages/ one per route
├── components/ reusable pieces
├── hooks/ custom hooks
└── index.css Tailwind entry
Design system¶
The default theme uses a cyberpunk palette. Tailwind config tokens (tailwind.config.js):
navy-900#0a0e27— page backgroundnavy-800#10152e— cardscyan-400#00d4ff— primary accent (links, borders, glows)purple-500#7b5cff— secondary accent (gradients)pink-400#ff5cf0— tertiary accent- Mono font: JetBrains Mono
- Sans: Inter
Badges used throughout:
<PrivacyBadge kind="blsct" />— shown on confidential outputs.<PrivacyBadge kind="transparent" />— shown on value-visible outputs.<OutputTypeBadge>— coinbase / coinstake / standard.
Adding a page¶
- Create
packages/frontend/src/pages/MyPage.tsx. - Add a route in
App.tsxunder the existingRoutes. - Add a link in
layout/Header.tsxor wherever appropriate. - Fetch data using the
api.tshelper for auth + base-URL handling.
Example:
// src/pages/MyPage.tsx
import { useEffect, useState } from 'react';
import { GlowCard, Loader } from '../components';
import { api } from '../api';
export default function MyPage() {
const [data, setData] = useState<any>(null);
useEffect(() => {
api.get('/api/stats').then(setData);
}, []);
if (!data) return <Loader />;
return (
<GlowCard title="Network stats">
<pre>{JSON.stringify(data, null, 2)}</pre>
</GlowCard>
);
}
Adding an API endpoint¶
- Create
packages/api/src/routes/myroute.tsexporting a Fastify plugin. - Add the route declaration with
fastify.get(…, { schema: { response: {…} } })— the Swagger doc generates from this schema. - Register it in
packages/api/src/index.ts.
// packages/api/src/routes/myroute.ts
import { FastifyPluginAsync } from 'fastify';
const myroute: FastifyPluginAsync = async (f) => {
f.get('/myroute', {
schema: {
response: {
200: { type: 'object', properties: { hello: { type: 'string' } } },
},
},
}, async () => ({ hello: 'world' }));
};
export default myroute;
// packages/api/src/index.ts
import myroute from './routes/myroute.js';
// ...
await fastify.register(myroute, { prefix: '/api' });
Replacing the palette¶
Edit tailwind.config.js and the tokens cascade through every component:
// tailwind.config.js
export default {
theme: {
extend: {
colors: {
navy: { 900: '#0a0e27', 800: '#10152e' },
accent: { 400: '#00d4ff' },
},
},
},
};
Swap the hex values for your branding. For a light-mode-first design, also set @layer base rules in index.css to flip the default.
Localisation¶
Not implemented by default. To add i18n, introduce react-i18next, wrap text in t('…') calls, and ship per-locale JSON bundles from packages/frontend/src/locales/. The API is already locale-agnostic (returns ISO timestamps and numeric values; formatting happens in the frontend).