Admin and monitoring dashboard for the Areal Finance protocol. SvelteKit, TypeScript, @sveltejs/adapter-static. Serves the five on-chain programs:
vault_swap)Plus an E2E scenario runner at /dev/e2e that reproduces full end-to-end flows (persists state across pages, handles idempotent initialisation).
Production: https://panel.areal.finance
npm install
npm run dev # http://localhost:5173
npm run build # → build/ (static, SPA fallback)
Static assets, so any static host works. Included script uses rsync:
cp .env.example .env
# edit DEPLOY_HOST, DEPLOY_PATH
bash scripts/deploy.sh
Nginx snippet for self-hosting:
server {
listen 80;
server_name panel.example.com;
root /var/www/panel.example.com;
index index.html;
location / {
try_files $uri $uri.html $uri/ /index.html;
}
location /_app {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
The dashboard ships frozen for Layer 10 — alongside the Layer 9 Nexus surfaces it already exposed, the System Overview surface (Substep 9) and the master E2E artifact viewer landed.
The / route renders 8 sections in a single read-only operator dashboard:
BotHeartbeats).BOT_STALE_THRESHOLD_MS,
crank wallet below LOW_SOL_THRESHOLD_LAMPORTS).Cards refresh on a 1 s tick (PUBLIC_DASHBOARD_CARD_INTERVAL_MS); the events
ticker refreshes at 2 s.
A master E2E artifact viewer lives at /dev/master. The static SPA cannot
spawn tsx, so the viewer is a paste-or-upload of e2e-runner-*.json files
from the data/ directory of a deploy host. Operators copy the artifact into
the textarea or upload it; the viewer renders the same shape the runner
emits server-side.
| Variable | Purpose |
|---|---|
PUBLIC_DASHBOARD_BOT_STALE_THRESHOLD_MS |
Time-without-heartbeat before a bot row marks stale |
PUBLIC_DASHBOARD_LOW_SOL_THRESHOLD_LAMPORTS |
Crank wallet balance threshold for the Alerts card |
PUBLIC_DASHBOARD_CARD_INTERVAL_MS |
Card-tick cadence (default 1000) |
See .env.example for the full default set.
Before tagging a Layer 9 dashboard release, confirm the following env-driven constants are populated for the target deployment:
| Variable | Purpose | Required by |
|---|---|---|
PUBLIC_USDC_MINT |
USDC mint addr for Nexus deposit / withdraw flows + convert path | /nexus/, /layer8/convert/ |
PUBLIC_RWT_USDC_POOL |
Master RWT/USDC pool PDA — drives the convert-to-rwt route resolver | /layer8/convert/ |
PUBLIC_NEXUS_MANAGER_BOT_URL |
Heartbeat endpoint for the nexus-manager bot panel (4th panel on /bots/) |
/bots/ |
The static build inlines these at compile time; changing them requires a rebuild + redeploy.
Mainnet policy (Substep 15 sec L-1 + SD-20): operator MUST override
PUBLIC_USDC_MINTfor mainnet deployments. Do not ship a build where this var resolves to the SD-20 devnet test-mint fallback — dashboard would silently route convert/deposit flows to a worthless mint. Same applies toPUBLIC_RWT_USDC_POOL: a canonical-PDA auto-derive is OK for devnet (per SD-21) but mainnet must pin the deployed master-pool address explicitly. CI release pipelines should assertprocess.env.NETWORK !== 'mainnet' || PUBLIC_USDC_MINT !== <devnet>before publishing.
src/lib/idl/*.json (copied from ArealFinance/contracts).@arlex/client for tx building and account decoding.