OASIS_LINUX/docs/devs/architecture/01-red-ssb.md
SITO ddd2787b73 Oasis 0.9.5 con Karvan para escritorio
Rama de desarrollo experimental sobre el Oasis de epsylon, sin afiliacion con el
proyecto original. Base: 0.9.5.

Trae el modulo Karvan —salas efimeras en memoria con autodestruccion por TTL, chat
que funciona sin JavaScript y llamadas de audio y video sobre WebRTC— con el enlace
en el menu lateral por el mismo patron que el resto de modulos: renderKarvanLink
calcado de renderPollsLink, entrada en modules_view y en la lista de /modules.

Los estilos del modulo van en su propia hoja, styles/karvan.css, siguiendo el patron
de highlight.css: asi se ve igual con cualquier tema, sin depender del tema movil.

Sin servidores ICE de terceros: no hay STUN de fabrica, porque un STUN aprende la IP
publica y el momento de cada llamada. Solo candidatos host salvo que se configure un
TURN propio en oasis-config.json, con credenciales efimeras por el mecanismo REST de
coturn.

El codigo propio vive separado —views/fork/, backend/fork_routes.js,
models/karvan_model.js y translations/fork/— de modo que sobre los ficheros de
upstream solo hay enganches de una linea y cada version nueva se integra sin
arrastrar nada.

Respecto al arbol de Android: fuera el wrapper y main.js, que es su arranque; el
tema vuelve a Dark-SNH y se restauran los modulos que en movil se recortan por peso.

Verificado arrancando sin OASIS_MOBILE: nueve rutas OK, menu lateral de upstream con
27 grupos y el enlace de Karvan, cero rastro de la interfaz movil (ni hexagonos, ni
topbar, ni barra inferior), y una sala creada y servida.
2026-08-19 00:35:08 +02:00

12 KiB

1. Oasis a nivel de red (Secure Scuttlebutt)

Oasis es un cliente/servidor de Secure Scuttlebutt (SSB). Toda la "red" de Oasis se construye sobre la pila clásica del ecosistema SSB: secret-stack + ssb-db + un montón de plugins.

Hay una separación clara en dos procesos:

  • Backend SSB (sbot)src/server/SSB_server.js: el nodo de red propiamente dicho. Es quien habla con otros peers.
  • Frontend web (GUI Koa)src/backend/backend.js: un servidor HTTP que actúa como cliente muxrpc del sbot, conectándose por un socket Unix local.
   RED SSB (otros peers Oasis, misma SHS cap)
                    │
   net:IP:8008~shs:<pubkey>  ·  ssb-lan (UDP)  ·  ssb-onion (Tor)
                    │
   ┌─────────────────────────────────────────────┐
   │  SBOT  (src/server/SSB_server.js)            │
   │  peer <-> MULTISERVER <-> SECRET-STACK (SHS) │
   │              <-> MUXRPC <-> PLUGINS          │
   └─────────────────────────┬───────────────────┘
                             │  unix socket ~noauth (muxrpc local, sin SHS)
                             ▼
   ┌─────────────────────────────────────────────┐
   │  FRONTEND  (src/backend/backend.js, Koa)     │
   │  cooler = src/client/gui.js → ssb-client     │
   │  app.listen({host, port:3000})               │
   └─────────────────────────┬───────────────────┘
                             ▼
                    Navegador  http://localhost:3000

1.1 Arranque de red

Scripts de arranque

  • install.sh: instala Node 22 y hace npm install en src/server (línea 23). Opcionalmente descarga modelos de IA. No toca la red.
  • oasis.sh es el lanzador. Modos relevantes:
    • server / pub (líneas 61-69): ejecuta node SSB_server.js startsolo el sbot headless, sin interfaz web.
    • gui o por defecto (líneas 73-81): ejecuta node backend.js — el frontend.
    • comandos pub whoami|invite|name|announce|follow|status|gossip (líneas 70-72) → delegan en scripts/oasis-pub.js.
  • src/server/package.json, script start: npm run start:ssb && sleep 10 && npm run start:backend. Arranca el sbot en segundo plano, espera 10 s (para que el socket Unix exista) y luego arranca el frontend.

Qué hace SSB_server.js paso a paso

(src/server/SSB_server.js)

  1. Líneas 7-11: carga secret-stack, ssb-caps (la capability SHS), ssb-db, la config (./ssb_config) y utilidades de metadatos.
  2. Líneas 13-52 (IIFE): monkey-patch de console.error/console.warn para silenciar ruido de red — rechazos de handshake por SHS cap incorrecta, excepciones EBT, etc. Un rechazo se convierte en un log limpio: [ts] REJECTED <ip:port> (wrong SHS cap).
  3. Líneas 56-81: construye el servidor con SecretStack({ caps }).use(plugin).use(plugin)... encadenando todos los plugins (ver tabla abajo).
  4. Líneas 83-86: si no es pub, carga ssb-lan (descubrimiento LAN por UDP) y el router LAN local ./lanRouter.
  5. Líneas 88-98: lógica de autofollow; carga ssb-autofollow si hay feeds.
  6. Líneas 123-196 (argv[0] === 'start'): instancia el servidor, escribe manifest.json (el catálogo de métodos muxrpc remotos), monta una barra de progreso de replicación, imprime metadatos y escucha eventos del hub de conexiones (server.conn.hub().listen()) para loguear CONNECTED / DISCONNECTED.
  7. Líneas 198-202: exporta { config, server, open() } — esto permite a la GUI reusar el servidor in-process si corre en el mismo proceso.

Plugins secret-stack cargados (líneas 56-98)

Plugin Función de red
ssb-db base de datos append-only de feeds
ssb-master identidad maestra / auth local
ssb-gossip gossip clásico (legacy) de peers
ssb-ebt Epidemic Broadcast Trees — replicación gossip eficiente
ssb-friends grafo social: hops, follows/blocks
ssb-blobs transferencia de ficheros binarios
ssb-meme blobs de imágenes/memes
ssb-conn gestor de conexiones moderno (hub, db, staging)
ssb-box cifrado de mensajes privados (box1)
ssb-search, ssb-private, ssb-friend-pub búsqueda, PM, pub de amigos
ssb-invite / ssb-invite-client invites (servidor si es pub, cliente si no)
ssb-replication-scheduler, ssb-partial-replication planificación de replicación
ssb-onion transporte Tor
ssb-unix-socket socket Unix local para clientes (la GUI)
ssb-no-auth conexiones locales sin handshake SHS
ssb-about, ssb-backlinks, ssb-links, ssb-tangle, ssb-query índices de vistas
ssb-lan + lanRouter descubrimiento LAN (solo si no es pub)

Nota: la replicación NO usa ssb-replicate directamente; la orquestan ssb-ebt + ssb-replication-scheduler + ssb-friends.


1.2 El protocolo SSB en términos del proyecto

  • secret-stack + handshake SHS (capability). SecretStack({ caps }) crea el nodo. La caps.shs está fijada en src/configs/server-config.json (líneas 5-7): "H5EC+V5BU9s0lWxCkt4z8a095Sj8a6TgiLKPYi1JD7s=". Es la clave de capacidad de red (Secret Handshake): dos peers solo completan el handshake si comparten exactamente esta cap. Actúa como "contraseña de red": Oasis forma su propia red SSB privada, distinta de la red SSB pública.

  • multiserver (transportes). Capa de transporte abstracta. La config connections (server-config.json, líneas 29-60) define:

    • incoming.net: transform: "shs", port: 8008 → TCP cifrado con SHS.
    • incoming.unix: transform: "noauth" → socket Unix local sin handshake, para que el frontend se conecte como cliente privilegiado.
    • outgoing.net: transform: "shs".
    • Una dirección multiserver típica: net:IP:8008~shs:<pubkey-base64>.
  • muxrpc (RPC sobre el stream). Una vez establecido el stream SHS, muxrpc multiplexa llamadas RPC asíncronas y pull-streams sobre la misma conexión. El manifest.json describe qué métodos remotos existen (sync/async/ source). Es como el frontend invoca ssb.publish(...), ssb.blobs.get(...), etc.

  • EBT (epidemic-broadcast-trees + ssb-ebt). El algoritmo de replicación gossip. Cada peer anuncia el seq (reloj vectorial) de los feeds que tiene; el otro envía solo los mensajes que faltan, formando árboles de difusión epidémica que evitan duplicados.

  • Identidad de los peers. Cada peer es un feed id ed25519: @<base64>.ed25519. En las direcciones multiserver, el sufijo ~shs:<pubkey> identifica criptográficamente al peer durante el handshake.


1.3 Federación / P2P

  • Descubrimiento LAN (src/server/lanRouter.js): plugin local custom. startRouter (líneas 55-64) arranca ssb.lan.start() (broadcast UDP) y consume ssb.lan.discoveredPeers(). Cada peer descubierto pasa por handleDiscoverystagePeer (líneas 15-45): lo stagea en ssb.conn.stage(...) (vía moderna) con fallback a ssb.gossip.add(...) (legacy); si eagerReplicate, fuerza ebt.request. Respeta el flag lanBroadcasting de oasis-config.json.

  • Pubs / invites. En modo pub se carga ssb-invite (servidor); en cliente, ssb-invite-client. Los comandos oasis.sh invite|announce|follow (→ scripts/oasis-pub.js) permiten a un pub publicar su dirección y generar códigos de invitación. Un invite contiene host:port:pubkey~seed; al canjearlo, el peer se conecta y el pub le sigue de vuelta (ssb-friend-pub).

  • Replicación por hops. ssb-friends define el grafo social. server-config.json fija friends.hops: 2 → el nodo replica los feeds de la gente que sigues y de la gente que ellos siguen (amigos de amigos). El ssb-replication-scheduler decide qué feeds pedir por EBT según ese grafo.

  • "Distributed not decentralized". No hay servidor central ni DHT global. Cada nodo Oasis tiene su propia copia local de la base de datos (logs append-only firmados con ed25519) y solo replica los feeds dentro de su radio social (hops) más los descubiertos por LAN. La red se federa por gossip entre peers que comparten la misma SHS cap. Es distribuida (datos replicados en muchos nodos autónomos, funciona offline) pero no descentralizada como una blockchain (no hay consenso global ni vista única; cada quien ve solo su subgrafo). El flag wish de oasis-config.json (whole / mutuals / only-lan) controla el alcance de replicación deseado.


1.4 Puertos y endpoints

Qué Dónde Puerto / dirección
muxrpc SSB (sbot) — otros peers se conectan aquí server-config.json incoming.net 8008/TCP transform shs
Socket Unix local — para el frontend incoming.unix unix:<ssb.path>/socket~noauth:<pubkey>
Frontend web (Koa) — tu navegador oasis_client.js / middleware.js:180 3000 host localhost (configurable con --host/--port)

Cómo se conecta el frontend al sbot (el "cooler", src/client/gui.js):

  1. Intenta require('../server/SSB_server') y reusar el server in-process si existe (sin socket, uso directo del objeto).
  2. Si no, construye remote = unix:<path>/socket~noauth:<pubkey> y se conecta con ssb-client (muxrpc por el socket Unix noauth).
  3. attemptConnectionWithBackoff: reintentos con backoff exponencial (de ahí el sleep 10 del arranque).
  4. Expone cooler.open() / cooler.close(). Todos los modelos del backend reciben este cooler y hacen await cooler.open() para obtener el cliente muxrpc.

Para exponer la GUI en un VPS se usa --host=0.0.0.0.


1.5 Blobs (ficheros / imágenes)

  • Plugin ssb-blobs (+ ssb-meme). Tamaño máximo en ssb_config.js: 50 MB.
  • Un blob se referencia por hash: &<sha256-base64>.sha256. Los mensajes del log solo llevan el hash, no el binario.
  • Flujo en src/backend/blobHandler.js:
    • Subida: ssbClient.blobs.add(...) recibe el contenido por pull-stream y devuelve el ref &...sha256.
    • Descarga por red: blobs.has(id) comprueba si ya está local; si no, blobs.want(id) lo pide a los peers conectados (gossip de "want/has" sobre muxrpc), y blobs.get(id) lo lee como stream.

Los blobs viajan sobre la misma conexión SHS/muxrpc, fuera del log append-only.


1.6 Caps / cifrado

  • ssb-caps define las capabilities de protocolo (shs, sign, invite). La shs cap real está fijada en server-config.json → red privada de Oasis.
  • Handshake SHS: autenticación mutua por ed25519 + confidencialidad del stream de transporte.
  • ssb-box: cifrado de mensajes privados box1 (hasta ~7 destinatarios, cifrado por clave pública de cada feed). ssb-private expone publish/read.
  • Grupos privados ("tribes"). No se usa box2/ssb-tribes. En su lugar Oasis implementa cifrado propio a nivel de aplicación en src/models/crypto.js, instanciado por dominio en backend.js (tribeCrypto, chatCrypto, padCrypto, mapCrypto, calendarCrypto, eventCrypto, forumCrypto). Los grupos se cifran con esas claves derivadas y se almacenan/replican como mensajes normales del feed.

1.7 Archivos clave de la capa de red

Archivo Rol
src/server/SSB_server.js Construye el sbot y carga los plugins (56-98)
src/server/ssb_config.js Fusiona server-config.json; fija blobs.max=50MB
src/server/ssb_metadata.js Deriva e imprime puerto SSB, hops, LAN, feed ID
src/server/lanRouter.js Descubrimiento/staging de peers LAN
src/configs/server-config.json caps.shs, pub, friends.hops, connections (puertos)
src/configs/oasis-config.json lanBroadcasting, wish, pmVisibility, módulos
src/client/gui.js El "cooler": cliente muxrpc por socket Unix noauth
src/backend/blobHandler.js add/has/want/get de blobs
scripts/oasis-pub.js Comandos pub (invite/announce/follow)

Siguiente: 02-arquitectura-software.md.