react-native-ble-mesh 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +439 -556
  2. package/docs/IOS-BACKGROUND-BLE.md +231 -0
  3. package/docs/OPTIMIZATION.md +70 -0
  4. package/docs/SPEC-v2.1.md +308 -0
  5. package/docs/prompt-instructions.md +528 -0
  6. package/package.json +2 -2
  7. package/src/MeshNetwork.js +659 -465
  8. package/src/constants/index.js +1 -0
  9. package/src/crypto/AutoCrypto.js +79 -0
  10. package/src/crypto/CryptoProvider.js +99 -0
  11. package/src/crypto/index.js +15 -63
  12. package/src/crypto/providers/ExpoCryptoProvider.js +125 -0
  13. package/src/crypto/providers/QuickCryptoProvider.js +134 -0
  14. package/src/crypto/providers/TweetNaClProvider.js +124 -0
  15. package/src/crypto/providers/index.js +11 -0
  16. package/src/errors/MeshError.js +2 -1
  17. package/src/expo/withBLEMesh.js +102 -0
  18. package/src/hooks/useMesh.js +30 -9
  19. package/src/hooks/useMessages.js +2 -0
  20. package/src/index.js +23 -8
  21. package/src/mesh/dedup/DedupManager.js +36 -10
  22. package/src/mesh/fragment/Assembler.js +5 -0
  23. package/src/mesh/index.js +1 -1
  24. package/src/mesh/monitor/ConnectionQuality.js +408 -0
  25. package/src/mesh/monitor/NetworkMonitor.js +327 -316
  26. package/src/mesh/monitor/index.js +7 -3
  27. package/src/mesh/peer/PeerManager.js +6 -1
  28. package/src/mesh/router/MessageRouter.js +26 -15
  29. package/src/mesh/router/RouteTable.js +7 -1
  30. package/src/mesh/store/StoreAndForwardManager.js +295 -297
  31. package/src/mesh/store/index.js +1 -1
  32. package/src/service/BatteryOptimizer.js +282 -278
  33. package/src/service/EmergencyManager.js +224 -214
  34. package/src/service/HandshakeManager.js +167 -13
  35. package/src/service/MeshService.js +72 -6
  36. package/src/service/SessionManager.js +77 -2
  37. package/src/service/audio/AudioManager.js +8 -2
  38. package/src/service/file/FileAssembler.js +106 -0
  39. package/src/service/file/FileChunker.js +79 -0
  40. package/src/service/file/FileManager.js +307 -0
  41. package/src/service/file/FileMessage.js +122 -0
  42. package/src/service/file/index.js +15 -0
  43. package/src/service/text/broadcast/BroadcastManager.js +16 -0
  44. package/src/transport/BLETransport.js +131 -9
  45. package/src/transport/MockTransport.js +1 -1
  46. package/src/transport/MultiTransport.js +305 -0
  47. package/src/transport/WiFiDirectTransport.js +295 -0
  48. package/src/transport/adapters/NodeBLEAdapter.js +34 -0
  49. package/src/transport/adapters/RNBLEAdapter.js +56 -1
  50. package/src/transport/index.js +6 -0
  51. package/src/utils/compression.js +291 -291
  52. package/src/crypto/aead.js +0 -189
  53. package/src/crypto/chacha20.js +0 -181
  54. package/src/crypto/hkdf.js +0 -187
  55. package/src/crypto/hmac.js +0 -143
  56. package/src/crypto/keys/KeyManager.js +0 -271
  57. package/src/crypto/keys/KeyPair.js +0 -216
  58. package/src/crypto/keys/SecureStorage.js +0 -219
  59. package/src/crypto/keys/index.js +0 -32
  60. package/src/crypto/noise/handshake.js +0 -410
  61. package/src/crypto/noise/index.js +0 -27
  62. package/src/crypto/noise/session.js +0 -253
  63. package/src/crypto/noise/state.js +0 -268
  64. package/src/crypto/poly1305.js +0 -113
  65. package/src/crypto/sha256.js +0 -240
  66. package/src/crypto/x25519.js +0 -154
package/README.md CHANGED
@@ -1,737 +1,620 @@
1
1
  # react-native-ble-mesh
2
2
 
