Skip to content

Arquitetura

A Raiznet é organizada em três camadas. Esta página distingue o que roda hoje do que está em design — veja o Roadmap para o quadro completo.

Camada de borda — sensores ESP32

Todos os dispositivos rodam o mesmo firmware base. O modo é determinado por configuração, não por hardware:

ModoEnergiaComportamento
sensor_mainsTomadaSempre ligado, mantém o Wi-Fi ativo; futuro relay ESP-NOW para vizinhos
sensor_batteryBateriaDorme a maior parte do tempo, acorda no horário agendado
gatewayTomadaApenas relay — faz a ponte de dispositivos ESP-NOW para o Wi-Fi (planejado)

Todo dispositivo tem o mesmo modelo de identidade: um par de chaves Ed25519 nascido no provisionamento (TRNG do hardware), guardado na flash, usado para assinar cada pacote de telemetria. O firmware de referência também gera a identidade do dono a partir de um mnemônico BIP-39 no seu portal cativo — veja Ciclo de vida do dispositivo.

Camada de malha — nós servidores

Cada servidor é um par (peer). Não existe "servidor principal". O que um nó faz hoje:

  • Recebe telemetria assinada via HTTP (POST /v1/telemetry) e valida cada assinatura
  • Aplica a política de privacidade por campo na ingestão
  • Armazena as leituras em dois bancos SQLite locais (público / privado)
  • Expõe a API HTTP em duas portas: uma pública, uma local

Em design (ADR-004): os nós passarão a persistir os dados públicos como um log de eventos assinado e somente-anexação, replicando-o ponto a ponto com outros nós da mesma rede — primeiro entre peers configurados via HTTP, depois por um transporte de discagem-por-pubkey com relays operados pela comunidade. A replicação ainda não está implementada — hoje, os nós são independentes.

Um servidor pode rodar em qualquer lugar onde o Node.js roda: VPS, Raspberry Pi, Mini PC, Android via Termux. Uma reimplementação do nó em Rust (raiznetd) está em andamento para mirar placas ARM muito pequenas com um binário estático — veja o Roadmap.

Endpoints duplos em um processo

Um único processo de servidor expõe duas interfaces HTTP:

EndpointPorta padrãoBindRotas de devices acessamAuth
Público:30000.0.0.0raiznet_public.dbNenhuma (só dados públicos)
Local:3001127.0.0.1raiznet_private.dbAinda nenhuma — planejado: challenge-response do dono

WARNING

Até a autenticação do dono entrar, a única proteção do endpoint local é o seu bind de loopback. Acesse-o remotamente via Tailscale/VPN — nunca o exponha diretamente.

Dois bancos de dados

BancoAlimentado porContémServido por
raiznet_public.dbIngestão pública (replicação planejada)Dispositivos e leituras publicáveis em redesEndpoint público
raiznet_private.dbApenas ingestão localDispositivos local_only + campos mantidos fora do lado públicoApenas endpoint local

Segurança por isolamento: uma consulta no endpoint público não consegue retornar dados privados porque a conexão com o banco privado simplesmente não está disponível para ela. O isolamento é imposto no nível do banco, não na camada de API.

Camada de cliente

ClienteDescriçãoStatus
CLIFerramenta de operação e depuraçãoNo repositório
Dashboard webInterface de visualizaçãoNo repositório
Gateway públicoUm nó exposto na internet — apenas mais um peer, sem dados privilegiadosPlanejado
App desktop (Tauri)Empacota um nó completo + UI, funciona offlineFase futura
App mobileReact Native ou CapacitorFase futura