# mycellium-ui

Cross-platform desktop GUI for [Mycelium](https://github.com/threefoldtech/mycelium) — Threefold's end-to-end encrypted IPv6 overlay network.

The app embeds the official `mycelium` binary as a Tauri sidecar and pilots it through its HTTP API on a loopback ephemeral port. Root privileges (required to create the TUN interface) are obtained via `pkexec`.

## Status

v1, Linux-only. Implements the full `docs/api.yaml` surface of mycelium v0.6.1: admin, peers (CRUD), routes (selected/fallback/queried), messages (send/receive/reply/status), topics (default + whitelist + sources + forward), pubkey lookup.

## Architecture

```
┌──────────────────────────────────────────────────────────────┐
│  WebView (Vue 3 + TS + Tailwind + radix-vue + Pinia)         │
│  Status / Peers / Routes / Messages / Topics / Settings      │
└────────────────┬─────────────────────────────────────────────┘
                 │  invoke() / Tauri events
┌────────────────┴─────────────────────────────────────────────┐
│  Tauri core (Rust, tokio + reqwest)                          │
│  • sidecar.rs — supervises mycelium via pkexec               │
│  • api/* — typed REST client                                 │
│  • poller.rs — emits peers://, stats://, routes://, messages://incoming │
└────────────────┬─────────────────────────────────────────────┘
                 │  HTTP loopback :ephemeral
┌────────────────┴─────────────────────────────────────────────┐
│  mycelium daemon (sidecar binary, runs as root via pkexec)   │
│  TUN0 ◄─► overlay network                                    │
└──────────────────────────────────────────────────────────────┘
```

There is no Unix socket / named pipe IPC — the daemon's own HTTP API is the integration point.

## Prerequisites (Debian / Ubuntu)

```bash
sudo apt install -y \
  libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-dev \
  libsoup-3.0-dev libayatana-appindicator3-dev librsvg2-dev \
  build-essential curl wget file libssl-dev libgtk-3-dev libxdo-dev \
  pkg-config policykit-1
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
```

Then Node 20+ and pnpm 10+.

## Setup

```bash
# 1. Install JS deps
pnpm install

# 2. Fetch the mycelium sidecar binary for your target triple
bash scripts/fetch-mycelium.sh           # uses MYCELIUM_VERSION (default v0.6.1)
# or: MYCELIUM_VERSION=v0.6.1 bash scripts/fetch-mycelium.sh

# 3. Run in dev
pnpm tauri dev
```

The first start triggers a `pkexec` dialog asking you to authenticate; the polkit policy installed by the `.deb` caches the auth for the user session.

## Build

```bash
pnpm tauri build               # → src-tauri/target/release/bundle/{deb,appimage}/
```

The `.deb` declares `Depends: policykit-1` and ships the polkit policy under `/usr/share/polkit-1/actions/tech.threefold.mycellium-ui.policy`. The AppImage relies on `pkexec` being present on the host — on systems without polkit, fall back to running with `sudo` after disabling the sidecar's pkexec wrapper.

## Layout

```
src/                     # Vue 3 frontend
  views/                 # one file per nav item
  components/            # shadcn-style UI primitives + dialogs
  stores/                # Pinia: node, peers, routes, messages, topics, config
  lib/                   # api wrapper, events, base64 + format helpers
src-tauri/
  src/
    sidecar.rs           # spawn + supervise mycelium
    elevation.rs         # pkexec command builder
    poller.rs            # 3 background loops (peers, routes, inbox long-poll)
    api/                 # REST client modules (admin, peers, routes,
                         #   messages, topics, pubkey)
    commands.rs          # #[tauri::command] handlers, 1:1 with REST
    error.rs             # AppError + Serialize-as-string for invoke()
  binaries/              # gitignored; populated by scripts/fetch-mycelium.sh
  packaging/polkit/      # XML policy bundled into the .deb
scripts/fetch-mycelium.sh
.github/workflows/ci.yml # pnpm typecheck + cargo fmt/clippy/test
```

## Verification matrix

| Test | How |
|------|-----|
| Sidecar starts under pkexec | `pnpm tauri dev`, daemon visible in `ps`, splash disappears in <10 s |
| Peers connect | Add `tcp://188.40.132.242:9651` from the Peers page; state turns to `alive` within ~10 s |
| Routes propagate | `Routes/Selected` becomes non-empty after ~30 s |
| Live event stream | Sidebar status dot tracks ready/idle, peers table updates without manual refresh |
| Bidirectional messages | Two instances on different VMs, exchange via Compose → Inbox |
| Identity regen | Settings → Regenerate; restart daemon; new IP appears on Status |
| `.deb` install | Fresh Ubuntu LTS / Debian 12; daemon spawns under polkit on first start |

## Known limitations (v1)

- Linux only. Windows is reachable (sidecar via `runas` / Wintun driver) but not implemented.
- Auto-start at login isn't wired — the desktop entry installed by the `.deb` is the manual launcher.
- The TOML config editor in Settings only exposes `peers`, `tunName`, `noTun`. Other keys (`metricsApiAddress`, etc.) are passed-through if you edit the file directly at `~/.local/share/tech.threefold.mycellium-ui/mycelium.toml` and restart the daemon.
- `message_status` is forwarded as opaque JSON; the upstream schema isn't pinned in the spec, so we don't strongly type it.
