Offline Bluetooth mesh chat + worldwide end-to-end encrypted DMs.
No accounts. No phone numbers. Messages hop phone-to-phone over BLE when offline, or travel the world as pure E2E ciphertext over public Nostr relays.
| Product name | Bitconnect |
| Version | 1.3.0+ (mesh protocol v2) |
| Platforms | Android (primary), iOS scaffolded |
| Workspace path | C:\bitconnect |
- Multi-hop BLE gossip on multiple channels (
#local,#general,#alerts, custom) - High TX power + low-latency scan for better practical range
- Phones relay for each other (effective range grows with density)
- Signed public posts (Ed25519); optional group E2E with a shared channel key
- Images over mesh — compressed, multi-chunk transfer, one bubble, tap to open full screen
- Delivery ACKs and read receipts (✓ / ✓✓)
- Store-and-forward ferry for text when peers reappear
- Power modes: Performance / Balanced / Saver (LPN-style)
- Private 1:1 DMs India ↔ USA (or any distance) when both have internet
- X25519 ECDH + ChaCha20-Poly1305 encryption on-device
- Relays cannot read message text
- Share identity via copy ID or paste
- Default mesh channels (
#local, etc.) are readable by anyone on the mesh - Use Create E2E group in Settings for encrypted local rooms
dist/bitconnect-release.apk
Most modern phones: arm64. Prefer a split ABI build for smaller size (see below).
adb install -r dist\bitconnect-release.apkOr copy the APK to the phone and open it (allow install from unknown sources).
Requirements: Android 8+ (API 26), Bluetooth for mesh, Internet for Worldwide DMs.
A single “fat” APK bundles multiple CPU architectures (~70MB+). Split builds are much smaller:
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-17.0.19.10-hotspot"
$env:ANDROID_HOME = "$env:LOCALAPPDATA\Android\Sdk"
$env:PATH = "$env:JAVA_HOME\bin;C:\Users\hafil\flutter\bin;$env:PATH"
cd apps/mobile
flutter pub get
flutter build apk --release --split-per-abiOutputs:
| File | Use |
|---|---|
app-arm64-v8a-release.apk |
Most modern phones (use this) |
app-armeabi-v7a-release.apk |
Older 32-bit phones |
app-x86_64-release.apk |
Emulators |
Copy the one you need:
copy build\app\outputs\flutter-apk\app-arm64-v8a-release.apk ..\..\dist\bitconnect-release.apkBottom navigation:
| Tab | Purpose |
|---|---|
| Local | Mesh channel chat, start/stop mesh, photos, receipts |
| Worldwide | E2E DMs, connect relays, contacts |
In-app:
| Entry | Purpose |
|---|---|
| Tune / Settings | Power mode, public channels, create/join encrypted groups |
| Channel chips | Switch #local / custom channels |
| Image | Attach photo (mesh: compressed multi-chunk; Worldwide: larger) |
| Tap image | Full-screen pinch-zoom viewer |
- Mesh images are compressed for BLE multi-chunk delivery: max 720px, JPEG ~56 KB target, down-scaled with high-quality average interpolation to preserve clarity within the BLE size limit.
- Worldwide images keep a larger 1024px / ~140 KB envelope for internet E2E.
- Rendering uses
FilterQuality.highin both the chat bubble and the full-screen viewer for the sharpest on-screen result. - Binary file packet (TLV: name / size / mime / content) — not JSON base64 chat spam.
- Split into binary BLE fragments, reassembled into one bubble.
- Tap the thumbnail → full-screen open.
- Prefer Worldwide if you need much larger photos (mesh is capped by BLE fragment size).
- Install Bitconnect on both devices.
- Set nicknames.
- Local → start mesh (tether icon) → allow Bluetooth / nearby devices.
- Chat on
#local. Keep the app open for best results. - Optional: ⋮ menu → Simulator mode for single-device multi-hop tests.
- Both phones online.
- Worldwide → Copy my ID.
- Friend pastes your ID → Save & chat.
- Connect relays → send locked messages.
- Settings → channel name → Create E2E group.
- Share the key out-of-band (secure chat / in person).
- Friend: Settings → paste key → Join encrypted channel.
apps/mobile/ Flutter app (Material 3 dark theme)
assets/branding/ App logo
lib/src/
theme/ Brand theme
screens/ Local, Worldwide, Settings, image viewer
widgets/ Bubbles, chips, composer
packages/
mesh_protocol/ Packets, gossip, crypto, ferry, media chunks (pure Dart)
mesh_transport/ FakeTransport + multi-node sim fabric
mesh_ble/ BLE central + Android dual-role bridge
mesh_internet/ Nostr client + Internet E2E service
docs/
PROTOCOL.md Mesh wire format
E2E_INTERNET.md Internet E2E threat model
DEMO.md Multi-phone demo checklist
dist/
bitconnect-release.apk Installable build (when present)
┌──────────────────────────────────────────────────┐
│ Flutter UI (Local | Worldwide) │
│ Theme · Settings · Image viewer │
├────────────────────┬─────────────────────────────┤
│ MeshController │ Identity (Ed25519+X25519) │
├────────────────────┼─────────────────────────────┤
│ MeshNode │ InternetE2eService │
│ gossip · ACK/read │ Nostr relays (ciphertext) │
│ ferry · rate limit│ X25519 sealed boxes │
│ group crypto │ │
│ media chunks │ │
├────────────────────┼─────────────────────────────┤
│ BLE / Fake │ WebSocket relays │
└────────────────────┴─────────────────────────────┘
mesh_protocolhas no Flutter dependency — unit-tested.- Bitconnect ID (shareable) = X25519 public key hex (64 chars).
| Item | Value | Why |
|---|---|---|
Android applicationId |
app.bitconnect.bitconnect |
Stable installs/upgrades |
| Flutter package name | bitconnect |
Import / path stability |
| Secure storage keys | bitconnect_* |
Existing identities still load |
| Protocol tags | bitconnect-e2e-v1, magic NT |
Wire compatibility |
- Flutter 3.22+ (e.g.
C:\Users\hafil\flutter) - JDK 17 for Android builds (JDK 26 is too new for current Gradle)
- Android SDK (
%LOCALAPPDATA%\Android\Sdk)
$env:PATH = "C:\Users\hafil\flutter\bin;$env:PATH"
$env:JAVA_HOME = "C:\Program Files\Eclipse Adoptium\jdk-17.0.19.10-hotspot"
flutter doctorcd apps/mobile
flutter pub get
flutter runcd packages/mesh_protocol
dart pub get
dart testCovers multi-hop gossip, E2E seal/open, rate limit, ferry, group crypto.
| Surface | Behavior |
|---|---|
| Public mesh channels | Not confidential — anyone on the mesh can read |
| Encrypted mesh groups | Shared-key E2E (share key out-of-band) |
| Worldwide DMs | Pure E2E; relays see ciphertext only |
| Nicknames | Not unique — trust fingerprint / Bitconnect ID |
| Keys | flutter_secure_storage on device |
Do not put secrets on open #local. Use Worldwide E2E or an encrypted group.
Details: docs/E2E_INTERNET.md · docs/PROTOCOL.md
| Topic | Reality |
|---|---|
| BLE range | ~tens of meters per hop; multi-hop needs intermediate phones |
| Mesh images | Small thumbnails by design; large photos use Worldwide |
| Background mesh | Best with app open; iOS dual-role is best-effort |
| Nostr delivery | Depends on public relays (no guarantee like WhatsApp) |
| App size | Prefer --split-per-abi; fat multi-ABI APK is larger |
| Signing | Release APK uses debug signing (sideload OK, not Play Store) |
See docs/DEMO.md for two-phone mesh, multi-hop, and Worldwide E2E acceptance steps.
MIT — see LICENSE.