diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..d6f26d7b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,185 @@ +name: Build BitChat Android APKs + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + workflow_dispatch: + inputs: + build_type: + description: 'Build type' + required: true + default: 'all' + type: choice + options: + - all + - debug + - release + +env: + JAVA_VERSION: '17' + JAVA_DISTRIBUTION: 'temurin' + +jobs: + build: + name: Build APKs + runs-on: ubuntu-latest + timeout-minutes: 60 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up JDK ${{ env.JAVA_VERSION }} + uses: actions/setup-java@v4 + with: + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRIBUTION }} + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Cache Gradle packages + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Build Debug APK + if: ${{ github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'debug' || github.event.inputs.build_type == '' }} + run: ./gradlew assembleDebug --no-daemon --max-workers=2 + continue-on-error: false + + - name: Generate Release Keystore + if: ${{ github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'release' || github.event.inputs.build_type == '' }} + env: + KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} + run: | + if [ ! -f "bitchat-release.keystore" ]; then + echo "Generating keystore for release build..." + keytool -genkeypair -v \ + -keystore bitchat-release.keystore \ + -alias bitchat \ + -keyalg RSA \ + -keysize 2048 \ + -validity 10000 \ + -storepass "${KEYSTORE_PASSWORD:-BitchatRelease2025!}" \ + -keypass "${KEYSTORE_PASSWORD:-BitchatRelease2025!}" \ + -dname "CN=BitChat Android, OU=Security, O=Permissionless Tech, L=Global, ST=World, C=US" + + # Create keystore.properties + echo "storeFile=bitchat-release.keystore" > app/keystore.properties + echo "storePassword=${KEYSTORE_PASSWORD:-BitchatRelease2025!}" >> app/keystore.properties + echo "keyAlias=bitchat" >> app/keystore.properties + echo "keyPassword=${KEYSTORE_PASSWORD:-BitchatRelease2025!}" >> app/keystore.properties + fi + + - name: Build Release APK + if: ${{ github.event.inputs.build_type == 'all' || github.event.inputs.build_type == 'release' || github.event.inputs.build_type == '' }} + run: ./gradlew assembleRelease --no-daemon --max-workers=2 + continue-on-error: true + + - name: List APK files + run: | + echo "=== Debug APKs ===" + find app/build/outputs/apk/debug -name "*.apk" -exec ls -lh {} \; 2>/dev/null || echo "No debug APKs found" + echo "" + echo "=== Release APKs ===" + find app/build/outputs/apk/release -name "*.apk" -exec ls -lh {} \; 2>/dev/null || echo "No release APKs found" + + - name: Upload Debug APKs + if: always() + uses: actions/upload-artifact@v4 + with: + name: debug-apks + path: app/build/outputs/apk/debug/*.apk + retention-days: 30 + if-no-files-found: warn + + - name: Upload Release APKs + if: always() + uses: actions/upload-artifact@v4 + with: + name: release-apks + path: app/build/outputs/apk/release/*.apk + retention-days: 30 + if-no-files-found: warn + + - name: Upload Release Keystore + if: success() + uses: actions/upload-artifact@v4 + with: + name: keystore + path: bitchat-release.keystore + retention-days: 90 + if-no-files-found: ignore + + - name: Create Release + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} + uses: softprops/action-gh-release@v1 + with: + tag_name: v1.7.2-${{ github.run_number }} + name: BitChat Android ${{ github.run_number }} + body: | + ## BitChat Android Build + + **Build Number:** ${{ github.run_number }} + **Commit:** ${{ github.sha }} + + ### APKs Included: + - Debug APKs (for testing) + - Release APKs (signed, for production) + + ### Installation: + 1. Download the appropriate APK for your device + 2. Enable "Install from unknown sources" + 3. Open the APK to install + files: | + app/build/outputs/apk/debug/*.apk + app/build/outputs/apk/release/*.apk + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + test: + name: Run Tests + runs-on: ubuntu-latest + needs: build + if: always() + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK ${{ env.JAVA_VERSION }} + uses: actions/setup-java@v4 + with: + java-version: ${{ env.JAVA_VERSION }} + distribution: ${{ env.JAVA_DISTRIBUTION }} + + - name: Setup Android SDK + uses: android-actions/setup-android@v3 + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Run unit tests + run: ./gradlew test --no-daemon + continue-on-error: true + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: app/build/reports/tests/ + retention-days: 7 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 64ac199e..e83f16ed 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,9 @@ google-services.json # Arti build artifacts (cloned repo and Rust build cache) tools/arti-build/.arti-source/ tools/arti-build/target/ + +# Keystore properties (secrets) +keystore.properties + +# Kotlin build sessions +.kotlin/ diff --git a/CODEBASE_ANALYSIS.md b/CODEBASE_ANALYSIS.md new file mode 100644 index 00000000..64a1de72 --- /dev/null +++ b/CODEBASE_ANALYSIS.md @@ -0,0 +1,1185 @@ +# BitChat Android - Comprehensive Codebase Analysis + +## Executive Summary + +**BitChat Android** is a sophisticated, secure, decentralized messaging application built with modern Android technologies. It implements a Bluetooth mesh network for peer-to-peer communication while maintaining 100% protocol compatibility with the iOS version. The app features end-to-end encryption, Tor integration for privacy, Nostr protocol support for geohash-based location channels, and a polished Jetpack Compose UI. + +**Repository:** `git@github.com:Satoshi-NaAkokwa/ikorochat-android.git` +**Note:** Repository name is "ikorochat-android" but contains the "BitChat Android" app (package: `com.bitchat.droid`) + +--- + +## 1. Project Architecture + +### 1.1 Technology Stack + +| Component | Technology | Version | Purpose | +|-----------|-----------|---------|---------| +| **Language** | Kotlin | 2.2.0 | Primary development language | +| **UI Framework** | Jetpack Compose | BOM 2025.06.01 | Declarative UI | +| **Design System** | Material Design 3 | Latest | Modern UI components | +| **Build System** | Gradle | 8.13 | Build automation | +| **Android Gradle Plugin** | AGP | 8.10.1 | Android build configuration | +| **Min SDK** | Android | 8.0 (API 26) | Minimum supported version | +| **Target SDK** | Android | 15 (API 35) | Target version | +| **Compile SDK** | Android | 15 (API 35) | Compilation target | + +### 1.2 Core Architecture Patterns + +1. **MVVM (Model-View-ViewModel)** - Separation of concerns for UI logic +2. **Repository Pattern** - Data layer abstraction +3. **Coordinator Pattern** - Complex navigation flows +4. **Service-Based Architecture** - Background mesh networking +5. **Protocol Layer** - Binary protocol handling + +### 1.3 Project Structure + +``` +app/src/main/ +├── java/com/bitchat/android/ +│ ├── BitchatApplication.kt # Application class +│ ├── MainActivity.kt # Main activity +│ ├── MainViewModel.kt # Global state +│ │ +│ ├── mesh/ # Bluetooth mesh networking +│ │ ├── BluetoothMeshService.kt # Core mesh coordinator +│ │ ├── BluetoothConnectionManager.kt # Connection lifecycle +│ │ ├── BluetoothGattClientManager.kt # GATT client role +│ │ ├── BluetoothGattServerManager.kt # GATT server role +│ │ ├── BluetoothPacketBroadcaster.kt # Packet transmission +│ │ ├── BluetoothConnectionTracker.kt # Connection state tracking +│ │ ├── BluetoothPermissionManager.kt # Permission handling +│ │ ├── PeerManager.kt # Peer state management +│ │ ├── SecurityManager.kt # Security & deduplication +│ │ ├── StoreForwardManager.kt # Offline message caching +│ │ ├── MessageHandler.kt # Message processing +│ │ ├── PacketProcessor.kt # Incoming packet routing +│ │ ├── PacketRelayManager.kt # Relay logic +│ │ ├── PeerFingerprintManager.kt # Peer identity +│ │ ├── PowerManager.kt # Battery optimization +│ │ ├── FragmentManager.kt # Message fragmentation +│ │ └── TransferProgressManager.kt # File transfer tracking +│ │ +│ ├── protocol/ # Binary protocol +│ │ ├── BinaryProtocol.kt # Packet encoding/decoding +│ │ ├── CompressionUtil.kt # LZ4 compression +│ │ └── MessagePadding.kt # Padding for security +│ │ +│ ├── noise/ # Noise Protocol implementation +│ │ ├── NoiseSession.kt # Session management +│ │ ├── NoiseSessionManager.kt # Session lifecycle +│ │ ├── NoiseChannelEncryption.kt # Channel encryption +│ │ └── NoiseEncryptionService.kt # Encryption service +│ │ +│ ├── crypto/ # Cryptography +│ │ └── EncryptionService.kt # X25519/Ed25519 operations +│ │ +│ ├── model/ # Data models +│ │ ├── BitchatMessage.kt # Message model +│ │ ├── BitchatFilePacket.kt # File transfer model +│ │ ├── FragmentPayload.kt # Fragmentation model +│ │ ├── IdentityAnnouncement.kt # Peer announcement +│ │ ├── NoiseEncrypted.kt # Encrypted payload +│ │ ├── RequestSyncPacket.kt # Sync request +│ │ └── RoutedPacket.kt # Routing wrapper +│ │ +│ ├── nostr/ # Nostr protocol client +│ │ ├── NostrProtocol.kt # NIP implementation +│ │ ├── NostrEvent.kt # Event model +│ │ ├── NostrIdentity.kt # Identity management +│ │ ├── NostrRelayManager.kt # Relay connections +│ │ ├── NostrTransport.kt # Network transport +│ │ ├── NostrSubscriptionManager.kt # Subscription management +│ │ ├── NostrRequest.kt # Request handling +│ │ ├── NostrCrypto.kt # Cryptographic operations +│ │ ├── NostrDirectMessageHandler.kt # DM handling +│ │ ├── NostrEmbeddedBitChat.kt # Embedded BitChat messages +│ │ ├── NostrEventDeduplicator.kt # Event deduplication +│ │ ├── NostrProofOfWork.kt # PoW mining +│ │ ├── PoWPreferenceManager.kt # PoW settings +│ │ ├── GeohashMessageHandler.kt # Geohash message handling +│ │ ├── GeohashAliasRegistry.kt # Alias persistence +│ │ ├── GeohashConversationRegistry.kt # Conversation metadata +│ │ ├── LocationNotesManager.kt # Location note management +│ │ ├── LocationNotesInitializer.kt # Initialization +│ │ ├── LocationNotesSheetPresenter.kt # UI presentation +│ │ ├── RelayDirectory.kt # Relay discovery +│ │ └── Bech32.kt # Address encoding +│ │ +│ ├── net/ # Network layer +│ │ ├── ArtiTorManager.kt # Tor integration (Arti) +│ │ ├── TorMode.kt # Tor mode enum +│ │ ├── TorPreferenceManager.kt # Tor settings +│ │ └── OkHttpProvider.kt # HTTP client +│ │ +│ ├── geohash/ # Location features +│ │ ├── Geohash.kt # Geohash encoding +│ │ ├── LocationChannel.kt # Channel model +│ │ ├── LocationChannelManager.kt # Channel management +│ │ ├── FusedLocationProvider.kt # Google Play Location +│ │ ├── SystemLocationProvider.kt # System location +│ │ ├── LocationProvider.kt # Provider interface +│ │ ├── GeocoderProvider.kt # Geocoding interface +│ │ ├── AndroidGeocoderProvider.kt # Android geocoder +│ │ ├── OpenStreetMapGeocoderProvider.kt # OSM geocoder +│ │ ├── GeocoderFactory.kt # Geocoder selection +│ │ └── GeohashBookmarksStore.kt # Bookmarks persistence +│ │ +│ ├── sync/ # Sync protocol +│ │ ├── GossipSyncManager.kt # Gossip-based sync +│ │ ├── GCSFilter.kt # Counting Bloom filter +│ │ ├── PacketIdUtil.kt # Packet ID utilities +│ │ └── SyncDefaults.kt # Default sync settings +│ │ +│ ├── services/ # Background services +│ │ ├── MeshForegroundService.kt # Foreground service +│ │ ├── MeshServiceHolder.kt # Service lifecycle +│ │ ├── MeshServicePreferences.kt # Service settings +│ │ ├── BootCompletedReceiver.kt # Boot receiver +│ │ ├── AppShutdownCoordinator.kt # Shutdown coordination +│ │ ├── AppStateStore.kt # App state persistence +│ │ ├── MessageRetentionService.kt # Message retention +│ │ ├── MessageRouter.kt # Message routing +│ │ ├── NicknameProvider.kt # Nickname resolution +│ │ ├── VerificationService.kt # Peer verification +│ │ ├── SeenMessageStore.kt # Seen message tracking +│ │ ├── ConversationAliasResolver.kt # Alias resolution +│ │ ├── meshgraph/ +│ │ │ ├── MeshGraphService.kt # Topology discovery +│ │ │ ├── RoutePlanner.kt # Route calculation +│ │ │ └── GossipTLV.kt # Gossip TLV encoding +│ │ └── favorites/ +│ │ └── FavoritesPersistenceService.kt # Favorites persistence +│ │ +│ ├── ui/ # UI components +│ │ ├── ChatScreen.kt # Main chat UI +│ │ ├── ChatViewModel.kt # Chat state management +│ │ ├── ChatState.kt # Chat state model +│ │ ├── ChatHeader.kt # Chat header +│ │ ├── ChatUIConstants.kt # UI constants +│ │ ├── ChatUIUtils.kt # UI utilities +│ │ ├── ChatViewModelUtils.kt # ViewModel utilities +│ │ ├── CommandProcessor.kt # IRC-style commands +│ │ ├── DataManager.kt # Data management +│ │ ├── MessageManager.kt # Message management +│ │ ├── MessageSpecialParser.kt # Special message parsing +│ │ ├── ChannelManager.kt # Channel management +│ │ ├── PrivateChatManager.kt # Private chat management +│ │ ├── MeshDelegateHandler.kt # Mesh delegate +│ │ ├── MeshPeerListSheet.kt # Peer list sheet +│ │ ├── ChatUserSheet.kt # User sheet +│ │ ├── AboutSheet.kt # About sheet +│ │ ├── SecurityVerificationSheet.kt # Verification sheet +│ │ ├── VerificationSheet.kt # Verification UI +│ │ ├── VerificationHandler.kt # Verification logic +│ │ ├── NotificationManager.kt # Notifications +│ │ ├── NotificationTextUtils.kt # Notification text +│ │ ├── OrientationAwareActivity.kt # Orientation handling +│ │ ├── InputComponents.kt # Input field components +│ │ ├── VoiceInputComponents.kt # Voice input +│ │ ├── MessageComponents.kt # Message display +│ │ ├── LocationChannelsSheet.kt # Location channels +│ │ ├── LocationNotesSheet.kt # Location notes +│ │ ├── LocationNotesButton.kt # Location notes button +│ │ ├── GeohashViewModel.kt # Geohash state +│ │ ├── GeohashPeopleList.kt # People list +│ │ ├── PoWStatusIndicator.kt # PoW status +│ │ ├── MediaSendingManager.kt # Media sending +│ │ ├── FileShareDispatcher.kt # File share dispatch +│ │ ├── MatrixEncryptionAnimation.kt # Animation +│ │ ├── LinkPreviewPill.kt # Link preview +│ │ ├── debug/ +│ │ │ ├── DebugSettingsSheet.kt # Debug settings +│ │ │ ├── DebugSettingsManager.kt # Debug manager +│ │ │ ├── DebugPreferenceManager.kt # Debug preferences +│ │ │ └── MeshGraph.kt # Mesh graph visualization +│ │ └── media/ # Media components +│ │ ├── ImageMessageItem.kt # Image display +│ │ ├── FileMessageItem.kt # File display +│ │ ├── AudioMessageItem.kt # Audio display +│ │ ├── VoiceNotePlayer.kt # Voice playback +│ │ ├── VoiceRecorder.kt # Voice recording +│ │ ├── VoiceVisualizer.kt # Voice visualization +│ │ ├── Waveform.kt # Waveform rendering +│ │ ├── WaveformViews.kt # Waveform views +│ │ ├── RealtimeScrollingWaveform.kt # Scrolling waveform +│ │ ├── FileViewerDialog.kt # File viewer +│ │ ├── FullScreenImageViewer.kt # Image viewer +│ │ ├── BlockRevealImage.kt # Reveal animation +│ │ ├── ImagePickerButton.kt # Image picker +│ │ ├── FilePickerButton.kt # File picker +│ │ ├── FileSendingAnimation.kt # Send animation +│ │ └── MediaPickerOptions.kt # Picker options +│ │ +│ ├── theme/ # Theme system +│ │ ├── Theme.kt # Theme definitions +│ │ ├── ThemePreference.kt # Theme preferences +│ │ └── Typography.kt # Typography +│ │ +│ ├── onboarding/ # Onboarding flow +│ │ ├── OnboardingCoordinator.kt # Onboarding orchestration +│ │ ├── OnboardingState.kt # Onboarding state +│ │ ├── PermissionManager.kt # Permission handling +│ │ ├── PermissionExplanationScreen.kt # Permission explanations +│ │ ├── BluetoothCheckScreen.kt # Bluetooth check +│ │ ├── BluetoothStatusManager.kt # Bluetooth status +│ │ ├── LocationCheckScreen.kt # Location check +│ │ ├── LocationStatusManager.kt # Location status +│ │ ├── BatteryOptimizationScreen.kt # Battery optimization +│ │ ├── BatteryOptimizationManager.kt # Battery status +│ │ ├── BackgroundLocationPermissionScreen.kt # Background location +│ │ ├── BackgroundLocationPreferenceManager.kt # Background location settings +│ │ └── InitializingScreen.kt # Initialization screen +│ │ +│ ├── features/ # Feature modules +│ │ ├── voice/ # Voice features +│ │ │ ├── VoiceRecorder.kt # Voice recording +│ │ │ ├── VoiceVisualizer.kt # Voice visualization +│ │ │ └── Waveform.kt # Waveform data +│ │ ├── media/ # Media features +│ │ │ ├── ImageUtils.kt # Image utilities +│ │ │ └── FileUtils.kt # File utilities +│ │ └── file/ # File features +│ │ └── FileUtils.kt # File operations +│ │ +│ ├── utils/ # Utilities +│ │ ├── AppConstants.kt # App constants +│ │ ├── BinaryEncodingUtils.kt # Binary encoding +│ │ ├── ByteArrayExtensions.kt # ByteArray extensions +│ │ └── ByteArrayWrapper.kt # ByteArray wrapper +│ │ +│ ├── util/ # Utilities (legacy) +│ │ ├── DeviceUtils.kt # Device utilities +│ │ └── NotificationIntervalManager.kt # Notification intervals +│ │ +│ └── identity/ # Identity management +│ └── SecureIdentityStateManager.kt # Secure identity state +│ +├── res/ # Resources +│ ├── drawable/ # Drawables +│ ├── layout/ # XML layouts (minimal) +│ ├── values/ # Values (strings, colors, etc.) +│ ├── xml/ # XML resources (providers, etc.) +│ └── assets/ # Assets (Nostr relays, etc.) +│ +├── jniLibs/ # Native libraries +│ ├── arm64-v8a/ # ARM 64-bit (Tor libraries) +│ ├── armeabi-v7a/ # ARM 32-bit +│ ├── x86/ # x86 emulator +│ └── x86_64/ # x86_64 emulator +│ +└── AndroidManifest.xml # Manifest +``` + +--- + +## 2. Protocol Implementation + +### 2.1 Binary Protocol (BitChat Protocol) + +**Purpose:** Efficient, low-latency messaging over Bluetooth LE + +**Version Support:** +- Version 1: Legacy (2-byte payload length) +- Version 2: Current (4-byte payload length + Source-Based Routing) + +**Packet Structure (v2):** +``` +[Header: 16 bytes] [SenderID: 8B] [RecipientID: 8B] [Route: N*8B] [Payload: Variable] [Signature: 64B] +``` + +**Header Fields:** +- Version: 1 byte (0x01 or 0x02) +- Type: 1 byte (message type) +- TTL: 1 byte (time-to-live, max 7 hops) +- Timestamp: 8 bytes (UInt64, big-endian) +- Flags: 1 byte (HAS_RECIPIENT, HAS_SIGNATURE, IS_COMPRESSED, HAS_ROUTE) +- Payload Length: 4 bytes (UInt32, big-endian, v2) + +**Message Types:** +- `ANNOUNCE (0x01)` - Peer presence announcement +- `MESSAGE (0x02)` - User messages (private and broadcast) +- `LEAVE (0x03)` - Peer departure notification +- `NOISE_HANDSHAKE (0x10)` - Noise protocol handshake +- `NOISE_ENCRYPTED (0x11)` - Encrypted transport message +- `FRAGMENT (0x20)` - Message fragmentation +- `REQUEST_SYNC (0x21)` - GCS-based sync request +- `FILE_TRANSFER (0x22)` - File transfer (images, audio, files) + +**Special Features:** +- Fragmentation for messages >150 bytes (BLE MTU limit) +- Compression with LZ4 for messages >100 bytes +- Source-Based Routing (v2) for efficient unicast +- Ed25519 signatures for authenticity +- Message padding for traffic analysis resistance + +**Cross-Platform Compatibility:** +- 100% binary protocol compatible with iOS BitChat +- Identical UUIDs for BLE services and characteristics +- Same encryption algorithms and key exchange + +### 2.2 Noise Protocol Implementation + +**Purpose:** Secure key exchange and encrypted transport + +**Pattern:** NK (One-way ephemeral static key pattern) + +**Cryptographic Primitives:** +- X25519 for ECDH key agreement +- Ed25519 for digital signatures +- AES-256-GCM for symmetric encryption +- HKDF for key derivation + +**Session Management:** +- `NoiseSession` - Individual session state +- `NoiseSessionManager` - Session lifecycle +- `NoiseChannelEncryption` - Channel encryption +- `NoiseEncryptionService` - Encryption operations + +**Security Features:** +- Forward secrecy (ephemeral keys) +- Perfect forward secrecy +- Message authentication +- Replay protection + +### 2.3 Nostr Protocol Implementation + +**Purpose:** Geohash-based location channels over internet + +**Implemented NIPs:** +- **NIP-01:** Basic protocol +- **NIP-02:** Contact list +- **NIP-17:** Private direct messages (gift-wrap) +- **NIP-42:** Authentication (challenge-response) + +**Event Types:** +- `kind 1` - Geohash-scoped text notes +- `kind 4` - Encrypted direct messages (legacy) +- `kind 13` - Sealed events +- `kind 14` - Private messages (rumor) +- `kind 1059` - Gift-wrapped events +- `kind 20000` - Ephemeral geohash messages +- `kind 20001` - Geohash presence events + +**Key Components:** +- `NostrProtocol` - NIP implementations +- `NostrEvent` - Event model +- `NostrIdentity` - Identity management (npub/nsec) +- `NostrRelayManager` - Relay connections +- `NostrTransport` - Network transport (via Tor) +- `NostrSubscriptionManager` - Subscription management + +**Security Features:** +- NIP-17 gift-wrap for private messages +- Proof of Work mining (optional, configurable) +- Tor integration for relay connections +- Event deduplication +- Bech32 encoding for addresses + +### 2.4 Sync Protocol (Gossip-Based) + +**Purpose:** Efficient state synchronization across mesh + +**Components:** +- `GossipSyncManager` - Sync coordination +- `GCSFilter` - Counting Bloom filter for deduplication +- `PacketIdUtil` - Packet ID utilities +- `MeshGraphService` - Topology discovery + +**Sync Features:** +- Bloom filter-based deduplication +- Configurable capacity and false positive rate +- Gossip-based state propagation +- Two-way edge verification +- Source-based route planning + +--- + +## 3. Cryptography & Security + +### 3.1 Cryptographic Libraries + +| Library | Version | Purpose | +|---------|---------|---------| +| BouncyCastle | 1.70 | X25519, Ed25519, AES-GCM | +| Google Tink | 1.10.0 | Additional crypto primitives | + +### 3.2 Key Management + +**Identity Keys:** +- X25519 static key pair (for key exchange) +- Ed25519 signing key pair (for signatures) +- Keypairs generated on first launch +- Stored in `EncryptedSharedPreferences` + +**Session Keys:** +- Ephemeral X25519 key pair per session +- Derived via Noise Protocol +- Rotated for forward secrecy + +**Nostr Keys:** +- Separate Ed25519 key pair for Nostr +- Npub/nsec encoding for sharing +- Persisted encrypted + +### 3.3 Encryption Flow + +**Direct Messages:** +1. Noise handshake (NK pattern) +2. Derive shared secret +3. Establish encrypted channel +4. AES-256-GCM encryption for messages + +**Channel Messages:** +1. Channel owner sets password +2. Argon2id key derivation +3. AES-256-GCM encryption +4. Password-based decryption + +**File Transfers:** +1. Generate random AES-256 key +2. Encrypt file with AES-256-GCM +3. Share key via encrypted channel +4. Decrypt on recipient side + +### 3.4 Security Features + +- **End-to-End Encryption:** All messages encrypted +- **Forward Secrecy:** Ephemeral session keys +- **Message Signatures:** Ed25519 for authenticity +- **Padding:** Random padding for traffic analysis resistance +- **Deduplication:** Bloom filter prevents replay attacks +- **Tor Integration:** Optional Tor for Nostr relay connections +- **Emergency Wipe:** Triple-tap logo to clear all data + +--- + +## 4. Networking Stack + +### 4.1 Bluetooth Mesh Networking + +**Architecture:** +- Dual-role BLE (central + peripheral) +- Automatic peer discovery +- Multi-hop message relay (max 7 hops) +- Store-and-forward for offline peers + +**Components:** +- `BluetoothConnectionManager` - Connection lifecycle +- `BluetoothGattClientManager` - GATT client operations +- `BluetoothGattServerManager` - GATT server operations +- `BluetoothPacketBroadcaster` - Packet transmission +- `PeerManager` - Peer state management + +**Connection Management:** +- Adaptive connection limits based on power mode +- Connection state tracking +- Automatic reconnection +- Connection quality monitoring (RSSI) + +**Power Optimization:** +- Adaptive scanning intervals +- Power mode-based connection limits +- Background duty cycling +- Battery-aware operation modes + +### 4.2 Tor Integration (Arti) + +**Implementation:** Rust-based Tor client (Arti) bridged to Android + +**Components:** +- `ArtiTorManager` - Tor lifecycle management +- `TorMode` - Tor mode configuration +- `TorPreferenceManager` - Tor settings +- Native libraries in `jniLibs/` + +**Tor Features:** +- SOCKS5 proxy for Nostr relay connections +- Circuit management +- Identity isolation +- Configurable relay selection + +**Tor Modes:** +- `Disabled` - No Tor +- `Enabled` - Tor for all Nostr connections +- `OnionOnly` - Tor for .onion relays only + +### 4.3 HTTP Client (OkHttp) + +**Purpose:** HTTP requests (Nostr relays, geocoding) + +**Components:** +- `OkHttpProvider` - OkHttp singleton +- Connection pooling +- Timeout configuration +- Tor proxy support + +--- + +## 5. User Interface + +### 5.1 UI Framework + +**Jetpack Compose:** +- Declarative UI +- Material Design 3 components +- Compose BOM 2025.06.01 +- Custom theming system + +**Theme System:** +- Dark/Light theme support +- Terminal-inspired aesthetic +- Material You integration (optional) +- Custom color schemes + +### 5.2 Core Screens + +**ChatScreen:** +- Message list with timestamps +- Message input with commands +- Peer list sidebar +- Channel management +- Private chat support + +**GeohashPickerActivity:** +- Map-based geohash selection +- Location channel browsing +- Bookmark management + +**Onboarding Screens:** +- Permission requests +- Bluetooth status check +- Location status check +- Battery optimization +- Initialization sequence + +### 5.3 UI Components + +**Message Components:** +- Text messages +- Image messages (with preview) +- Audio messages (with waveform) +- File messages (with type icons) +- System messages (with special styling) + +**Input Components:** +- Message input field +- Voice recording button +- Image picker button +- File picker button +- Command suggestions + +**Sheets:** +- Peer list sheet +- User sheet (peer details) +- Security verification sheet +- About sheet +- Location notes sheet +- Debug settings sheet + +### 5.4 Media Features + +**Image Handling:** +- Image picker from gallery +- Camera capture +- Image compression +- EXIF orientation handling +- Full-screen image viewer + +**Voice Messages:** +- Voice recording with visualizer +- Real-time waveform display +- Playback controls +- Audio file compression + +**File Sharing:** +- File picker (images, audio, video, documents) +- File transfer over mesh +- Transfer progress tracking +- File viewer for received files + +### 5.5 Commands (IRC-Style) + +**Channel Commands:** +- `/j #channel` - Join or create channel +- `/pass [password]` - Set channel password +- `/save` - Toggle message retention +- `/transfer @name` - Transfer ownership + +**User Commands:** +- `/m @name message` - Send private message +- `/w` - List online users +- `/block @name` - Block peer +- `/unblock @name` - Unblock peer + +**Utility Commands:** +- `/channels` - Show discovered channels +- `/clear` - Clear chat messages + +--- + +## 6. Data Persistence + +### 6.1 Storage Mechanisms + +**SharedPreferences:** +- User preferences +- Channel settings +- Tor settings +- Debug settings + +**EncryptedSharedPreferences:** +- Identity keys +- Nostr keys +- Sensitive preferences + +**SQLite Database:** +- Message history (if retention enabled) +- Peer information +- Channel metadata +- Favorites + +**File System:** +- Cached files +- Downloaded files +- Temporary files + +### 6.2 Persistence Components + +**FavoritesPersistenceService:** +- Favorite peer management +- Persistence layer +- Query operations + +**GeohashBookmarksStore:** +- Geohash bookmarks +- Channel aliases +- Conversation metadata + +**MessageRetentionService:** +- Optional message saving +- Owner-controlled retention +- Persistent storage + +--- + +## 7. Background Services + +### 7.1 Foreground Service + +**MeshForegroundService:** +- Persistent mesh networking +- BLE scanning in background +- Notification with status +- Auto-start on boot (optional) + +**Service Types:** +- `connectedDevice` - BLE operations +- `dataSync` - Message sync +- `location` - Location-based features + +### 7.2 Broadcast Receivers + +**BootCompletedReceiver:** +- Auto-start mesh service on boot +- Check user preference +- Request necessary permissions + +**NotificationPermissionChangedReceiver:** +- Listen for notification permission grants +- Restart notification system + +### 7.3 Service Management + +**MeshServiceHolder:** +- Service lifecycle management +- Binding to activities +- State coordination + +**AppShutdownCoordinator:** +- Graceful shutdown +- Resource cleanup +- State persistence + +--- + +## 8. Dependencies Analysis + +### 8.1 Core Dependencies + +**AndroidX:** +- `core-ktx:1.16.0` - Core KTX extensions +- `appcompat:1.7.1` - AppCompat compatibility +- `lifecycle-runtime-ktx:2.9.1` - Lifecycle components +- `activity-compose:1.10.1` - Compose activity integration + +**Compose:** +- Compose BOM 2025.06.01 +- Material Design 3 +- Navigation Compose 2.9.1 + +### 8.2 Networking + +**Nordic BLE:** +- `no.nordicsemi.android:ble:2.6.1` +- Reliable BLE operations +- GATT client/server +- Connection management + +**OkHttp:** +- `okhttp:4.12.0` +- HTTP client +- Connection pooling +- Tor proxy support + +### 8.3 Cryptography + +**BouncyCastle:** +- `bcprov-jdk15on:1.70` +- X25519, Ed25519 +- AES-GCM +- HKDF + +**Google Tink:** +- `tink-android:1.10.0` +- Additional crypto primitives + +**Android Security:** +- `security-crypto:1.1.0-beta01` +- EncryptedSharedPreferences + +### 8.4 Location & Maps + +**Google Play Services:** +- `play-services-location:21.3.0` +- Fused Location Provider +- Geofencing support + +### 8.5 Media + +**CameraX:** +- `camera-camera2:1.5.2` +- `camera-lifecycle:1.5.2` +- `camera-compose:1.5.2` + +**ML Kit:** +- `barcode-scanning:17.3.0` +- QR code scanning + +**ZXing:** +- `core:3.5.4` +- QR code generation + +### 8.6 JSON & Serialization + +**Gson:** +- `gson:2.13.1` +- JSON parsing +- Nostr event serialization + +### 8.7 Coroutines + +**Kotlin Coroutines:** +- `kotlinx-coroutines-android:1.10.2` +- Asynchronous operations +- Concurrency management + +### 8.8 Permissions + +**Accompanist:** +- `accompanist-permissions:0.37.3` +- Runtime permission handling + +--- + +## 9. Build Configuration + +### 9.1 Build Types + +**Debug:** +- Debuggable +- No code shrinking +- Multiple ABIs (including x86 for emulator) +- Signing with debug keystore + +**Release:** +- Minified (ProGuard/R8) +- Shrunk resources +- Optimized bytecode +- Multiple APK splits (arm64-v8a, armeabi-v7a, x86_64, universal) + +### 9.2 APK Splits + +**Architectures:** +- `arm64-v8a` - ARM 64-bit (recommended for most devices) +- `armeabi-v7a` - ARM 32-bit +- `x86_64` - x86_64 emulator +- `x86` - x86 emulator +- `universal` - All architectures (for F-Droid) + +**Automatic Splitting:** +- Enabled for `assemble` tasks +- Disabled for `bundle` tasks +- Based on Gradle task names + +### 9.3 ProGuard Configuration + +**Rules:** +- `proguard-rules.pro` +- Keeps required classes +- Obfuscates implementation +- Shrinks unused code + +### 9.4 Gradle Properties + +**Key Properties:** +```properties +org.gradle.jvmargs=-Xmx2048m +android.useAndroidX=true +android.enableJetifier=true +kotlin.code.style=official +android.nonTransitiveRClass=true +``` + +--- + +## 10. Permissions + +### 10.1 Required Permissions + +**Networking:** +- `INTERNET` - Nostr relay connections +- `ACCESS_NETWORK_STATE` - Network state + +**Bluetooth:** +- `BLUETOOTH_ADVERTISE` - BLE advertising +- `BLUETOOTH_CONNECT` - BLE connections +- `BLUETOOTH_SCAN` - BLE scanning + +**Location:** +- `ACCESS_COARSE_LOCATION` - BLE scanning (required) +- `ACCESS_FINE_LOCATION` - Precise location +- `ACCESS_BACKGROUND_LOCATION` - Background location + +**Notifications:** +- `POST_NOTIFICATIONS` - Message notifications + +**Foreground Services:** +- `FOREGROUND_SERVICE` - Foreground service +- `FOREGROUND_SERVICE_CONNECTED_DEVICE` - BLE operations +- `FOREGROUND_SERVICE_DATA_SYNC` - Message sync +- `FOREGROUND_SERVICE_LOCATION` - Location features +- `RECEIVE_BOOT_COMPLETED` - Auto-start on boot + +**Media:** +- `RECORD_AUDIO` - Voice notes +- `CAMERA` - QR scanning +- `READ_MEDIA_IMAGES` - Image access +- `READ_MEDIA_VIDEO` - Video access +- `READ_MEDIA_AUDIO` - Audio access + +**Other:** +- `VIBRATE` - Haptic feedback +- `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` - Battery optimization + +### 10.2 Permission Handling + +**Runtime Permissions:** +- Comprehensive onboarding flow +- Educational explanations +- Contextual requests +- Graceful degradation + +**Bluetooth Permissions (API 31+):** +- `BLUETOOTH_SCAN` with `android:usesPermissionFlags="neverForLocation"` (when not using location) +- Location permission required for BLE scanning + +**Background Location:** +- Optional feature +- Explicit user consent +- Educational UI +- Revokable at any time + +--- + +## 11. Testing + +### 11.1 Test Structure + +**Unit Tests:** +- Located in `app/src/test/` +- JUnit 4.13.2 +- Mockito 4.1.0 +- Kotlinx Coroutines Test + +**Instrumented Tests:** +- Located in `app/src/androidTest/` +- Espresso 3.6.1 +- Compose Testing + +### 11.2 Test Commands + +```bash +# Unit tests +./gradlew test +./gradlew testDebugUnitTest + +# Instrumented tests +./gradlew connectedAndroidTest +./gradlew connectedDebugAndroidTest + +# Lint +./gradlew lint +./gradlew lintDebug +``` + +--- + +## 12. Deployment + +### 12.1 Google Play Store + +**Requirements:** +- Target API 35 (Android 15) +- AAB format (recommended) +- Privacy policy URL +- Content rating questionnaire +- Permission justifications + +**Store Listing:** +- Full description (from README) +- Short description +- Screenshots (minimum 2) +- Icon (512x512) +- Feature graphic (1024x500) + +### 12.2 GitHub Releases + +**Release Artifacts:** +- Debug APKs (split by architecture) +- Release APKs (split by architecture) +- Universal APK (for F-Droid) +- Changelog (from CHANGELOG.md) + +### 12.3 F-Droid + +**Requirements:** +- Universal APK +- No proprietary dependencies +- Buildable from source +- Updated metadata + +--- + +## 13. Known Issues & Limitations + +### 13.1 Known Issues + +- Debug settings sheet crash on some devices (fixed in 1.4.0) +- Battery optimization may stop mesh service +- Background location requires explicit consent +- Tor connection can be slow on initial start + +### 13.2 Limitations + +- Max 7 hops for message relay +- BLE MTU limits message size (requires fragmentation) +- File transfer limited by mesh bandwidth +- No multi-device sync +- No cloud backup + +--- + +## 14. Future Enhancements + +### 14.1 Potential Improvements + +- Multi-device sync via Nostr +- Cloud backup (encrypted) +- Enhanced group features +- Voice/video calls (WebRTC over mesh) +- File preview generation +- Message reactions +- Typing indicators +- Read receipts (beyond current implementation) +- Enhanced search +- Message export/import + +### 14.2 Technical Debt + +- Migrate remaining code to Compose +- Improve test coverage +- Add integration tests +- Refactor large viewmodels +- Improve error handling +- Add crash reporting +- Performance profiling +- Memory leak detection + +--- + +## 15. Security Considerations + +### 15.1 Threat Model + +**Assumptions:** +- Adversaries can observe network traffic +- Adversaries can inject packets +- Adversaries can capture devices +- Adversaries can compromise relays + +**Mitigations:** +- End-to-end encryption +- Perfect forward secrecy +- Message signatures +- Traffic padding +- Bloom filter deduplication +- Tor integration + +### 15.2 Best Practices + +- Never log sensitive data +- Use `EncryptedSharedPreferences` for secrets +- Validate all incoming packets +- Implement proper key rotation +- Use TLS/SSL for Nostr (via Tor) +- Regular security audits +- Dependency updates + +--- + +## 16. Development Guidelines + +### 16.1 Code Style + +- Kotlin official style guide +- 4-space indentation +- KDoc documentation +- Meaningful variable names +- Single responsibility principle + +### 16.2 Git Workflow + +- Feature branches +- Pull requests +- Code review required +- CI/CD checks +- Semantic versioning + +### 16.3 Testing Strategy + +- Unit tests for business logic +- Integration tests for services +- UI tests for critical flows +- Manual testing on devices +- Beta testing with users + +--- + +## 17. Documentation + +### 17.1 Internal Documentation + +- Code comments (KDoc) +- README.md (overview) +- CHANGELOG.md (release notes) +- docs/ directory (protocol specs) + +### 17.2 External Documentation + +- User guide (in app) +- Privacy policy +- Terms of service +- GitHub issues/PRs +- Discussions + +--- + +## 18. Performance Optimization + +### 18.1 Battery Optimization + +- Adaptive scanning intervals +- Power mode-based connection limits +- Background duty cycling +- Efficient BLE operations +- Tor connection pooling + +### 18.2 Memory Optimization + +- Image compression +- Message pagination +- Efficient data structures +- Memory profiling +- Leak detection + +### 18.3 Network Optimization + +- Message aggregation +- Compression (LZ4) +- Bloom filter deduplication +- Efficient routing +- Connection pooling + +--- + +## 19. Accessibility + +### 19.1 Accessibility Features + +- Screen reader support +- Keyboard navigation +- High contrast mode +- Font scaling +- Touch target sizes + +### 19.2 Compliance + +- Android accessibility guidelines +- WCAG 2.1 (where applicable) +- Material Design accessibility + +--- + +## 20. Internationalization + +### 20.1 Current Status + +- English only (primary) +- No RTL support currently +- English strings in `res/values/strings.xml` + +### 20.2 Future i18n + +- Multiple language support +- RTL layout support +- Locale-aware formatting +- Localized date/time + +--- + +## Conclusion + +BitChat Android is a sophisticated, secure, decentralized messaging application with a modern architecture. It successfully implements complex networking protocols (Bluetooth mesh, Nostr), cryptography (Noise Protocol, Ed25519), and UI frameworks (Jetpack Compose). The codebase is well-organized, with clear separation of concerns and comprehensive feature coverage. + +**Key Strengths:** +- Modern Android development practices +- Strong security and privacy focus +- Cross-platform compatibility +- Rich feature set +- Clean architecture + +**Areas for Improvement:** +- Test coverage +- Documentation +- Performance optimization +- Accessibility support +- Internationalization + +The project is production-ready and actively maintained, with regular updates and improvements. + +--- + +**Analysis Date:** 2025-04-11 +**App Version:** 1.7.2 (versionCode 33) +**Repository:** `git@github.com:Satoshi-NaAkokwa/ikorochat-android.git` \ No newline at end of file diff --git a/SETUP.md b/SETUP.md new file mode 100644 index 00000000..c928070d --- /dev/null +++ b/SETUP.md @@ -0,0 +1,586 @@ +# BitChat Android - Setup Guide + +## Project Overview + +**BitChat for Android** is a secure, decentralized, peer-to-peer messaging app that operates over Bluetooth mesh networks. It provides encrypted communication without requiring internet connectivity for local mesh chats. + +- **Package Name:** `com.bitchat.droid` +- **Application ID:** `com.bitchat.droid` +- **Min SDK:** 26 (Android 8.0) +- **Target SDK:** 35 (Android 15) +- **Compile SDK:** 35 (Android 15) +- **Current Version:** 1.7.2 (versionCode 33) +- **Language:** Kotlin 2.2.0 +- **UI Framework:** Jetpack Compose with Material Design 3 + +## Key Features + +- ✅ **Cross-Platform Compatible:** 100% protocol compatible with iOS BitChat +- ✅ **Bluetooth Mesh Networking:** Automatic peer discovery and multi-hop message relay +- ✅ **End-to-End Encryption:** Noise Protocol (X25519) + Ed25519 signatures +- ✅ **Channel-Based Messaging:** Topic-based group chats with password protection +- ✅ **Store & Forward:** Messages cached for offline peers +- ✅ **Nostr Integration:** Geohash-based location channels over internet +- ✅ **Tor Support:** Built-in Tor integration via Arti (Rust implementation) +- ✅ **File Sharing:** Images, audio notes, and file transfers +- ✅ **Privacy First:** No accounts, no phone numbers, ephemeral by default + +## Architecture Overview + +### Core Components + +1. **BluetoothMeshService** - Central mesh networking coordinator + - Manages BLE connections (central + peripheral roles) + - Handles packet routing and relay logic + - Coordinates peer discovery and connection management + +2. **Security Architecture** + - **Noise Protocol** (NK pattern) for secure key exchange + - **Ed25519** for digital signatures + - **X25519** for ECDH key agreement + - **AES-256-GCM** for message encryption + +3. **Binary Protocol** + - Version 1: Legacy 2-byte payload length + - Version 2: 4-byte payload length + Source-Based Routing + - Packet types: Announce, Message, Leave, Noise Handshake, Noise Encrypted, Fragment, Request Sync, File Transfer + +4. **Nostr Protocol** (NIP-01, NIP-17, NIP-42) + - Geohash-scoped text notes (kind 1, 20000) + - Private direct messages (kind 14, 13, 1059) + - Presence events (kind 20001) + - Proof of Work mining support + +5. **Mesh Graph Service** + - Gossip-based topology discovery + - Two-way edge verification + - Source-based route planning + - Bloom filter deduplication + +### Module Structure + +``` +app/src/main/java/com/bitchat/android/ +├── BitchatApplication.kt # Application initialization +├── MainActivity.kt # Main activity & permission handling +├── MainViewModel.kt # Global app state +├── mesh/ # Bluetooth mesh networking +│ ├── BluetoothMeshService.kt # Core mesh service +│ ├── BluetoothConnectionManager.kt +│ ├── BluetoothGattClientManager.kt +│ ├── BluetoothGattServerManager.kt +│ ├── PeerManager.kt +│ ├── SecurityManager.kt +│ ├── StoreForwardManager.kt +│ └── MessageHandler.kt +├── protocol/ # Binary protocol implementation +│ ├── BinaryProtocol.kt # Packet encoding/decoding +│ └── CompressionUtil.kt # LZ4 compression +├── noise/ # Noise Protocol implementation +│ ├── NoiseSession.kt +│ ├── NoiseSessionManager.kt +│ └── NoiseChannelEncryption.kt +├── nostr/ # Nostr protocol client +│ ├── NostrProtocol.kt +│ ├── NostrEvent.kt +│ ├── NostrIdentity.kt +│ ├── NostrRelayManager.kt +│ └── GeohashMessageHandler.kt +├── crypto/ # Cryptographic operations +│ └── EncryptionService.kt +├── model/ # Data models +│ ├── BitchatMessage.kt +│ ├── BitchatFilePacket.kt +│ └── RoutedPacket.kt +├── ui/ # Jetpack Compose UI +│ ├── ChatScreen.kt +│ ├── ChatViewModel.kt +│ └── theme/ +├── geohash/ # Location-based features +│ ├── Geohash.kt +│ ├── LocationChannelManager.kt +│ └── FusedLocationProvider.kt +├── net/ # Network layer +│ ├── ArtiTorManager.kt # Tor integration +│ ├── TorMode.kt +│ └── OkHttpProvider.kt +├── sync/ # Sync protocol +│ ├── GossipSyncManager.kt +│ ├── GCSFilter.kt +│ └── PacketIdUtil.kt +└── services/ # Background services + ├── MeshForegroundService.kt # Foreground service + └── MeshGraphService.kt # Topology discovery +``` + +## Dependencies + +### Core Android +- `androidx.core.ktx:1.16.0` +- `androidx.activity.compose:1.10.1` +- `androidx.appcompat:1.7.1` +- `androidx.lifecycle:*:2.9.1` +- `androidx.navigation.compose:2.9.1` + +### UI Framework +- Jetpack Compose BOM `2025.06.01` +- Material Design 3 +- `com.google.accompanist:accompanist-permissions:0.37.3` + +### Cryptography +- `org.bouncycastle:bcprov-jdk15on:1.70` +- `com.google.crypto.tink:tink-android:1.10.0` + +### Networking +- `no.nordicsemi.android:ble:2.6.1` - Bluetooth Low Energy +- `com.squareup.okhttp3:okhttp:4.12.0` - HTTP client +- `org.torproject:tor-android-binary:0.4.4.6` - Tor (legacy) + +### Location & Maps +- `com.google.android.gms:play-services-location:21.3.0` + +### Media +- `androidx.camera:*:1.5.2` - CameraX for QR scanning +- `com.google.mlkit:barcode-scanning:17.3.0` - ML Kit +- `com.google.zxing:core:3.5.4` - QR code generation + +### Storage & Security +- `androidx.security:security-crypto:1.1.0-beta01` - EncryptedSharedPreferences +- `com.google.code.gson:gson:2.13.1` - JSON parsing + +### Coroutines +- `org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2` + +## Build Requirements + +### System Requirements + +- **Java:** OpenJDK 17 or higher +- **Android SDK:** API 26-35 +- **Gradle:** 8.13 (via wrapper) +- **Android Gradle Plugin:** 8.10.1 +- **Kotlin:** 2.2.0 + +### Installation Steps + +#### 1. Install Java 17+ + +```bash +# Ubuntu/Debian +sudo apt update +sudo apt install openjdk-17-jdk + +# Set JAVA_HOME +export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc +``` + +#### 2. Install Android SDK + +Option A: Using Android Studio +```bash +# Install Android Studio +sudo snap install android-studio --classic + +# Open Android Studio and install SDKs via SDK Manager: +# - Android SDK Platform-Tools +# - Android SDK Build-Tools 35.0.0 +# - Android 15 (API 35) +# - Android 14 (API 34) +# - Android 8.0 (API 26) - Minimum +``` + +Option B: Command Line Only +```bash +# Download command line tools +wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip +unzip commandlinetools-linux-11076708_latest.zip +mkdir -p ~/Android/sdk/cmdline-tools/latest +mv cmdline-tools/* ~/Android/sdk/cmdline-tools/latest/ + +# Set environment variables +export ANDROID_HOME=$HOME/Android/sdk +export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools +echo 'export ANDROID_HOME=$HOME/Android/sdk' >> ~/.bashrc +echo 'export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools' >> ~/.bashrc + +# Accept licenses +yes | sdkmanager --licenses + +# Install required SDKs +sdkmanager "platform-tools" +sdkmanager "platforms;android-35" +sdkmanager "platforms;android-34" +sdkmanager "platforms;android-26" +sdkmanager "build-tools;35.0.0" +``` + +#### 3. Clone Repository + +```bash +git clone git@github.com:Satoshi-NaAkokwa/ikorochat-android.git +cd ikorochat-android +``` + +#### 4. Build Project + +```bash +# Clean build +./gradlew clean + +# Build debug APK +./gradlew assembleDebug + +# Build release APK +./gradlew assembleRelease + +# Build app bundle for Play Store +./gradlew bundleRelease + +# Run tests +./gradlew test +./gradlew connectedAndroidTest +``` + +#### 5. Install on Device + +```bash +# Install debug APK +adb install -r app/build/outputs/apk/debug/app-debug.apk + +# Install release APK +adb install -r app/build/outputs/apk/release/app-release.apk + +# Or use gradle task +./gradlew installDebug +``` + +## Build Outputs + +### Debug Builds + +Location: `app/build/outputs/apk/debug/` + +- `app-debug.apk` - Universal debug APK (all architectures) +- `app-armeabi-v7a-debug.apk` - ARM 32-bit +- `app-arm64-v8a-debug.apk` - ARM 64-bit (recommended for most devices) +- `app-x86-debug.apk` - x86 emulator +- `app-x86_64-debug.apk` - x86_64 emulator + +### Release Builds + +Location: `app/build/outputs/apk/release/` + +Same APK splits as debug, but with: +- Code minification (ProGuard/R8) +- Resource shrinking +- Optimized bytecode +- Smaller APK size + +### App Bundle + +Location: `app/build/outputs/bundle/release/` + +- `app-release.aab` - Android App Bundle for Google Play Store +- Handles architecture distribution automatically + +## Configuration + +### Build Variants + +The project supports automatic APK splitting based on architecture: + +```kotlin +// Splits enabled for assemble tasks, disabled for bundle tasks +val enableSplits = gradle.startParameter.taskNames.any { taskName -> + taskName.contains("assemble", ignoreCase = true) && + !taskName.contains("bundle", ignoreCase = true) +} +``` + +### Signing Configuration + +Release builds require a signing configuration. Set up in `app/build.gradle.kts`: + +```kotlin +signingConfigs { + create("release") { + storeFile = file("path/to/keystore.jks") + storePassword = "your_store_password" + keyAlias = "your_key_alias" + keyPassword = "your_key_password" + } +} +``` + +**IMPORTANT:** Never commit keystore files or passwords. Use: +- Environment variables +- `keystore.properties` file (git-ignored) +- CI/CD secret management + +### Gradle Properties + +Key properties in `gradle.properties`: + +```properties +org.gradle.jvmargs=-Xmx2048m +android.useAndroidX=true +android.enableJetifier=true +kotlin.code.style=official +android.nonTransitiveRClass=true +``` + +## Permissions + +### Required Permissions + +The app requires the following permissions: + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +### Runtime Permissions + +The app handles runtime permissions for: +- Bluetooth (API 31+) +- Location +- Camera (QR scanning) +- Microphone (voice notes) +- Notifications (API 33+) + +## Testing + +### Unit Tests + +```bash +./gradlew test +./gradlew testDebugUnitTest +``` + +### Instrumented Tests + +```bash +./gradlew connectedAndroidTest +./gradlew connectedDebugAndroidTest +``` + +### Lint Checks + +```bash +./gradlew lint +./gradlew lintDebug +``` + +## Troubleshooting + +### Build Issues + +**Issue:** "JAVA_HOME is not set" +```bash +export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +``` + +**Issue:** "Android SDK not found" +```bash +export ANDROID_HOME=$HOME/Android/sdk +export PATH=$PATH:$ANDROID_HOME/platform-tools +``` + +**Issue:** Gradle daemon out of memory +```bash +./gradlew --stop +./gradlew -Dorg.gradle.jvmargs="-Xmx4g" build +``` + +### Dependency Issues + +**Issue:** "Could not resolve nordic-ble" +- Check Maven Central repository in `settings.gradle.kts` + +**Issue:** "Tor native library not found" +- Native libraries are in `app/src/main/jniLibs/` (from arti-custom.aar) + +### BLE Issues + +**Issue:** BLE not scanning +- Verify location permissions granted +- Check GPS is enabled +- Android 12+ requires `ACCESS_FINE_LOCATION` for BLE + +**Issue:** Connections failing +- Ensure both devices have BLE hardware +- Check Bluetooth permissions granted +- Verify devices are discoverable + +## Development Workflow + +### Recommended Commands + +```bash +# Clean build +./gradlew clean + +# Build and install debug +./gradlew assembleDebug installDebug + +# Run tests +./gradlew test connectedAndroidTest lint + +# Generate release build +./gradlew assembleRelease +``` + +### Android Studio Setup + +1. Open project in Android Studio +2. Wait for Gradle sync to complete +3. Run configuration: `app` module +4. Select device or emulator +5. Click Run ▶️ + +### Debugging + +- Enable USB debugging on device +- Use Android Studio Logcat +- Filter by tag: `BluetoothMeshService`, `NostrClient`, `TorManager` + +## Security Notes + +### Secrets Management + +**DO NOT commit:** +- Keystore files (`.jks`, `.keystore`) +- API keys +- Passwords +- Signing certificates + +**DO use:** +- Environment variables +- `local.properties` (git-ignored) +- CI/CD secret storage +- EncryptedSharedPreferences for runtime secrets + +### Cryptographic Implementation + +The app uses: +- **BouncyCastle** for cryptographic primitives +- **Custom Noise Protocol** implementation (NK pattern) +- **Ed25519** for signatures +- **X25519** for key exchange +- **AES-256-GCM** for encryption + +### Security Best Practices + +1. Never log sensitive data (keys, passwords, plaintext messages) +2. Use `EncryptedSharedPreferences` for storing sensitive preferences +3. Validate all incoming packets before processing +4. Implement proper key rotation +5. Use TLS/SSL for Nostr relay connections (via Tor) + +## Google Play Store Submission + +### Pre-Submission Checklist + +- [ ] Target API 35 (Android 15) +- [ ] Comply with Play Store policies +- [ ] Provide privacy policy URL +- [ ] Complete content rating questionnaire +- [ ] Test on multiple devices +- [ ] Verify all permissions are justified +- [ ] Test in-app purchases (if any) +- [ ] Check for crashes and ANRs + +### Upload Steps + +```bash +# Generate app bundle +./gradlew bundleRelease + +# Upload to Google Play Console +# Location: app/build/outputs/bundle/release/app-release.aab +``` + +### Store Listing Requirements + +- **Full Description:** Use README.md content +- **Short Description:** "Secure P2P messaging over Bluetooth mesh" +- **Screenshots:** At least 2 phone screenshots +- **Icon:** 512x512 PNG +- **Feature Graphic:** 1024x500 PNG +- **Privacy Policy:** Required for apps with location permissions + +## CI/CD + +### GitHub Actions (Recommended) + +```yaml +name: Build +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Build with Gradle + run: ./gradlew build +``` + +## Additional Resources + +- **BitChat Protocol Docs:** `/docs/` +- **iOS Version:** https://github.com/jackjackbits/bitchat +- **Android Developer Docs:** https://developer.android.com +- **Jetpack Compose:** https://developer.android.com/jetpack/compose +- **Nostr Protocol:** https://github.com/nostr-protocol/nips +- **Noise Protocol:** https://noiseprotocol.org/ + +## Support & Issues + +- **Bug Reports:** Create GitHub issue +- **Feature Requests:** GitHub Discussions +- **Security Issues:** Private disclosure +- **Questions:** GitHub Discussions + +--- + +Last Updated: 2025-04-11 +Version: 1.7.2 (versionCode 33) \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 700655fe..a711143e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,3 +1,5 @@ +import java.util.Properties + plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.android) @@ -8,6 +10,21 @@ plugins { android { namespace = "com.bitchat.android" compileSdk = libs.versions.compileSdk.get().toInt() + + // Signing configuration for release builds + val keystoreFile = file("keystore.properties") + if (keystoreFile.exists()) { + val props = Properties() + props.load(keystoreFile.inputStream()) + signingConfigs { + create("release") { + storeFile = file(props.getProperty("storeFile")) + storePassword = props.getProperty("storePassword") + keyAlias = props.getProperty("keyAlias") + keyPassword = props.getProperty("keyPassword") + } + } + } defaultConfig { applicationId = "com.bitchat.droid" @@ -43,6 +60,10 @@ android { getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) + // Use signing config for release builds + if (file("keystore.properties").exists()) { + signingConfig = signingConfigs.getByName("release") + } } } diff --git a/build-monitor.sh b/build-monitor.sh new file mode 100755 index 00000000..2159f203 --- /dev/null +++ b/build-monitor.sh @@ -0,0 +1,261 @@ +#!/bin/bash +# BitChat Android - Intelligent Build Monitor and Reactivation System +# This script monitors the build process, reactivates if stopped, and completes the build + +set -e + +PROJECT_DIR="/home/openclaw/.openclaw/workspace/ikorochat-android" +LOG_FILE="$PROJECT_DIR/build-monitor.log" +STATE_FILE="$PROJECT_DIR/.build-state" +MAX_RETRIES=5 +RETRY_COUNT=0 + +export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +export ANDROID_HOME=$HOME/Android/sdk +export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin:$ANDROID_HOME/platform-tools + +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" +} + +check_build_status() { + # Check for APKs + DEBUG_APKS=$(find "$PROJECT_DIR/app/build/outputs/apk/debug" -name "*.apk" 2>/dev/null | wc -l) + RELEASE_APKS=$(find "$PROJECT_DIR/app/build/outputs/apk/release" -name "*.apk" 2>/dev/null | wc -l) + + echo "DEBUG_APKS=$DEBUG_APKS" + echo "RELEASE_APKS=$RELEASE_APKS" +} + +is_gradle_running() { + pgrep -f "GradleDaemon" > /dev/null 2>&1 + return $? +} + +kill_stale_gradle() { + if is_gradle_running; then + log "Killing stale Gradle processes..." + pkill -9 -f "GradleDaemon" || true + pkill -9 -f "gradlew" || true + sleep 5 + fi +} + +clean_build_cache() { + log "Cleaning build cache..." + cd "$PROJECT_DIR" + rm -rf app/build/.gradle + rm -rf .gradle/8.13/executionHistory + rm -rf .gradle/8.13/fileHashes + rm -rf app/build/intermediates/incremental +} + +build_debug() { + log "Building DEBUG APK..." + cd "$PROJECT_DIR" + _JAVA_OPTIONS="-Xmx2g" ./gradlew assembleDebug --no-daemon --max-workers=1 2>&1 | tee -a "$LOG_FILE" + + if [ $? -eq 0 ]; then + log "✅ DEBUG build successful!" + return 0 + else + log "❌ DEBUG build failed!" + return 1 + fi +} + +build_release() { + log "Building RELEASE APK..." + cd "$PROJECT_DIR" + + # Check if keystore exists + if [ ! -f "$PROJECT_DIR/bitchat-release.keystore" ]; then + log "Keystore not found, generating..." + keytool -genkeypair -v -keystore bitchat-release.keystore \ + -alias bitchat -keyalg RSA -keysize 2048 -validity 10000 \ + -storepass "BitchatRelease2025!" -keypass "BitchatRelease2025!" \ + -dname "CN=BitChat Android, OU=Security, O=Permissionless Tech, L=Global, ST=World, C=US" + fi + + _JAVA_OPTIONS="-Xmx2g" ./gradlew assembleRelease --no-daemon --max-workers=1 2>&1 | tee -a "$LOG_FILE" + + if [ $? -eq 0 ]; then + log "✅ RELEASE build successful!" + return 0 + else + log "❌ RELEASE build failed!" + return 1 + fi +} + +verify_apk() { + local apk_path="$1" + if [ -f "$apk_path" ]; then + log "Verifying APK: $apk_path" + $ANDROID_HOME/build-tools/35.0.0/aapt dump badging "$apk_path" | head -5 + return 0 + else + log "APK not found: $apk_path" + return 1 + fi +} + +sign_apk_manual() { + # If automatic signing failed, sign manually + log "Attempting manual APK signing..." + cd "$PROJECT_DIR" + + UNSIGNED_APK="$PROJECT_DIR/app/build/outputs/apk/release/app-arm64-v8a-release-unsigned.apk" + SIGNED_APK="$PROJECT_DIR/bitchat-release-arm64.apk" + + if [ -f "$UNSIGNED_APK" ]; then + $ANDROID_HOME/build-tools/35.0.0/zipalign -v 4 "$UNSIGNED_APK" "$PROJECT_DIR/app-aligned.apk" + $ANDROID_HOME/build-tools/35.0.0/apksigner sign \ + --ks "$PROJECT_DIR/bitchat-release.keystore" \ + --ks-pass pass:"BitchatRelease2025!" \ + --key-pass pass:"BitchatRelease2025!" \ + --ks-key-alias bitchat \ + --out "$SIGNED_APK" \ + "$PROJECT_DIR/app-aligned.apk" + + if [ -f "$SIGNED_APK" ]; then + log "✅ Manual signing successful: $SIGNED_APK" + return 0 + fi + fi + return 1 +} + +copy_apks_to_workspace() { + log "Copying APKs to workspace..." + mkdir -p "$PROJECT_DIR/builds" + + # Copy debug APKs + find "$PROJECT_DIR/app/build/outputs/apk/debug" -name "*.apk" -exec cp {} "$PROJECT_DIR/builds/" \; 2>/dev/null || true + + # Copy release APKs + find "$PROJECT_DIR/app/build/outputs/apk/release" -name "*.apk" -exec cp {} "$PROJECT_DIR/builds/" \; 2>/dev/null || true + + # Create easy-access copies + if [ -f "$PROJECT_DIR/builds/app-arm64-v8a-debug.apk" ]; then + cp "$PROJECT_DIR/builds/app-arm64-v8a-debug.apk" "$PROJECT_DIR/bitchat-debug-arm64.apk" + fi + + if [ -f "$PROJECT_DIR/builds/app-arm64-v8a-release.apk" ]; then + cp "$PROJECT_DIR/builds/app-arm64-v8a-release.apk" "$PROJECT_DIR/bitchat-release-arm64.apk" + fi +} + +generate_build_report() { + log "Generating build report..." + + REPORT_FILE="$PROJECT_DIR/BUILD_REPORT.md" + + cat > "$REPORT_FILE" << EOF +# BitChat Android Build Report + +Generated: $(date) + +## Build Status + +### Debug APKs +$(find "$PROJECT_DIR/builds" -name "*debug*.apk" -exec ls -lh {} \; 2>/dev/null) + +### Release APKs +$(find "$PROJECT_DIR/builds" -name "*release*.apk" -exec ls -lh {} \; 2>/dev/null) + +## Keystore Information + +**File:** bitchat-release.keystore +**Alias:** bitchat +**Password:** BitchatRelease2025! +**Validity:** 10000 days + +## Installation Instructions + +1. Download the appropriate APK for your device: + - \`bitchat-debug-arm64.apk\` - For testing on most modern phones + - \`bitchat-release-arm64.apk\` - For production use (if available) + +2. Enable "Install from unknown sources" in your phone settings + +3. Open the APK file to install + +4. Grant Bluetooth and Location permissions when prompted + +## Build Logs + +See: build-monitor.log + +EOF + + log "Build report saved to: $REPORT_FILE" +} + +# Main execution +main() { + log "==========================================" + log "BitChat Android Build Monitor Started" + log "==========================================" + + # Check current state + STATUS=$(check_build_status) + log "Current state: $STATUS" + + # Parse status + DEBUG_COUNT=$(echo "$STATUS" | grep "DEBUG_APKS" | cut -d= -f2) + RELEASE_COUNT=$(echo "$STATUS" | grep "RELEASE_APKS" | cut -d= -f2) + + # Build debug if needed + if [ "$DEBUG_COUNT" -eq 0 ] 2>/dev/null; then + log "Debug APKs not found, building..." + kill_stale_gradle + clean_build_cache + + if ! build_debug; then + log "Debug build failed, retrying with fresh environment..." + kill_stale_gradle + sleep 10 + build_debug || log "Debug build failed after retry" + fi + else + log "Debug APKs already exist: $DEBUG_COUNT files" + fi + + # Build release + log "Building release APK..." + kill_stale_gradle + sleep 5 + + if ! build_release; then + log "Release build failed, attempting manual signing..." + sign_apk_manual || log "Manual signing also failed" + fi + + # Copy APKs + copy_apks_to_workspace + + # Generate report + generate_build_report + + # Final status + log "==========================================" + log "Final Build Status:" + find "$PROJECT_DIR/builds" -name "*.apk" -exec ls -lh {} \; 2>/dev/null | tee -a "$LOG_FILE" + log "==========================================" + + # Check if successful + FINAL_RELEASE=$(find "$PROJECT_DIR/builds" -name "*release*.apk" 2>/dev/null | wc -l) + if [ "$FINAL_RELEASE" -gt 0 ]; then + log "✅ BUILD COMPLETE - Release APKs available!" + echo "COMPLETE" > "$STATE_FILE" + exit 0 + else + log "⚠️ Build incomplete - check logs" + echo "INCOMPLETE" > "$STATE_FILE" + exit 1 + fi +} + +# Run main +main "$@" \ No newline at end of file diff --git a/cron-build-manager.sh b/cron-build-manager.sh new file mode 100755 index 00000000..3500b25c --- /dev/null +++ b/cron-build-manager.sh @@ -0,0 +1,125 @@ +#!/bin/bash +# BitChat Android - Cron Job Manager for Build Reactivation +# This manages the cron job that monitors and reactivates the build process + +PROJECT_DIR="/home/openclaw/.openclaw/workspace/ikorochat-android" +CRON_MARKER="# BITCHAT_BUILD_MONITOR" +BUILD_MONITOR_SCRIPT="$PROJECT_DIR/build-monitor.sh" +CRON_LOG="$PROJECT_DIR/cron-reactivation.log" + +setup_cron() { + echo "[$(date)] Setting up build monitor cron job..." + + # Create cron entry that runs every 5 minutes + CRON_ENTRY="*/5 * * * * $BUILD_MONITOR_SCRIPT >> $CRON_LOG 2>&1 $CRON_MARKER" + + # Check if cron already exists + if crontab -l 2>/dev/null | grep -q "BITCHAT_BUILD_MONITOR"; then + echo "Cron job already exists, skipping setup" + return 0 + fi + + # Add to crontab + (crontab -l 2>/dev/null; echo "$CRON_ENTRY") | crontab - + + echo "✅ Cron job installed - will check build every 5 minutes" + echo "Log file: $CRON_LOG" +} + +remove_cron() { + echo "[$(date)] Removing build monitor cron job..." + + # Remove our cron entry + crontab -l 2>/dev/null | grep -v "BITCHAT_BUILD_MONITOR" | crontab - + + echo "✅ Cron job removed" +} + +check_build_status() { + STATE_FILE="$PROJECT_DIR/.build-state" + + if [ -f "$STATE_FILE" ]; then + STATE=$(cat "$STATE_FILE") + echo "Build state: $STATE" + + if [ "$STATE" = "COMPLETE" ]; then + echo "✅ Build is complete!" + return 0 + fi + fi + + # Check for APKs directly + RELEASE_APKS=$(find "$PROJECT_DIR/builds" -name "*release*.apk" 2>/dev/null | wc -l) + if [ "$RELEASE_APKS" -gt 0 ]; then + echo "✅ Release APKs found!" + return 0 + fi + + echo "Build not complete yet" + return 1 +} + +force_build() { + echo "[$(date)] Force starting build process..." + "$BUILD_MONITOR_SCRIPT" +} + +show_status() { + echo "==========================================" + echo "BitChat Android Build Status" + echo "==========================================" + echo "" + + # Check cron + if crontab -l 2>/dev/null | grep -q "BITCHAT_BUILD_MONITOR"; then + echo "Cron Job: ✅ Active" + else + echo "Cron Job: ❌ Not active" + fi + + echo "" + echo "APKs Available:" + find "$PROJECT_DIR/builds" -name "*.apk" -exec ls -lh {} \; 2>/dev/null || echo "No APKs found" + + echo "" + echo "Recent Log Entries:" + tail -20 "$PROJECT_DIR/build-monitor.log" 2>/dev/null || echo "No log file" + + echo "" + check_build_status + echo "==========================================" +} + +# Main command handler +case "${1:-status}" in + setup) + setup_cron + ;; + remove|cleanup) + remove_cron + ;; + status) + show_status + ;; + force) + force_build + ;; + check) + if check_build_status; then + echo "Build complete, cleaning up cron..." + remove_cron + else + echo "Build incomplete, cron will continue monitoring" + fi + ;; + *) + echo "Usage: $0 {setup|remove|status|force|check}" + echo "" + echo "Commands:" + echo " setup - Install cron job to monitor build" + echo " remove - Remove cron job" + echo " status - Show current build status" + echo " force - Force start the build now" + echo " check - Check if build complete, cleanup if done" + ;; +esac \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 0838af96..e4275db0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,4 +26,4 @@ android.nonTransitiveRClass=false kotlin.code.style=official # JVM heap size configuration to prevent OutOfMemoryError -org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError \ No newline at end of file +org.gradle.jvmargs=-Xmx1g -XX:+UseG1GC