SDKs and platforms

Which microcontrollers can run Offline Protocol?

ESP32 hardware runs Offline Protocol today. The IntelligenceMesh Relay, an ESP32-based M5StickC Plus2, relays encrypted Offline Protocol mesh traffic over Bluetooth LE from the moment it is switched on. For your own device, the Rust crate offline-protocol-leaf builds for the ESP32-C6, ESP32-H2, ESP32-C3 and ESP32-C2, Cortex-M0, Cortex-M33 and WASI, and makes the device an encrypted member of a phone's MLS group.

TL;DR

The ESP32-based IntelligenceMesh Relay relays encrypted Offline Protocol mesh traffic over Bluetooth LE as soon as it is switched on. For your own hardware, offline-protocol-leaf builds for the RISC-V ESP32 chips, Cortex-M0, Cortex-M33 and WASI. Firmware supplies the radio, entropy, time at pairing, storage and authorization, and a phone or other full peer sets up the group.

Learning objectives

After reading this article you will be able to:

  • Describe what the ESP32-based IntelligenceMesh Relay does on an Offline Protocol mesh
  • List the chip families and Rust targets offline-protocol-leaf builds for, including the esp-hal results
  • Plan the radio, entropy, time, storage and authorization a leaf device's firmware integrates

ESP32 hardware running Offline Protocol

ESP32 hardware runs Offline Protocol today as a mesh relay. The IntelligenceMesh Relay is an M5StickC Plus2 with an ESP32-PICO-V3-02 (dual-core, Wi-Fi, Bluetooth 4.2), pre-flashed with IntelligenceMesh by Offline Protocol firmware. According to its product page:

  • It relays encrypted Offline Protocol mesh traffic over Bluetooth LE, using BLE GATT in both roles, peripheral and central, and relays Bitchat mesh traffic at the same time.
  • It works with what you build. The page lists it as compatible with every Offline Protocol app and every project built on the open SDKs.
  • It needs no setup. When it is switched on it starts discovering nearby mesh devices and relaying their messages, with no Wi-Fi and no account.
  • It pairs with the IntelligenceMesh companion app for relay stats, themes and over-the-air firmware updates.
  • It has a developer module system. A JSON-based API lets a React Native app push data over Bluetooth LE for the relay to render on its screen.

A relay like this extends range for the phones and hosts around it, which is the job a fixed node does in a mesh network. For what an ESP32 is and how the chips in the family differ, see what is an ESP32?

offline-protocol-leaf for your own device

offline-protocol-leaf is the Rust crate for firmware teams who want their own device, such as a door lock, a sensor or a mains-powered relay, to be an encrypted Offline Protocol peer. It parses frames, validates addressing and runs RFC 9420 MLS through mls-rs, holding an end-to-end encrypted conversation with a phone under the same guarantees a phone gets: the same frames, the same envelope and the same trust gates. Its API centres on two types:

  • LeafDevice, a frame-level state machine. Hand it an inbound message and it returns the frames to send and what happened.
  • LeafStore, one blob-storage seam the device implements over its secure key storage, with persist-before-emit enforced.

The leaf joins a group as a member that never issues commits. The phone, or another full peer such as a Linux host, creates the group and issues every commit; the device joins, opens, answers and persists. A Raspberry Pi running the Python package is one such full peer. Each leaf pairs with a full peer over the radio path its firmware provides.

The crate builds without the standard library for bare-metal targets, as what is no_std Rust? describes. With Rust 1.87 or newer:

cargo add offline-protocol-leaf@=0.31.0 --no-default-features --features bare-metal-rng

Keep bare-metal-rng and the default std feature apart.

offline-protocol-leaf build targets

As of 0.31.0 (October 2026), offline-protocol-leaf builds for these targets. CI builds and lints the crate for the four bare-metal rows and gates the WASI build:

Chip familyRust targetInside an esp-hal 1.2.2 firmware
Cortex-M33 (for example Silicon Labs xG24)thumbv8m.main-none-eabihfNot applicable
ESP32-C6, ESP32-H2riscv32imac-unknown-none-elfType-checks
ESP32-C3, ESP32-C2riscv32imc-unknown-none-elfSettle one portable-atomic backend (see the notes below)
Cortex-M0 and M0+ (for example RP2040)thumbv6m-none-eabiNot applicable
WebAssembly with WASIwasm32-wasip1Not applicable

The ESP32 rows cover the RISC-V members of the family. The Xtensa chips (the original ESP32, the ESP32-S2 and the ESP32-S3) use Rust targets outside rustup and are not in the crate’s target list.

ESP32 RISC-V and Cortex-M integration notes

Each target family has one or two integration details for the firmware build:

  • ESP32-C6 and ESP32-H2. The crate type-checks in a firmware crate that also depends on esp-hal 1.2.2, checked with cargo check.
  • ESP32-C3 and ESP32-C2. mls-rs and esp-hal 1.2.2 select different portable-atomic backends on these chips, so a firmware that combines the two settles which backend it uses.
  • ESP32-C3, ESP32-C2 and Cortex-M0. These targets have no atomic compare-and-swap, so the firmware links a critical-section implementation.
  • Every target. Build the store handle with shared_store, which works everywhere.

WASI build of the leaf

The leaf also builds for wasm32-wasip1, and CI gates both halves:

  • The no_std build without bare-metal-rng. On WASI, getrandom reads the runtime’s random_get, so the host registers no symbol, and keys are as strong as the runtime’s entropy source.
  • The std build through the wasi_host_shim example. The shim takes the time and the frames from the runtime over its standard streams and prints the frames the device owes.

From an SDK checkout:

rustup target add wasm32-wasip1
cargo build -p offline-protocol-leaf --example wasi_host_shim --target wasm32-wasip1 --release

The WASI target is wasm32-wasip1; wasm32-unknown-unknown is a different target and is not one the crate supports.

Firmware integration for an Offline Protocol leaf

A leaf device’s firmware integrates five things around the crate:

IntegrationWhat firmware supplies
RadioReceive and send protocol frames over the device’s chosen link.
EntropyWire getrandom to the part’s hardware source with getrandom::register_custom_getrandom!. The crate leaves this to the firmware on purpose, so each device uses its own hardware source.
TimePass now_unix_secs at pairing, so key packages carry the right validity and are accepted.
Durable storageImplement LeafStore atomically per entry, so ratchet state survives a power cut intact.
AuthorizationDecide when the radio accepts a pairing and what a given peer may read or actuate. A session proves who a peer is; the firmware decides what that peer is allowed to do.

For internet transport, the firmware either implements a relay client with connection, authentication and address proof, or works beside a companion full peer that already has one. An existing direct upload from the device to its own backend can stay as it is. Measure flash, RAM, latency, power, storage endurance and restart behaviour on the part you choose, as the embedded docs recommend. For the general picture of fitting end-to-end encryption onto a microcontroller, see can a microcontroller run encrypted mesh messaging?

Frequently asked questions

Is there ESP32 hardware that runs Offline Protocol today?

Yes. The IntelligenceMesh Relay is an M5StickC Plus2 with an ESP32-PICO-V3-02, pre-flashed with IntelligenceMesh by Offline Protocol firmware. It relays encrypted Offline Protocol mesh traffic over Bluetooth LE, and Bitchat traffic at the same time, with no setup.

Does the IntelligenceMesh Relay work with apps I build on the SDK?

Yes. The product page says it is compatible with every Offline Protocol app and every project built on the open SDKs. It runs Bluetooth LE in both the peripheral and the central role.

Which ESP32 chips does offline-protocol-leaf build for?

The RISC-V ESP32 chips. The ESP32-C6 and ESP32-H2 use the riscv32imac-unknown-none-elf target, and the ESP32-C3 and ESP32-C2 use riscv32imc-unknown-none-elf. The ESP32-C6 and ESP32-H2 also type-check inside an esp-hal 1.2.2 firmware.

How do leaf devices talk to each other?

Through a full peer, such as a phone or a Linux host. It creates the group and performs every commit, and each leaf pairs with it over the radio path its firmware supplies, so every device in the group reads the same end-to-end encrypted conversation.

How does a leaf device reach the internet?

The firmware either implements a relay client with connection, authentication and address proof, or works beside a companion full peer that already has one. A direct upload the device already makes to its own backend can stay as it is.

Sources

Build it with Offline Protocol

The embedded page covers the full-peer and leaf split, the build targets, the WASI build, the install command and the firmware responsibilities table.

Read Rust and constrained devices