Phase 2 of issue 0001. uniweb becomes a pure frontend (web/ only), like unibus_android: the SPA talks directly to the bus and the Go gateway is gone. - busService.ts: the new data layer over the bus SDK, replacing the old api module. It holds the user's wallet identity and a connected BusClient IN THE BROWSER and opens the session locally — the private key is never sent anywhere (closes the gateway-era hole where the browser POSTed its private key to /api/session). - Wire account/App/ChatShell/ChatPanel/WalletLogin/Recover/Join to busService; subscribeRoom replaces the SSE streamRoom; ApiError -> SessionError. - SDK: ControlPlane.createRoom + listMemberRooms, and fetchRoom mapped to the real control-plane wire shape (snake_case, no id) — all verified by the live round-trip. - Delete cmd/webgw, go.mod, go.sum, src/api.ts and the orphan operator Login. uniweb now has zero Go and no dependency on unibus as a module. - vite: drop the /api proxy, dev server on 5173 to match the bus CORS allowlist; add vite-env typings. app.md: lang ts, no uses_functions, e2e_checks are now web-only. Bump 0.3.0. Onboarding by token is now admin-side (the bus has no self-register endpoint; the gateway only mocked it). tsc + pnpm build + 19/19 unit green.
7.8 KiB
name, lang, domain, version, description, tags, uses_functions, uses_types, framework, entry_point, dir_path, repo_url, icon, e2e_checks
| name | lang | domain | version | description | tags | uses_functions | uses_types | framework | entry_point | dir_path | repo_url | icon | e2e_checks | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| uniweb | ts | infra | 0.3.0 | Cliente web browser-nativo del bus unibus: SPA de chat (React+Mantine) con wallet por usuario (BIP39) que habla DIRECTO al bus (nats.ws + control-plane HTTPS firmado), sin gateway. La clave privada nunca sale del navegador. |
|
react | web/src/main.tsx | projects/message_bus/apps/uniweb | https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/dataforge/uniweb |
|
|
Qué es
uniweb es el cliente web browser-nativo del bus unibus: la interfaz
que un humano usa desde el navegador para hablar por el bus. Es solo frontend (web/) —
una SPA, sin backend Go, sin gateway. Habla directamente con el bus, igual que
unibus_android lo hace en Kotlin:
- Control plane — HTTPS firmado al
membershipd(rooms, claves, miembros). Cada request lleva la firma Ed25519 del usuario (cabecerasX-Unibus-*). - Data plane — NATS sobre WebSocket (
nats.ws), autenticado con el nkey derivado de la identidad del usuario.
Stack: React 18 + Vite + Mantine v9. 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 sale del navegador: firma, sella y descifra en el cliente. No hay servidor al que enviarla.
El SDK del bus (web/src/bus/)
El protocolo y el cifrado E2E del bus están portados a TypeScript, validados byte a byte
contra la implementación Go de referencia (vectores de unibus cmd/busvectors):
crypto.ts— Ed25519, ChaCha20-Poly1305, sealed box (nonce BLAKE2b, igual que Go).frame.ts— wire format =encoding/jsonde Go byte a byte.room.ts— Policy (ModeNATS / ModeMatrix).busauth.ts— nkey NATS (base32 + crc16) + firma de requests del control-plane.client.ts— envelope de room +BusClient+ControlPlaneHTTP firmado.wstransport.ts— transportenats.ws.
busService.ts es la capa de datos de la SPA sobre el SDK (reemplazó al viejo módulo api
que hablaba con el gateway). Ya no depende de unibus como módulo Go: el desacople es
total.
Ejemplo
# El bus ya corre (cluster unibus con WebSocket habilitado, --ws-port). Apunta la SPA a un
# nodo y arráncala en dev (puerto 5173, que coincide con la CORS allowlist del cluster):
cd web && pnpm install
VITE_BUS_HTTP=https://<nodo>:8470 VITE_BUS_WS=wss://<nodo>:8480 pnpm dev
# Navegador: http://localhost:5173
# Producción: build estático y sirve web/dist con cualquier static server.
cd web && pnpm build # genera web/dist
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 es el cliente web encima.
Gotchas
wss://con CA self-signed: el cluster sirve el WebSocket con el cert del bus (CA propia). Un navegador rechazawss://self-signed salvo que se importe la CA o se ponga un reverse proxy con cert válido (Let's Encrypt). En dev se puede aceptar el cert a mano.- Onboarding admin-side: el bus no tiene endpoint de auto-registro (el viejo gateway lo
mockeaba). En
enforce, una identidad nueva debe ser autorizada por un admin (membershipd user add) antes de poder abrir sesión; el flujo de Join muestra la clave pública del usuario para que un admin la autorice. - CORS: el dev server corre en
http://localhost:5173para coincidir con la--cors-originsdel cluster. Otro origen necesita añadirse a esa allowlist. - 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.3.0 (2026-06-14) —
uniwebse vuelve cliente browser-nativo puro (issue 0001, Fase 2): la SPA se cablea al SDK del bus (busService.tsreemplaza el móduloapi) y se elimina el gateway Go (cmd/webgw,go.mod,go.sum).uniwebqueda como soloweb/, sin nada de Go, sin dependencia deunibuscomo módulo. La clave privada se usa solo en el navegador (saveAndOpen/unlockAndOpenabren la sesión localmente; ya NO se hacePOST /api/sessioncon la privada — se cierra el agujero E2E del modelo gateway). Validado end-to-end contra el cluster descentralizado real (Fase 3): identidad registrada conecta pornats.wsy hace round-trip de un mensaje cifrado (crear room → publicar → recibir descifrado + firma verificada). El onboarding por token queda admin-side (el bus no tiene auto-registro).tsc+pnpm build+ 19/19 unit verdes. -
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 queuniwebdeje 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/jsonde Go byte a byte),room.ts(Policy),busauth.ts(nkey NATS + firma de requests del control-plane),client.ts(envelope de room puro +BusClientsobre una interfaz de transporte + cliente HTTP firmado) ywstransport.ts(adaptadornats.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ónnats.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) desdeunibusv0.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 losreplacecross-repo. -
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 queuniwebdeje 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/jsonde Go byte a byte),room.ts(Policy),busauth.ts(nkey NATS + firma de requests del control-plane),client.ts(envelope de room puro +BusClientsobre una interfaz de transporte + cliente HTTP firmado) ywstransport.ts(adaptadornats.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ónnats.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) desdeunibusv0.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 losreplacecross-repo.