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

> Discover BitChat's dual transport architecture blending Bluetooth mesh and Nostr for resilient offline and online messaging. Experience seamless communication.

- Repository: [permissionlesstech/bitchat](https://github.com/permissionlesstech/bitchat)
- Tags: architecture
- Published: 2026-08-19

---

**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](https://github.com/permissionlesstech/bitchat/blob/main/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](https://github.com/permissionlesstech/bitchat/blob/main/bitchat/ViewModels/ChatOutgoingCoordinator.swift#L97).

## 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`](https://github.com/permissionlesstech/bitchat/blob/main/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](https://github.com/permissionlesstech/bitchat/blob/main/docs/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`](https://github.com/permissionlesstech/bitchat/blob/main/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`](https://github.com/permissionlesstech/bitchat/blob/main/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)

```swift
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)

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

```

### Manual Nostr Invocation (Rarely Needed)

```swift
// 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`](https://github.com/permissionlesstech/bitchat/blob/main/BLEService.swift) and documented in [`BLE-ARCHITECTURE-V3.md`](https://github.com/permissionlesstech/bitchat/blob/main/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`](https://github.com/permissionlesstech/bitchat/blob/main/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.