How BitChat Achieves Global Reach Using the Nostr Protocol
BitChat combines a local Bluetooth mesh with the decentralized Nostr protocol to provide worldwide messaging without central servers, using geohash-based location channels and custom encrypted envelopes.
BitChat is an open-source messaging application that achieves global reach using the Nostr protocol while maintaining offline-first capabilities through Bluetooth mesh networking. Unlike traditional messaging apps that rely on centralized servers or phone number registration, BitChat leverages Nostr's distributed relay network to route messages globally when local peer-to-peer connections are unavailable. This dual-transport architecture ensures users can communicate across any distance without sacrificing privacy or requiring internet infrastructure beyond standard Nostr relays.
Geohash-Based Location Channels for Global Discovery
BitChat routes messages over Nostr relays using location channels identified by geohash prefixes ranging from block-level to city-wide coverage. Each geographic area corresponds to a separate Nostr event kind, allowing peers in the same physical region to discover each other globally through the relay network.
According to the repository documentation, these channels organize presence and messaging by geographic proximity, enabling users to find nearby contacts even when they are not connected via Bluetooth. This design is documented in docs/GeohashPresenceSpec.md and implemented throughout the Nostr transport layer.
Custom Private-Envelope Encryption (Kind 1059)
Rather than reusing existing Nostr Improvement Proposals (NIPs) such as NIP-44, BitChat defines its own encrypted envelope standard. The protocol uses kind-1059 events that carry BitChat-specific payloads encrypted with XChaCha20-Poly1305.
In bitchat/Nostr/NostrEmbeddedBitChat.swift, the encodePMForNostr method constructs these envelopes:
// Encode a private message into a BitChat-over-Nostr envelope
let embedded = NostrEmbeddedBitChat.encodePMForNostr(
content: "Hello world",
messageID: UUID().uuidString,
recipientPeerID: peerID,
senderPeerID: senderPeerID
)!
This custom format ensures that only BitChat clients can decode the message content, providing application-layer encryption independent of the transport method.
Transport Fallback Logic in NostrTransport.swift
The NostrTransport class in bitchat/Services/NostrTransport.swift implements the critical logic that enables global reach. When a user sends a private message, BitChat first attempts delivery via the local Bluetooth mesh. If the recipient is unreachable locally, the system falls back to Nostr automatically.
The transport layer resolves the recipient's Nostr public key (npub) and converts it to hex format before publishing:
// Resolve the recipient's Nostr public key (npub) and convert to hex
private func resolveRecipientNpub(for peerID: PeerID) -> String? {
if let noiseKey = Data(hexString: peerID.id),
let fav = dependencies.favoriteStatusForNoiseKey(noiseKey),
let npub = fav.peerNostrPublicKey {
return npub
}
if peerID.id.count == 16,
let fav = dependencies.favoriteStatusForPeerID(peerID),
let npub = fav.peerNostrPublicKey {
return npub
}
return nil
}
Once resolved, the encrypted envelope is published via the relay manager:
// Publish the envelope via the relay manager
dependencies.sendEvent(event) // `event` created by NostrProtocol.createPrivateMessage
This fallback mechanism ensures that messages reach their destinations whether users are in the same room or on different continents.
Built-in Relay Infrastructure with Tor Support
BitChat ships with a curated set of well-known Nostr relays accessible via both clearnet and .onion Tor endpoints. This built-in relay set eliminates the need for users to configure servers manually while providing resilience against network censorship.
For users in restrictive network environments, the TorURLSession class can route all outbound Nostr traffic through the Tor network. This optional integration, documented in docs/TOR-INTEGRATION.md, provides additional privacy by masking the origin IP address when publishing or querying events from relays.
Acknowledgment Pacing for Relay Stability
To maintain reliability without overwhelming public relays, BitChat implements an AckPacer that regulates the transmission of delivery confirmations and read receipts. This pacing mechanism prevents rate-limiting issues common in decentralized relay networks.
The acknowledgment logic in NostrTransport.swift (lines 84-92) uses a shared pacer to enqueue ACK events:
// Pace acknowledgments to respect relay rate limits
dependencies.ackPacer.enqueue {
// send ACK as a private-envelope Nostr event
}
By spacing these metadata events appropriately, BitChat maintains healthy relay connections while ensuring message delivery status remains accurate across the global network.
Summary
- Geohash channels enable location-based message routing through Nostr relays, allowing global discovery of nearby peers.
- Kind-1059 private envelopes provide custom XChaCha20-Poly1305 encryption specifically designed for BitChat's security model.
- Automatic transport fallback switches from Bluetooth mesh to Nostr relays when local delivery fails, ensuring universal reachability.
- Built-in relay diversity includes both clearnet and Tor endpoints, with optional Tor routing for enhanced privacy.
- Acknowledgment pacing prevents rate-limiting through the
AckPacersystem, maintaining stable connections to public relays.
Frequently Asked Questions
What Nostr event kind does BitChat use for private messages?
BitChat uses kind-1059 for its private message envelopes. This custom event type, defined in NostrEmbeddedBitChat.swift, carries XChaCha20-Poly1305 encrypted payloads rather than using standard NIPs like NIP-44, ensuring compatibility only with BitChat clients.
How does BitChat encrypt messages sent over Nostr?
Messages are encrypted using XChaCha20-Poly1305 within a custom private-envelope format. The encodePMForNostr method in NostrEmbeddedBitChat.swift packages the content into this encrypted structure before transmission via relays, providing end-to-end encryption independent of the Nostr transport layer.
Can BitChat work without an internet connection?
Yes. BitChat operates primarily over a local Bluetooth mesh network that requires no internet infrastructure. The Nostr protocol serves as a fallback mechanism when Bluetooth connectivity is unavailable, ensuring users can communicate both offline and globally through the same application interface.
How does BitChat protect user privacy when using public Nostr relays?
BitChat protects privacy through three mechanisms: custom encryption that prevents relay operators from reading message content, optional Tor routing via TorURLSession that hides IP addresses, and the use of Nostr public keys (npub) instead of phone numbers or email addresses for user identification.
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 →