Skip to the content
Back to Nymchat

Knowledge base Off the internet

Bluetooth mesh

Messaging with no internet, no cell service and no infrastructure of any kind. Nearby devices link over Bluetooth LE and relay for each other, so a message reaches people beyond radio range by hopping through the devices in between.

What the mesh is

The mesh is a second transport running alongside the relays, not a separate app or a separate identity. Public channels and private messages both work over it, and the app decides which route to take on its own: online sends go over the internet and fall back to Bluetooth when it is unavailable, while a peer reachable only over the radio stays on the mesh either way.

It is a flood network. Each device passes packets on to the devices it can hear, with a hop limit of 7, deduplicating what it has already seen so a packet does not circulate forever. Two people who cannot hear each other directly still exchange messages as long as there is a chain of devices between them.

Under that, every pair of peers runs a Noise XX handshake and talks over its own encrypted session. Packets are padded and, when large, fragmented, so the size of what you send says as little as possible about what it is.

A flood only reaches whoever is listening at that moment, so three things carry a message past that: devices remember recent public history and pass it to whoever missed it, nearby peers carry sealed mail for someone out of range, and anything sent with no internet is published later when the internet comes back.

Turning it on

Open the Bluetooth mesh panel and press Turn on. What happens next depends on what you are running it on.

The Nymchat Bluetooth mesh panel, showing mesh status, paired devices, peers on the mesh and a radio log.
The mesh panel: status, paired devices, peers heard, and a live radio log.

On Android and iOS

The app runs both Bluetooth roles at once — advertising itself and scanning for others — so any two nearby devices link up regardless of which one noticed the other. Grant the Bluetooth permission when asked and it finds peers by itself.

In a browser

The web app joins the same mesh through Web Bluetooth, on Chromium browsers: Chrome, Edge, Opera and Brave. On Safari and Firefox, which do not implement Web Bluetooth, the mesh controls are hidden entirely rather than offered and then failing.

A browser joins as a leaf

A browser can only take the Bluetooth central role: it cannot advertise itself, so other devices cannot discover it. It connects outward to nearby phones and relays through them. You pick each device once through the browser's own device chooser, after which it reconnects on its own. Two browsers cannot link to each other directly.

Sharing a mesh with Bitchat

Nymchat implements Bitchat's mesh protocol on the wire, byte for byte — the same GATT service and characteristic UUIDs, the same packet header, the same message types, the same default hop limit. The two apps are not bridged through anything; they are simply on the same mesh, and a Nymchat device and a Bitchat device discover each other and exchange encrypted messages directly.

Announce packets can also carry a nostrLink: a signed link from a mesh peer to their real Nostr identity. When one is present and verifies, a peer you met over Bluetooth shows up as the same person you know from the relays.

The history reconciliation and the carried mail described below are Bitchat's formats too, so the two apps do not just coexist on the same mesh — they sync each other's public history and carry each other's envelopes.

History the mesh carries

A flood delivers a public message to whoever is in radio range at that moment. Walk into the room a minute late and it is gone. So every device keeps a window of the recent public messages it has heard — up to 6 hours, capped at 1,000 packets — and reconciles that window with each peer it meets, roughly every 15 seconds. Whatever you are missing, they send you; whatever they are missing, you send them.

The comparison is done with a compact probabilistic set (a Golomb-coded filter), so reconciling a thousand messages costs about a kilobyte rather than sixteen. It is the same format Bitchat uses, so the two apps sync each other's history rather than each holding half of the room's.

The window is stored on the device, so it survives a restart. That is what lets a phone act as a town crier: walk between two groups that have never been in range of each other, or come back hours later, and it hands over what the other side missed.

Public messages only

Only public traffic is ever carried this way — the messages already visible to anyone in radio range. Private messages, handshakes and encrypted sessions are never part of it.

Mail carried by other people

If you write to someone who is not in radio range, there is nobody to hand the message to. Nymchat seals it to that person's key and gives sealed copies to a few peers who are nearby. They carry it, and deliver it if they meet the recipient.

The copy is opaque to whoever carries it. The only routing information it holds is a tag that rotates daily and can only be computed by someone who already knows the recipient's key, so two envelopes for the same person on different days do not look related to anyone else. Only the recipient can open one — and when they do, they learn who wrote it, because the sender's identity is sealed inside.

Copies do not multiply. Each carrier holds a budget that halves when it hands a share to someone else, so a message spreads to a handful of carriers and then stops. Mail expires after 24 hours, and only peers whose identity has been verified are ever given any.

Where it can, Nymchat seals the envelope to a one-time key rather than to the recipient's long-lived one. Every device publishes a small batch of these, signed so they cannot be faked, and the batch travels the same way carried history does — which is what makes it available while its owner is away, exactly when their mail is being carried. The recipient deletes each key once it has been used. That deletion is the point: an envelope copied off the air cannot be opened afterward, not even by someone who later gets hold of the recipient's identity key.

Deletion waits about 48 hours, because several carriers may be holding copies of the same envelope and they arrive whenever their carriers happen to meet you; deleting on the first one would make every later copy look like lost mail. When a sender has never seen your batch — a device you have not shared a room with — they fall back to your long-lived key. The message still arrives; only that stronger guarantee is missing.

What a carrier learns

Handing someone an envelope tells them that a message exists and that you sent it. Never the content, never who it is for — but the fact. If that trade is not one you want to make, Ghost Mode never uses couriers at all (see below).

Sends made with no internet

A message you send while offline goes out over the radio immediately, which reaches whoever is nearby — and nobody else, because as far as the relays are concerned it never existed. Nymchat holds on to it, and publishes it the moment the internet comes back, keeping its original send time so it stays where you wrote it in the conversation.

Anyone who already received it over Bluetooth will not see it twice: the republished copy carries a marker that lets their device recognize it. Held messages expire after 24 hours; one that never makes it is marked as failed rather than left looking sent.

It does not only wait, though. At the same time, Nymchat asks nearby peers who still have a signal to publish the message on its behalf — one connection in the room is enough for everyone in it. The message is signed by your device before it leaves, so the peer that carries it is a postbox: it cannot change a word of what it publishes, and the relays would reject it if it tried. It works the other way too, so a device with no signal of its own can still read a channel through a neighbour that has one.

This is a shortcut, never the only copy. Nothing tells your device whether a neighbour actually managed to publish, so the message stays queued for your own connection either way. If both work, the two copies are byte-for-byte the same message and the relays keep one. Only channel messages travel this way — asking someone to post a private message would tell them who you are writing to — and never in Ghost Mode, where the signature would point straight back at your real identity.

Ghost Mode

A mesh device is a radio that announces itself repeatedly, which is exactly what makes it easy to follow across places and sessions. Ghost Mode is the opt-in answer.

While it is on, every identifier an announce carries is replaced with a throwaway value, and all of them rotate together:

  • the Noise static key — which the peer ID and fingerprint derive from;
  • the Ed25519 signing key;
  • the advertised Bluetooth name;
  • the nickname;
  • the announced nostrLink, which stays real but becomes ephemeral, so peers can still reach you without anything resolving to your npub.

Rotation happens on a jittered epoch of roughly 15 minutes. Retired identities stay decryptable for up to 8 epochs so a late reply still arrives, and a conversation started while ghosted is pinned to the mesh for good rather than silently migrating to the relays under your real key.

Avatar and banner sharing is refused while Ghost Mode is active: a repeated image links two epochs together faster than any key would.

Two of the delivery paths above are switched off with it, for the same reason. A ghosted device never asks anyone to carry mail for it — a courier still holding an envelope after you rotate is a thread between the two identities. And a conversation pinned to the mesh is never republished to the relays, because that copy would be signed with your real key and tell the other person exactly who the ghost was. A ghosted device also publishes no one-time keys: nothing can be carried to or from it anyway, so the batch would be one more thing the throwaway identity broadcasts for no delivery it could ever earn.

Ghost Mode is not anonymity

It makes a device much harder to follow. It does not make it untraceable. The Bluetooth hardware address is controlled by the operating system, not by the app, and timing and social patterns stay correlatable — the same person, in the same place, talking to the same people, at the same times.

Limits

  • Range is Bluetooth range. Tens of meters in the open, less through walls. The mesh extends reach by hopping, not by shouting louder. The peer list in the mesh panel will tell you which it is: ping a peer and it reports the round trip and how many hops away they actually are.
  • Bandwidth is small. Frames are capped at 512 bytes and larger messages are fragmented. It is built for text, not for media.
  • Delivery is best-effort. A 7-hop flood makes no promises, and neither do the paths that extend it: carried history reaches you only if you meet a device that kept it, and a courier only delivers if it happens to meet the recipient. A message with nobody to carry it waits, and after 24 hours it stops waiting.
  • Browsers are leaves, per above, and depend on a phone being nearby.
  • The radio costs battery, because scanning and advertising continuously is what makes the mesh work.