Mysten Incubation
Features

Web Dashboard

A bundled-in-CLI control-plane and Sui explorer web UI with live data over an in-process GraphQL server.

The dashboard() plugin serves a web UI — a control plane plus a Sui explorer — backed by an in-process GraphQL server reading the stack's live projection. It's a normal stack member: add it like any other plugin and the router fronts it under a stack-scoped hostname.

devstack.config.ts
import { defineDevstack, sui, account, postgres, dashboard } from '@mysten-incubation/devstack';

export default defineDevstack({
	members: [sui(), account('alice'), account('bob'), postgres(), dashboard()],
	stackName: 'main',
});

Opening the UI

Like the wallet and other service endpoints, the dashboard is reached through a stable, stack-scoped router hostname rather than its raw process port. The dashboard route uses the api role on its own entrypoint port (9810), so the default-stack URL is:

http://api.<app>.localhost:9810

Non-default stacks insert the stack segment: http://api.<stack>.<app>.localhost:9810. The plugin also resolves to a direct loopback url (the broker-allocated port) for tooling that bypasses the router, but the router-fronted hostname above is the one to open in a browser — it's what the in-process CORS allowlist is keyed to.

What you can see and do

The dashboard is read-mostly, with a small set of guarded controls:

  • Sui explorer — addresses, objects, packages, and transactions, with resolve-first search.
  • Walrus & Seal panels — service status and live data for the storage and key-server plugins.
  • Postgres stats — per-instance database stats (when a postgres() member is in the stack).
  • Logs & traces — the cross-service log store and trace spans.
  • Snapshot & restore progress — capture and restore narrated live.
  • Controls — restart, shutdown, and advance-clock, each behind a confirmation.
  • Faucet fund — a one-click fund action: SUI funds a fixed amount; WAL and DEEP take an editable amount. Funding reuses the same registered in-process funding strategies the boot-time account-funding pass dispatches through. See Faucet and Funding Strategies.

Options

All fields are optional.

  • port — preferred loopback port for the dashboard's HTTP/GraphQL server. The port broker forward-scans if it's busy.
  • bindAddress — the NIC the server binds, default '0.0.0.0'. The router runs in Docker and must reach this host process through the host-gateway address on native Linux, so a 127.0.0.1-only listener would be unreachable (and 502 through the router). The public URL stays router-fronted and stack-scoped regardless.
  • allowedOrigins — extra CORS origins merged onto the stack-scoped allowlist, for headless test runners and custom dev hosts. This deliberately does not auto-allow a bare *.localhost form: that is not stack-scoped, so a sibling stack could otherwise drive the destructive control-plane mutations cross-origin.

The queryable cross-service log store the dashboard reads is owned by the supervisor, not this plugin. Tune its retention with environment variables:

  • DEVSTACK_DASHBOARD_LOG_CAPACITY — per-service record cap, default 2000.
  • DEVSTACK_DASHBOARD_LOG_MAX_SERVICES — distinct-service ring cap, default 256.

Security

The dashboard's destructive control-plane mutations (restart, shutdown, advance-clock, fund) are guarded by a stack-scoped CORS allowlist owned by the dashboard server itself. The allowlist covers this stack's own router-fronted origin, the direct loopback origins, and any caller-supplied allowedOrigins — but not a bare *.localhost. A sibling stack's origin therefore cannot drive these mutations cross-origin.

On this page