Offline Bluetooth P2P mesh messenger with channels and end‑to‑end encryption.
- Public channel (plaintext) for bring‑up
- Private channels (Sender Keys, AEAD ChaCha20‑Poly1305)
- 1:1 Direct Messages with X3DH bootstrap (control channel) + Double Ratchet (send/recv chains)
- Store‑and‑forward mesh over BLE, TTL + hop relay + de‑dup
- Transports: Android (BLE + Nearby), iOS (BLE + MultipeerConnectivity)
- Background: Android ForegroundService; iOS background modes
- Persistence: channels, messages (per‑bubble delivery persisted), identity
- Invites: QR, text invite code; preview name/type; sender key hash; Invite Inbox (accept/decline)
- Channels: member management (add/remove, roles), signed re‑key with verification, pinned channels
- Chat UX: long‑press Copy/Delete, swipe‑to‑delete (own messages), delivery receipts per bubble
- Diagnostics: BLE Capabilities, Scan control, Raw scan count, RSSI per peer, Active links with MTU, Throughput/Loss (kbps, counts, acks, duplicates), transport chip in Chat
Prereqs: Flutter stable (3.35+), Android SDK, Xcode for iOS.
Android:
flutter build apkiOS:
open ios/Runner.xcworkspace # build from XcodeAndroid Manifest includes:
- BLUETOOTH, BLUETOOTH_ADMIN (maxSdk 30)
- BLUETOOTH_SCAN, BLUETOOTH_CONNECT, BLUETOOTH_ADVERTISE
- FOREGROUND_SERVICE, POST_NOTIFICATIONS
- REQUEST_IGNORE_BATTERY_OPTIMIZATIONS (prompt shown only while app is in use)
- Foreground service
MeshForegroundService(connectedDevice|dataSync)
iOS Info.plist:
- UIBackgroundModes: bluetooth‑central, bluetooth‑peripheral
- NSBluetoothAlwaysUsageDescription: Bluetooth relaying for offline messaging
- Onboard
- Set your Display Name; see Safety Number (text + QR). You can edit later in Settings.
- Run Quick Setup to grant Bluetooth/Location and disable battery optimization (Android).
- Channels
- Create a channel (toggle Private for encrypted)
- Share via: QR Invite, Invite Code, or Sender Key Hash (verify)
- Join via: Scan QR or paste Invite Code
- Chat
- Messages relay across multiple hops. Private channels encrypt/decrypt automatically.
- Tooltip on bubbles shows sent time. Delivery receipts are shown per bubble (via ACK hop count).
- Peers
- See nearby devices (Mesh service or name). Open a DM or send a channel invite.
- Manual Connect button can force a BLE link.
- Use Diagnostics tiles to verify: Adapter=true, BLE=true, Adv=true (>=1 device), Scan=Running, Raw scan>0.
- Re‑key & Members
- Private channels auto‑rotate Sender Keys periodically (and on demand). Rekey messages are signed and verified.
- Channel Details lets you add/remove members and set roles; updates are signed and propagated.
- Chat shows a banner prompting verification after a re‑key.
See TESTING.md for field tests (corridor, multi‑room, outdoor) and battery notes. Use Throughput/Loss and the transport chip to validate delivery.
Vendor notes:
- Xiaomi/MIUI: Allow Autostart; Battery saver → No restrictions for MeshChat; grant Nearby Devices and Location; ensure Location is ON.
- Tecno/HiOS: Allow background activity; No battery restrictions; grant Nearby Devices and Location; ensure Location is ON.
Summary in SECURITY.md. Keys are stored using flutter_secure_storage. Private channels use Sender Keys (ChaCha20‑Poly1305). 1:1 sessions use X3DH to derive a shared secret and Double Ratchet for forward secrecy.
- Member management (add/remove, roles), full membership sync
- Re‑key announcement security hardening (signature + replay protection)
- Background delivery receipts batching; richer diagnostics (RSSI/hops per link)
- Identity export/import UI; Battery Mode (Normal/Aggressive)
This project is licensed under the GNU General Public License v2.0 (GPL‑2.0).
See the LICENSE file for details.