BitChat Dual Transport Architecture: How Bluetooth Mesh and Nostr Protocol Enable Resilient Messaging

BitChat’s dual transport architecture combines a local Bluetooth Low Energy (BLE) mesh network for offline peer-to-peer communication with the global Nostr relay network for internet-based messaging, automatically selecting the optimal path for every message.

The permissionlesstech/bitchat repository implements a novel messaging stack that prioritizes privacy and resilience by routing communications through two distinct transports. This design ensures messages reach their recipients whether devices are within direct radio range or separated by continents, using BLE for local mesh networking and Nostr for global reach.

What Is the Dual Transport Architecture?

The dual transport architecture in BitChat consists of two complementary networking layers working in tandem. According to the README.md, this approach creates "a decentralized peer-to-peer messaging app with dual transport architecture: local Bluetooth mesh networks for offline communication and internet-based Nostr protocol for global reach."

The system operates on a BLE-first principle. When a user sends a message, BitChat first attempts to transmit via the local Bluetooth mesh. If no BLE path exists, it automatically falls back to the Nostr protocol. If neither transport is available, the message enters a queue until connectivity returns. This automatic selection logic lives in ChatOutgoingCoordinator.sendMessage(_:) at line 97 of ChatOutgoingCoordinator.swift.

Bluetooth Mesh Transport Layer

The Bluetooth Mesh (BLE) transport provides fully offline communication capabilities. Devices discover peers via CoreBluetooth, form a low-power mesh topology, and exchange encrypted packets using the Noise protocol.

Key Characteristics

  • Multi-hop relaying: Messages traverse up to 7 hops, allowing peers far beyond direct radio range to receive communications
  • End-to-end encryption: The Noise protocol provides forward secrecy for live sessions
  • Battery optimization: Automatic duty-cycling and compact binary packet formats minimize power consumption
  • Zero infrastructure: Functions without internet access, making it ideal for disaster zones or network outages

The core implementation resides in Services/BLE/BLEService.swift, specifically within the BLEService.sendMessage(...) method. This file handles peer discovery, mesh formation, and the relay logic detailed in BLE-ARCHITECTURE-V3.md.

Nostr Protocol Transport Layer

When BLE connectivity is unavailable, BitChat falls back to the Nostr Protocol. This transport wraps messages in BitChat-specific private envelopes using XChaCha20-Poly1305 encryption and publishes them as kind-1059 events to geographically-targeted relays.

Key Characteristics

  • Global reach: Access to 440+ public relays ensures worldwide message delivery
  • Geohash channels: Location-based routing supports block-level, neighborhood, and city-scale channels
  • Recipient routing: Uses the recipient’s Nostr public key for routing while maintaining app-specific encryption
  • Private envelopes: Messages remain encrypted even from relay operators

The Nostr implementation lives in Services/NostrTransport.swift, which provides the minimal wrapper needed to publish BitChat private envelopes to the relay network.

How Transport Selection Works

The transport selection logic follows a specific hierarchy defined in ChatOutgoingCoordinator.swift. When sendMessage(_:) is invoked, the coordinator evaluates the following conditions:

  1. Trim and validate the message, ignoring empty strings or local commands
  2. Handle slash commands locally without network transmission
  3. Check for private-chat peers: If a specific recipient is selected, attempt BLE direct message first, then fall back to Nostr
  4. Route by channel type:
    • .mesh channels: Invoke BLEService.sendMessage(...) to transmit via the Bluetooth mesh
    • Location channels: Serialize into Nostr kind-1059 events and publish to geohash-targeted relays

This architecture ensures that the local mesh remains the preferred path for speed and privacy, while the internet path provides resilience when devices are out of BLE range.

Implementing Dual Transport in Code

Developers interacting with the BitChat codebase can leverage the dual transport stack through the coordinator or direct service calls.

Sending a Public Message (BLE First, Nostr Fallback)

let coordinator = ChatOutgoingCoordinator(context: someContext)

// Transmits over BLE mesh if peers are available,
// otherwise publishes to Nostr relays automatically
coordinator.sendMessage("Hello world")

Sending a Private Message (BLE Direct)

// Forces BLE-only transmission to a specific peer
BLEService.shared.sendMessage(
    "Secret note",
    mentions: [],
    to: PeerID("alice-device-id")
)

Manual Nostr Invocation (Rarely Needed)

// Direct Nostr transmission when automatic selection is bypassed
NostrTransport.shared.sendMessage(
    "Hello from the internet",
    mentions: []
)

Summary

  • BitChat’s dual transport architecture combines local Bluetooth mesh networking with global Nostr relay connectivity to maximize message delivery resilience.
  • BLE transport provides offline, multi-hop messaging with Noise protocol encryption, implemented in BLEService.swift and documented in BLE-ARCHITECTURE-V3.md.
  • Nostr transport offers global reach via kind-1059 events and XChaCha20-Poly1305 encryption, handling geographic routing through geohash channels.
  • Automatic selection occurs in ChatOutgoingCoordinator.swift, which prioritizes BLE for .mesh channels and falls back to Nostr for internet-based delivery.
  • Both transports use distinct encryption schemes but maintain end-to-end security, ensuring messages remain private from both relay operators and intermediate mesh nodes.

Frequently Asked Questions

How does BitChat decide whether to use Bluetooth or Nostr?

BitChat follows a BLE-first routing strategy implemented in ChatOutgoingCoordinator.sendMessage(_:). If the active channel is .mesh and BLE peers are available, it transmits via BLEService.sendMessage(...). If no BLE path exists or the channel requires global reach, it automatically serializes the message as a Nostr kind-1059 event and publishes to geohash-targeted relays.

What encryption does each transport layer use?

The Bluetooth mesh layer uses the Noise protocol for forward-secret session encryption, while the Nostr layer wraps messages in XChaCha20-Poly1305 private envelopes. This means BLE transmissions are encrypted hop-by-hop through the mesh, and Nostr events remain encrypted from the 440+ relays that store and forward them.

Can BitChat function without any internet connection?

Yes. The Bluetooth Mesh transport operates entirely offline, allowing devices to form local networks and relay messages up to 7 hops without internet access. This makes BitChat functional in disaster scenarios, protests, or remote areas where infrastructure has failed, though messages cannot reach recipients outside the physical mesh range without the Nostr fallback.

What are geohash channels in BitChat?

Geohash channels are location-based routing mechanisms in the Nostr transport layer. Instead of broadcasting globally, BitChat publishes kind-1059 events to relays targeting specific geographic precision levels—ranging from city-wide to block-level granularity. This reduces relay spam and enables location-specific communication while maintaining the decentralized architecture.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →