react-native-ble-mesh 1.1.1 → 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 (65) hide show
  1. package/README.md +288 -172
  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/package.json +1 -1
  6. package/src/MeshNetwork.js +659 -465
  7. package/src/constants/index.js +1 -0
  8. package/src/crypto/AutoCrypto.js +79 -0
  9. package/src/crypto/CryptoProvider.js +99 -0
  10. package/src/crypto/index.js +15 -63
  11. package/src/crypto/providers/ExpoCryptoProvider.js +125 -0
  12. package/src/crypto/providers/QuickCryptoProvider.js +134 -0
  13. package/src/crypto/providers/TweetNaClProvider.js +124 -0
  14. package/src/crypto/providers/index.js +11 -0
  15. package/src/errors/MeshError.js +2 -1
  16. package/src/expo/withBLEMesh.js +102 -0
  17. package/src/hooks/useMesh.js +30 -9
  18. package/src/hooks/useMessages.js +2 -0
  19. package/src/index.js +23 -8
  20. package/src/mesh/dedup/DedupManager.js +36 -10
  21. package/src/mesh/fragment/Assembler.js +5 -0
  22. package/src/mesh/index.js +1 -1
  23. package/src/mesh/monitor/ConnectionQuality.js +408 -0
  24. package/src/mesh/monitor/NetworkMonitor.js +327 -316
  25. package/src/mesh/monitor/index.js +7 -3
  26. package/src/mesh/peer/PeerManager.js +6 -1
  27. package/src/mesh/router/MessageRouter.js +26 -15
  28. package/src/mesh/router/RouteTable.js +7 -1
  29. package/src/mesh/store/StoreAndForwardManager.js +295 -297
  30. package/src/mesh/store/index.js +1 -1
  31. package/src/service/BatteryOptimizer.js +282 -278
  32. package/src/service/EmergencyManager.js +224 -214
  33. package/src/service/HandshakeManager.js +167 -13
  34. package/src/service/MeshService.js +72 -6
  35. package/src/service/SessionManager.js +77 -2
  36. package/src/service/audio/AudioManager.js +8 -2
  37. package/src/service/file/FileAssembler.js +106 -0
  38. package/src/service/file/FileChunker.js +79 -0
  39. package/src/service/file/FileManager.js +307 -0
  40. package/src/service/file/FileMessage.js +122 -0
  41. package/src/service/file/index.js +15 -0
  42. package/src/service/text/broadcast/BroadcastManager.js +16 -0
  43. package/src/transport/BLETransport.js +131 -9
  44. package/src/transport/MockTransport.js +1 -1
  45. package/src/transport/MultiTransport.js +305 -0
  46. package/src/transport/WiFiDirectTransport.js +295 -0
  47. package/src/transport/adapters/NodeBLEAdapter.js +34 -0
  48. package/src/transport/adapters/RNBLEAdapter.js +56 -1
  49. package/src/transport/index.js +6 -0
  50. package/src/utils/compression.js +291 -291
  51. package/src/crypto/aead.js +0 -189
  52. package/src/crypto/chacha20.js +0 -181
  53. package/src/crypto/hkdf.js +0 -187
  54. package/src/crypto/hmac.js +0 -143
  55. package/src/crypto/keys/KeyManager.js +0 -271
  56. package/src/crypto/keys/KeyPair.js +0 -216
  57. package/src/crypto/keys/SecureStorage.js +0 -219
  58. package/src/crypto/keys/index.js +0 -32
  59. package/src/crypto/noise/handshake.js +0 -410
  60. package/src/crypto/noise/index.js +0 -27
  61. package/src/crypto/noise/session.js +0 -253
  62. package/src/crypto/noise/state.js +0 -268
  63. package/src/crypto/poly1305.js +0 -113
  64. package/src/crypto/sha256.js +0 -240
  65. package/src/crypto/x25519.js +0 -154
package/README.md CHANGED
@@ -7,14 +7,15 @@
7
7
  [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg?style=flat-square)](https://opensource.org/licenses/MIT)
8
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg?style=flat-square)](https://www.typescriptlang.org/)
9
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)]()
10
11
 
11
12
  ---
12
13
 
13
14
  ## What is this?
14
15
 
15
- Imagine you're at a concert, camping trip, or during a power outage - **no WiFi, no cell service**. How do you text your friends?
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?
16
17
 
17
- **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.
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.
18
19
 
19
20
  ```
20
21
  You Friend's Your
@@ -22,7 +23,7 @@ Imagine you're at a concert, camping trip, or during a power outage - **no WiFi,
22
23
  Phone (300m away!)
23
24
  ```
24
25
 
25
- **Think of it like a game of telephone, but for text messages!**
26
+ **Think of it like a game of telephone, but for text messages and photos!**
26
27
 
27
28
  ---
28
29
 
@@ -56,9 +57,13 @@ mesh.on('messageReceived', (msg) => {
56
57
  |---------|--------------|
57
58
  | No WiFi or cell service | Works with just Bluetooth! |
58
59
  | Friend is too far away | Messages hop through other phones |
59
- | Worried about privacy? | All messages are encrypted |
60
+ | Need to send photos? | Send files & images up to 10MB! |
61
+ | Worried about privacy? | Encrypted with battle-tested crypto |
60
62
  | Phone battery dying? | Smart power saving built-in |
61
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 |
62
67
 
63
68
  ---
64
69
 
@@ -67,8 +72,84 @@ mesh.on('messageReceived', (msg) => {
67
72
  ### 📡 Messages That Hop
68
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!
69
74
 
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!
77
+
78
+ ```javascript
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
84
+ });
85
+
86
+ // Watch the progress
87
+ mesh.on('fileSendProgress', ({ name, percent }) => {
88
+ console.log(`Sending ${name}: ${percent}%`);
89
+ });
90
+
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
95
+ });
96
+ ```
97
+
98
+ ### 📶 Connection Quality
99
+ See how good your connection is to each person — like signal bars on your phone!
100
+
101
+ ```javascript
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
+ });
113
+ ```
114
+
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
121
+
122
+ ```javascript
123
+ import { MultiTransport } from 'react-native-ble-mesh';
124
+
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
130
+ });
131
+
132
+ const mesh = new MeshNetwork({ nickname: 'Alex' });
133
+ await mesh.start(transport);
134
+ // That's it! The library handles everything.
135
+ ```
136
+
70
137
  ### 🔒 Secret Messages
71
- Private messages are scrambled (encrypted) so only your friend can read them. Even if someone else's phone passes along the message, they can't peek!
138
+ Pick the encryption that works best for your app. The library auto-detects the fastest option:
139
+
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 |
145
+
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
151
+ });
152
+ ```
72
153
 
73
154
  ### 📬 Offline Delivery
74
155
  Friend's phone turned off? No problem! Your message waits and delivers when they come back online.
@@ -78,6 +159,7 @@ Choose how much battery to use:
78
159
  - **High Power** = Faster messages, more battery
79
160
  - **Balanced** = Good speed, normal battery (default)
80
161
  - **Low Power** = Slower messages, saves battery
162
+ - **Auto** = Let the phone decide based on battery level!
81
163
 
82
164
  ### 🚨 Panic Button
83
165
  Triple-tap to instantly delete all messages and data. Everything gone in less than 0.2 seconds!
@@ -89,20 +171,46 @@ Create chat rooms like `#camping-trip` or `#concert-squad`. Only people who join
89
171
 
90
172
  ## Installation
91
173
 
92
- ### Step 1: Install the package
174
+ ### Option A: Expo Projects (Easiest!) 🎯
93
175
 
94
176
  ```bash
95
- npm install react-native-ble-mesh react-native-ble-plx react-native-get-random-values
177
+ npx expo install react-native-ble-mesh react-native-ble-plx react-native-get-random-values
178
+ ```
179
+
180
+ Add the plugin to your `app.json`:
181
+
182
+ ```json
183
+ {
184
+ "expo": {
185
+ "plugins": [
186
+ ["react-native-ble-mesh", {
187
+ "bluetoothAlwaysPermission": "Chat with nearby friends using Bluetooth"
188
+ }]
189
+ ]
190
+ }
191
+ }
96
192
  ```
97
193
 
98
- ### Step 2: iOS Setup
194
+ **That's it! The plugin handles all the permissions for you.** ✅
99
195
 
196
+ Then build your dev client:
100
197
  ```bash
101
- cd ios && pod install && cd ..
198
+ npx expo prebuild
199
+ npx expo run:ios # or run:android
102
200
  ```
103
201
 
104
- Add these lines to your `ios/YourApp/Info.plist`:
202
+ ### Option B: Bare React Native
105
203
 
204
+ ```bash
205
+ npm install react-native-ble-mesh react-native-ble-plx react-native-get-random-values
206
+ ```
207
+
208
+ **iOS Setup:**
209
+ ```bash
210
+ cd ios && pod install && cd ..
211
+ ```
212
+
213
+ Add to `ios/YourApp/Info.plist`:
106
214
  ```xml
107
215
  <key>NSBluetoothAlwaysUsageDescription</key>
108
216
  <string>Chat with nearby friends using Bluetooth</string>
@@ -115,28 +223,31 @@ Add these lines to your `ios/YourApp/Info.plist`:
115
223
  </array>
116
224
  ```
117
225
 
118
- ### Step 3: Android Setup
119
-
120
- Add these lines to `android/app/src/main/AndroidManifest.xml`:
121
-
226
+ **Android Setup:** Add to `android/app/src/main/AndroidManifest.xml`:
122
227
  ```xml
123
- <uses-permission android:name="android.permission.BLUETOOTH" />
124
- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
125
228
  <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
126
229
  <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
127
230
  <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
128
231
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
129
232
  ```
130
233
 
131
- ### Step 4: Add this to the TOP of your app
234
+ ### Final Step (Both Options)
235
+
236
+ Add this as the **very first line** in your app:
132
237
 
133
238
  ```javascript
134
- // This MUST be the very first line in index.js or App.js
135
239
  import 'react-native-get-random-values';
240
+ ```
136
241
 
137
- // Now add your other imports
138
- import { AppRegistry } from 'react-native';
139
- // ...
242
+ ### Optional: Extra Speed & Features
243
+
244
+ ```bash
245
+ # Want encryption? Pick one:
246
+ npm install tweetnacl # Works everywhere
247
+ npm install react-native-quick-crypto # Fastest (native)
248
+
249
+ # Want Wi-Fi Direct for big file transfers?
250
+ npm install react-native-wifi-p2p
140
251
  ```
141
252
 
142
253
  ---
@@ -148,7 +259,6 @@ import { AppRegistry } from 'react-native';
148
259
  ```javascript
149
260
  import { MeshNetwork } from 'react-native-ble-mesh';
150
261
 
151
- // Create and start
152
262
  const mesh = new MeshNetwork({ nickname: 'YourName' });
153
263
  await mesh.start();
154
264
 
@@ -156,93 +266,96 @@ await mesh.start();
156
266
  await mesh.broadcast('Hi everyone!');
157
267
 
158
268
  // Send private message to one person
159
- await mesh.sendDirect('friend-id-here', 'Hey, just for you!');
269
+ await mesh.sendDirect('friend-id', 'Hey, just for you!');
160
270
 
161
271
  // Receive messages
162
272
  mesh.on('messageReceived', ({ from, text }) => {
163
273
  console.log(`${from}: ${text}`);
164
274
  });
165
275
 
166
- // When done
167
276
  await mesh.stop();
168
277
  ```
169
278
 
170
- ### Example 2: Group Channels
279
+ ### Example 2: Send a Photo
171
280
 
172
281
  ```javascript
173
- // Join a channel (like a chat room)
174
- await mesh.joinChannel('#road-trip');
282
+ // Send a photo
283
+ await mesh.sendFile('friend-id', {
284
+ data: imageBytes,
285
+ name: 'selfie.jpg',
286
+ mimeType: 'image/jpeg',
287
+ });
175
288
 
176
- // Send message to everyone in the channel
177
- await mesh.sendToChannel('#road-trip', 'Are we there yet?');
289
+ // Track sending progress
290
+ mesh.on('fileSendProgress', ({ percent }) => {
291
+ console.log(`${percent}% sent`);
292
+ });
178
293
 
179
- // Leave when done
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
+ });
300
+ ```
301
+
302
+ ### Example 3: Group Channels
303
+
304
+ ```javascript
305
+ await mesh.joinChannel('#road-trip');
306
+ await mesh.sendToChannel('#road-trip', 'Are we there yet?');
180
307
  await mesh.leaveChannel('#road-trip');
181
308
  ```
182
309
 
183
- ### Example 3: Save Battery
310
+ ### Example 4: Check Connection Quality
184
311
 
185
312
  ```javascript
186
- const mesh = new MeshNetwork({
187
- nickname: 'PowerSaver',
188
- batteryMode: 'low', // Uses less battery
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})`);
189
322
  });
323
+ ```
190
324
 
191
- // Or let it decide automatically based on battery level
325
+ ### Example 5: Save Battery
326
+
327
+ ```javascript
192
328
  const mesh = new MeshNetwork({
193
329
  nickname: 'Smart',
194
- batteryMode: 'auto', // Adjusts automatically!
330
+ batteryMode: 'auto', // Adjusts based on your battery level!
195
331
  });
196
332
  ```
197
333
 
198
- ### Example 4: Emergency Delete
334
+ ### Example 6: Emergency Delete
199
335
 
200
336
  ```javascript
201
- // Enable panic mode
202
- mesh.enablePanicMode({
203
- trigger: 'triple_tap', // Triple tap to wipe
204
- });
337
+ mesh.enablePanicMode({ trigger: 'triple_tap' });
205
338
 
206
- // Or wipe everything immediately
339
+ // Or wipe everything right now
207
340
  await mesh.wipeAllData();
208
341
  // All messages, keys, and data = GONE! 💨
209
342
  ```
210
343
 
211
- ### Example 5: Check Network Health
212
-
213
- ```javascript
214
- const health = mesh.getNetworkHealth();
215
-
216
- console.log(`Connected to ${health.activeNodes} people`);
217
- console.log(`Network status: ${health.overallHealth}`); // 'good', 'fair', or 'poor'
218
- ```
219
-
220
344
  ---
221
345
 
222
346
  ## Using React Hooks
223
347
 
224
- If you're using React, we have easy hooks!
225
-
226
348
  ```javascript
227
- import React, { useEffect } from 'react';
228
- import { View, Text, Button } from 'react-native';
229
349
  import { useMesh, useMessages, usePeers } from 'react-native-ble-mesh/hooks';
230
350
  import { BLETransport } from 'react-native-ble-mesh';
231
351
 
232
352
  function ChatScreen() {
233
- // Manage mesh lifecycle
234
353
  const { mesh, state, initialize, destroy } = useMesh({ displayName: 'Alex' });
235
-
236
- // Message handling (pass mesh instance)
237
354
  const { messages, sendBroadcast } = useMessages(mesh);
238
-
239
- // Peer tracking (pass mesh instance)
240
355
  const { peers, connectedCount } = usePeers(mesh);
241
356
 
242
- // Start mesh on mount
243
357
  useEffect(() => {
244
- const transport = new BLETransport();
245
- initialize(transport);
358
+ initialize(new BLETransport());
246
359
  return () => destroy();
247
360
  }, []);
248
361
 
@@ -251,22 +364,18 @@ function ChatScreen() {
251
364
  return (
252
365
  <View>
253
366
  <Text>Connected to {connectedCount} people</Text>
254
-
255
367
  {messages.map(msg => (
256
368
  <Text key={msg.id}>{msg.senderId}: {msg.content}</Text>
257
369
  ))}
258
-
259
370
  <Button title="Say Hi!" onPress={() => sendBroadcast('Hello!')} />
260
371
  </View>
261
372
  );
262
373
  }
263
374
  ```
264
375
 
265
- > **Note:** The hooks (`useMesh`, `useMessages`, `usePeers`) work with the lower-level `MeshService`. For simpler usage, use the `MeshNetwork` class directly as shown in the Quick Start examples above.
266
-
267
376
  ---
268
377
 
269
- ## All The Things You Can Do
378
+ ## Everything You Can Do
270
379
 
271
380
  ### Starting & Stopping
272
381
 
@@ -274,40 +383,49 @@ function ChatScreen() {
274
383
  |--------|--------------|
275
384
  | `mesh.start()` | Turn on the mesh network |
276
385
  | `mesh.stop()` | Turn it off (can restart later) |
277
- | `mesh.destroy()` | Completely shut down (can't restart) |
386
+ | `mesh.destroy()` | Completely shut down |
278
387
 
279
388
  ### Sending Messages
280
389
 
281
390
  | Method | What It Does |
282
391
  |--------|--------------|
283
392
  | `mesh.broadcast('Hi!')` | Send to everyone nearby |
284
- | `mesh.sendDirect(id, 'Hey')` | Send private message to one person |
285
- | `mesh.sendToChannel('#fun', 'Yo')` | Send to a group channel |
393
+ | `mesh.sendDirect(id, 'Hey')` | Private message to one person |
394
+ | `mesh.sendToChannel('#fun', 'Yo')` | Send to a group |
286
395
 
287
- ### Channels (Group Chats)
396
+ ### Sending Files
288
397
 
289
398
  | Method | What It Does |
290
399
  |--------|--------------|
291
- | `mesh.joinChannel('#name')` | Join a channel |
292
- | `mesh.leaveChannel('#name')` | Leave a channel |
293
- | `mesh.getChannels()` | See what channels you're in |
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 |
294
403
 
295
- ### People Management
404
+ ### Connection Quality
296
405
 
297
406
  | Method | What It Does |
298
407
  |--------|--------------|
299
- | `mesh.getPeers()` | See everyone nearby |
300
- | `mesh.blockPeer(id)` | Block someone |
301
- | `mesh.unblockPeer(id)` | Unblock someone |
408
+ | `mesh.getConnectionQuality(id)` | Signal quality for one person |
409
+ | `mesh.getAllConnectionQuality()` | Signal quality for everyone |
302
410
 
303
- ### Your Identity
411
+ ### Channels (Group Chats)
304
412
 
305
413
  | Method | What It Does |
306
414
  |--------|--------------|
307
- | `mesh.getIdentity()` | Get your info |
308
- | `mesh.setNickname('New Name')` | Change your display name |
415
+ | `mesh.joinChannel('#name')` | Join a group |
416
+ | `mesh.leaveChannel('#name')` | Leave a group |
417
+ | `mesh.getChannels()` | See your groups |
418
+
419
+ ### People
420
+
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 |
309
427
 
310
- ### Safety Features
428
+ ### Safety
311
429
 
312
430
  | Method | What It Does |
313
431
  |--------|--------------|
@@ -318,61 +436,48 @@ function ChatScreen() {
318
436
 
319
437
  | Method | What It Does |
320
438
  |--------|--------------|
321
- | `mesh.getStatus()` | Get current status |
322
- | `mesh.getNetworkHealth()` | Check how good the network is |
323
- | `mesh.getBatteryMode()` | See current battery mode |
439
+ | `mesh.getStatus()` | Current status |
440
+ | `mesh.getNetworkHealth()` | How good is the network? |
441
+ | `mesh.getBatteryMode()` | Current battery mode |
324
442
  | `mesh.setBatteryMode('low')` | Change battery mode |
325
443
 
326
444
  ---
327
445
 
328
446
  ## Events (When Things Happen)
329
447
 
330
- Listen for these events:
331
-
332
448
  ```javascript
333
- // Network started/stopped
334
- mesh.on('started', () => { });
335
- mesh.on('stopped', () => { });
336
-
337
- // Someone sent a message (any type)
338
- mesh.on('messageReceived', ({ from, text, timestamp, type }) => { });
339
-
340
- // Private message received
341
- mesh.on('directMessage', ({ from, text, timestamp }) => { });
342
-
343
- // Channel message received
344
- mesh.on('channelMessage', ({ channel, from, text, timestamp }) => { });
345
-
346
- // Message was delivered successfully
347
- mesh.on('messageDelivered', ({ messageId, peerId }) => { });
348
-
349
- // Found a new person nearby
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
350
462
  mesh.on('peerDiscovered', (peer) => { });
351
-
352
- // Connected to someone
353
463
  mesh.on('peerConnected', (peer) => { });
354
-
355
- // Someone left
356
464
  mesh.on('peerDisconnected', (peer) => { });
357
465
 
358
- // Channel events
359
- mesh.on('channelJoined', ({ channel }) => { });
360
- mesh.on('channelLeft', ({ channel }) => { });
466
+ // Connection Quality
467
+ mesh.on('connectionQualityChanged', ({ peerId, level, score }) => { });
361
468
 
362
- // Network quality changed
363
- mesh.on('networkHealthChanged', (healthInfo) => { });
469
+ // Network
470
+ mesh.on('started', () => { });
471
+ mesh.on('stopped', () => { });
472
+ mesh.on('networkHealthChanged', (info) => { });
473
+ mesh.on('error', (error) => { });
364
474
 
365
- // Message cached for offline peer
475
+ // Offline delivery
366
476
  mesh.on('messageCached', ({ peerId, text }) => { });
367
-
368
- // Cached messages delivered when peer came online
369
477
  mesh.on('cachedMessagesDelivered', ({ peerId, delivered }) => { });
370
478
 
371
- // Data was wiped (panic mode)
479
+ // Safety
372
480
  mesh.on('dataWiped', (result) => { });
373
-
374
- // Something went wrong
375
- mesh.on('error', (error) => { });
376
481
  ```
377
482
 
378
483
  ---
@@ -381,45 +486,60 @@ mesh.on('error', (error) => { });
381
486
 
382
487
  **Very secure!** Here's what protects your messages:
383
488
 
384
- | Feature | What It Means |
385
- |---------|---------------|
386
- | **Noise Protocol** | Military-grade handshake to verify who you're talking to |
387
- | **ChaCha20 Encryption** | Your messages are scrambled so only the recipient can read them |
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 |
388
493
  | **Forward Secrecy** | Even if someone steals your keys later, old messages stay secret |
389
- | **No Permanent IDs** | You don't have a permanent identity that can be tracked |
494
+ | **No Permanent IDs** | You can't be tracked you're just "a phone" |
495
+ | **Panic Wipe** | One tap and everything disappears forever |
496
+
497
+ ---
498
+
499
+ ## iOS Background Mode
500
+
501
+ Want the mesh to keep working when the app is in the background? We've got you covered.
502
+
503
+ **Short version:** Add `bluetooth-central` and `bluetooth-peripheral` to your background modes (the Expo plugin does this automatically).
504
+
505
+ **Detailed version:** See our [iOS Background BLE Guide](docs/IOS-BACKGROUND-BLE.md) — covers all the limitations, workarounds, and known bugs.
390
506
 
391
507
  ---
392
508
 
393
509
  ## Frequently Asked Questions
394
510
 
395
- ### How far can messages travel?
396
- With one hop: about 30 meters (100 feet). With 7 hops through other phones: up to 300+ meters!
511
+ **How far can messages travel?**
512
+ One hop: ~30 meters (100 feet). With 7 hops through other phones: 300+ meters!
397
513
 
398
- ### Does it work if Bluetooth is off?
514
+ **Does it work if Bluetooth is off?**
399
515
  No, Bluetooth must be on. But you don't need WiFi or cell service!
400
516
 
401
- ### Can someone read my private messages?
402
- No! Private messages are encrypted. Only you and your friend have the keys.
517
+ **Can someone read my private messages?**
518
+ Nope! They're encrypted. Only you and your friend have the keys.
519
+
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.
403
522
 
404
- ### How many people can be in the network?
405
- The library supports 50+ connected peers at once.
523
+ **Does it work with Expo?**
524
+ Yes! Just add the plugin to `app.json` and build a dev client.
406
525
 
407
- ### Does it drain my battery?
408
- It uses some battery (Bluetooth is on), but you can use "low power" mode to minimize drain.
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.
409
528
 
410
- ### Does it work in the background?
411
- On iOS, it works with some limitations. On Android, it works fully in the background.
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).
412
531
 
413
532
  ---
414
533
 
415
534
  ## Use Cases
416
535
 
417
- - **Concerts & Festivals** - Text friends when cell towers are overloaded
418
- - **Camping & Hiking** - Stay connected in the wilderness
419
- - **Emergencies** - Communicate during power outages or disasters
420
- - **Protests & Events** - When networks are restricted
421
- - **Gaming** - Local multiplayer without internet
422
- - **Schools** - Classroom activities without WiFi
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
423
543
 
424
544
  ---
425
545
 
@@ -428,36 +548,39 @@ On iOS, it works with some limitations. On Android, it works fully in the backgr
428
548
  ```
429
549
  react-native-ble-mesh/
430
550
  ├── src/
431
- │ ├── index.js # Main entry point
432
- │ ├── MeshNetwork.js # High-level API
433
- │ ├── crypto/ # Encryption stuff
434
- │ ├── mesh/ # Routing & networking
435
- │ ├── transport/ # Bluetooth layer
436
- └── hooks/ # React hooks
437
- ├── docs/ # Documentation
438
- └── __tests__/ # Tests
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 ✅
439
562
  ```
440
563
 
441
564
  ---
442
565
 
443
566
  ## More Documentation
444
567
 
445
- - [Full API Reference](docs/API.md) - Every method explained
446
- - [React Native Guide](docs/REACT_NATIVE.md) - Platform-specific setup
447
- - [Security Details](docs/SECURITY.md) - How encryption works
448
- - [Protocol Spec](docs/PROTOCOL.md) - Technical wire format
449
- - [AI/Agent Instructions](docs/prompt-instructions.md) - For AI assistants
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
450
576
 
451
577
  ---
452
578
 
453
579
  ## Testing
454
580
 
455
581
  ```bash
456
- # Run all tests
457
- npm test
458
-
459
- # Run with coverage report
460
- npm run test:coverage
582
+ npm test # Run all 432 tests
583
+ npm run test:coverage # With coverage report
461
584
  ```
462
585
 
463
586
  ---
@@ -476,24 +599,17 @@ We love contributions! Here's how:
476
599
 
477
600
  ## Credits
478
601
 
479
- Inspired by [BitChat](https://github.com/nicegram/nicegram-bitchat) - the original decentralized mesh chat.
602
+ Inspired by [BitChat](https://github.com/nicegram/nicegram-bitchat) the original decentralized mesh chat.
480
603
 
481
604
  Built with:
482
- - [react-native-ble-plx](https://github.com/Polidea/react-native-ble-plx) - Bluetooth Low Energy
483
- - [Noise Protocol](https://noiseprotocol.org/) - Secure handshakes
605
+ - [react-native-ble-plx](https://github.com/Polidea/react-native-ble-plx) Bluetooth Low Energy
606
+ - [tweetnacl](https://tweetnacl.js.org/) Encryption
484
607
 
485
608
  ---
486
609
 
487
610
  ## License
488
611
 
489
- MIT License - do whatever you want with it! See [LICENSE](LICENSE) for details.
490
-
491
- ---
492
-
493
- ## Get Help
494
-
495
- - **Issues**: [GitHub Issues](https://github.com/suhailtajshaik/react-native-ble-mesh/issues)
496
- - **Questions**: Open a Discussion on GitHub
612
+ MIT License do whatever you want with it! See [LICENSE](LICENSE) for details.
497
613
 
498
614
  ---
499
615