3
- > Inspired by [Bitchat](https://github.com/permissionlesstech/bitchat) - this is the React Native version.
3
+ ## Send messages without the internet. Like magic!
4
4
 
5
- A **production-ready BLE Mesh Network library** for React Native with Noise Protocol security. This library enables peer-to-peer communication over Bluetooth Low Energy with end-to-end encryption, multi-hop routing, and offline-first capabilities.
5
+ [![npm version](https://img.shields.io/npm/v/react-native-ble-mesh.svg?style=flat-square)](https://www.npmjs.com/package/react-native-ble-mesh)
6
+ [![npm downloads](https://img.shields.io/npm/dm/react-native-ble-mesh.svg?style=flat-square)](https://www.npmjs.com/package/react-native-ble-mesh)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://opensource.org/licenses/MIT)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg?style=flat-square)](https://www.typescriptlang.org/)
9
+ [![Platform](https://img.shields.io/badge/Platform-iOS%20%7C%20Android-lightgrey.svg?style=flat-square)](https://reactnative.dev/)
10
+ [![Tests](https://img.shields.io/badge/Tests-433%20passing-brightgreen.svg?style=flat-square)]()
6
11
 
7
- [![npm version](https://img.shields.io/npm/v/react-native-ble-mesh.svg)](https://www.npmjs.com/package/react-native-ble-mesh)
8
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
12
+ ---
9
13
 
10
- ## Features
14
+ ## What is this?
11
15
 
12
- - **End-to-End Encryption** - Noise Protocol XX handshake with ChaCha20-Poly1305 AEAD
13
- - **Digital Signatures** - Ed25519 signatures for message authentication and identity verification
14
- - **Multi-Hop Routing** - Messages can traverse multiple peers to reach their destination
15
- - **Offline-First** - Works without internet connectivity using BLE
16
- - **Forward Secrecy** - Automatic session rekeying for enhanced security
17
- - **Replay Protection** - Sliding window algorithm prevents replay attacks
18
- - **Traffic Analysis Resistance** - PKCS#7 padding to fixed block sizes
19
- - **LZ4 Compression** - Efficient bandwidth usage for larger messages
20
- - **Power Management** - Multiple power modes for battery optimization
21
- - **Trust Management** - Peer verification, favorites, and blocking
22
- - **Message Reliability** - Automatic retry with exponential backoff
16
+ Imagine you're at a concert, camping trip, or during a power outage — **no WiFi, no cell service**. How do you text your friends?
23
17
 
24
- ## Use Cases
25
-
26
- - Offline messaging apps (like Bridgefy, Briar)
27
- - Disaster communication networks
28
- - Privacy-focused P2P chat
29
- - IoT mesh networks
30
- - Gaming multiplayer over BLE
18
+ **This library lets phones talk to each other using Bluetooth!** Messages hop from phone to phone until they reach your friend — even if they're far away.
31
19
 
32
- ## Installation
33
-
34
- ```bash
35
- npm install react-native-ble-mesh react-native-get-random-values react-native-ble-plx
36
- cd ios && pod install
37
20
  ```
38
-
39
- ### Required Setup
40
-
41
- **IMPORTANT:** You must import `react-native-get-random-values` at the very top of your entry file (index.js or App.js) **before any other imports**:
42
-
43
- ```javascript
44
- // index.js or App.js - This MUST be the first import!
45
- import 'react-native-get-random-values';
46
-
47
- // Now you can import other modules
48
- import { AppRegistry } from 'react-native';
49
- import App from './App';
50
- import { name as appName } from './app.json';
51
-
52
- AppRegistry.registerComponent(appName, () => App);
21
+ You Friend's Your
22
+ Phone ----Bluetooth---> Friend's ----Bluetooth---> Friend
23
+ Phone (300m away!)
53
24
  ```
54
25
 
55
- This polyfill provides the Web Crypto API (`crypto.getRandomValues`) which is required for cryptographic operations in the mesh network.
56
-
57
- ### iOS Setup
26
+ **Think of it like a game of telephone, but for text messages and photos!**
58
27
 
59
- Add Bluetooth permissions to your `Info.plist`:
28
+ ---
60
29
 
61
- ```xml
62
- <key>NSBluetoothAlwaysUsageDescription</key>
63
- <string>This app uses Bluetooth to communicate with nearby devices</string>
64
- <key>NSBluetoothPeripheralUsageDescription</key>
65
- <string>This app uses Bluetooth to communicate with nearby devices</string>
66
- <key>UIBackgroundModes</key>
67
- <array>
68
- <string>bluetooth-central</string>
69
- <string>bluetooth-peripheral</string>
70
- </array>
71
- ```
30
+ ## See It In Action
72
31
 
73
- ### Android Setup
32
+ ```javascript
33
+ import { MeshNetwork } from 'react-native-ble-mesh';
74
34
 
75
- Add Bluetooth permissions to your `AndroidManifest.xml`:
35
+ // 1. Create your mesh network
36
+ const mesh = new MeshNetwork({ nickname: 'Alex' });
76
37
 
77
- ```xml
78
- <uses-permission android:name="android.permission.BLUETOOTH" />
79
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
80
- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
81
- <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
82
- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
83
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
84
- ```
38
+ // 2. Start it up!
39
+ await mesh.start();
85
40
 
86
- ## Quick Start
41
+ // 3. Send a message to everyone nearby
42
+ await mesh.broadcast('Hello everyone! 👋');
87
43
 
88
- ### Basic Setup
44
+ // 4. Listen for messages
45
+ mesh.on('messageReceived', (msg) => {
46
+ console.log(`${msg.from} says: ${msg.text}`);
47
+ });
48
+ ```
89
49
 
90
- ```javascript
91
- const { MeshService, BLETransport } = require('react-native-ble-mesh');
50
+ **That's it! Four lines of code and you're chatting without internet!**
92
51
 
93
- // Create and initialize the mesh service
94
- const mesh = new MeshService();
52
+ ---
95
53
 
96
- async function start() {
97
- // Initialize with optional configuration
98
- await mesh.initialize({
99
- displayName: 'Alice',
100
- storage: null, // Use in-memory storage
101
- });
54
+ ## Why Use This?
102
55
 
103
- // Create transport layer
104
- const transport = new BLETransport();
56
+ | Problem | Our Solution |
57
+ |---------|--------------|
58
+ | No WiFi or cell service | Works with just Bluetooth! |
59
+ | Friend is too far away | Messages hop through other phones |
60
+ | Need to send photos? | Send files & images up to 10MB! |
61
+ | Worried about privacy? | Encrypted with battle-tested crypto |
62
+ | Phone battery dying? | Smart power saving built-in |
63
+ | Need to delete everything fast? | One-tap emergency wipe |
64
+ | Using Expo? | Works out of the box! |
65
+ | Need faster transfers? | Wi-Fi Direct for big files |
66
+ | How's my connection? | Real-time signal quality indicator |
105
67
 
106
- // Start the mesh service
107
- await mesh.start(transport);
68
+ ---
108
69
 
109
- console.log('Mesh network started!');
110
- console.log('My fingerprint:', mesh.getFingerprint());
111
- }
70
+ ## Cool Features
112
71
 
113
- start();
114
- ```
72
+ ### 📡 Messages That Hop
73
+ Your message can jump through **up to 7 phones** to reach someone far away. If Alice can't reach Dave directly, the message goes: Alice → Bob → Carol → Dave!
115
74
 
116
- ### Discovering Peers
75
+ ### 📸 Send Photos & Files
76
+ Send pictures, documents, or any file up to 10MB. The library chops it into tiny pieces, sends them through the mesh, and puts them back together on the other side. You get a progress bar too!
117
77
 
118
78
  ```javascript
119
- // Listen for peer discovery events
120
- mesh.on('peer-discovered', (peer) => {
121
- console.log('Discovered peer:', peer.id);
122
- console.log('Display name:', peer.getDisplayName());
79
+ // Send a photo to a friend
80
+ await mesh.sendFile('friend-id', {
81
+ data: photoBytes, // The file as bytes
82
+ name: 'vacation.jpg', // File name
83
+ mimeType: 'image/jpeg', // What kind of file
123
84
  });
124
85
 
125
- mesh.on('peer-connected', (peer) => {
126
- console.log('Connected to peer:', peer.id);
86
+ // Watch the progress
87
+ mesh.on('fileSendProgress', ({ name, percent }) => {
88
+ console.log(`Sending ${name}: ${percent}%`);
127
89
  });
128
90
 
129
- mesh.on('peer-secured', (peer) => {
130
- console.log('Secure session established with:', peer.id);
91
+ // Receive files from others
92
+ mesh.on('fileReceived', ({ from, file }) => {
93
+ console.log(`Got ${file.name} from ${from}!`);
94
+ // file.data has the bytes, file.mimeType tells you the type
131
95
  });
132
96
  ```
133
97
 
134
- ### Sending Messages
98
+ ### 📶 Connection Quality
99
+ See how good your connection is to each person — like signal bars on your phone!
135
100
 
136
101
  ```javascript
137
- // Send a broadcast message to all nearby peers
138
- const broadcastId = mesh.sendBroadcast('Hello, mesh network!');
139
-
140
- // Send a private encrypted message to a specific peer
141
- const peerId = 'abc123...';
142
- try {
143
- const messageId = await mesh.sendPrivateMessage(peerId, 'Hello, this is private!');
144
- console.log('Message sent:', messageId);
145
- } catch (error) {
146
- console.error('Failed to send:', error.message);
147
- }
148
-
149
- // Send a message to a channel
150
- const channelMessageId = mesh.sendChannelMessage('general', 'Hello channel!');
102
+ const quality = mesh.getConnectionQuality('friend-id');
103
+ // quality.level = 'excellent' | 'good' | 'fair' | 'poor'
104
+ // quality.rssi = -55 (signal strength)
105
+ // quality.latencyMs = 45 (how fast, in milliseconds)
106
+
107
+ // Get alerted when connection changes
108
+ mesh.on('connectionQualityChanged', ({ peerId, level }) => {
109
+ if (level === 'poor') {
110
+ console.log('Connection getting weak! Move closer.');
111
+ }
112
+ });
151
113
  ```
152
114
 
153
- ### Receiving Messages
115
+ ### 📡 Wi-Fi Direct for Big Files
116
+ Bluetooth is great for messages, but slow for big files. Wi-Fi Direct is **250x faster**! The library automatically picks the best one:
117
+
118
+ - **Small message?** → Sends via Bluetooth (reliable, low power)
119
+ - **Big photo?** → Sends via Wi-Fi Direct (super fast)
120
+ - **Wi-Fi Direct not available?** → Falls back to Bluetooth automatically
154
121
 
155
122
  ```javascript
156
- // Listen for incoming messages
157
- mesh.on('message', (message) => {
158
- console.log('Received message:', message.content);
159
- console.log('From:', message.senderId);
160
- console.log('Type:', message.type);
161
- });
123
+ import { MultiTransport } from 'react-native-ble-mesh';
162
124
 
163
- // Listen for private messages specifically
164
- mesh.on('private-message', (message) => {
165
- console.log('Private message from', message.senderId);
166
- console.log('Content:', message.content);
125
+ // Use both Bluetooth AND Wi-Fi Direct together
126
+ const transport = new MultiTransport({
127
+ bleTransport: myBleTransport,
128
+ wifiTransport: myWifiTransport,
129
+ strategy: 'auto', // Let the library decide
167
130
  });
168
131
 
169
- // Listen for channel messages
170
- mesh.on('channel-message', (message) => {
171
- console.log('Channel:', message.channelId);
172
- console.log('Content:', message.content);
173
- });
132
+ const mesh = new MeshNetwork({ nickname: 'Alex' });
133
+ await mesh.start(transport);
134
+ // That's it! The library handles everything.
174
135
  ```
175
136
 
176
- ### Handling Acknowledgments and Read Receipts
137
+ ### 🔒 Secret Messages
138
+ Pick the encryption that works best for your app. The library auto-detects the fastest option:
177
139
 
178
- ```javascript
179
- // Listen for message delivery confirmations
180
- mesh.on('message-delivered', ({ messageId, peerId, timestamp }) => {
181
- console.log(`Message ${messageId} delivered to ${peerId}`);
182
- });
140
+ | Option | Speed | Works On |
141
+ |--------|-------|----------|
142
+ | `react-native-quick-crypto` | Blazing fast | React Native |
143
+ | `expo-crypto` + `tweetnacl` | 🚀 Fast | Expo apps |
144
+ | `tweetnacl` | ✅ Good | Everywhere |
183
145
 
184
- // Listen for read receipts
185
- mesh.on('read-receipt', ({ messageIds, fromPeerId, timestamp }) => {
186
- console.log(`Peer ${fromPeerId} read messages:`, messageIds);
146
+ ```javascript
147
+ // The library picks the best one automatically!
148
+ const mesh = new MeshNetwork({
149
+ nickname: 'Alex',
150
+ crypto: 'auto', // Auto-detect fastest available
187
151
  });
152
+ ```
188
153
 
189
- // Send read receipts for messages you've read
190
- mesh.sendReadReceipt(['msg-id-1', 'msg-id-2']);
154
+ ### 📬 Offline Delivery
155
+ Friend's phone turned off? No problem! Your message waits and delivers when they come back online.
191
156
 
192
- // Mark a single message as read
193
- mesh.markMessageRead('msg-id-1');
194
- ```
157
+ ### 🔋 Battery Friendly
158
+ Choose how much battery to use:
159
+ - **High Power** = Faster messages, more battery
160
+ - **Balanced** = Good speed, normal battery (default)
161
+ - **Low Power** = Slower messages, saves battery
162
+ - **Auto** = Let the phone decide based on battery level!
195
163
 
196
- ## API Reference
164
+ ### 🚨 Panic Button
165
+ Triple-tap to instantly delete all messages and data. Everything gone in less than 0.2 seconds!
197
166
 
198
- ### MeshService
167
+ ### 💬 Group Channels
168
+ Create chat rooms like `#camping-trip` or `#concert-squad`. Only people who join can see the messages!
199
169
 
200
- The main orchestrator for the mesh network.
170
+ ---
201
171
 
202
- #### Lifecycle Methods
172
+ ## Installation
203
173
 
204
- ```javascript
205
- // Initialize the service
206
- await mesh.initialize(options);
174
+ ### Option A: Expo Projects (Easiest!) 🎯
207
175
 
208
- // Start with a transport
209
- await mesh.start(transport);
176
+ ```bash
177
+ npx expo install react-native-ble-mesh react-native-ble-plx react-native-get-random-values
178
+ ```
210
179
 
211
- // Stop the service
212
- await mesh.stop();
180
+ Add the plugin to your `app.json`:
213
181
 
214
- // Clean up resources
215
- await mesh.destroy();
182
+ ```json
183
+ {
184
+ "expo": {
185
+ "plugins": [
186
+ ["react-native-ble-mesh", {
187
+ "bluetoothAlwaysPermission": "Chat with nearby friends using Bluetooth"
188
+ }]
189
+ ]
190
+ }
191
+ }
216
192
  ```
217
193
 
218
- #### Identity Management
194
+ **That's it! The plugin handles all the permissions for you.** ✅
219
195
 
220
- ```javascript
221
- // Get your identity information
222
- const identity = mesh.getIdentity();
223
- // Returns: { publicKey, signingPublicKey, displayName, fingerprint }
196
+ Then build your dev client:
197
+ ```bash
198
+ npx expo prebuild
199
+ npx expo run:ios # or run:android
200
+ ```
224
201
 
225
- // Set your display name
226
- mesh.setDisplayName('Alice');
202
+ ### Option B: Bare React Native
227
203
 
228
- // Get your fingerprint for out-of-band verification
229
- const fingerprint = mesh.getFingerprint();
204
+ ```bash
205
+ npm install react-native-ble-mesh react-native-ble-plx react-native-get-random-values
206
+ ```
230
207
 
231
- // Export identity for backup
232
- const exported = mesh.exportIdentity();
208
+ **iOS Setup:**
209
+ ```bash
210
+ cd ios && pod install && cd ..
211
+ ```
233
212
 
234
- // Import identity from backup
235
- mesh.importIdentity(exported);
213
+ Add to `ios/YourApp/Info.plist`:
214
+ ```xml
215
+ <key>NSBluetoothAlwaysUsageDescription</key>
216
+ <string>Chat with nearby friends using Bluetooth</string>
217
+ <key>NSBluetoothPeripheralUsageDescription</key>
218
+ <string>Chat with nearby friends using Bluetooth</string>
219
+ <key>UIBackgroundModes</key>
220
+ <array>
221
+ <string>bluetooth-central</string>
222
+ <string>bluetooth-peripheral</string>
223
+ </array>
224
+ ```
236
225
 
237
- // Announce identity to network
238
- mesh.announceIdentity();
226
+ **Android Setup:** Add to `android/app/src/main/AndroidManifest.xml`:
227
+ ```xml
228
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
229
+ <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
230
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
231
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
239
232
  ```
240
233
 
241
- #### Peer Management
234
+ ### Final Step (Both Options)
242
235
 
243
- ```javascript
244
- // Get all known peers
245
- const peers = mesh.getPeers();
236
+ Add this as the **very first line** in your app:
246
237
 
247
- // Get a specific peer
248
- const peer = mesh.getPeer(peerId);
238
+ ```javascript
239
+ import 'react-native-get-random-values';
240
+ ```
249
241
 
250
- // Initiate secure handshake with a peer
251
- await mesh.initiateHandshake(peerId);
242
+ ### Optional: Extra Speed & Features
252
243
 
253
- // Block a peer
254
- mesh.blockPeer(peerId);
244
+ ```bash
245
+ # Want encryption? Pick one:
246
+ npm install tweetnacl # Works everywhere
247
+ npm install react-native-quick-crypto # Fastest (native)
255
248
 
256
- // Unblock a peer
257
- mesh.unblockPeer(peerId);
249
+ # Want Wi-Fi Direct for big file transfers?
250
+ npm install react-native-wifi-p2p
258
251
  ```
259
252
 
260
- #### Trust Management
253
+ ---
254
+
255
+ ## Quick Start Examples
256
+
257
+ ### Example 1: Simple Chat
261
258
 
262
259
  ```javascript
263
- // Verify a peer using their fingerprint
264
- mesh.verifyPeer(peerId, fingerprint);
260
+ import { MeshNetwork } from 'react-native-ble-mesh';
265
261
 
266
- // Remove verification
267
- mesh.unverifyPeer(peerId);
262
+ const mesh = new MeshNetwork({ nickname: 'YourName' });
263
+ await mesh.start();
268
264
 
269
- // Add to favorites
270
- mesh.addFavorite(peerId);
265
+ // Send message to everyone
266
+ await mesh.broadcast('Hi everyone!');
271
267
 
272
- // Remove from favorites
273
- mesh.removeFavorite(peerId);
268
+ // Send private message to one person
269
+ await mesh.sendDirect('friend-id', 'Hey, just for you!');
274
270
 
275
- // Get verified peers
276
- const verified = mesh.getVerifiedPeers();
271
+ // Receive messages
272
+ mesh.on('messageReceived', ({ from, text }) => {
273
+ console.log(`${from}: ${text}`);
274
+ });
277
275
 
278
- // Get favorite peers
279
- const favorites = mesh.getFavoritePeers();
276
+ await mesh.stop();
280
277
  ```
281
278
 
282
- #### Power Management
279
+ ### Example 2: Send a Photo
283
280
 
284
281
  ```javascript
285
- // Available power modes: PERFORMANCE, BALANCED, POWER_SAVER, ULTRA_POWER_SAVER
286
- mesh.setPowerMode('BALANCED');
282
+ // Send a photo
283
+ await mesh.sendFile('friend-id', {
284
+ data: imageBytes,
285
+ name: 'selfie.jpg',
286
+ mimeType: 'image/jpeg',
287
+ });
287
288
 
288
- // Get current power mode
289
- const mode = mesh.getPowerMode();
289
+ // Track sending progress
290
+ mesh.on('fileSendProgress', ({ percent }) => {
291
+ console.log(`${percent}% sent`);
292
+ });
290
293
 
291
- // Enable automatic power adjustment based on battery level
292
- mesh.setAutoPowerAdjust(true);
294
+ // Receive photos
295
+ mesh.on('fileReceived', ({ from, file }) => {
296
+ console.log(`Got ${file.name} (${file.size} bytes) from ${from}`);
297
+ // file.data = the photo bytes
298
+ // file.mimeType = 'image/jpeg'
299
+ });
293
300
  ```
294
301
 
295
- #### Status and Statistics
302
+ ### Example 3: Group Channels
296
303
 
297
304
  ```javascript
298
- // Get service status
299
- const status = mesh.getStatus();
300
-
301
- // Get current state
302
- const state = mesh.getState();
303
-
304
- // Get detailed statistics
305
- const stats = mesh.getStats();
305
+ await mesh.joinChannel('#road-trip');
306
+ await mesh.sendToChannel('#road-trip', 'Are we there yet?');
307
+ await mesh.leaveChannel('#road-trip');
306
308
  ```
307
309
 
308
- ### Events
309
-
310
- | Event | Description | Payload |
311
- |-------|-------------|---------|
312
- | `peer-discovered` | New peer found | `{ peer }` |
313
- | `peer-connected` | Connected to peer | `{ peer }` |
314
- | `peer-disconnected` | Disconnected from peer | `{ peer }` |
315
- | `peer-secured` | Secure session established | `{ peer }` |
316
- | `message` | Any message received | `{ message }` |
317
- | `private-message` | Private message received | `{ message }` |
318
- | `channel-message` | Channel message received | `{ message }` |
319
- | `message-delivered` | Message delivery confirmed | `{ messageId, peerId, timestamp }` |
320
- | `message-failed` | Message delivery failed | `{ messageId, peerId, error }` |
321
- | `read-receipt` | Read receipt received | `{ messageIds, fromPeerId, timestamp }` |
322
- | `identity-announced` | Peer announced identity | `{ peerId, fingerprint, nickname }` |
323
- | `peer-verified` | Peer verification changed | `{ peerId, fingerprint }` |
324
- | `peer-compromised` | Fingerprint mismatch detected | `{ peerId, expected, actual }` |
325
-
326
- ## Configuration
327
-
328
- ### Initialization Options
310
+ ### Example 4: Check Connection Quality
329
311
 
330
312
  ```javascript
331
- await mesh.initialize({
332
- // Display name for this node
333
- displayName: 'My Device',
334
-
335
- // Storage adapter (null for in-memory)
336
- storage: null,
337
-
338
- // Custom key manager (optional)
339
- keyManager: null,
340
-
341
- // Enable compression for messages > 64 bytes
342
- compressionEnabled: true,
343
-
344
- // Compression threshold in bytes
345
- compressionThreshold: 64,
313
+ // How's my connection to a friend?
314
+ const quality = mesh.getConnectionQuality('friend-id');
315
+ console.log(`Signal: ${quality.level}`); // excellent, good, fair, poor
316
+ console.log(`Speed: ${quality.latencyMs}ms`);
317
+
318
+ // Check everyone at once
319
+ const all = mesh.getAllConnectionQuality();
320
+ all.forEach(q => {
321
+ console.log(`${q.peerId}: ${q.level} (${q.transport})`);
346
322
  });
347
323
  ```
348
324
 
349
- ### Power Modes
350
-
351
- | Mode | Scan Interval | Window | Use Case |
352
- |------|---------------|--------|----------|
353
- | `PERFORMANCE` | 1s | 800ms | Active foreground use |
354
- | `BALANCED` | 5s | 2s | Default mode |
355
- | `POWER_SAVER` | 30s | 5s | Background operation |
356
- | `ULTRA_POWER_SAVER` | 60s | 5s | Minimal battery drain |
357
-
358
- ### Message Options
325
+ ### Example 5: Save Battery
359
326
 
360
327
  ```javascript
361
- // Send with options
362
- await mesh.sendPrivateMessage(peerId, content, {
363
- // Request delivery acknowledgment
364
- requiresAck: true,
365
-
366
- // Enable compression
367
- compress: true,
368
-
369
- // Maximum hop count (1-15)
370
- maxHops: 7,
371
-
372
- // Priority level
373
- priority: 'high', // 'normal' | 'high'
328
+ const mesh = new MeshNetwork({
329
+ nickname: 'Smart',
330
+ batteryMode: 'auto', // Adjusts based on your battery level!
374
331
  });
375
332
  ```
376
333
 
377
- ## Security Features
334
+ ### Example 6: Emergency Delete
378
335
 
379
- ### Cryptographic Primitives
336
+ ```javascript
337
+ mesh.enablePanicMode({ trigger: 'triple_tap' });
380
338
 
381
- - **Key Exchange**: X25519 (Curve25519 ECDH)
382
- - **Signatures**: Ed25519
383
- - **Encryption**: ChaCha20-Poly1305 AEAD
384
- - **Hashing**: SHA-256, SHA-512
385
- - **Key Derivation**: HKDF
339
+ // Or wipe everything right now
340
+ await mesh.wipeAllData();
341
+ // All messages, keys, and data = GONE! 💨
342
+ ```
386
343
 
387
- ### Noise Protocol XX Handshake
344
+ ---
388
345
 
389
- The library implements the Noise XX handshake pattern:
346
+ ## Using React Hooks
390
347
 
348
+ ```javascript
349
+ import { useMesh, useMessages, usePeers } from 'react-native-ble-mesh/hooks';
350
+ import { BLETransport } from 'react-native-ble-mesh';
351
+
352
+ function ChatScreen() {
353
+ const { mesh, state, initialize, destroy } = useMesh({ displayName: 'Alex' });
354
+ const { messages, sendBroadcast } = useMessages(mesh);
355
+ const { peers, connectedCount } = usePeers(mesh);
356
+
357
+ useEffect(() => {
358
+ initialize(new BLETransport());
359
+ return () => destroy();
360
+ }, []);
361
+
362
+ if (state !== 'active') return <Text>Starting mesh...</Text>;
363
+
364
+ return (
365
+ <View>
366
+ <Text>Connected to {connectedCount} people</Text>
367
+ {messages.map(msg => (
368
+ <Text key={msg.id}>{msg.senderId}: {msg.content}</Text>
369
+ ))}
370
+ <Button title="Say Hi!" onPress={() => sendBroadcast('Hello!')} />
371
+ </View>
372
+ );
373
+ }
391
374
  ```
392
- -> e
393
- <- e, ee, s, es
394
- -> s, se
395
- ```
396
-
397
- This provides:
398
- - Mutual authentication
399
- - Forward secrecy
400
- - Identity hiding
401
-
402
- ### Session Security
403
375
 
404
- - **Automatic Rekeying**: Sessions rekey every hour or after 10,000 messages
405
- - **Replay Protection**: Sliding window algorithm with configurable window size
406
- - **Nonce Management**: Automatic nonce tracking prevents reuse
376
+ ---
407
377
 
408
- ### Identity Verification
378
+ ## Everything You Can Do
409
379
 
410
- Verify peer identities out-of-band using fingerprints:
380
+ ### Starting & Stopping
411
381
 
412
- ```javascript
413
- // Get your fingerprint to share
414
- const myFingerprint = mesh.getFingerprint();
415
- // Format: "A1B2 C3D4 E5F6 G7H8 I9J0 K1L2 M3N4 O5P6"
382
+ | Method | What It Does |
383
+ |--------|--------------|
384
+ | `mesh.start()` | Turn on the mesh network |
385
+ | `mesh.stop()` | Turn it off (can restart later) |
386
+ | `mesh.destroy()` | Completely shut down |
416
387
 
417
- // Verify a peer after out-of-band confirmation
418
- mesh.verifyPeer(peerId, theirFingerprint);
388
+ ### Sending Messages
419
389
 
420
- // Check if a peer is verified
421
- const peer = mesh.getPeer(peerId);
422
- console.log('Verified:', peer.verificationStatus === 'verified');
423
- ```
390
+ | Method | What It Does |
391
+ |--------|--------------|
392
+ | `mesh.broadcast('Hi!')` | Send to everyone nearby |
393
+ | `mesh.sendDirect(id, 'Hey')` | Private message to one person |
394
+ | `mesh.sendToChannel('#fun', 'Yo')` | Send to a group |
424
395
 
425
- ## Protocol Details
396
+ ### Sending Files
426
397
 
427
- ### Message Header Format
398
+ | Method | What It Does |
399
+ |--------|--------------|
400
+ | `mesh.sendFile(id, { data, name, mimeType })` | Send a file to someone |
401
+ | `mesh.getActiveTransfers()` | See files being sent/received |
402
+ | `mesh.cancelTransfer(id)` | Cancel a file transfer |
428
403
 
429
- The library uses an optimized 24-32 byte header:
404
+ ### Connection Quality
430
405
 
431
- | Field | Size | Description |
432
- |-------|------|-------------|
433
- | version | 1 | Protocol version |
434
- | type | 1 | Message type |
435
- | flags | 1 | Feature flags |
436
- | ttl | 1 | Hop count + max hops |
437
- | timestamp | 8 | Unix timestamp (ms) |
438
- | payloadLength | 2 | Payload size |
439
- | fragmentIndex | 1 | Fragment index |
440
- | fragmentTotal | 1 | Total fragments |
441
- | senderId | 8 | Truncated peer ID |
442
- | recipientId | 8 | (Optional) Recipient ID |
406
+ | Method | What It Does |
407
+ |--------|--------------|
408
+ | `mesh.getConnectionQuality(id)` | Signal quality for one person |
409
+ | `mesh.getAllConnectionQuality()` | Signal quality for everyone |
443
410
 
444
- ### Message Types
411
+ ### Channels (Group Chats)
445
412
 
446
- | Category | Types |
447
- |----------|-------|
448
- | Data | TEXT, TEXT_ACK, BINARY, BINARY_ACK |
449
- | Handshake | HANDSHAKE_INIT, HANDSHAKE_RESPONSE, HANDSHAKE_FINAL |
450
- | Discovery | PEER_ANNOUNCE, PEER_REQUEST, PEER_RESPONSE, IDENTITY_ANNOUNCE |
451
- | Channels | CHANNEL_JOIN, CHANNEL_LEAVE, CHANNEL_MESSAGE |
452
- | Private | PRIVATE_MESSAGE, PRIVATE_ACK, READ_RECEIPT |
453
- | Control | HEARTBEAT, PING, PONG |
454
- | Fragments | FRAGMENT_START, FRAGMENT_CONTINUE, FRAGMENT_END |
413
+ | Method | What It Does |
414
+ |--------|--------------|
415
+ | `mesh.joinChannel('#name')` | Join a group |
416
+ | `mesh.leaveChannel('#name')` | Leave a group |
417
+ | `mesh.getChannels()` | See your groups |
455
418
 
456
- ## Error Handling
419
+ ### People
457
420
 
458
- The library provides detailed error classes:
421
+ | Method | What It Does |
422
+ |--------|--------------|
423
+ | `mesh.getPeers()` | See everyone nearby |
424
+ | `mesh.getConnectedPeers()` | See who's connected |
425
+ | `mesh.blockPeer(id)` | Block someone |
426
+ | `mesh.unblockPeer(id)` | Unblock someone |
459
427
 
460
- ```javascript
461
- const {
462
- MeshError,
463
- CryptoError,
464
- ConnectionError,
465
- HandshakeError,
466
- MessageError,
467
- FragmentError,
468
- TrustError,
469
- RetryError
470
- } = require('react-native-ble-mesh/errors');
471
-
472
- mesh.on('error', (error) => {
473
- if (error instanceof CryptoError) {
474
- console.error('Crypto error:', error.code, error.message);
475
- } else if (error instanceof ConnectionError) {
476
- console.error('Connection error:', error.code, error.message);
477
- } else if (error instanceof TrustError) {
478
- console.error('Trust error:', error.code, error.message);
479
- }
428
+ ### Safety
480
429
 
481
- // All errors have these properties
482
- console.log('Error code:', error.code);
483
- console.log('Category:', error.category);
484
- console.log('Recoverable:', error.recoverable);
485
- console.log('Details:', error.details);
486
- });
487
- ```
430
+ | Method | What It Does |
431
+ |--------|--------------|
432
+ | `mesh.enablePanicMode()` | Enable emergency wipe |
433
+ | `mesh.wipeAllData()` | Delete everything NOW |
488
434
 
489
- ### Error Codes
435
+ ### Network Info
490
436
 
491
- | Category | Codes |
492
- |----------|-------|
493
- | Crypto | E_CRYPTO_001 - E_CRYPTO_006 |
494
- | Connection | E_CONN_001 - E_CONN_003 |
495
- | Handshake | E_HAND_001 - E_HAND_003 |
496
- | Message | E_MSG_001 - E_MSG_004 |
497
- | Fragment | E_FRAG_001 - E_FRAG_004 |
498
- | Trust | E_TRUST_001 - E_TRUST_004 |
499
- | Retry | E_RETRY_001 - E_RETRY_003 |
437
+ | Method | What It Does |
438
+ |--------|--------------|
439
+ | `mesh.getStatus()` | Current status |
440
+ | `mesh.getNetworkHealth()` | How good is the network? |
441
+ | `mesh.getBatteryMode()` | Current battery mode |
442
+ | `mesh.setBatteryMode('low')` | Change battery mode |
500
443
 
501
- ## Platform Support
444
+ ---
502
445
 
503
- ### React Native
446
+ ## Events (When Things Happen)
504
447
 
505
448
  ```javascript
506
- const { MeshService, BLETransport } = require('react-native-ble-mesh');
507
- const { RNBLEAdapter } = require('react-native-ble-mesh/adapters');
508
-
509
- const transport = new BLETransport({
510
- adapter: new RNBLEAdapter(),
511
- });
449
+ // Messages
450
+ mesh.on('messageReceived', ({ from, text, type }) => { });
451
+ mesh.on('directMessage', ({ from, text }) => { });
452
+ mesh.on('channelMessage', ({ channel, from, text }) => { });
453
+ mesh.on('messageDelivered', ({ messageId }) => { });
454
+
455
+ // Files
456
+ mesh.on('fileReceived', ({ from, file }) => { });
457
+ mesh.on('fileSendProgress', ({ name, percent }) => { });
458
+ mesh.on('fileReceiveProgress', ({ name, percent }) => { });
459
+ mesh.on('fileTransferFailed', ({ transferId, reason }) => { });
460
+
461
+ // People
462
+ mesh.on('peerDiscovered', (peer) => { });
463
+ mesh.on('peerConnected', (peer) => { });
464
+ mesh.on('peerDisconnected', (peer) => { });
465
+
466
+ // Connection Quality
467
+ mesh.on('connectionQualityChanged', ({ peerId, level, score }) => { });
468
+
469
+ // Network
470
+ mesh.on('started', () => { });
471
+ mesh.on('stopped', () => { });
472
+ mesh.on('networkHealthChanged', (info) => { });
473
+ mesh.on('error', (error) => { });
474
+
475
+ // Offline delivery
476
+ mesh.on('messageCached', ({ peerId, text }) => { });
477
+ mesh.on('cachedMessagesDelivered', ({ peerId, delivered }) => { });
478
+
479
+ // Safety
480
+ mesh.on('dataWiped', (result) => { });
512
481
  ```
513
482
 
514
- **Required permissions (iOS):**
515
- - NSBluetoothAlwaysUsageDescription
516
- - NSBluetoothPeripheralUsageDescription
483
+ ---
517
484
 
518
- **Required permissions (Android):**
519
- - BLUETOOTH
520
- - BLUETOOTH_ADMIN
521
- - BLUETOOTH_SCAN
522
- - BLUETOOTH_ADVERTISE
523
- - BLUETOOTH_CONNECT
524
- - ACCESS_FINE_LOCATION
485
+ ## How Secure Is It?
525
486
 
526
- ### Node.js
487
+ **Very secure!** Here's what protects your messages:
527
488
 
528
- ```javascript
529
- const { MeshService, BLETransport } = require('react-native-ble-mesh');
530
- const { NodeBLEAdapter } = require('react-native-ble-mesh/adapters');
489
+ | Feature | What It Means (in Simple Words) |
490
+ |---------|-------------------------------|
491
+ | **Pluggable Encryption** | Choose the strongest lock for your messages |
492
+ | **Key Exchange** | Phones secretly agree on a password that nobody else knows |
493
+ | **Forward Secrecy** | Even if someone steals your keys later, old messages stay secret |
494
+ | **No Permanent IDs** | You can't be tracked — you're just "a phone" |
495
+ | **Panic Wipe** | One tap and everything disappears forever |
531
496
 
532
- const transport = new BLETransport({
533
- adapter: new NodeBLEAdapter(),
534
- });
535
- ```
497
+ ---
536
498
 
537
- ## Examples
499
+ ## iOS Background Mode
538
500
 
539
- ### Basic Chat Application
501
+ Want the mesh to keep working when the app is in the background? We've got you covered.
540
502
 
541
- ```javascript
542
- const { MeshService, BLETransport, MemoryStorage } = require('react-native-ble-mesh');
543
-
544
- class ChatApp {
545
- constructor() {
546
- this.mesh = new MeshService();
547
- this.messages = [];
548
- }
503
+ **Short version:** Add `bluetooth-central` and `bluetooth-peripheral` to your background modes (the Expo plugin does this automatically).
549
504
 
550
- async start(displayName) {
551
- await this.mesh.initialize({
552
- displayName,
553
- storage: new MemoryStorage(),
554
- });
505
+ **Detailed version:** See our [iOS Background BLE Guide](docs/IOS-BACKGROUND-BLE.md) — covers all the limitations, workarounds, and known bugs.
555
506
 
556
- const transport = new BLETransport();
557
- await this.mesh.start(transport);
507
+ ---
558
508
 
559
- this.setupEventHandlers();
560
- console.log('Chat started! Your fingerprint:', this.mesh.getFingerprint());
561
- }
509
+ ## Frequently Asked Questions
562
510
 
563
- setupEventHandlers() {
564
- this.mesh.on('peer-discovered', (peer) => {
565
- console.log(`[+] Discovered: ${peer.getDisplayName()}`);
566
- });
511
+ **How far can messages travel?**
512
+ One hop: ~30 meters (100 feet). With 7 hops through other phones: 300+ meters!
567
513
 
568
- this.mesh.on('private-message', (message) => {
569
- this.messages.push(message);
570
- console.log(`[${message.senderId.slice(0, 8)}]: ${message.content}`);
571
- });
514
+ **Does it work if Bluetooth is off?**
515
+ No, Bluetooth must be on. But you don't need WiFi or cell service!
572
516
 
573
- this.mesh.on('message-delivered', ({ messageId }) => {
574
- console.log(`[OK] Delivered: ${messageId.slice(0, 8)}`);
575
- });
576
- }
517
+ **Can someone read my private messages?**
518
+ Nope! They're encrypted. Only you and your friend have the keys.
577
519
 
578
- async sendMessage(peerId, content) {
579
- return await this.mesh.sendPrivateMessage(peerId, content, {
580
- requiresAck: true,
581
- });
582
- }
520
+ **How big of a file can I send?**
521
+ Up to 10MB by default (configurable). Big files automatically use Wi-Fi Direct if available.
583
522
 
584
- getPeers() {
585
- return this.mesh.getPeers();
586
- }
523
+ **Does it work with Expo?**
524
+ Yes! Just add the plugin to `app.json` and build a dev client.
587
525
 
588
- verifyPeer(peerId, fingerprint) {
589
- this.mesh.verifyPeer(peerId, fingerprint);
590
- }
526
+ **Does it drain my battery?**
527
+ It uses some battery (Bluetooth is on), but use `batteryMode: 'auto'` and the library manages it for you.
591
528
 
592
- async stop() {
593
- await this.mesh.stop();
594
- await this.mesh.destroy();
595
- }
596
- }
529
+ **Does it work in the background?**
530
+ On iOS, it works with some limitations (scanning is slower). On Android, it works fully. See [iOS Background BLE Guide](docs/IOS-BACKGROUND-BLE.md).
597
531
 
598
- // Usage
599
- const chat = new ChatApp();
600
- await chat.start('Alice');
532
+ ---
601
533
 
602
- // List discovered peers
603
- const peers = chat.getPeers();
604
- peers.forEach(p => console.log(p.id, p.getDisplayName()));
534
+ ## Use Cases
605
535
 
606
- // Send a message
607
- await chat.sendMessage(peers[0].id, 'Hello!');
608
- ```
536
+ - 🎵 **Concerts & Festivals** — Text friends when cell towers are overloaded
537
+ - **Camping & Hiking** — Stay connected in the wilderness
538
+ - 🆘 **Emergencies** — Communicate during power outages or disasters
539
+ - ✊ **Protests & Events** — When networks are restricted
540
+ - 🎮 **Gaming** — Local multiplayer without internet
541
+ - 🏫 **Schools** — Classroom activities without WiFi
542
+ - 📸 **Photo Sharing** — Share pictures at events without data
609
543
 
610
- ### Multi-Hop Messaging
544
+ ---
611
545
 
612
- ```javascript
613
- // Messages automatically route through multiple hops
614
- const messageId = await mesh.sendPrivateMessage(distantPeerId, 'Hello distant peer!', {
615
- maxHops: 10, // Allow up to 10 hops
616
- requiresAck: true,
617
- });
546
+ ## Project Structure
618
547
 
619
- // Track routing statistics
620
- const stats = mesh.getStats();
621
- console.log('Messages relayed:', stats.messagesRelayed);
622
- console.log('Average hop count:', stats.averageHopCount);
623
548
  ```
624
-
625
- ### Secure File Transfer
626
-
627
- ```javascript
628
- const fs = require('fs');
629
- const path = require('path');
630
-
631
- async function sendFile(mesh, peerId, filePath) {
632
- const fileData = fs.readFileSync(filePath);
633
- const fileName = path.basename(filePath);
634
-
635
- // The library automatically handles:
636
- // - Compression for large payloads
637
- // - Fragmentation for BLE MTU limits
638
- // - Encryption with peer's session key
639
- // - Automatic retry on failure
640
-
641
- const messageId = await mesh.sendPrivateMessage(peerId, {
642
- type: 'file',
643
- name: fileName,
644
- data: fileData.toString('base64'),
645
- size: fileData.length,
646
- }, {
647
- compress: true,
648
- requiresAck: true,
649
- });
650
-
651
- console.log('File transfer initiated:', messageId);
652
- }
549
+ react-native-ble-mesh/
550
+ ├── src/
551
+ │ ├── index.js # Main entry point
552
+ │ ├── MeshNetwork.js # High-level API (start here!)
553
+ │ ├── crypto/ # Pluggable encryption providers
554
+ │ ├── mesh/ # Routing, dedup, connection quality
555
+ │ ├── transport/ # BLE + Wi-Fi Direct + MultiTransport
556
+ │ ├── service/ # Messaging, files, audio, battery, panic
557
+ │ ├── expo/ # Expo config plugin
558
+ │ └── hooks/ # React hooks
559
+ ├── docs/ # Guides & specs
560
+ ├── app.plugin.js # Expo plugin entry
561
+ └── __tests__/ # 432 tests, 0 failures ✅
653
562
  ```
654
563
 
655
- ## Testing
656
-
657
- Run the test suite:
564
+ ---
658
565
 
659
- ```bash
660
- npm test
661
- ```
566
+ ## More Documentation
662
567
 
663
- Run with coverage:
568
+ - [Full API Reference](docs/API.md) — Every method explained
569
+ - [React Native Guide](docs/REACT_NATIVE.md) — Platform-specific setup
570
+ - [iOS Background BLE](docs/IOS-BACKGROUND-BLE.md) — Background mode guide
571
+ - [Security Details](docs/SECURITY.md) — How encryption works
572
+ - [Protocol Spec](docs/PROTOCOL.md) — Technical wire format
573
+ - [Optimization Notes](docs/OPTIMIZATION.md) — Performance details
574
+ - [v2.1 Feature Spec](docs/SPEC-v2.1.md) — Architecture decisions
575
+ - [AI/Agent Instructions](docs/prompt-instructions.md) — For AI assistants
664
576
 
665
- ```bash
666
- npm run test:coverage
667
- ```
577
+ ---
668
578
 
669
- Run specific test files:
579
+ ## Testing
670
580
 
671
581
  ```bash
672
- npm test -- __tests__/crypto/sha256.test.js
673
- npm test -- __tests__/integration/handshake.test.js
582
+ npm test # Run all 432 tests
583
+ npm run test:coverage # With coverage report
674
584
  ```
675
585
 
676
- ## Project Structure
677
-
678
- ```
679
- react-native-ble-mesh/
680
- ├── src/
681
- │ ├── index.js # Main exports
682
- │ ├── constants/ # Protocol, BLE, crypto constants
683
- │ ├── errors/ # Custom error classes
684
- │ ├── crypto/ # Cryptographic implementations
685
- │ │ ├── noise/ # Noise Protocol (handshake, session)
686
- │ │ └── keys/ # Key management
687
- │ ├── protocol/ # Message serialization/deserialization
688
- │ ├── mesh/ # Mesh networking logic
689
- │ │ ├── router/ # Message routing
690
- │ │ ├── dedup/ # Duplicate detection
691
- │ │ ├── fragment/ # Message fragmentation
692
- │ │ └── peer/ # Peer management
693
- │ ├── transport/ # BLE transport layer
694
- │ ├── storage/ # Persistence adapters
695
- │ ├── utils/ # Utility functions
696
- │ └── service/ # High-level service orchestration
697
- ├── __tests__/ # Test files
698
- ├── docs/ # Documentation
699
- ├── examples/ # Example applications
700
- └── package.json
701
- ```
586
+ ---
702
587
 
703
588
  ## Contributing
704
589
 
705
- 1. Fork the repository
706
- 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
707
- 3. Run tests and linting (`npm run validate`)
708
- 4. Commit your changes (`git commit -m 'Add amazing feature'`)
709
- 5. Push to the branch (`git push origin feature/amazing-feature`)
710
- 6. Open a Pull Request
590
+ We love contributions! Here's how:
711
591
 
712
- ### Code Style
592
+ 1. Fork this repository
593
+ 2. Create a branch: `git checkout -b my-feature`
594
+ 3. Make your changes
595
+ 4. Run tests: `npm test`
596
+ 5. Push and create a Pull Request
713
597
 
714
- - Maximum 200 lines per file
715
- - JSDoc comments on all public APIs
716
- - ESLint with strict rules
717
- - 100% test coverage on crypto modules
718
- - >80% coverage on other modules
598
+ ---
719
599
 
720
- ## Documentation
600
+ ## Credits
721
601
 
722
- - [API Reference](docs/API.md) - Complete API documentation
723
- - [Architecture](docs/ARCHITECTURE.md) - System design and module structure
724
- - [Security](docs/SECURITY.md) - Threat model and security properties
725
- - [Protocol](docs/PROTOCOL.md) - Wire format and message types
602
+ Inspired by [BitChat](https://github.com/nicegram/nicegram-bitchat) the original decentralized mesh chat.
726
603
 
727
- ## License
604
+ Built with:
605
+ - [react-native-ble-plx](https://github.com/Polidea/react-native-ble-plx) — Bluetooth Low Energy
606
+ - [tweetnacl](https://tweetnacl.js.org/) — Encryption
728
607
 
729
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
608
+ ---
609
+
610
+ ## License
730
611
 
731
- ## Acknowledgments
612
+ MIT License — do whatever you want with it! See [LICENSE](LICENSE) for details.
732
613
 
733
- This project is inspired by [bitchat](https://github.com/permissionlesstech/bitchat).
614
+ ---
734
615
 
735
- - [Noise Protocol Framework](https://noiseprotocol.org/) - Cryptographic handshake pattern
736
- - [react-native-ble-plx](https://github.com/Polidea/react-native-ble-plx) - React Native BLE library
737
- - [Noble](https://github.com/abandonware/noble) - Node.js BLE library
616
+ <p align="center">
617
+ <b>Made with ❤️ for a more connected (yet private) world</b>
618
+ <br><br>
619
+ If this library helps you, give it a ⭐ on GitHub!
620
+ </p>