bitle

Bitle is a self-powered ESP32-C3 BitChat relay node. It extends BitChat's Bluetooth mesh by hosting a dedicated BLE gateway that handles Noise XX handshakes, validates BitChat packets, and re-broadcasts encrypted payloads without user interaction. Nodes link to phones and to each other, carry encrypted mail for offline recipients, and keep themselves current with signed firmware updates that propagate across the mesh. The current hardware uses an ESP32-C3 with a flexible 2.4 GHz antenna, weatherproof enclosure, solar input, and battery pack. Bitle is well suited to extend the mesh network range in places like remote trails, campsites, or any offline comms grid.

The firmware implements the full Noise XX handshake pattern, binding Ed25519 identities the same way the BitChat mobile apps do. Once flashed to an ESP32-C3, a Bitle node powers on, starts advertising, and begins relaying traffic autonomously — no phone, no configuration, no internet required.

Nodes are more than repeaters. Each one runs a dual-role BLE stack that stays connected to phones and to other Bitle nodes at the same time, a store-and-forward mailbox that holds end-to-end-encrypted messages for offline recipients and hands them over when they reappear, and gossip sync that backfills recent public traffic for returning peers. Ed25519-signed firmware updates spread node-to-node with automatic rollback — deployed hardware never needs to be touched again.

Designed for field deployment in environments where infrastructure is absent. Solar charging keeps nodes alive on remote trails and campsites indefinitely. The weatherproof enclosure protects hardware in the conditions where off-grid comms matter most.

Firmware source code is open and MIT-licensed. Clone the repo, flash a board, and drop it in the field. → github.com/bitleproject/bitle

Features

Full BitChat handshake Implements the Noise XX pattern with the bundled noise_ref library, performing Ed25519 identity binding like the mobile apps.
Dual-role BLE relay Advertises a NimBLE GATT service phones subscribe to while simultaneously dialing other Bitle nodes — one node holds links to phones and Bitles at once, relaying packets across gaps no phone can bridge.
Store-and-forward A courier mailbox accepts end-to-end-encrypted envelopes for offline recipients and hands them over when the recipient reappears. Contents stay opaque to the relay; storage is strictly bounded to on-device flash.
Gossip sync Reconciles recent signed public traffic with peers using BitChat's set-reconciliation filter, so returning phones backfill what they missed while they were away.
Signed mesh OTA Ed25519-signed firmware updates propagate node-to-node over BLE with dual-slot rollback — a bad image reverts itself, and deployed nodes stay current without physical access.
Time sync & nicknames Reconstructs wall-clock time from directly connected phones (no RTC needed) and advertises deterministic Bitle-#### nicknames configurable through NVS.
Solar/battery ready Firmware is fully autonomous; once flashed it will advertise, accept connections, and keep the mesh alive indefinitely without user interaction.

Repository layout

├── CMakeLists.txt # ESP-IDF project entry ├── partitions.csv # 4 MB dual-slot OTA + mailbox layout ├── sdkconfig.defaults # configuration seed ├── components/ │ ├── bitchat_utils/ # BLE-derived clock w/ authority tiers │ └── noise_ref/ # Bundled Noise-C reference library ├── docs/OTA.md # OTA + node-to-node design ├── tools/ # key generation, image signing, test harness └── main/ ├── main.c ├── bitchat_ble.{c,h} # dual-role BLE, relay, fragments ├── noise_handshake.{c,h} # Noise XX, announces, dispatch ├── packet_codec.{c,h} # BitChat binary packet codec ├── bitle_hash.{c,h} # SHA-256/HMAC via PSA ├── bitle_ota.{c,h} # signed dual-slot OTA ├── ota_owner_pubkey.h # OTA trust anchor (public key) ├── bitle_courier.{c,h} # store-and-forward mailbox ├── bitle_store.{c,h} # flash sector-ring store ├── bitle_sync.{c,h} # gossip sync └── nickname_manager.{c,h} # Bitle-#### nicknames
→ view firmware on github

Parts list

Everything needed to build a basic Bitle node:

01 ESP32-C3 Seeed Studio XIAO ESP32C3 Microcontroller
02 Antenna 2.4GHz Mini Flexible WiFi Antenna with uFL Connector
03 Charger Universal USB / DC / Solar Lithium Ion/Polymer charger — bq24074
04 DC Jack Adapter 3.8/1.3mm or 3.5/1.1mm to 5.5/2.1mm DC Jack Adapter Cable
05 Battery Lithium Ion Cylindrical Battery — 3.7v 2200mAh
06 Solar Panel 6V 2W Solar Panel — ETFE (Voltaic P126)

Building & flashing

Developed and tested with ESP-IDF v6.0 (requires IDF ≥ 5.0); targets esp32c3. Adjust the serial port flag for your setup — sdkconfig is generated from sdkconfig.defaults during the first build.

source ~/esp-idf/export.sh
idf.py set-target esp32c3
idf.py build
idf.py -p /dev/cu.usbmodem101 flash monitor

For field deployment, drop the firmware onto an ESP32-C3 in your Bitle enclosure, connect power, and the node will immediately begin extending nearby BitChat meshes — relaying live traffic, carrying mail for offline peers, and keeping itself up to date on its own.

Running your own independent fleet? Generate your own OTA signing key before flashing so your nodes trust you, not the Bitle project — see the owner key notes in the README.