Files
uniweb/app.md
T
agent b72976e06c feat(bus): complete TypeScript SDK — auth, room envelope, client, transport
Second half of the browser-native bus SDK (issue 0001, Phase 1), making uniweb a
peer of the bus in its own right (like unibus_android) without the Go gateway:

- busauth.ts: NATS user nkey from the Ed25519 key (base32 + crc16, no nkeys dep)
  and control-plane request signing (CanonicalRequest + X-Unibus-* headers).
- room.ts: Policy / Room types (ModeNATS, ModeMatrix).
- client.ts: the pure room ENVELOPE (sealRoomMessage/openRoomMessage — AEAD with
  the subject as AAD, Ed25519 sign, drop on verify/decrypt failure), a transport-
  agnostic BusClient, and a signed ControlPlane HTTP client (fetch room/key/members,
  open the sealed room key locally).
- wstransport.ts: concrete nats.ws WebSocket transport (validated E2E in Phase 3).
- index.ts: public SDK surface.

Parity pinned by vectors from unibus cmd/busvectors (extended with nkey + signed
control-request vectors): 19/19 green. The user's private key signs everything in
the browser and is never sent to any server. Bumps uniweb to 0.2.0.

Remaining for Phase 1 completion: the live nats.ws connection + control-plane,
which need a running unibus with the WebSocket listener — exercised in Phase 3.
2026-06-13 22:54:54 +02:00

5.8 KiB

name, lang, domain, version, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, repo_url, icon, service, e2e_checks
name lang domain version description tags uses_functions uses_types framework entry_point dir_path repo_url icon service e2e_checks
uniweb go infra 0.2.0 Frontend web del bus unibus: SPA de chat (React+Mantine) con wallet por usuario (BIP39) + gateway Go (REST+SSE) que actúa de peer del bus para el navegador.
service
messaging
web
frontend
e2e
generate_identity_go_cybersecurity
seal_aead_go_cybersecurity
open_aead_go_cybersecurity
seal_key_box_go_cybersecurity
open_key_box_go_cybersecurity
sign_ed25519_go_cybersecurity
verify_ed25519_go_cybersecurity
react cmd/webgw projects/message_bus/apps/uniweb https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/dataforge/uniweb
phosphor accent
chats-circle #6366f1
port health_endpoint health_timeout_s systemd_unit systemd_scope restart_policy runtime pc_targets is_local_only
8481 null 3 null null always manual
lucas-linux
false
id cmd timeout_s
build CGO_ENABLED=0 go build ./... 180
id cmd timeout_s
vet CGO_ENABLED=0 go vet ./... 120
id cmd timeout_s
unit CGO_ENABLED=0 go test ./... 120
id cmd timeout_s
web_build cd web && pnpm install --frozen-lockfile && pnpm build 180

Qué es

uniweb es el frontend web del bus unibus: la interfaz que un humano usa desde el navegador para hablar por el bus. Se separó de unibus (v0.13.0) para que el plano del bus (membresía, claves, librería cliente) quede limpio y el frontend tenga su propia carpeta de servicio y su propio ciclo de release.

Tiene dos mitades que viven juntas:

  • SPA (web/) — React 18 + Vite + Mantine v9. Pantallas de chat y onboarding wallet (join por invitación, login por passphrase local, recover por mnemónica). La identidad criptográfica de cada usuario se deriva de forma determinista de una frase BIP39 de 12 palabras y se cifra at-rest en el dispositivo (AES-256-GCM); la clave privada nunca viaja al servidor en claro.
  • Gateway (cmd/webgw) — binario Go (package main, REST + SSE) que actúa como peer del bus en nombre del navegador. Mantiene una sesión wallet por usuario, registra claves públicas por token de invitación, y traduce HTTP/SSE ↔ el protocolo del bus usando la librería cliente de unibus.

Cómo se acopla a unibus

uniweb consume unibus como módulo Go, no reimplementa nada del bus:

replace github.com/enmanuel/unibus => ../unibus     # pkg/{busauth,client,frame,room}
replace fn-registry => ../../../../                  # functions/cybersecurity

Los replace no son transitivos en Go, así que uniweb (módulo principal) declara los dos: el de unibus (de donde importa la librería cliente) y el de fn-registry (de donde pkg/client toma las primitivas de cifrado). Compila con CGO_ENABLED=0 igual que unibus.

Ejemplo

# 1. Backend: el control-plane del bus (en la carpeta de unibus)
cd ../unibus && CGO_ENABLED=0 go run ./cmd/membershipd   # :8470

# 2. Build de la SPA
cd web && pnpm install && pnpm build                     # genera web/dist

# 3. Gateway sirviendo la SPA + API contra el control-plane
cd .. && CGO_ENABLED=0 go run ./cmd/webgw \
  --port 8481 --ctrl-url http://127.0.0.1:8470 --web-dir web/dist
# Navegador: http://127.0.0.1:8481

# Desarrollo de la SPA con hot-reload (gateway en modo API-only, sin --web-dir):
cd web && pnpm dev    # vite proxya /api + /stream al gateway

Cuándo usarla

Cuando quieras que un humano hable por el bus desde un navegador, o cuando trabajes en la UI de chat / el onboarding wallet. Para la lógica del bus en sí (membresía, claves, peers programáticos) ve a unibus; uniweb solo es la capa web encima.

Gotchas

  • El gateway necesita el control-plane de unibus vivo (--ctrl-url, por defecto http://127.0.0.1:8470); si no, las sesiones fallan al abrir el peer.
  • --web-dir es opcional: vacío = API-only (úsalo con el dev server de vite); apuntando a web/dist = sirve la SPA buildeada. Un path inválido degrada a API-only con un WARN, no peta.
  • Build cross-repo: uniweb no compila si ../unibus no está presente en disco (el replace es local). Para deploy hay que llevar ambos repos, o vendorizar unibus.
  • La passphrase del wallet nunca se guarda ni se envía; perderla en un dispositivo sin la mnemónica BIP39 = identidad irrecuperable en ese dispositivo (recuperable en otro con las 12 palabras).

Capability growth log

  • v0.2.0 (2026-06-13) — SDK del bus en TypeScript (web/src/bus/), issue 0001 Fase 1: el protocolo y el cifrado E2E del bus portados al navegador para que uniweb deje de depender del gateway Go. Módulos: crypto.ts (Ed25519, ChaCha20-Poly1305, sealed box con nonce BLAKE2b igual que Go), frame.ts (wire format = encoding/json de Go byte a byte), room.ts (Policy), busauth.ts (nkey NATS + firma de requests del control-plane), client.ts (envelope de room puro + BusClient sobre una interfaz de transporte + cliente HTTP firmado) y wstransport.ts (adaptador nats.ws). Paridad cross-language verificada contra vectores Go (cmd/busvectors): 19/19 tests verdes — endpoint id, firma Ed25519, AEAD, sealed box, frame marshal/sign, nkey y canonical request. La clave privada del usuario nunca se serializa hacia la red. La conexión nats.ws + control-plane reales se validan en la Fase 3 (E2E) por requerir un unibus vivo con WebSocket.
  • v0.1.0 (2026-06-13) — scaffold inicial: extracción de la SPA (web/) y el gateway (cmd/webgw) desde unibus v0.13.0 a su propia app/sub-repo. Sin cambios de capacidad respecto a lo que ya vivía en unibus 0.12.0 (wallet BIP39 + sesiones por usuario); solo cambia la ubicación y el módulo Go. go build/vet/test + pnpm build verdes en la nueva ubicación con los replace cross-repo.