## bitchat for Android
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. No accounts, no phone numbers, no central servers.
This is the Android implementation of bitchat, fully protocol-compatible with the [iOS version](https://github.com/permissionlesstech/bitchat) for cross-platform mesh communication.
[bitchat.free](http://bitchat.free)
[GitHub Releases](https://github.com/permissionlesstech/bitchat-android/releases)
[
](https://play.google.com/store/apps/details?id=com.bitchat.droid)
## Verify GitHub APKs
GitHub release APKs must match the signing-certificate SHA-256 below. This is the
certificate fingerprint, not the checksum of an APK file. It is the same pin
used by the release tooling in `gradle.properties`.
```text
com.bitchat.droid
3B:03:FA:66:A5:45:13:21:10:07:92:F5:B5:5A:7B:49:66:D5:C8:DC:10:C6:DA:A4:0A:A9:5E:A4:89:53:1B:CA
```
[Copy the verification info](docs/github-apk-verification.txt) for
[AppVerifier](https://github.com/soupslurpr/AppVerifier), which compares the
installed app's package name and signing-certificate hashes with supplied
verification info. You can also verify an APK before installation:
```sh
apksigner verify --print-certs bitchat-android-arm64.apk
```
Verification must succeed, and the reported signer certificate SHA-256 must
match the pin above (ignoring case and colon separators). Stop on a mismatch;
do not uninstall an existing app to bypass a signature conflict. Google Play
can use a different app-signing key, so this pin is specifically for **GitHub
release APKs**, not an assertion about Play-delivered APKs.
For independent authentication, obtain the expected fingerprint through a
separately trusted project channel. A fingerprint and APK downloaded from the
same compromised page are not independent evidence. This repository does not
claim that a second publication channel has been provisioned. See
[the verification guide](docs/reproducible-builds.md) for provenance, payload,
and reproducibility checks and the separate Google Play verification process.
## See it in action
| Offline mesh conversation |
Geohash globe picker |
 |
 |
## License
This project is released into the public domain. See the [LICENSE](LICENSE.md) file for details.
## Features
- **Dual Transport Architecture**: Bluetooth LE mesh for offline messaging, Nostr relays for internet-based messaging
- **Location-Based Channels**: Geographic chat rooms using geohash coordinates over Nostr relays
- **Intelligent Message Routing**: Automatically chooses the best transport, with queuing and retry when a peer is unreachable
- **End-to-End Encryption**: [Noise Protocol](https://noiseprotocol.org) (XX pattern, X25519 + ChaCha20-Poly1305) for private messages over the mesh
- **Decentralized Mesh Network**: Automatic peer discovery and multi-hop relay over Bluetooth LE (max 7 hops)
- **Wi-Fi Aware Transport**: Higher-bandwidth local mesh on supported devices
- **Channel Chats**: Topic-based group messaging with optional password protection (Argon2id + AES-256-GCM)
- **IRC-Style Commands**: Familiar `/join`, `/msg`, `/who` style interface
- **Tor Support**: Built-in Tor (Arti) for private internet connectivity
- **Emergency Wipe**: Triple-tap to instantly clear all data
- **Cross-Platform**: Binary protocol compatible with bitchat on iOS and macOS
## Technical Architecture
### Bluetooth Mesh Network (Offline)
- Direct peer-to-peer within Bluetooth range, multi-hop relay through nearby devices
- Noise Protocol sessions with forward secrecy; peer identities derived from static keys
- Compact binary packet format with fragmentation, TTL routing, and deduplication
- Adaptive duty cycling and connection limits for battery efficiency
- Foreground service keeps the mesh alive within Android background execution limits
### Nostr Protocol (Internet)
- Global reach via public relays, geohash-based location channels
- Private messages fall back to Nostr for mutual favorites when the mesh is unavailable
- Ephemeral keys per geohash area
### Android Stack
- Kotlin, Jetpack Compose (Material 3), MVVM
- Coroutines and Flow for all networking and state
- Core components: `MeshForegroundService` (persistent connectivity), `BluetoothMeshService` / `WifiAwareMeshService` (transports), `UnifiedMeshService` (transport selection), `NoiseSessionManager` (encryption sessions), `MessageRouter` (mesh/Nostr routing with outbox retry)
## Building
Requires Android Studio and the Android SDK (API 26+).
```bash
git clone https://github.com/permissionlesstech/bitchat-android.git
cd bitchat-android
./gradlew assembleDebug
```
Install on a connected device:
```bash
adb install -r app/build/outputs/apk/debug/app-debug.apk
```
The app requests Bluetooth, location (required for BLE scanning), and notification permissions at runtime.
Release APKs and the Android App Bundle can be rebuilt byte-for-byte in the
pinned Linux container. Maintainers should follow the
[Android release guide](docs/maintainer-release-guide.md). See
[Reproducible builds](docs/reproducible-builds.md) for the build trust model
and public GitHub/Google Play verification procedures.
## Testing
```bash
# Unit tests
./gradlew test
# Lint
./gradlew lint
# Instrumented tests (requires a device or emulator)
./gradlew connectedAndroidTest
```
Note that BLE mesh behavior is difficult to emulate; protocol and session logic is covered by unit tests, while radio-level behavior needs real devices.