Skip to content

Tech Stack

Current stack (implemented)

LayerTechnologyVersion
RuntimeNode.js24 LTS
LanguageTypeScript (strict)5.x
HTTPFastify5.x
SQL storagebetter-sqlite311.x
Validationzod3.x
Crypto (Ed25519)hypercore-crypto (libsodium)3.x
BIP-39 seeds@scure/bip391.x
Loggerpino9.x
Monorepopnpm workspaces9.x
Testsvitest3.x
DocsVitePress1.x
FirmwarePlatformIO + Arduino framework (ESP32)

Planned / under evaluation

LayerTechnologyStatus
Canonical serializationProtobuf (@bufbuild/protobuf on Node, nanopb on ESP32)Schemas exist, codegen not active — see ADR-001
Geolocationh3-jsPlanned with the map features
Filter set operationsRoaring BitmapsPlanned with filters
Desktop appTauri 2.xFuture phase
Node replicationSigned event log + peer syncIn design — see Roadmap

Repository structure

raiznet/
├── apps/
│   ├── server/          # Fastify node (public + local endpoints)
│   ├── cli/             # Operations and debug tool
│   ├── website/         # raiznet.com landing page
│   ├── dashboard/       # Web dashboard
│   └── prototype/       # UI design canvas (React + Vite)
├── packages/
│   ├── protocol/        # .proto schemas (canonical format, planned)
│   ├── crypto/          # Key derivation, signing, AES-256-GCM
│   └── core/            # Shared abstractions
├── firmware/
│   ├── safraSense/      # Reference ESP32 firmware (full sensor)
│   └── esp32-sensor/    # Minimal sample
└── docs/                # This site

The production firmware for Arateki's SafraSense hardware lives in a separate repository; the firmware in this repo is the open reference implementation of the protocol.

Design decisions

Do not introduce without discussion:

  • NestJS — too heavy
  • Express — obsolete vs Fastify
  • ORMs — better-sqlite3 directly
  • Redis — not justified at this stage
  • Docker in dev — runs local
  • Kafka — not necessary

SQLite role

Today, SQLite is the node's primary local storage: ingest validates a block and writes it directly to raiznet_public.db / raiznet_private.db.

The design goal is for the source of truth to become a signed append-only event log, with SQLite as a derived index that can be deleted and rebuilt by replaying the log (see ADR-002). The wide-table schema is already shaped for that:

  • Fast aggregated queries (fixed REAL columns per sensor)
  • No ORM — direct SQL with typed results
  • New sensor types require adding three columns (_plain, _cipher, _nonce) per field