A distributed key-value store optimized for mobile edge devices with MQTT-based communication and real-time synchronization.
import 'package:merkle_kv_core/merkle_kv_core.dart';
// 1. Configure (constructor or builder)
final config = MerkleKVConfig(
mqttHost: 'broker.example.com',
clientId: 'mobile-device-1',
nodeId: 'unique-device-id',
topicPrefix: 'myapp/production', // Multi-tenant support
);
// Or fluent builder (recommended)
final built = MerkleKVConfig.builder()
.host('broker.example.com')
.clientId('mobile-device-1')
.nodeId('unique-device-id')
.topicPrefix('myapp/production')
.build();
// 2. Initialize
final client = MerkleKVMobile(config);
await client.start();
// 3. Use
await client.set('user:123', 'Alice');
final value = await client.get('user:123');
await client.delete('user:123');
// 4. Real-time sync between devices happens automaticallyDownload the latest demo APK from our releases:
# Download latest beta APK (87MB)
curl -L -o merkle_kv_demo.apk \
"https://github.com/hackerChocomica/MerkleKV-Mobile/releases/download/v1.0.0-beta.1/merkle_kv_demo.apk"
# Install on Android device
adb install merkle_kv_demo.apkUse our reliable build script that handles CI/CD correctly:
# Clone repository
git clone https://github.com/hackerChocomica/MerkleKV-Mobile.git
cd MerkleKV-Mobile
# Build APK using our script (recommended)
./scripts/build-flutter.sh
# APK will be created at:
# apps/flutter_demo/build/app/outputs/flutter-apk/app-debug.apkWhy use the build script?
- β Handles working directory correctly for CI/CD
- β Automatically detects project structure
- β Verifies all required files exist
- β Shows detailed progress and file listings
- β Reports APK size and location
If you prefer manual commands:
cd apps/flutter_demo
# Verify target files exist
ls -la lib/main*.dart
# Build APK
flutter build apk --debug
# APK location: build/app/outputs/flutter-apk/app-debug.apk- iOS: See docs/iOS-Release-Guide.md and the automated workflow ios-release.yml
- Android: See docs/Android-Release-Guide.md for signing, release APK/AAB, and Play Console steps
βββββββββββββββββββ MQTT βββββββββββββββββββ
β Mobile App A βββββββββββββΊβ Mobile App B β
β β β β
β βββββββββββββββ β β βββββββββββββββ β
β β MerkleKV β β β β MerkleKV β β
β β Mobile β β β β Mobile β β
β β β β β β β β
β β β’ Storage β β β β β’ Storage β β
β β β’ Sync β β β β β’ Sync β β
β β β’ Commands β β β β β’ Commands β β
β βββββββββββββββ β β βββββββββββββββ β
βββββββββββββββββββ βββββββββββββββββββ
β β
βββββββββββββββ βββββββββββββ
βΌ βΌ
βββββββββββββββββββ
β MQTT Broker β
β β
β β’ Message Routing
β β’ Topic Management
β β’ Multi-Tenant ACL
βββββββββββββββββββ
Add to your pubspec.yaml:
dependencies:
merkle_kv_core: ^1.0.0flutter pub getOption 1: Local Development (Mosquitto)
# Install
brew install mosquitto # macOS
apt install mosquitto # Ubuntu
# Start
mosquitto -p 1883 -vOption 2: Cloud (HiveMQ)
final config = MerkleKVConfig(
mqttHost: 'your-cluster.hivemq.cloud',
mqttPort: 8883,
mqttUseTls: true,
username: 'your-username',
password: 'your-password',
// ... other config
);final config = MerkleKVConfig(
mqttHost: 'broker.example.com',
clientId: 'mobile-app-1',
nodeId: 'device-uuid-123',
);// Customer A - Production
final customerA = MerkleKVConfig(
mqttHost: 'broker.example.com',
clientId: 'device-001',
nodeId: 'customer-a-device-001',
topicPrefix: 'customer-a/production',
);
// Customer B - Production
final customerB = MerkleKVConfig(
mqttHost: 'broker.example.com',
clientId: 'device-001', // Same ID, different tenant
nodeId: 'customer-b-device-001',
topicPrefix: 'customer-b/production',
);
// Topics are completely isolated:
// Customer A: customer-a/production/device-001/cmd
// Customer B: customer-b/production/device-001/cmdfinal config = MerkleKVConfig(
mqttHost: 'broker.example.com',
clientId: 'mobile-device-1',
nodeId: 'device-uuid-123',
persistenceEnabled: true,
storagePath: '/path/to/storage',
);// Data changes sync automatically between devices
// Device A
await clientA.set('shared-counter', '1');
// Device B (receives update automatically)
final value = await clientB.get('shared-counter'); // Returns '1'
// Device B updates
await clientB.set('shared-counter', '2');
// Device A (receives update automatically)
final updated = await clientA.get('shared-counter'); // Returns '2'// Listen for replication events
client.replicationEvents.listen((event) {
print('Key ${event.key} changed to ${event.value}');
});
// Replication publishing is handled internally; no extra flag needed
final config = MerkleKVConfig(
// ... basic config
);Option A β Simple (username/password over TLS):
final secureConfig = MerkleKVConfig(
mqttHost: 'secure-broker.example.com',
mqttPort: 8883, // TLS port
mqttUseTls: true,
clientId: 'production-client-1',
nodeId: 'prod-device-uuid-123',
username: 'mqtt-user',
password: 'secure-password',
);Option B β Advanced (explicit TLS and auth via MqttSecurityConfig):
final secureConfig = MerkleKVConfig(
mqttHost: 'secure-broker.example.com',
mqttPort: 8883,
clientId: 'production-client-1',
nodeId: 'prod-device-uuid-123',
mqttSecurity: MqttSecurityConfig(
enableTLS: true,
minTLSVersion: TLSVersion.v1_2,
enforceHostnameValidation: true,
enforceSANValidation: true,
authMethod: AuthenticationMethod.usernamePassword,
// Provide secrets from secure storage in production
username: 'mqtt-user',
password: 'secure-password',
),
);// Tenant isolation prevents data leakage
final tenant1Config = MerkleKVConfig(
mqttHost: 'broker.example.com',
clientId: 'device-001',
nodeId: 'tenant1-device-001',
topicPrefix: 'tenant1/production', // Complete isolation
);
final tenant2Config = MerkleKVConfig(
mqttHost: 'broker.example.com',
clientId: 'device-001', // Same client ID, different tenant
nodeId: 'tenant2-device-001',
topicPrefix: 'tenant2/production', // Complete isolation
);- Enable certificate pinning in production
- Use ACL files for MQTT broker user permissions
- Implement device registration and key rotation
- Monitor connection health and authentication failures
// Check replication performance
final metrics = await client.getReplicationMetrics();
print('Published: ${metrics.eventsPublished}');
print('Queue size: ${metrics.outboxSize}');
print('Failed: ${metrics.publishFailures}');
// Monitor storage usage
final storageMetrics = await client.getStorageMetrics();
print('Total entries: ${storageMetrics.totalEntries}');
print('Storage size: ${storageMetrics.totalSizeBytes}');- Use appropriate
topicPrefixfor tenant isolation - Enable persistence only when needed
- Monitor outbox queue for delivery issues
- Implement proper error handling and retry logic
- Use connection pooling for multiple clients
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β Flutter App β β MerkleKV Core β β MQTT Broker β
β β β β β β
β βββββββββββββββ β β ββββββββββββββββ β β βββββββββββββββ β
β β UI β βββββΊβ β Commands β βββββΊβ β Topics β β
β βββββββββββββββ β β ββββββββββββββββ β β βββββββββββββββ β
β β β ββββββββββββββββ β β βββββββββββββββ β
β β Models β βββββΊβ β Storage β β β β TLS β β
β βββββββββββββββ β β β Engine β β β β Security β β
β β β ββββββββββββββββ β β βββββββββββββββ β
β βββββββββββββββ β β ββββββββββββββββ β β βββββββββββββββ β
β β Services β βββββΊβ β Replication β βββββΊβ β ACL β β
β βββββββββββββββ β β β Events β β β β Permissions β β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
- Commands: GET/SET/DEL operations with response correlation
- Storage: In-memory with optional persistence and conflict resolution
- Replication: Real-time sync via MQTT with anti-entropy recovery
- Security: TLS encryption with multi-tenant topic isolation
{prefix}/{client_id}/cmd # Command channel
{prefix}/{client_id}/res # Response channel
{prefix}/replication/events # Shared replication
| Resource | Description | Level |
|---|---|---|
| Quick Start | 5-minute setup guide | Beginner |
| Configuration Examples | Production configs | Intermediate |
| Architecture Guide | Deep technical dive | Advanced |
| API Reference | Complete API docs | Reference |
| Security Guide | Production security | Advanced |
| MQTT Security Config | Configure TLS and auth | Reference |
| CBOR Replication | Serialization details | Advanced |
| Contributing Guide | Development setup | Contributor |
- Flutter SDK 3.16.0 or higher
- Dart SDK 3.0.0 or higher
- Android SDK (for APK builds)
- Docker (for MQTT broker)
# Clone repository
git clone https://github.com/hackerChocomica/MerkleKV-Mobile.git
cd MerkleKV-Mobile
# Install dependencies
flutter pub get
cd packages/merkle_kv_core && dart pub get
# Start MQTT broker for testing
docker run -d --name test-mosquitto -p 1883:1883 eclipse-mosquitto:1.6
# Verify broker connectivity
./scripts/mqtt_health_check.sh| Script | Purpose | Usage |
|---|---|---|
./scripts/build-flutter.sh |
Build Flutter APK reliably | ./scripts/build-flutter.sh |
./scripts/build_ios_release.sh |
Build iOS IPA locally (macOS) | ./scripts/build_ios_release.sh -v 1.2.0 -b 42 |
./scripts/mqtt_health_check.sh |
Test MQTT broker connection | ./scripts/mqtt_health_check.sh |
./scripts/test_broker_connectivity.sh |
Comprehensive MQTT testing | ./scripts/test_broker_connectivity.sh |
./scripts/run_integration_tests.sh |
Run integration test suite | ./scripts/run_integration_tests.sh |
# Core package tests (static analysis)
cd packages/merkle_kv_core
dart analyze .
# MQTT integration testing (requires broker)
./scripts/mqtt_health_check.sh
# Flutter widget testing
cd apps/flutter_demo
flutter testNote: Full dart test is disabled due to Dart SDK issues. Use static analysis and MQTT integration testing instead.
- β CI/CD Build Fixes: Reliable Flutter APK builds with proper script handling
- β Multi-Tenant Isolation: Prefix-based topic isolation with UTF-8 validation
- β Connection Lifecycle Management: Auto-reconnection with exponential backoff
- β Anti-Entropy Protocol: Merkle tree-based synchronization
- β Event Publishing: Reliable replication with CBOR serialization
- β Production Ready: Comprehensive testing and CI/CD
- π± Mobile-First: Designed for mobile edge devices
- π Real-Time Sync: Automatic data synchronization between devices
- π‘ MQTT-Based: Uses MQTT instead of TCP for mobile-friendly communication
- π Multi-Tenant: Secure tenant isolation with topic prefixes
- β‘ High Performance: In-memory storage with efficient sync protocols
- Merkle Tree Building: >11,000 entries/second
- Event Publishing: High-throughput with batching
- Memory Usage: Optimized for mobile devices
- Network Efficiency: CBOR serialization + compression
- APK Size: ~87MB (debug), optimized for production
| Topic | Description | Link |
|---|---|---|
| Build Scripts | Reliable CI/CD build process | β Scripts README |
| API Reference | Complete API documentation | β API Docs |
| Architecture | System design, protocols, components | β Architecture |
| Contributing | Development workflow, testing | β Contributing |
| Security | Production security guidelines | β Security |
| Changelog | Version history and releases | β Changelog |
We welcome contributions! Please see our Contributing Guide for details on:
- Setting up development environment
- Running tests and linting
- Submitting pull requests
- Code style guidelines
This project is licensed under the MIT License - see the LICENSE file for details.
- Repository: GitHub - MerkleKV Mobile
- Issues: GitHub Issues
- Releases: GitHub Releases
- Security: Security Policy
Latest Release: v1.0.0-beta.1 - APK builds working, CI/CD fixes, multi-tenant support