Merge branch 'master' into chat-relays

This commit is contained in:
Evgeny Poberezkin
2026-01-24 18:20:06 +00:00
5 changed files with 392 additions and 2 deletions
+92
View File
@@ -1 +1,93 @@
# SimpleX Chat iOS app
This file provides guidance when working with code in this repository.
## iOS App Overview
The iOS app is a SwiftUI application that interfaces with the Haskell core library via FFI. It shares the SimpleXChat framework with two extensions: Notification Service Extension (NSE) for push notifications and Share Extension (SE) for sharing content from other apps.
## Build & Development
Open `SimpleX.xcodeproj` in Xcode. The project has five targets:
- **SimpleX (iOS)** - Main app (Bundle ID: `chat.simplex.app`)
- **SimpleXChat** - Framework containing FFI bridge and shared types
- **SimpleX NSE** - Notification Service Extension
- **SimpleX SE** - Share Extension
- **Tests iOS** - UI tests
Build and run via Xcode (Product > Build/Run). Tests run via Product > Test or:
```bash
xcodebuild test -scheme "SimpleX (iOS)" -destination 'platform=iOS Simulator,name=iPhone 15'
```
Deployment target: iOS 15.0+, Swift 5.0.
## Architecture
### Haskell Core Integration
The app calls the Haskell core library through C FFI defined in `SimpleXChat/SimpleX.h`:
- `chat_migrate_init_key()` - Initialize/migrate database
- `chat_send_cmd_retry()` - Send command to chat controller
- `chat_recv_msg_wait()` - Receive messages from controller
Swift wrappers in `SimpleXChat/API.swift`:
- `chatMigrateInit()` - Initialize chat controller
- `sendSimpleXCmd<R>()` - Send typed commands and parse responses
- `recvSimpleXMsg<R>()` - Receive typed messages
Haskell runtime initialization (`SimpleXChat/hs_init.c`) uses different memory configurations:
- Main app: 64MB heap
- NSE: 512KB heap (minimal footprint for background processing)
- SE: 1MB heap
Pre-compiled Haskell libraries are in `Libraries/{ios,mac,sim}/`.
### State Management
- **ChatModel** (`Shared/Model/ChatModel.swift`) - Main singleton `ObservableObject` for app-wide state (chat list, active chat, users)
- **ItemsModel** - Manages chat items within a selected chat (similar to Kotlin's ChatsContext)
- **AppTheme** - Theme management and customization
### App Structure
Entry point: `Shared/SimpleXApp.swift`
Key directories in `Shared/`:
- `Model/` - Data models and API layer (`ChatModel.swift`, `SimpleXAPI.swift`)
- `Views/` - SwiftUI views organized by feature:
- `ChatList/` - Chat list and user picker
- `Chat/` - Message display and composition
- `Call/` - VoIP call UI
- `UserSettings/` - App settings
- `LocalAuth/` - Passcode and biometric authentication
- `Database/` - Database initialization and migration
### Shared Data Between Targets
All three targets share data via App Group (`group.chat.simplex.app`):
- `SimpleXChat/AppGroup.swift` - GroupDefaults wrapper for typed shared preferences
- Keychain for sensitive data: `kcDatabasePassword`, `kcAppPassword`, `kcSelfDestructPassword`
### Key Types
Types are defined in `SimpleXChat/`:
- `ChatTypes.swift` - User, Chat, Message, Group types
- `APITypes.swift` - API request/response types
Commands follow `ChatCmdProtocol` (has `cmdString` property), sent as JSON through FFI.
## Localization
31 languages supported. Localization files in `SimpleX Localizations/`.
Workflow:
- `Product > Export Localizations` - Export XLIFF files
- `Product > Import Localizations` - Import updated translations
## Background Capabilities
Configured in Info.plist:
- Background modes: audio, fetch, remote-notification, voip
- URL scheme: `simplex://` for deep linking
- BGTaskScheduler: `chat.simplex.app.receive`
+99 -2
View File
@@ -1,8 +1,105 @@
# Android App Development
This readme is currently a stub and as such is in development.
This is a guide to contributing to the develop of the SimpleX android and desktop apps.
Ultimately, this readme will act as a guide to contributing to the develop of the SimpleX android app.
## Project Overview
This is the **Kotlin Multiplatform (KMP)** mobile and desktop client for SimpleX Chat, sharing code between Android and Desktop (JVM) platforms using Compose Multiplatform for UI.
## Build Commands
```bash
# Android debug APK
./gradlew assembleDebug
# Android release APK
./gradlew assembleRelease
# Desktop distribution (current OS)
./gradlew :desktop:packageDistributionForCurrentOS
# Run desktop/JVM tests
./gradlew desktopTest
# Run Android instrumented tests (requires connected device/emulator)
./gradlew connectedAndroidTest
# Build native libraries for all platforms
./gradlew common:cmakeBuild -PcrossCompile
# Clean build
./gradlew clean
```
## Architecture
### Module Structure
- **`common/`** - Shared code (Compose UI, models, business logic)
- `src/commonMain/` - Cross-platform code
- `src/androidMain/` - Android-specific implementations
- `src/desktopMain/` - Desktop-specific implementations
- **`android/`** - Android app container
- **`desktop/`** - Desktop JVM app container
### Key Components (`common/src/commonMain/kotlin/chat/simplex/common/`)
- **`model/ChatModel.kt`** - Main state container with reactive properties (MutableState, MutableStateFlow)
- **`model/SimpleXAPI.kt`** - API bindings to Haskell core library via FFI
- **`platform/Core.kt`** - FFI interface to native `libapp` library
- **`platform/`** - Platform abstraction layer (expect/actual pattern for Android/Desktop specifics)
- **`views/`** - Compose UI screens organized by feature (chat, chatlist, call, usersettings, etc.)
- **`ui/theme/`** - Design system (colors, typography, shapes)
### Native Integration
The app calls into a Haskell core library via JNI/FFI:
- CMake builds in `common/src/commonMain/cpp/android/` and `cpp/desktop/`
- Cross-compilation toolchains in `cpp/toolchains/`
- Built libraries go to `cpp/desktop/libs/` (organized by platform)
## Configuration
### `local.properties` (create from `local.properties.example`)
```properties
compression.level=0 # APK compression (0-9)
enable_debuggable=true # Debug mode
application_id.suffix=.debug # Multiple app instances on same device
app.name=SimpleX Debug # App name for debug builds
```
### `gradle.properties`
Contains versions (Kotlin, Compose, AGP) and app version info. Key settings:
- `kotlin.jvm.target=11`
- `database.backend=sqlite` (or `postgres`)
## Testing
Tests are in:
- `common/src/commonTest/kotlin/` - Cross-platform tests
- `common/src/desktopTest/kotlin/` - Desktop-specific tests (run with `./gradlew desktopTest`)
- `android/src/androidTest/` - Android instrumented tests
## Resources & Localization
- String resources: `common/src/commonMain/resources/MR/base/strings.xml` + 21 language variants
- Uses Moko Resources (`dev.icerock.moko:resources`) for cross-platform resource management
- The `adjustFormatting` gradle task validates string resources during build
## Platform-Specific Notes
### Android
- Min SDK 26, Target SDK 35
- NDK 23.1.7779620
- Supports ABI splits: `arm64-v8a`, `armeabi-v7a`
- Deep linking requires SHA certificate fingerprint in `assetlinks.json` (see README.md)
### Desktop
- Distributions: DMG (macOS), MSI/EXE (Windows), DEB (Linux)
- Mac signing/notarization configured via `local.properties`
- Video playback uses VLCJ
## Gotchas
+25
View File
@@ -7,6 +7,31 @@ revision: 25.07.2025
# Contributing guide
## Focus on user problems
We do not make code changes to improve code - any change must address a specific user problem or request.
## Discuss the plans as early as possible
Please discuss the problem you want to solve and your detailed implementation plan with the project team prior to contributing, to avoid wasted time and additional changes. Acceptance of your contribution depends on your willingness and ability to iterate the proposed contribution to achieve the required quality level, coding style, test coverage, and alignment with user requirements as they are understood by the project team.
## Follow project structure, coding style and approaches
./contributing/PROJECT.md has information about the structure of this `simplex-chat` repository.
./contributing/CODE.md has details about general requirements common for `simplexmq` and `simplex-chat` repositories.
This files can be used with LLM prompts, e.g. if you use Claude Code you can create CLAUDE.md file in project root importing content from these files:
```markdown
@README.md
@docs/CONTRIBUTING.md
@docs/contributing/PROJECT.md
@docs/contributing/CODE.md
```
For Android/Desktop and iOS apps you can additionally import `apps/multiplatform/README.md` and `apps/ios/README.md`.
## Compiling with SQLCipher encryption enabled
Add `cabal.project.local` to project root with the location of OpenSSL headers and libraries and flag setting encryption mode:
+84
View File
@@ -0,0 +1,84 @@
# Coding and building
This file provides guidance on coding style and approaches and on building the code.
## Code Style and Formatting
The project uses **fourmolu** for Haskell code formatting. Configuration is in `fourmolu.yaml`.
**Key formatting rules:**
- 2-space indentation
- Trailing function arrows, commas, and import/export style
- Record brace without space: `{field = value}`
- Single newline between declarations
- Never use unicode symbols
- Inline `let` style with right-aligned `in`
**Format code before committing:**
```bash
# Format a single file
fourmolu -i src/Simplex/Messaging/Protocol.hs
```
Some files that use CPP language extension cannot be formatted as a whole, so individual code fragments need to be formatted.
**Follow existing code patterns:**
- Match the style of surrounding code
- Use qualified imports with short aliases (e.g., `import qualified Data.ByteString.Char8 as B`)
- Use record syntax for types with multiple fields
- Prefer explicit pattern matching over partial functions
**Comments policy:**
- Avoid redundant comments that restate what the code already says
- Only comment on non-obvious design decisions or tricky implementation details
- Function names and type signatures should be self-documenting
- Do not add comments like "wire format encoding" (Encoding class is always wire format) or "check if X" when the function name already says that
- Assume a competent Haskell reader
**Diff and refactoring:**
- Avoid unnecessary changes and code movements
- Never do refactoring unless it substantially reduces cost of solving the current problem, including the cost of refactoring
- Aim to minimize the code changes - do what is minimally required to solve users' problems
### Haskell Extensions
- `StrictData` enabled by default
- Use STM for safe concurrency
- Assume concurrency in PostgreSQL queries
- Comprehensive warning flags with strict pattern matching
## Build Commands
```bash
# Standard build
cabal build
# Fast build
cabal build --ghc-options -O0
# Build specific executables
cabal build exe:simplex-chat
# Build with PostgreSQL client support
cabal build -fclient_postgres
# Client-only library build (no server code)
cabal build -fclient_library
# Find binary location
cabal list-bin exe:simplex-chat
```
### Cabal Flags
- `swift`: Enable Swift JSON format
- `client_library`: Build without server code
- `client_postgres`: Use PostgreSQL instead of SQLite for agent persistence
- `server_postgres`: PostgreSQL support for server queue/notification store
## External Dependencies
Custom forks specified in `cabal.project`:
- `aeson`, `hs-socks` (SimpleX forks)
- `direct-sqlcipher`, `sqlcipher-simple` (encrypted SQLite)
- `warp`, `warp-tls` (HTTP server)
+92
View File
@@ -0,0 +1,92 @@
# SimpleX-Chat repository
This file provides guidance on the project structure to help working with code in this repository.
## Project Overview
SimpleX Chat is a decentralized, privacy-focused messaging platform with **no user identifiers**. Users are identified by disposable, per-connection message queue addresses instead of any persistent ID.
**Key components:**
- **Core library** (Haskell): `src/Simplex/Chat/` - chat protocol, controller, message handling, database storage
- **Terminal CLI**: `src/Simplex/Chat/Terminal/`
- **Mobile apps**: `apps/multiplatform/` (Kotlin Compose Multiplatform for Android/Desktop)
- **iOS app**: `apps/ios/` (SwiftUI)
- **Bot framework**: `bots/`, `packages/simplex-chat-nodejs/`
- **Website**: `website/` (11ty + Tailwind CSS)
## Specifications
Chat protocol: docs/protocol/simplex-chat.md
RFCs: docs/rfcs
## Core Haskell Modules
- `Controller.hs` - Main chat controller, orchestrates all chat operations
- `Types.hs` - Core type definitions (contacts, groups, messages, profiles)
- `Protocol.hs` - Chat protocol encoding/decoding
- `Messages.hs` - Message types and handling
- `Store/` - Database layer (SQLite by default, PostgreSQL optional)
- `Messages.hs` - Message storage
- `Groups.hs` - Group storage
- `Direct.hs` - Direct chat storage
- `Connections.hs` - Connection management
- `Mobile.hs` - FFI interface
- `Library/` - commands and events processing
- `Commands.hs` - all supported chat commands. They can be sent via CLI or via FFI functions.
- `Subscriber.hs` - processing events from the [agent](../../../simplexmq/src/Simplex/Messaging/Agent/Protocol.hs)
### Database Migrations
SQLite migrations are in `src/Simplex/Chat/Store/SQLite/Migrations/`. PostgreSQL migrations are in `src/Simplex/Chat/Store/Postgres/Migrations/`. Each migration is a separate module named `M{YYYYMMDD}_{description}.hs`.
**Important:** The `chat_schema.sql` files in both migration directories are **auto-generated by tests** - do not edit them directly. They reflect the final schema state after all migrations are applied.
When creating a new migration:
1. Create the migration module (e.g., `M20260122_feature.hs`)
2. Register it in the corresponding `Migrations.hs` file
3. Add the module to `simplex-chat.cabal` under exposed-modules
4. Schema files will be updated automatically when tests are run
### Test Structure
Tests are in `tests/`:
- `ChatTests/` - Integration tests (Direct, Groups, Files, Profiles)
- `ProtocolTests.hs` - Protocol encoding/decoding tests
- `JSONTests.hs` - JSON serialization tests
- `Bots/` - Bot-specific tests
## Key Dependencies
The project uses several custom forks managed via `cabal.project`:
- `simplexmq` - Core SimpleX Messaging Protocol (separate [repo](../../../simplexmq/README.md))
- `direct-sqlcipher` - SQLite with encryption
- `aeson` - JSON serialization (custom fork)
## Android/Desktop (Kotlin Multiplatform)
```bash
cd apps/multiplatform
# Build Android debug APK
./gradlew assembleDebug
# Build desktop
./gradlew :desktop:packageDistributionForCurrentOS
# Run Android tests
./gradlew connectedAndroidTest
```
### iOS
Open `apps/ios/SimpleX.xcodeproj` in Xcode. Build targets include the main app, Share Extension, and Notification Service Extension.
### Website
```bash
cd website
npm install
npm run start # Dev server
npm run build # Production build
```