Skip to content

Arquitectura

Raiznet está organizada en tres capas. Esta página distingue lo que corre hoy de lo que está en diseño — consulta la Hoja de ruta para el panorama completo.

Capa de borde — sensores ESP32

Todos los dispositivos ejecutan el mismo firmware base. El modo se determina por configuración, no por hardware:

ModoEnergíaComportamiento
sensor_mainsToma de corrienteSiempre encendido, mantiene la Wi-Fi activa; futuro relay ESP-NOW para vecinos
sensor_batteryBateríaDuerme la mayor parte del tiempo, despierta según horario
gatewayToma de corrienteSolo relay — hace de puente de dispositivos ESP-NOW hacia la Wi-Fi (planificado)

Todo dispositivo tiene el mismo modelo de identidad: un par de claves Ed25519 nacido en el aprovisionamiento (TRNG del hardware), guardado en la flash, usado para firmar cada paquete de telemetría. El firmware de referencia también genera la identidad del dueño a partir de un mnemónico BIP-39 en su portal cautivo — consulta Ciclo de vida del dispositivo.

Capa de malla — nodos servidores

Cada servidor es un par (peer). No existe un "servidor principal". Lo que un nodo hace hoy:

  • Recibe telemetría firmada por HTTP (POST /v1/telemetry) y valida cada firma
  • Aplica la política de privacidad por campo en la ingesta
  • Almacena las lecturas en dos bases SQLite locales (pública / privada)
  • Expone la API HTTP en dos puertos: uno público, uno local

En diseño (ADR-004): los nodos pasarán a persistir los datos públicos como un log de eventos firmado y de solo anexado, replicándolo punto a punto con otros nodos de la misma red — primero entre pares configurados por HTTP, luego por un transporte de marcado-por-pubkey con relays operados por la comunidad. La replicación aún no está implementada — hoy, los nodos son independientes.

Un servidor puede correr donde sea que corra Node.js: VPS, Raspberry Pi, Mini PC, Android vía Termux. Una reimplementación del nodo en Rust (raiznetd) está en marcha para apuntar a placas ARM muy pequeñas con un binario estático — consulta la Hoja de ruta.

Endpoints duales en un proceso

Un único proceso de servidor expone dos interfaces HTTP:

EndpointPuerto por defectoBindRutas de devices acceden aAuth
Público:30000.0.0.0raiznet_public.dbNinguna (solo datos públicos)
Local:3001127.0.0.1raiznet_private.dbAún ninguna — planificado: challenge-response del dueño

WARNING

Hasta que entre la autenticación del dueño, la única protección del endpoint local es su bind de loopback. Accede a él remotamente vía Tailscale/VPN — nunca lo expongas directamente.

Dos bases de datos

BaseAlimentada porContieneServida por
raiznet_public.dbIngesta pública (replicación planificada)Dispositivos y lecturas publicables en redesEndpoint público
raiznet_private.dbSolo ingesta localDispositivos local_only + campos mantenidos fuera del lado públicoSolo endpoint local

Seguridad por aislamiento: una consulta en el endpoint público no puede devolver datos privados porque la conexión a la base privada simplemente no está disponible para ella. El aislamiento se impone a nivel de base de datos, no en la capa de API.

Capa de cliente

ClienteDescripciónEstado
CLIHerramienta de operación y depuraciónEn el repositorio
Dashboard webInterfaz de visualizaciónEn el repositorio
Gateway públicoUn nodo expuesto en internet — solo otro par, sin datos privilegiadosPlanificado
App de escritorio (Tauri)Empaqueta un nodo completo + UI, funciona offlineFase futura
App móvilReact Native o CapacitorFase futura