What Are the Two Transport Layers Used in BitChat? A Deep Dive into the Hybrid Architecture
BitChat combines a Bluetooth Mesh Network for offline peer-to-peer communication and the Nostr Protocol for internet-based global messaging, automatically routing messages through whichever transport layer is available.
The permissionlesstech/bitchat repository implements a sophisticated dual-transport architecture that ensures messages can be sent whether users are standing next to each other or across the globe. This hybrid approach eliminates dependency on centralized servers while maintaining privacy through end-to-end encryption across both transport layers used in BitChat.
The Bluetooth Mesh Transport Layer (Offline)
BitChat's first transport layer leverages Bluetooth Low Energy (BLE) to create a local mesh network that operates entirely without internet connectivity.
Core Implementation in BLEService.swift
The offline transport is implemented in bitchat/Services/BLE/BLEService.swift, which handles direct BLE links with multi-hop routing capabilities supporting up to 7 hops between devices. The service manages automatic peer discovery and duty-cycled power management to preserve battery life during extended offline use.
When a device enters range, BLEService initiates a Noise-encrypted session using compact binary packets. This design ensures that even in crowded RF environments, the protocol maintains low latency for real-time chat, voice bursts, and file transfers.
Security and Routing Features
The Bluetooth transport layer uses the Noise protocol framework for handshake and encryption, providing forward secrecy without requiring pre-shared keys. Adaptive power management adjusts transmission strength based on distance to neighboring nodes, while the mesh topology allows messages to hop through intermediate devices to reach recipients outside direct radio range.
The Nostr Protocol Transport Layer (Internet)
When offline mesh connectivity is unavailable, BitChat falls back to its second transport layer: the Nostr protocol (nprotocol), a decentralized relay network that provides global message delivery.
Global Relay Network Implementation
The internet transport is managed by bitchat/Nostr/NostrRelayManager.swift, which maintains websocket connections to public Nostr relays. Unlike traditional client-server messaging, this approach distributes messages across a federated network of relays, preventing any single point of failure or censorship.
BitChat extends standard Nostr functionality by supporting location-based channels derived from geohash coordinates, enabling local community discovery even when using global internet infrastructure.
Encryption and Event Structure
Messages sent via Nostr are wrapped in BitChat's private-envelope format, which encrypts payloads using XChaCha20-Poly1305 before transmission. These encrypted envelopes are embedded inside Nostr kind-1059 events, as defined in bitchat/Nostr/NostrProtocol.swift. This double-layer encryption ensures that relay operators cannot read message contents, while the standard Nostr event format maintains compatibility with the broader relay ecosystem.
How BitChat's Transport Layers Work Together
BitChat's MessageRouter intelligently selects between transport layers based on real-time connectivity conditions, implemented and tested in bitchat/Services/MessageRouterTests.swift.
Bluetooth-First Routing Logic
The application always attempts Bluetooth-first delivery. When preparing to send a message, BitCheck checks BLEService.shared.isConnected(to: recipientID). If the recipient is within BLE range, the message transmits directly through the encrypted mesh layer without ever touching the internet.
// Prepare a chat payload
let payload = ChatMessage(text: "Hello, world!", channel: .local)
// Try Bluetooth first
if BLEService.shared.isConnected(to: recipientID) {
BLEService.shared.send(payload, to: recipientID)
} else {
// Fallback to Nostr
NostrRelayManager.shared.send(payload, to: recipientPublicKey)
}
Smart Queuing and Fallback Mechanisms
When no BLE route exists—either because the recipient is out of range or offline—the system automatically falls back to NostrRelayManager. Outgoing messages enter a local queue when both transport layers are unavailable, resuming delivery automatically when either Bluetooth or Nostr connectivity returns.
This hybrid design grants offline resilience through the mesh network and global accessibility through Nostr, all without requiring phone numbers, user accounts, or central servers.
Code Examples
Sending via Bluetooth Mesh
In BLEService.swift, the send(_:to:) function transmits Noise-encrypted binary data directly to peer characteristics:
// BLEService.swift – sending a packet
func send(_ packet: BitchatPacket, to peer: PeerID) {
// Packet is already Noise-encrypted
let data = packet.toBinaryData()
peripheral.writeValue(data, for: characteristic, type: .withResponse)
}
Sending via Nostr Relay
The NostrRelayManager constructs encrypted envelopes before forwarding to websocket relays:
// NostrRelayManager.swift – sending over Nostr
func send(_ payload: ChatMessage, to pubKey: Data) {
let envelope = PrivateEnvelope(message: payload, recipientKey: pubKey)
let event = NostrEvent(kind: 1059, content: envelope.serialized)
relayConnection?.send(.data(event.encode()), completionHandler: { _ in … })
}
Summary
- Dual-transport architecture: BitChat uses Bluetooth Mesh for local offline communication and Nostr Protocol for internet-based global messaging.
- Bluetooth layer: Implemented in
BLEService.swift, supports 7-hop mesh routing, Noise protocol encryption, and duty-cycled power management. - Nostr layer: Managed by
NostrRelayManager.swift, useskind-1059events with XChaCha20-Poly1305 encrypted envelopes for relay-based delivery. - Intelligent routing: Bluetooth-first with automatic Nostr fallback, plus local message queuing when both layers are unavailable.
- Privacy-preserving: No phone numbers or central servers required; end-to-end encryption protects content across both transport layers.
Frequently Asked Questions
What are the two transport layers used in BitChat?
BitChat uses a Bluetooth Mesh Network for offline peer-to-peer communication and the Nostr Protocol for internet-based messaging. The Bluetooth layer handles local device-to-device communication through BLE, while the Nostr layer connects to global websocket relays when offline mesh connectivity is unavailable.
How does BitChat decide between Bluetooth and Nostr transports?
BitChat implements a Bluetooth-first routing strategy. The MessageRouter checks BLEService.shared.isConnected() to determine if the recipient is within direct radio range. If true, it sends via the encrypted mesh network. If false, it automatically falls back to NostrRelayManager to deliver the message through internet relays.
Is BitChat truly offline-capable without internet?
Yes. When devices are within approximately 30-100 meters of each other (or up to 7 hops through intermediate devices), BitChat can send text, voice, and files entirely over Bluetooth Mesh without cellular data, WiFi, or any internet connection. The Noise protocol encryption ensures these offline messages remain secure even in broadcast RF environments.
What encryption protocols secure BitChat's transport layers?
BitChat uses the Noise protocol for Bluetooth transport, providing forward secrecy and mutual authentication during BLE sessions. For Nostr transport, messages are encrypted using XChaCha20-Poly1305 inside a private envelope format before being wrapped in Nostr events, ensuring relay operators cannot access plaintext content.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →