react-native-ble-mesh 1.1.0 → 1.1.1

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.
package/README.md CHANGED
@@ -1,68 +1,113 @@
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/)
6
10
 
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)
11
+ ---
9
12
 
10
- ## Features
13
+ ## What is this?
11
14
 
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
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?
23
16
 
24
- ## Use Cases
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.
25
18
 
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
19
+ ```
20
+ You Friend's Your
21
+ Phone ----Bluetooth---> Friend's ----Bluetooth---> Friend
22
+ Phone (300m away!)
23
+ ```
31
24
 
32
- ## Installation
25
+ **Think of it like a game of telephone, but for text messages!**
33
26
 
34
- ```bash
35
- npm install react-native-ble-mesh react-native-get-random-values react-native-ble-plx
36
- cd ios && pod install
27
+ ---
28
+
29
+ ## See It In Action
30
+
31
+ ```javascript
32
+ import { MeshNetwork } from 'react-native-ble-mesh';
33
+
34
+ // 1. Create your mesh network
35
+ const mesh = new MeshNetwork({ nickname: 'Alex' });
36
+
37
+ // 2. Start it up!
38
+ await mesh.start();
39
+
40
+ // 3. Send a message to everyone nearby
41
+ await mesh.broadcast('Hello everyone! 👋');
42
+
43
+ // 4. Listen for messages
44
+ mesh.on('messageReceived', (msg) => {
45
+ console.log(`${msg.from} says: ${msg.text}`);
46
+ });
37
47
  ```
38
48
 
39
- ### Required Setup
49
+ **That's it! Four lines of code and you're chatting without internet!**
40
50
 
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**:
51
+ ---
42
52
 
43
- ```javascript
44
- // index.js or App.js - This MUST be the first import!
45
- import 'react-native-get-random-values';
53
+ ## Why Use This?
46
54
 
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';
55
+ | Problem | Our Solution |
56
+ |---------|--------------|
57
+ | No WiFi or cell service | Works with just Bluetooth! |
58
+ | Friend is too far away | Messages hop through other phones |
59
+ | Worried about privacy? | All messages are encrypted |
60
+ | Phone battery dying? | Smart power saving built-in |
61
+ | Need to delete everything fast? | One-tap emergency wipe |
62
+
63
+ ---
51
64
 
52
- AppRegistry.registerComponent(appName, () => App);
65
+ ## Cool Features
66
+
67
+ ### 📡 Messages That Hop
68
+ 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
+
70
+ ### 🔒 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!
72
+
73
+ ### 📬 Offline Delivery
74
+ Friend's phone turned off? No problem! Your message waits and delivers when they come back online.
75
+
76
+ ### 🔋 Battery Friendly
77
+ Choose how much battery to use:
78
+ - **High Power** = Faster messages, more battery
79
+ - **Balanced** = Good speed, normal battery (default)
80
+ - **Low Power** = Slower messages, saves battery
81
+
82
+ ### 🚨 Panic Button
83
+ Triple-tap to instantly delete all messages and data. Everything gone in less than 0.2 seconds!
84
+
85
+ ### 💬 Group Channels
86
+ Create chat rooms like `#camping-trip` or `#concert-squad`. Only people who join can see the messages!
87
+
88
+ ---
89
+
90
+ ## Installation
91
+
92
+ ### Step 1: Install the package
93
+
94
+ ```bash
95
+ npm install react-native-ble-mesh react-native-ble-plx react-native-get-random-values
53
96
  ```
54
97
 
55
- This polyfill provides the Web Crypto API (`crypto.getRandomValues`) which is required for cryptographic operations in the mesh network.
98
+ ### Step 2: iOS Setup
56
99
 
57
- ### iOS Setup
100
+ ```bash
101
+ cd ios && pod install && cd ..
102
+ ```
58
103
 
59
- Add Bluetooth permissions to your `Info.plist`:
104
+ Add these lines to your `ios/YourApp/Info.plist`:
60
105
 
61
106
  ```xml
62
107
  <key>NSBluetoothAlwaysUsageDescription</key>
63
- <string>This app uses Bluetooth to communicate with nearby devices</string>
108
+ <string>Chat with nearby friends using Bluetooth</string>
64
109
  <key>NSBluetoothPeripheralUsageDescription</key>
65
- <string>This app uses Bluetooth to communicate with nearby devices</string>
110
+ <string>Chat with nearby friends using Bluetooth</string>
66
111
  <key>UIBackgroundModes</key>
67
112
  <array>
68
113
  <string>bluetooth-central</string>
@@ -70,9 +115,9 @@ Add Bluetooth permissions to your `Info.plist`:
70
115
  </array>
71
116
  ```
72
117
 
73
- ### Android Setup
118
+ ### Step 3: Android Setup
74
119
 
75
- Add Bluetooth permissions to your `AndroidManifest.xml`:
120
+ Add these lines to `android/app/src/main/AndroidManifest.xml`:
76
121
 
77
122
  ```xml
78
123
  <uses-permission android:name="android.permission.BLUETOOTH" />
@@ -83,655 +128,377 @@ Add Bluetooth permissions to your `AndroidManifest.xml`:
83
128
  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
84
129
  ```
85
130
 
86
- ## Quick Start
87
-
88
- ### Basic Setup
131
+ ### Step 4: Add this to the TOP of your app
89
132
 
90
133
  ```javascript
91
- const { MeshService, BLETransport } = require('react-native-ble-mesh');
134
+ // This MUST be the very first line in index.js or App.js
135
+ import 'react-native-get-random-values';
92
136
 
93
- // Create and initialize the mesh service
94
- const mesh = new MeshService();
137
+ // Now add your other imports
138
+ import { AppRegistry } from 'react-native';
139
+ // ...
140
+ ```
95
141
 
96
- async function start() {
97
- // Initialize with optional configuration
98
- await mesh.initialize({
99
- displayName: 'Alice',
100
- storage: null, // Use in-memory storage
101
- });
142
+ ---
102
143
 
103
- // Create transport layer
104
- const transport = new BLETransport();
144
+ ## Quick Start Examples
105
145
 
106
- // Start the mesh service
107
- await mesh.start(transport);
146
+ ### Example 1: Simple Chat
108
147
 
109
- console.log('Mesh network started!');
110
- console.log('My fingerprint:', mesh.getFingerprint());
111
- }
148
+ ```javascript
149
+ import { MeshNetwork } from 'react-native-ble-mesh';
112
150
 
113
- start();
114
- ```
151
+ // Create and start
152
+ const mesh = new MeshNetwork({ nickname: 'YourName' });
153
+ await mesh.start();
115
154
 
116
- ### Discovering Peers
155
+ // Send message to everyone
156
+ await mesh.broadcast('Hi everyone!');
117
157
 
118
- ```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());
123
- });
158
+ // Send private message to one person
159
+ await mesh.sendDirect('friend-id-here', 'Hey, just for you!');
124
160
 
125
- mesh.on('peer-connected', (peer) => {
126
- console.log('Connected to peer:', peer.id);
161
+ // Receive messages
162
+ mesh.on('messageReceived', ({ from, text }) => {
163
+ console.log(`${from}: ${text}`);
127
164
  });
128
165
 
129
- mesh.on('peer-secured', (peer) => {
130
- console.log('Secure session established with:', peer.id);
131
- });
166
+ // When done
167
+ await mesh.stop();
132
168
  ```
133
169
 
134
- ### Sending Messages
170
+ ### Example 2: Group Channels
135
171
 
136
172
  ```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
- }
173
+ // Join a channel (like a chat room)
174
+ await mesh.joinChannel('#road-trip');
175
+
176
+ // Send message to everyone in the channel
177
+ await mesh.sendToChannel('#road-trip', 'Are we there yet?');
148
178
 
149
- // Send a message to a channel
150
- const channelMessageId = mesh.sendChannelMessage('general', 'Hello channel!');
179
+ // Leave when done
180
+ await mesh.leaveChannel('#road-trip');
151
181
  ```
152
182
 
153
- ### Receiving Messages
183
+ ### Example 3: Save Battery
154
184
 
155
185
  ```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
- });
162
-
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);
186
+ const mesh = new MeshNetwork({
187
+ nickname: 'PowerSaver',
188
+ batteryMode: 'low', // Uses less battery
167
189
  });
168
190
 
169
- // Listen for channel messages
170
- mesh.on('channel-message', (message) => {
171
- console.log('Channel:', message.channelId);
172
- console.log('Content:', message.content);
191
+ // Or let it decide automatically based on battery level
192
+ const mesh = new MeshNetwork({
193
+ nickname: 'Smart',
194
+ batteryMode: 'auto', // Adjusts automatically!
173
195
  });
174
196
  ```
175
197
 
176
- ### Handling Acknowledgments and Read Receipts
198
+ ### Example 4: Emergency Delete
177
199
 
178
200
  ```javascript
179
- // Listen for message delivery confirmations
180
- mesh.on('message-delivered', ({ messageId, peerId, timestamp }) => {
181
- console.log(`Message ${messageId} delivered to ${peerId}`);
201
+ // Enable panic mode
202
+ mesh.enablePanicMode({
203
+ trigger: 'triple_tap', // Triple tap to wipe
182
204
  });
183
205
 
184
- // Listen for read receipts
185
- mesh.on('read-receipt', ({ messageIds, fromPeerId, timestamp }) => {
186
- console.log(`Peer ${fromPeerId} read messages:`, messageIds);
187
- });
188
-
189
- // Send read receipts for messages you've read
190
- mesh.sendReadReceipt(['msg-id-1', 'msg-id-2']);
191
-
192
- // Mark a single message as read
193
- mesh.markMessageRead('msg-id-1');
206
+ // Or wipe everything immediately
207
+ await mesh.wipeAllData();
208
+ // All messages, keys, and data = GONE! 💨
194
209
  ```
195
210
 
196
- ## API Reference
197
-
198
- ### MeshService
199
-
200
- The main orchestrator for the mesh network.
201
-
202
- #### Lifecycle Methods
211
+ ### Example 5: Check Network Health
203
212
 
204
213
  ```javascript
205
- // Initialize the service
206
- await mesh.initialize(options);
207
-
208
- // Start with a transport
209
- await mesh.start(transport);
210
-
211
- // Stop the service
212
- await mesh.stop();
214
+ const health = mesh.getNetworkHealth();
213
215
 
214
- // Clean up resources
215
- await mesh.destroy();
216
+ console.log(`Connected to ${health.activeNodes} people`);
217
+ console.log(`Network status: ${health.overallHealth}`); // 'good', 'fair', or 'poor'
216
218
  ```
217
219
 
218
- #### Identity Management
219
-
220
- ```javascript
221
- // Get your identity information
222
- const identity = mesh.getIdentity();
223
- // Returns: { publicKey, signingPublicKey, displayName, fingerprint }
224
-
225
- // Set your display name
226
- mesh.setDisplayName('Alice');
227
-
228
- // Get your fingerprint for out-of-band verification
229
- const fingerprint = mesh.getFingerprint();
220
+ ---
230
221
 
231
- // Export identity for backup
232
- const exported = mesh.exportIdentity();
222
+ ## Using React Hooks
233
223
 
234
- // Import identity from backup
235
- mesh.importIdentity(exported);
236
-
237
- // Announce identity to network
238
- mesh.announceIdentity();
239
- ```
240
-
241
- #### Peer Management
224
+ If you're using React, we have easy hooks!
242
225
 
243
226
  ```javascript
244
- // Get all known peers
245
- const peers = mesh.getPeers();
246
-
247
- // Get a specific peer
248
- const peer = mesh.getPeer(peerId);
227
+ import React, { useEffect } from 'react';
228
+ import { View, Text, Button } from 'react-native';
229
+ import { useMesh, useMessages, usePeers } from 'react-native-ble-mesh/hooks';
230
+ import { BLETransport } from 'react-native-ble-mesh';
249
231
 
250
- // Initiate secure handshake with a peer
251
- await mesh.initiateHandshake(peerId);
232
+ function ChatScreen() {
233
+ // Manage mesh lifecycle
234
+ const { mesh, state, initialize, destroy } = useMesh({ displayName: 'Alex' });
252
235
 
253
- // Block a peer
254
- mesh.blockPeer(peerId);
236
+ // Message handling (pass mesh instance)
237
+ const { messages, sendBroadcast } = useMessages(mesh);
255
238
 
256
- // Unblock a peer
257
- mesh.unblockPeer(peerId);
258
- ```
259
-
260
- #### Trust Management
261
-
262
- ```javascript
263
- // Verify a peer using their fingerprint
264
- mesh.verifyPeer(peerId, fingerprint);
239
+ // Peer tracking (pass mesh instance)
240
+ const { peers, connectedCount } = usePeers(mesh);
265
241
 
266
- // Remove verification
267
- mesh.unverifyPeer(peerId);
242
+ // Start mesh on mount
243
+ useEffect(() => {
244
+ const transport = new BLETransport();
245
+ initialize(transport);
246
+ return () => destroy();
247
+ }, []);
268
248
 
269
- // Add to favorites
270
- mesh.addFavorite(peerId);
249
+ if (state !== 'active') return <Text>Starting mesh...</Text>;
271
250
 
272
- // Remove from favorites
273
- mesh.removeFavorite(peerId);
251
+ return (
252
+ <View>
253
+ <Text>Connected to {connectedCount} people</Text>
274
254
 
275
- // Get verified peers
276
- const verified = mesh.getVerifiedPeers();
255
+ {messages.map(msg => (
256
+ <Text key={msg.id}>{msg.senderId}: {msg.content}</Text>
257
+ ))}
277
258
 
278
- // Get favorite peers
279
- const favorites = mesh.getFavoritePeers();
259
+ <Button title="Say Hi!" onPress={() => sendBroadcast('Hello!')} />
260
+ </View>
261
+ );
262
+ }
280
263
  ```
281
264
 
282
- #### Power Management
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.
283
266
 
284
- ```javascript
285
- // Available power modes: PERFORMANCE, BALANCED, POWER_SAVER, ULTRA_POWER_SAVER
286
- mesh.setPowerMode('BALANCED');
267
+ ---
287
268
 
288
- // Get current power mode
289
- const mode = mesh.getPowerMode();
269
+ ## All The Things You Can Do
290
270
 
291
- // Enable automatic power adjustment based on battery level
292
- mesh.setAutoPowerAdjust(true);
293
- ```
271
+ ### Starting & Stopping
294
272
 
295
- #### Status and Statistics
273
+ | Method | What It Does |
274
+ |--------|--------------|
275
+ | `mesh.start()` | Turn on the mesh network |
276
+ | `mesh.stop()` | Turn it off (can restart later) |
277
+ | `mesh.destroy()` | Completely shut down (can't restart) |
296
278
 
297
- ```javascript
298
- // Get service status
299
- const status = mesh.getStatus();
279
+ ### Sending Messages
300
280
 
301
- // Get current state
302
- const state = mesh.getState();
281
+ | Method | What It Does |
282
+ |--------|--------------|
283
+ | `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 |
303
286
 
304
- // Get detailed statistics
305
- const stats = mesh.getStats();
306
- ```
287
+ ### Channels (Group Chats)
307
288
 
308
- ### Events
289
+ | Method | What It Does |
290
+ |--------|--------------|
291
+ | `mesh.joinChannel('#name')` | Join a channel |
292
+ | `mesh.leaveChannel('#name')` | Leave a channel |
293
+ | `mesh.getChannels()` | See what channels you're in |
309
294
 
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 }` |
295
+ ### People Management
325
296
 
326
- ## Configuration
297
+ | Method | What It Does |
298
+ |--------|--------------|
299
+ | `mesh.getPeers()` | See everyone nearby |
300
+ | `mesh.blockPeer(id)` | Block someone |
301
+ | `mesh.unblockPeer(id)` | Unblock someone |
327
302
 
328
- ### Initialization Options
303
+ ### Your Identity
329
304
 
330
- ```javascript
331
- await mesh.initialize({
332
- // Display name for this node
333
- displayName: 'My Device',
305
+ | Method | What It Does |
306
+ |--------|--------------|
307
+ | `mesh.getIdentity()` | Get your info |
308
+ | `mesh.setNickname('New Name')` | Change your display name |
334
309
 
335
- // Storage adapter (null for in-memory)
336
- storage: null,
310
+ ### Safety Features
337
311
 
338
- // Custom key manager (optional)
339
- keyManager: null,
312
+ | Method | What It Does |
313
+ |--------|--------------|
314
+ | `mesh.enablePanicMode()` | Enable emergency wipe |
315
+ | `mesh.wipeAllData()` | Delete everything NOW |
340
316
 
341
- // Enable compression for messages > 64 bytes
342
- compressionEnabled: true,
317
+ ### Network Info
343
318
 
344
- // Compression threshold in bytes
345
- compressionThreshold: 64,
346
- });
347
- ```
319
+ | Method | What It Does |
320
+ |--------|--------------|
321
+ | `mesh.getStatus()` | Get current status |
322
+ | `mesh.getNetworkHealth()` | Check how good the network is |
323
+ | `mesh.getBatteryMode()` | See current battery mode |
324
+ | `mesh.setBatteryMode('low')` | Change battery mode |
348
325
 
349
- ### Power Modes
326
+ ---
350
327
 
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 |
328
+ ## Events (When Things Happen)
357
329
 
358
- ### Message Options
330
+ Listen for these events:
359
331
 
360
332
  ```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'
374
- });
375
- ```
333
+ // Network started/stopped
334
+ mesh.on('started', () => { });
335
+ mesh.on('stopped', () => { });
376
336
 
377
- ## Security Features
337
+ // Someone sent a message (any type)
338
+ mesh.on('messageReceived', ({ from, text, timestamp, type }) => { });
378
339
 
379
- ### Cryptographic Primitives
340
+ // Private message received
341
+ mesh.on('directMessage', ({ from, text, timestamp }) => { });
380
342
 
381
- - **Key Exchange**: X25519 (Curve25519 ECDH)
382
- - **Signatures**: Ed25519
383
- - **Encryption**: ChaCha20-Poly1305 AEAD
384
- - **Hashing**: SHA-256, SHA-512
385
- - **Key Derivation**: HKDF
343
+ // Channel message received
344
+ mesh.on('channelMessage', ({ channel, from, text, timestamp }) => { });
386
345
 
387
- ### Noise Protocol XX Handshake
346
+ // Message was delivered successfully
347
+ mesh.on('messageDelivered', ({ messageId, peerId }) => { });
388
348
 
389
- The library implements the Noise XX handshake pattern:
390
-
391
- ```
392
- -> e
393
- <- e, ee, s, es
394
- -> s, se
395
- ```
349
+ // Found a new person nearby
350
+ mesh.on('peerDiscovered', (peer) => { });
396
351
 
397
- This provides:
398
- - Mutual authentication
399
- - Forward secrecy
400
- - Identity hiding
352
+ // Connected to someone
353
+ mesh.on('peerConnected', (peer) => { });
401
354
 
402
- ### Session Security
355
+ // Someone left
356
+ mesh.on('peerDisconnected', (peer) => { });
403
357
 
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
358
+ // Channel events
359
+ mesh.on('channelJoined', ({ channel }) => { });
360
+ mesh.on('channelLeft', ({ channel }) => { });
407
361
 
408
- ### Identity Verification
362
+ // Network quality changed
363
+ mesh.on('networkHealthChanged', (healthInfo) => { });
409
364
 
410
- Verify peer identities out-of-band using fingerprints:
365
+ // Message cached for offline peer
366
+ mesh.on('messageCached', ({ peerId, text }) => { });
411
367
 
412
- ```javascript
413
- // Get your fingerprint to share
414
- const myFingerprint = mesh.getFingerprint();
415
- // Format: "A1B2 C3D4 E5F6 G7H8 I9J0 K1L2 M3N4 O5P6"
368
+ // Cached messages delivered when peer came online
369
+ mesh.on('cachedMessagesDelivered', ({ peerId, delivered }) => { });
416
370
 
417
- // Verify a peer after out-of-band confirmation
418
- mesh.verifyPeer(peerId, theirFingerprint);
371
+ // Data was wiped (panic mode)
372
+ mesh.on('dataWiped', (result) => { });
419
373
 
420
- // Check if a peer is verified
421
- const peer = mesh.getPeer(peerId);
422
- console.log('Verified:', peer.verificationStatus === 'verified');
374
+ // Something went wrong
375
+ mesh.on('error', (error) => { });
423
376
  ```
424
377
 
425
- ## Protocol Details
378
+ ---
426
379
 
427
- ### Message Header Format
380
+ ## How Secure Is It?
428
381
 
429
- The library uses an optimized 24-32 byte header:
382
+ **Very secure!** Here's what protects your messages:
430
383
 
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 |
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 |
388
+ | **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 |
443
390
 
444
- ### Message Types
391
+ ---
445
392
 
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 |
393
+ ## Frequently Asked Questions
455
394
 
456
- ## Error Handling
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!
457
397
 
458
- The library provides detailed error classes:
398
+ ### Does it work if Bluetooth is off?
399
+ No, Bluetooth must be on. But you don't need WiFi or cell service!
459
400
 
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
- }
480
-
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
- ```
401
+ ### Can someone read my private messages?
402
+ No! Private messages are encrypted. Only you and your friend have the keys.
488
403
 
489
- ### Error Codes
404
+ ### How many people can be in the network?
405
+ The library supports 50+ connected peers at once.
490
406
 
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 |
407
+ ### Does it drain my battery?
408
+ It uses some battery (Bluetooth is on), but you can use "low power" mode to minimize drain.
500
409
 
501
- ## Platform Support
410
+ ### Does it work in the background?
411
+ On iOS, it works with some limitations. On Android, it works fully in the background.
502
412
 
503
- ### React Native
413
+ ---
504
414
 
505
- ```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
- });
512
- ```
513
-
514
- **Required permissions (iOS):**
515
- - NSBluetoothAlwaysUsageDescription
516
- - NSBluetoothPeripheralUsageDescription
415
+ ## Use Cases
517
416
 
518
- **Required permissions (Android):**
519
- - BLUETOOTH
520
- - BLUETOOTH_ADMIN
521
- - BLUETOOTH_SCAN
522
- - BLUETOOTH_ADVERTISE
523
- - BLUETOOTH_CONNECT
524
- - ACCESS_FINE_LOCATION
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
525
423
 
526
- ### Node.js
424
+ ---
527
425
 
528
- ```javascript
529
- const { MeshService, BLETransport } = require('react-native-ble-mesh');
530
- const { NodeBLEAdapter } = require('react-native-ble-mesh/adapters');
426
+ ## Project Structure
531
427
 
532
- const transport = new BLETransport({
533
- adapter: new NodeBLEAdapter(),
534
- });
535
428
  ```
536
-
537
- ## Examples
538
-
539
- ### Basic Chat Application
540
-
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
- }
549
-
550
- async start(displayName) {
551
- await this.mesh.initialize({
552
- displayName,
553
- storage: new MemoryStorage(),
554
- });
555
-
556
- const transport = new BLETransport();
557
- await this.mesh.start(transport);
558
-
559
- this.setupEventHandlers();
560
- console.log('Chat started! Your fingerprint:', this.mesh.getFingerprint());
561
- }
562
-
563
- setupEventHandlers() {
564
- this.mesh.on('peer-discovered', (peer) => {
565
- console.log(`[+] Discovered: ${peer.getDisplayName()}`);
566
- });
567
-
568
- this.mesh.on('private-message', (message) => {
569
- this.messages.push(message);
570
- console.log(`[${message.senderId.slice(0, 8)}]: ${message.content}`);
571
- });
572
-
573
- this.mesh.on('message-delivered', ({ messageId }) => {
574
- console.log(`[OK] Delivered: ${messageId.slice(0, 8)}`);
575
- });
576
- }
577
-
578
- async sendMessage(peerId, content) {
579
- return await this.mesh.sendPrivateMessage(peerId, content, {
580
- requiresAck: true,
581
- });
582
- }
583
-
584
- getPeers() {
585
- return this.mesh.getPeers();
586
- }
587
-
588
- verifyPeer(peerId, fingerprint) {
589
- this.mesh.verifyPeer(peerId, fingerprint);
590
- }
591
-
592
- async stop() {
593
- await this.mesh.stop();
594
- await this.mesh.destroy();
595
- }
596
- }
597
-
598
- // Usage
599
- const chat = new ChatApp();
600
- await chat.start('Alice');
601
-
602
- // List discovered peers
603
- const peers = chat.getPeers();
604
- peers.forEach(p => console.log(p.id, p.getDisplayName()));
605
-
606
- // Send a message
607
- await chat.sendMessage(peers[0].id, 'Hello!');
429
+ react-native-ble-mesh/
430
+ ├── 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
608
439
  ```
609
440
 
610
- ### Multi-Hop Messaging
611
-
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
- });
441
+ ---
618
442
 
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
- ```
443
+ ## More Documentation
624
444
 
625
- ### Secure File Transfer
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
626
450
 
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
- }
653
- ```
451
+ ---
654
452
 
655
453
  ## Testing
656
454
 
657
- Run the test suite:
658
-
659
455
  ```bash
456
+ # Run all tests
660
457
  npm test
661
- ```
662
458
 
663
- Run with coverage:
664
-
665
- ```bash
459
+ # Run with coverage report
666
460
  npm run test:coverage
667
461
  ```
668
462
 
669
- Run specific test files:
463
+ ---
670
464
 
671
- ```bash
672
- npm test -- __tests__/crypto/sha256.test.js
673
- npm test -- __tests__/integration/handshake.test.js
674
- ```
675
-
676
- ## Project Structure
465
+ ## Contributing
677
466
 
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
- ```
467
+ We love contributions! Here's how:
702
468
 
703
- ## Contributing
469
+ 1. Fork this repository
470
+ 2. Create a branch: `git checkout -b my-feature`
471
+ 3. Make your changes
472
+ 4. Run tests: `npm test`
473
+ 5. Push and create a Pull Request
704
474
 
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
475
+ ---
711
476
 
712
- ### Code Style
477
+ ## Credits
713
478
 
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
479
+ Inspired by [BitChat](https://github.com/nicegram/nicegram-bitchat) - the original decentralized mesh chat.
719
480
 
720
- ## Documentation
481
+ 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
721
484
 
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
485
+ ---
726
486
 
727
487
  ## License
728
488
 
729
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
489
+ MIT License - do whatever you want with it! See [LICENSE](LICENSE) for details.
490
+
491
+ ---
492
+
493
+ ## Get Help
730
494
 
731
- ## Acknowledgments
495
+ - **Issues**: [GitHub Issues](https://github.com/suhailtajshaik/react-native-ble-mesh/issues)
496
+ - **Questions**: Open a Discussion on GitHub
732
497
 
733
- This project is inspired by [bitchat](https://github.com/permissionlesstech/bitchat).
498
+ ---
734
499
 
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
500
+ <p align="center">
501
+ <b>Made with ❤️ for a more connected (yet private) world</b>
502
+ <br><br>
503
+ If this library helps you, give it a ⭐ on GitHub!
504
+ </p>