react-native-ble-mesh 1.0.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/CHANGELOG.md +151 -0
- package/LICENSE +21 -0
- package/README.md +706 -0
- package/docs/API.md +462 -0
- package/docs/ARCHITECTURE.md +384 -0
- package/docs/CONTRIBUTING.md +244 -0
- package/docs/NODE_QUICKSTART.md +259 -0
- package/docs/PROTOCOL.md +195 -0
- package/docs/REACT_NATIVE.md +315 -0
- package/docs/SECURITY.md +152 -0
- package/docs/api/constants_audio.js.html +184 -0
- package/docs/api/constants_ble.js.html +165 -0
- package/docs/api/constants_crypto.js.html +107 -0
- package/docs/api/constants_errors.js.html +256 -0
- package/docs/api/constants_events.js.html +148 -0
- package/docs/api/constants_index.js.html +76 -0
- package/docs/api/constants_protocol.js.html +205 -0
- package/docs/api/crypto_aead.js.html +243 -0
- package/docs/api/crypto_chacha20.js.html +235 -0
- package/docs/api/crypto_hkdf.js.html +241 -0
- package/docs/api/crypto_hmac.js.html +197 -0
- package/docs/api/crypto_index.js.html +126 -0
- package/docs/api/crypto_keys_KeyManager.js.html +325 -0
- package/docs/api/crypto_keys_KeyPair.js.html +270 -0
- package/docs/api/crypto_keys_SecureStorage.js.html +273 -0
- package/docs/api/crypto_keys_index.js.html +86 -0
- package/docs/api/crypto_noise_handshake.js.html +464 -0
- package/docs/api/crypto_noise_index.js.html +81 -0
- package/docs/api/crypto_noise_session.js.html +307 -0
- package/docs/api/crypto_noise_state.js.html +322 -0
- package/docs/api/crypto_poly1305.js.html +167 -0
- package/docs/api/crypto_sha256.js.html +294 -0
- package/docs/api/crypto_x25519.js.html +208 -0
- package/docs/api/errors_AudioError.js.html +218 -0
- package/docs/api/errors_ConnectionError.js.html +163 -0
- package/docs/api/errors_CryptoError.js.html +157 -0
- package/docs/api/errors_HandshakeError.js.html +176 -0
- package/docs/api/errors_MeshError.js.html +154 -0
- package/docs/api/errors_MessageError.js.html +183 -0
- package/docs/api/errors_ValidationError.js.html +204 -0
- package/docs/api/errors_index.js.html +78 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.svg +1830 -0
- package/docs/api/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Light-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
- package/docs/api/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.svg +1831 -0
- package/docs/api/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/api/hooks_AppStateManager.js.html +233 -0
- package/docs/api/hooks_index.js.html +87 -0
- package/docs/api/hooks_useMesh.js.html +213 -0
- package/docs/api/hooks_useMessages.js.html +263 -0
- package/docs/api/hooks_usePeers.js.html +165 -0
- package/docs/api/index.html +868 -0
- package/docs/api/index.js.html +236 -0
- package/docs/api/mesh_dedup_BloomFilter.js.html +261 -0
- package/docs/api/mesh_dedup_DedupManager.js.html +266 -0
- package/docs/api/mesh_dedup_MessageCache.js.html +273 -0
- package/docs/api/mesh_dedup_index.js.html +70 -0
- package/docs/api/mesh_fragment_Assembler.js.html +335 -0
- package/docs/api/mesh_fragment_Fragmenter.js.html +230 -0
- package/docs/api/mesh_fragment_index.js.html +75 -0
- package/docs/api/mesh_index.js.html +72 -0
- package/docs/api/mesh_peer_Peer.js.html +296 -0
- package/docs/api/mesh_peer_PeerDiscovery.js.html +334 -0
- package/docs/api/mesh_peer_PeerManager.js.html +320 -0
- package/docs/api/mesh_peer_index.js.html +70 -0
- package/docs/api/mesh_router_MessageRouter.js.html +411 -0
- package/docs/api/mesh_router_PathFinder.js.html +386 -0
- package/docs/api/mesh_router_RouteTable.js.html +346 -0
- package/docs/api/mesh_router_index.js.html +70 -0
- package/docs/api/module-audio_buffer.html +168 -0
- package/docs/api/module-audio_buffer_FrameBuffer-FrameBuffer.html +2971 -0
- package/docs/api/module-audio_buffer_FrameBuffer.html +178 -0
- package/docs/api/module-audio_buffer_JitterBuffer-JitterBuffer.html +2761 -0
- package/docs/api/module-audio_buffer_JitterBuffer.html +178 -0
- package/docs/api/module-audio_codec.html +168 -0
- package/docs/api/module-audio_codec_LC3Codec-LC3Codec.html +2876 -0
- package/docs/api/module-audio_codec_LC3Codec.html +178 -0
- package/docs/api/module-audio_codec_LC3Decoder-LC3Decoder.html +1788 -0
- package/docs/api/module-audio_codec_LC3Decoder.html +178 -0
- package/docs/api/module-audio_codec_LC3Encoder-LC3Encoder.html +1512 -0
- package/docs/api/module-audio_codec_LC3Encoder.html +178 -0
- package/docs/api/module-audio_session.html +168 -0
- package/docs/api/module-audio_session_AudioSession-AudioSession.html +3922 -0
- package/docs/api/module-audio_session_AudioSession.html +178 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessage.html +3690 -0
- package/docs/api/module-audio_session_VoiceMessage-VoiceMessageRecorder.html +1780 -0
- package/docs/api/module-audio_session_VoiceMessage.html +332 -0
- package/docs/api/module-audio_transport.html +168 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioAssembler.html +1545 -0
- package/docs/api/module-audio_transport_AudioFragmenter-AudioFragmenter.html +658 -0
- package/docs/api/module-audio_transport_AudioFragmenter.html +181 -0
- package/docs/api/module-audio_transport_AudioFramer.html +1414 -0
- package/docs/api/module-constants.html +168 -0
- package/docs/api/module-constants_audio.html +1782 -0
- package/docs/api/module-constants_ble.html +940 -0
- package/docs/api/module-constants_crypto.html +823 -0
- package/docs/api/module-constants_errors.html +316 -0
- package/docs/api/module-constants_events.html +244 -0
- package/docs/api/module-constants_protocol.html +1534 -0
- package/docs/api/module-crypto.html +169 -0
- package/docs/api/module-crypto_aead.html +1625 -0
- package/docs/api/module-crypto_chacha20.html +1440 -0
- package/docs/api/module-crypto_hkdf.html +1421 -0
- package/docs/api/module-crypto_hmac.html +828 -0
- package/docs/api/module-crypto_keys.html +169 -0
- package/docs/api/module-crypto_keys_KeyManager-KeyManager.html +2364 -0
- package/docs/api/module-crypto_keys_KeyManager.html +252 -0
- package/docs/api/module-crypto_keys_KeyPair.html +245 -0
- package/docs/api/module-crypto_keys_SecureStorage-MemorySecureStorage.html +923 -0
- package/docs/api/module-crypto_keys_SecureStorage-SecureStorage.html +942 -0
- package/docs/api/module-crypto_keys_SecureStorage.html +516 -0
- package/docs/api/module-crypto_noise.html +169 -0
- package/docs/api/module-crypto_noise_handshake-NoiseHandshake.html +2240 -0
- package/docs/api/module-crypto_noise_handshake.html +782 -0
- package/docs/api/module-crypto_noise_session-NoiseSession.html +1804 -0
- package/docs/api/module-crypto_noise_session.html +325 -0
- package/docs/api/module-crypto_noise_state-SymmetricState.html +1387 -0
- package/docs/api/module-crypto_noise_state.html +324 -0
- package/docs/api/module-crypto_poly1305.html +884 -0
- package/docs/api/module-crypto_sha256-HashContext.html +447 -0
- package/docs/api/module-crypto_sha256.html +942 -0
- package/docs/api/module-crypto_x25519.html +1503 -0
- package/docs/api/module-errors.html +168 -0
- package/docs/api/module-errors_AudioError-AudioError.html +4711 -0
- package/docs/api/module-errors_AudioError.html +178 -0
- package/docs/api/module-errors_ConnectionError-ConnectionError.html +3649 -0
- package/docs/api/module-errors_ConnectionError.html +178 -0
- package/docs/api/module-errors_CryptoError-CryptoError.html +3453 -0
- package/docs/api/module-errors_CryptoError.html +178 -0
- package/docs/api/module-errors_HandshakeError-HandshakeError.html +4261 -0
- package/docs/api/module-errors_HandshakeError.html +178 -0
- package/docs/api/module-errors_MeshError-MeshError.html +2155 -0
- package/docs/api/module-errors_MeshError.html +178 -0
- package/docs/api/module-errors_MessageError-MessageError.html +4545 -0
- package/docs/api/module-errors_MessageError.html +178 -0
- package/docs/api/module-errors_ValidationError-ValidationError.html +3432 -0
- package/docs/api/module-errors_ValidationError.html +178 -0
- package/docs/api/module-hooks.html +182 -0
- package/docs/api/module-hooks_AppStateManager-AppStateManager.html +1620 -0
- package/docs/api/module-hooks_AppStateManager.html +178 -0
- package/docs/api/module-hooks_useMesh.html +457 -0
- package/docs/api/module-hooks_useMessages.html +466 -0
- package/docs/api/module-hooks_usePeers.html +348 -0
- package/docs/api/module-mesh.html +168 -0
- package/docs/api/module-mesh_dedup.html +168 -0
- package/docs/api/module-mesh_dedup_BloomFilter-BloomFilter.html +2158 -0
- package/docs/api/module-mesh_dedup_BloomFilter.html +178 -0
- package/docs/api/module-mesh_dedup_DedupManager-DedupManager.html +2880 -0
- package/docs/api/module-mesh_dedup_DedupManager.html +178 -0
- package/docs/api/module-mesh_dedup_MessageCache-CacheNode.html +246 -0
- package/docs/api/module-mesh_dedup_MessageCache-MessageCache.html +2314 -0
- package/docs/api/module-mesh_dedup_MessageCache.html +181 -0
- package/docs/api/module-mesh_fragment.html +168 -0
- package/docs/api/module-mesh_fragment_Assembler-Assembler.html +2869 -0
- package/docs/api/module-mesh_fragment_Assembler-PendingFragmentSet.html +895 -0
- package/docs/api/module-mesh_fragment_Assembler.html +181 -0
- package/docs/api/module-mesh_fragment_Fragmenter.html +1084 -0
- package/docs/api/module-mesh_peer.html +168 -0
- package/docs/api/module-mesh_peer_Peer-Peer.html +4986 -0
- package/docs/api/module-mesh_peer_Peer.html +178 -0
- package/docs/api/module-mesh_peer_PeerDiscovery-PeerDiscovery.html +3423 -0
- package/docs/api/module-mesh_peer_PeerDiscovery.html +438 -0
- package/docs/api/module-mesh_peer_PeerManager-PeerManager.html +5258 -0
- package/docs/api/module-mesh_peer_PeerManager.html +178 -0
- package/docs/api/module-mesh_router.html +168 -0
- package/docs/api/module-mesh_router_MessageRouter-MessageRouter.html +3285 -0
- package/docs/api/module-mesh_router_MessageRouter.html +178 -0
- package/docs/api/module-mesh_router_PathFinder-PathFinder.html +3323 -0
- package/docs/api/module-mesh_router_PathFinder.html +421 -0
- package/docs/api/module-mesh_router_RouteTable-RouteTable.html +4115 -0
- package/docs/api/module-mesh_router_RouteTable.html +421 -0
- package/docs/api/module-protocol.html +169 -0
- package/docs/api/module-protocol_crc32.html +815 -0
- package/docs/api/module-protocol_deserializer.html +1393 -0
- package/docs/api/module-protocol_header-MessageHeader.html +2879 -0
- package/docs/api/module-protocol_header.html +892 -0
- package/docs/api/module-protocol_message-Message.html +4682 -0
- package/docs/api/module-protocol_message.html +178 -0
- package/docs/api/module-protocol_serializer.html +911 -0
- package/docs/api/module-protocol_validator.html +1396 -0
- package/docs/api/module-rn-ble-mesh.html +866 -0
- package/docs/api/module-service.html +168 -0
- package/docs/api/module-service_HandshakeManager-HandshakeManager.html +185 -0
- package/docs/api/module-service_HandshakeManager.html +175 -0
- package/docs/api/module-service_MeshService-MeshService.html +185 -0
- package/docs/api/module-service_MeshService.html +175 -0
- package/docs/api/module-service_SessionManager-SessionManager.html +174 -0
- package/docs/api/module-service_SessionManager.html +175 -0
- package/docs/api/module-service_audio.html +168 -0
- package/docs/api/module-service_audio_AudioManager-AudioManager.html +4653 -0
- package/docs/api/module-service_audio_AudioManager.html +254 -0
- package/docs/api/module-service_text.html +168 -0
- package/docs/api/module-service_text_TextManager-TextManager.html +6104 -0
- package/docs/api/module-service_text_TextManager.html +254 -0
- package/docs/api/module-service_text_broadcast.html +168 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager-BroadcastManager.html +2434 -0
- package/docs/api/module-service_text_broadcast_BroadcastManager.html +254 -0
- package/docs/api/module-service_text_channel.html +168 -0
- package/docs/api/module-service_text_channel_Channel-Channel.html +4337 -0
- package/docs/api/module-service_text_channel_Channel.html +178 -0
- package/docs/api/module-service_text_channel_ChannelManager-ChannelManager.html +1927 -0
- package/docs/api/module-service_text_channel_ChannelManager.html +175 -0
- package/docs/api/module-service_text_message.html +168 -0
- package/docs/api/module-service_text_message_TextMessage-TextMessage.html +4162 -0
- package/docs/api/module-service_text_message_TextMessage.html +178 -0
- package/docs/api/module-service_text_message_TextSerializer.html +1725 -0
- package/docs/api/module-storage.html +168 -0
- package/docs/api/module-storage_AsyncStorageAdapter-AsyncStorageAdapter.html +4159 -0
- package/docs/api/module-storage_AsyncStorageAdapter.html +178 -0
- package/docs/api/module-storage_MemoryStorage-MemoryStorage.html +3154 -0
- package/docs/api/module-storage_MemoryStorage.html +178 -0
- package/docs/api/module-storage_MessageStore-MessageStore.html +5299 -0
- package/docs/api/module-storage_MessageStore.html +178 -0
- package/docs/api/module-storage_Storage-Storage.html +4169 -0
- package/docs/api/module-storage_Storage.html +178 -0
- package/docs/api/module-transport.html +168 -0
- package/docs/api/module-transport_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_BLEAdapter.html +178 -0
- package/docs/api/module-transport_BLETransport-BLETransport.html +3263 -0
- package/docs/api/module-transport_BLETransport.html +178 -0
- package/docs/api/module-transport_MockTransport-MockTransport.html +3947 -0
- package/docs/api/module-transport_MockTransport.html +178 -0
- package/docs/api/module-transport_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_RNBLEAdapter.html +178 -0
- package/docs/api/module-transport_Transport-Transport.html +4071 -0
- package/docs/api/module-transport_Transport.html +254 -0
- package/docs/api/module-transport_adapters.html +168 -0
- package/docs/api/module-transport_adapters_BLEAdapter-BLEAdapter.html +4724 -0
- package/docs/api/module-transport_adapters_BLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter-NodeBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_NodeBLEAdapter.html +178 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter-RNBLEAdapter.html +3216 -0
- package/docs/api/module-transport_adapters_RNBLEAdapter.html +178 -0
- package/docs/api/module-utils.html +168 -0
- package/docs/api/module-utils_BoundedMap-BoundedMap.html +3301 -0
- package/docs/api/module-utils_BoundedMap.html +178 -0
- package/docs/api/module-utils_EventEmitter-EventEmitter.html +3358 -0
- package/docs/api/module-utils_EventEmitter.html +178 -0
- package/docs/api/module-utils_LRUCache-LRUCache.html +4134 -0
- package/docs/api/module-utils_LRUCache.html +178 -0
- package/docs/api/module-utils_RateLimiter-RateLimiter.html +2176 -0
- package/docs/api/module-utils_RateLimiter.html +500 -0
- package/docs/api/module-utils_TimeoutManager-TimeoutManager.html +1781 -0
- package/docs/api/module-utils_TimeoutManager.html +175 -0
- package/docs/api/module-utils_bytes.html +1789 -0
- package/docs/api/module-utils_debug.html +837 -0
- package/docs/api/module-utils_encoding.html +1184 -0
- package/docs/api/module-utils_retry.html +1457 -0
- package/docs/api/module-utils_time.html +1665 -0
- package/docs/api/module-utils_uuid.html +1269 -0
- package/docs/api/module-utils_validation.html +2176 -0
- package/docs/api/protocol_crc32.js.html +147 -0
- package/docs/api/protocol_deserializer.js.html +295 -0
- package/docs/api/protocol_header.js.html +276 -0
- package/docs/api/protocol_index.js.html +120 -0
- package/docs/api/protocol_message.js.html +287 -0
- package/docs/api/protocol_serializer.js.html +240 -0
- package/docs/api/protocol_validator.js.html +330 -0
- package/docs/api/scripts/linenumber.js +25 -0
- package/docs/api/scripts/prettify/Apache-License-2.0.txt +202 -0
- package/docs/api/scripts/prettify/lang-css.js +2 -0
- package/docs/api/scripts/prettify/prettify.js +28 -0
- package/docs/api/service_HandshakeManager.js.html +232 -0
- package/docs/api/service_MeshService.js.html +371 -0
- package/docs/api/service_SessionManager.js.html +153 -0
- package/docs/api/service_audio_AudioManager.js.html +541 -0
- package/docs/api/service_audio_buffer_FrameBuffer.js.html +223 -0
- package/docs/api/service_audio_buffer_JitterBuffer.js.html +244 -0
- package/docs/api/service_audio_buffer_index.js.html +68 -0
- package/docs/api/service_audio_codec_LC3Codec.js.html +345 -0
- package/docs/api/service_audio_codec_LC3Decoder.js.html +185 -0
- package/docs/api/service_audio_codec_LC3Encoder.js.html +194 -0
- package/docs/api/service_audio_codec_index.js.html +70 -0
- package/docs/api/service_audio_index.js.html +96 -0
- package/docs/api/service_audio_session_AudioSession.js.html +348 -0
- package/docs/api/service_audio_session_VoiceMessage.js.html +432 -0
- package/docs/api/service_audio_session_index.js.html +70 -0
- package/docs/api/service_audio_transport_AudioFragmenter.js.html +314 -0
- package/docs/api/service_audio_transport_AudioFramer.js.html +236 -0
- package/docs/api/service_audio_transport_index.js.html +69 -0
- package/docs/api/service_index.js.html +93 -0
- package/docs/api/service_text_TextManager.js.html +578 -0
- package/docs/api/service_text_broadcast_BroadcastManager.js.html +276 -0
- package/docs/api/service_text_broadcast_index.js.html +66 -0
- package/docs/api/service_text_channel_Channel.js.html +280 -0
- package/docs/api/service_text_channel_ChannelManager.js.html +225 -0
- package/docs/api/service_text_channel_index.js.html +68 -0
- package/docs/api/service_text_index.js.html +85 -0
- package/docs/api/service_text_message_TextMessage.js.html +350 -0
- package/docs/api/service_text_message_TextSerializer.js.html +218 -0
- package/docs/api/service_text_message_index.js.html +68 -0
- package/docs/api/storage_AsyncStorageAdapter.js.html +357 -0
- package/docs/api/storage_MemoryStorage.js.html +279 -0
- package/docs/api/storage_MessageStore.js.html +369 -0
- package/docs/api/storage_Storage.js.html +214 -0
- package/docs/api/storage_index.js.html +72 -0
- package/docs/api/styles/jsdoc-default.css +358 -0
- package/docs/api/styles/prettify-jsdoc.css +111 -0
- package/docs/api/styles/prettify-tomorrow.css +132 -0
- package/docs/api/transport_BLEAdapter.js.html +231 -0
- package/docs/api/transport_BLETransport.js.html +411 -0
- package/docs/api/transport_MockTransport.js.html +339 -0
- package/docs/api/transport_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_Transport.js.html +242 -0
- package/docs/api/transport_adapters_BLEAdapter.js.html +231 -0
- package/docs/api/transport_adapters_NodeBLEAdapter.js.html +479 -0
- package/docs/api/transport_adapters_RNBLEAdapter.js.html +382 -0
- package/docs/api/transport_adapters_index.js.html +70 -0
- package/docs/api/transport_index.js.html +87 -0
- package/docs/api/utils_BoundedMap.js.html +205 -0
- package/docs/api/utils_EventEmitter.js.html +259 -0
- package/docs/api/utils_LRUCache.js.html +256 -0
- package/docs/api/utils_RateLimiter.js.html +256 -0
- package/docs/api/utils_TimeoutManager.js.html +218 -0
- package/docs/api/utils_base64%0A%0AThis%20implementation%20avoids%20string%20concatenation%20in%20loops%20which%20is%20O(n%C2%B2).%0AUses%20array%20building%20which%20is%20O(n)%20-%20critical%20for%20React%20Native%20performance.module_.html +717 -0
- package/docs/api/utils_base64.js.html +205 -0
- package/docs/api/utils_bytes.js.html +241 -0
- package/docs/api/utils_debug.js.html +205 -0
- package/docs/api/utils_encoding.js.html +302 -0
- package/docs/api/utils_index.js.html +160 -0
- package/docs/api/utils_retry.js.html +200 -0
- package/docs/api/utils_time.js.html +220 -0
- package/docs/api/utils_uuid.js.html +199 -0
- package/docs/api/utils_validation.js.html +259 -0
- package/examples/node-chat/chat.js +220 -0
- package/examples/node-quickstart/index.js +94 -0
- package/examples/testing/test-helper.js +182 -0
- package/package.json +111 -0
- package/src/constants/audio.js +130 -0
- package/src/constants/ble.js +111 -0
- package/src/constants/crypto.js +53 -0
- package/src/constants/errors.js +202 -0
- package/src/constants/events.js +94 -0
- package/src/constants/index.js +22 -0
- package/src/constants/protocol.js +151 -0
- package/src/crypto/aead.js +189 -0
- package/src/crypto/chacha20.js +181 -0
- package/src/crypto/hkdf.js +187 -0
- package/src/crypto/hmac.js +143 -0
- package/src/crypto/index.js +72 -0
- package/src/crypto/keys/KeyManager.js +271 -0
- package/src/crypto/keys/KeyPair.js +216 -0
- package/src/crypto/keys/SecureStorage.js +219 -0
- package/src/crypto/keys/index.js +32 -0
- package/src/crypto/noise/handshake.js +410 -0
- package/src/crypto/noise/index.js +27 -0
- package/src/crypto/noise/session.js +253 -0
- package/src/crypto/noise/state.js +268 -0
- package/src/crypto/poly1305.js +113 -0
- package/src/crypto/sha256.js +240 -0
- package/src/crypto/x25519.js +154 -0
- package/src/errors/AudioError.js +164 -0
- package/src/errors/ConnectionError.js +109 -0
- package/src/errors/CryptoError.js +103 -0
- package/src/errors/HandshakeError.js +122 -0
- package/src/errors/MeshError.js +100 -0
- package/src/errors/MessageError.js +129 -0
- package/src/errors/ValidationError.js +150 -0
- package/src/errors/index.js +24 -0
- package/src/hooks/AppStateManager.js +179 -0
- package/src/hooks/index.js +33 -0
- package/src/hooks/useMesh.js +159 -0
- package/src/hooks/useMessages.js +209 -0
- package/src/hooks/usePeers.js +111 -0
- package/src/index.d.ts +494 -0
- package/src/index.js +182 -0
- package/src/index.mjs +62 -0
- package/src/mesh/dedup/BloomFilter.js +207 -0
- package/src/mesh/dedup/DedupManager.js +212 -0
- package/src/mesh/dedup/MessageCache.js +219 -0
- package/src/mesh/dedup/index.js +16 -0
- package/src/mesh/fragment/Assembler.js +281 -0
- package/src/mesh/fragment/Fragmenter.js +176 -0
- package/src/mesh/fragment/index.js +21 -0
- package/src/mesh/index.js +18 -0
- package/src/mesh/peer/Peer.js +242 -0
- package/src/mesh/peer/PeerDiscovery.js +280 -0
- package/src/mesh/peer/PeerManager.js +266 -0
- package/src/mesh/peer/index.js +16 -0
- package/src/mesh/router/MessageRouter.js +357 -0
- package/src/mesh/router/PathFinder.js +332 -0
- package/src/mesh/router/RouteTable.js +292 -0
- package/src/mesh/router/index.js +16 -0
- package/src/protocol/crc32.js +93 -0
- package/src/protocol/deserializer.js +241 -0
- package/src/protocol/header.js +222 -0
- package/src/protocol/index.js +66 -0
- package/src/protocol/message.js +233 -0
- package/src/protocol/serializer.js +186 -0
- package/src/protocol/validator.js +276 -0
- package/src/service/HandshakeManager.js +178 -0
- package/src/service/MeshService.js +317 -0
- package/src/service/SessionManager.js +99 -0
- package/src/service/audio/AudioManager.js +487 -0
- package/src/service/audio/buffer/FrameBuffer.js +169 -0
- package/src/service/audio/buffer/JitterBuffer.js +190 -0
- package/src/service/audio/buffer/index.js +14 -0
- package/src/service/audio/codec/LC3Codec.js +291 -0
- package/src/service/audio/codec/LC3Decoder.js +131 -0
- package/src/service/audio/codec/LC3Encoder.js +140 -0
- package/src/service/audio/codec/index.js +16 -0
- package/src/service/audio/index.js +42 -0
- package/src/service/audio/session/AudioSession.js +294 -0
- package/src/service/audio/session/VoiceMessage.js +378 -0
- package/src/service/audio/session/index.js +16 -0
- package/src/service/audio/transport/AudioFragmenter.js +260 -0
- package/src/service/audio/transport/AudioFramer.js +182 -0
- package/src/service/audio/transport/index.js +15 -0
- package/src/service/index.js +39 -0
- package/src/service/text/TextManager.js +524 -0
- package/src/service/text/broadcast/BroadcastManager.js +222 -0
- package/src/service/text/broadcast/index.js +12 -0
- package/src/service/text/channel/Channel.js +226 -0
- package/src/service/text/channel/ChannelManager.js +171 -0
- package/src/service/text/channel/index.js +14 -0
- package/src/service/text/index.js +31 -0
- package/src/service/text/message/TextMessage.js +296 -0
- package/src/service/text/message/TextSerializer.js +164 -0
- package/src/service/text/message/index.js +14 -0
- package/src/storage/AsyncStorageAdapter.js +303 -0
- package/src/storage/MemoryStorage.js +225 -0
- package/src/storage/MessageStore.js +315 -0
- package/src/storage/Storage.js +160 -0
- package/src/storage/index.js +18 -0
- package/src/transport/BLEAdapter.js +177 -0
- package/src/transport/BLETransport.js +357 -0
- package/src/transport/MockTransport.js +285 -0
- package/src/transport/NodeBLEAdapter.js +425 -0
- package/src/transport/RNBLEAdapter.js +328 -0
- package/src/transport/Transport.js +188 -0
- package/src/transport/adapters/BLEAdapter.js +177 -0
- package/src/transport/adapters/NodeBLEAdapter.js +425 -0
- package/src/transport/adapters/RNBLEAdapter.js +328 -0
- package/src/transport/adapters/index.js +16 -0
- package/src/transport/index.js +33 -0
- package/src/utils/BoundedMap.js +151 -0
- package/src/utils/EventEmitter.js +205 -0
- package/src/utils/LRUCache.js +202 -0
- package/src/utils/RateLimiter.js +202 -0
- package/src/utils/TimeoutManager.js +164 -0
- package/src/utils/base64.js +151 -0
- package/src/utils/bytes.js +187 -0
- package/src/utils/debug.js +151 -0
- package/src/utils/encoding.js +248 -0
- package/src/utils/index.js +106 -0
- package/src/utils/retry.js +146 -0
- package/src/utils/time.js +166 -0
- package/src/utils/uuid.js +145 -0
- package/src/utils/validation.js +205 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* KeyManager for identity and key lifecycle management.
|
|
5
|
+
* Handles persistent identity storage and retrieval.
|
|
6
|
+
* @module crypto/keys/KeyManager
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { KeyPair } = require('./KeyPair');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default storage key for identity
|
|
13
|
+
* @constant {string}
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_IDENTITY_KEY = 'mesh_identity';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* KeyManager handles identity key management for the mesh network.
|
|
19
|
+
* Provides methods to generate, store, and retrieve identity keys.
|
|
20
|
+
*
|
|
21
|
+
* @class
|
|
22
|
+
*/
|
|
23
|
+
class KeyManager {
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new KeyManager.
|
|
26
|
+
* @param {object} [options={}] - Configuration options
|
|
27
|
+
* @param {object} [options.storage] - Storage adapter (SecureStorage interface)
|
|
28
|
+
* @param {string} [options.identityKey] - Storage key for identity
|
|
29
|
+
*/
|
|
30
|
+
constructor(options = {}) {
|
|
31
|
+
/** @type {object|null} */
|
|
32
|
+
this._storage = options.storage || null;
|
|
33
|
+
|
|
34
|
+
/** @type {string} */
|
|
35
|
+
this._identityKey = options.identityKey || DEFAULT_IDENTITY_KEY;
|
|
36
|
+
|
|
37
|
+
/** @type {KeyPair|null} */
|
|
38
|
+
this._identity = null;
|
|
39
|
+
|
|
40
|
+
/** @type {string|null} */
|
|
41
|
+
this._displayName = null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generates a new identity key pair.
|
|
46
|
+
* Does not persist automatically - call saveIdentity() to persist.
|
|
47
|
+
* @returns {KeyPair} New identity key pair
|
|
48
|
+
*/
|
|
49
|
+
generateIdentity() {
|
|
50
|
+
// Destroy existing identity if present
|
|
51
|
+
if (this._identity) {
|
|
52
|
+
this._identity.destroy();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this._identity = KeyPair.generate();
|
|
56
|
+
return this._identity;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets the current identity, generating one if needed.
|
|
61
|
+
* If storage is configured, attempts to load from storage first.
|
|
62
|
+
* @returns {Promise<KeyPair>} Current or new identity
|
|
63
|
+
*/
|
|
64
|
+
async getOrCreateIdentity() {
|
|
65
|
+
// Return existing identity if available
|
|
66
|
+
if (this._identity && !this._identity.isDestroyed()) {
|
|
67
|
+
return this._identity;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Try to load from storage
|
|
71
|
+
if (this._storage) {
|
|
72
|
+
const loaded = await this.loadIdentity();
|
|
73
|
+
if (loaded) {
|
|
74
|
+
return loaded;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Generate new identity
|
|
79
|
+
this.generateIdentity();
|
|
80
|
+
|
|
81
|
+
// Persist if storage is available
|
|
82
|
+
if (this._storage) {
|
|
83
|
+
await this.saveIdentity();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return this._identity;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Gets the current identity without generating.
|
|
91
|
+
* @returns {KeyPair|null} Current identity or null
|
|
92
|
+
*/
|
|
93
|
+
getIdentity() {
|
|
94
|
+
if (this._identity && !this._identity.isDestroyed()) {
|
|
95
|
+
return this._identity;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Gets the public key of the current identity.
|
|
102
|
+
* @returns {Uint8Array|null} Public key or null if no identity
|
|
103
|
+
*/
|
|
104
|
+
getPublicKey() {
|
|
105
|
+
const identity = this.getIdentity();
|
|
106
|
+
return identity ? identity.publicKey : null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Saves the current identity to storage.
|
|
111
|
+
* @returns {Promise<boolean>} True if saved successfully
|
|
112
|
+
* @throws {Error} If no identity or storage not configured
|
|
113
|
+
*/
|
|
114
|
+
async saveIdentity() {
|
|
115
|
+
if (!this._identity) {
|
|
116
|
+
throw new Error('No identity to save');
|
|
117
|
+
}
|
|
118
|
+
if (!this._storage) {
|
|
119
|
+
throw new Error('Storage not configured');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const data = {
|
|
123
|
+
keyPair: this._identity.export(),
|
|
124
|
+
displayName: this._displayName,
|
|
125
|
+
createdAt: Date.now()
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
await this._storage.set(this._identityKey, JSON.stringify(data));
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Loads identity from storage.
|
|
134
|
+
* @returns {Promise<KeyPair|null>} Loaded identity or null
|
|
135
|
+
*/
|
|
136
|
+
async loadIdentity() {
|
|
137
|
+
if (!this._storage) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const data = await this._storage.get(this._identityKey);
|
|
143
|
+
if (!data) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const parsed = JSON.parse(data);
|
|
148
|
+
if (!parsed.keyPair) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this._identity = KeyPair.fromExported(parsed.keyPair);
|
|
153
|
+
this._displayName = parsed.displayName || null;
|
|
154
|
+
|
|
155
|
+
return this._identity;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
console.warn('Failed to load identity:', error.message);
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Imports an identity from exported data.
|
|
164
|
+
* @param {object} exported - Exported identity data
|
|
165
|
+
* @param {object} exported.publicKey - Public key as byte array
|
|
166
|
+
* @param {object} exported.secretKey - Secret key as byte array
|
|
167
|
+
* @returns {KeyPair} Imported identity
|
|
168
|
+
*/
|
|
169
|
+
importIdentity(exported) {
|
|
170
|
+
// Destroy existing identity
|
|
171
|
+
if (this._identity) {
|
|
172
|
+
this._identity.destroy();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
this._identity = KeyPair.fromExported(exported);
|
|
176
|
+
return this._identity;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Exports the current identity for backup.
|
|
181
|
+
* WARNING: Contains sensitive key material.
|
|
182
|
+
* @returns {object|null} Exported identity or null
|
|
183
|
+
*/
|
|
184
|
+
exportIdentity() {
|
|
185
|
+
if (!this._identity || this._identity.isDestroyed()) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
...this._identity.export(),
|
|
191
|
+
displayName: this._displayName
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Sets the display name for this identity.
|
|
197
|
+
* @param {string} name - Display name
|
|
198
|
+
*/
|
|
199
|
+
setDisplayName(name) {
|
|
200
|
+
if (typeof name !== 'string') {
|
|
201
|
+
throw new Error('Display name must be a string');
|
|
202
|
+
}
|
|
203
|
+
this._displayName = name;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Gets the display name.
|
|
208
|
+
* @returns {string|null} Display name or null
|
|
209
|
+
*/
|
|
210
|
+
getDisplayName() {
|
|
211
|
+
return this._displayName;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Deletes the identity from storage and memory.
|
|
216
|
+
* @returns {Promise<void>}
|
|
217
|
+
*/
|
|
218
|
+
async deleteIdentity() {
|
|
219
|
+
if (this._identity) {
|
|
220
|
+
this._identity.destroy();
|
|
221
|
+
this._identity = null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
this._displayName = null;
|
|
225
|
+
|
|
226
|
+
if (this._storage) {
|
|
227
|
+
await this._storage.delete(this._identityKey);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Checks if an identity exists (in memory or storage).
|
|
233
|
+
* @returns {Promise<boolean>} True if identity exists
|
|
234
|
+
*/
|
|
235
|
+
async hasIdentity() {
|
|
236
|
+
if (this._identity && !this._identity.isDestroyed()) {
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (this._storage) {
|
|
241
|
+
const data = await this._storage.get(this._identityKey);
|
|
242
|
+
return data !== null && data !== undefined;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Sets the storage adapter.
|
|
250
|
+
* @param {object} storage - Storage adapter implementing SecureStorage interface
|
|
251
|
+
*/
|
|
252
|
+
setStorage(storage) {
|
|
253
|
+
this._storage = storage;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Clears all in-memory data (does not affect storage).
|
|
258
|
+
*/
|
|
259
|
+
clear() {
|
|
260
|
+
if (this._identity) {
|
|
261
|
+
this._identity.destroy();
|
|
262
|
+
this._identity = null;
|
|
263
|
+
}
|
|
264
|
+
this._displayName = null;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
module.exports = {
|
|
269
|
+
KeyManager,
|
|
270
|
+
DEFAULT_IDENTITY_KEY
|
|
271
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* KeyPair class for X25519 key management.
|
|
5
|
+
* Provides a secure wrapper around public/private key pairs.
|
|
6
|
+
* @module crypto/keys/KeyPair
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { generateKeyPair: x25519GenerateKeyPair, scalarMultBase } = require('../x25519');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Key size in bytes (X25519)
|
|
13
|
+
* @constant {number}
|
|
14
|
+
*/
|
|
15
|
+
const KEY_SIZE = 32;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* KeyPair represents an X25519 key pair for Noise Protocol handshakes.
|
|
19
|
+
* Provides secure key management with proper cleanup.
|
|
20
|
+
*
|
|
21
|
+
* @class
|
|
22
|
+
*/
|
|
23
|
+
class KeyPair {
|
|
24
|
+
/**
|
|
25
|
+
* Creates a KeyPair instance.
|
|
26
|
+
* Use static factory methods instead of constructor directly.
|
|
27
|
+
* @param {Uint8Array} publicKey - 32-byte public key
|
|
28
|
+
* @param {Uint8Array} secretKey - 32-byte secret key
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
constructor(publicKey, secretKey) {
|
|
32
|
+
if (!(publicKey instanceof Uint8Array) || publicKey.length !== KEY_SIZE) {
|
|
33
|
+
throw new Error(`Public key must be ${KEY_SIZE} bytes`);
|
|
34
|
+
}
|
|
35
|
+
if (!(secretKey instanceof Uint8Array) || secretKey.length !== KEY_SIZE) {
|
|
36
|
+
throw new Error(`Secret key must be ${KEY_SIZE} bytes`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @type {Uint8Array} */
|
|
40
|
+
this._publicKey = new Uint8Array(publicKey);
|
|
41
|
+
|
|
42
|
+
/** @type {Uint8Array} */
|
|
43
|
+
this._secretKey = new Uint8Array(secretKey);
|
|
44
|
+
|
|
45
|
+
/** @type {boolean} */
|
|
46
|
+
this._destroyed = false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Gets the public key.
|
|
51
|
+
* @returns {Uint8Array} Copy of the public key
|
|
52
|
+
* @throws {Error} If key pair has been destroyed
|
|
53
|
+
*/
|
|
54
|
+
get publicKey() {
|
|
55
|
+
this._checkDestroyed();
|
|
56
|
+
return new Uint8Array(this._publicKey);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Gets the secret key.
|
|
61
|
+
* @returns {Uint8Array} Copy of the secret key
|
|
62
|
+
* @throws {Error} If key pair has been destroyed
|
|
63
|
+
*/
|
|
64
|
+
get secretKey() {
|
|
65
|
+
this._checkDestroyed();
|
|
66
|
+
return new Uint8Array(this._secretKey);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Generates a new random X25519 key pair.
|
|
71
|
+
* @returns {KeyPair} New key pair
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* const keyPair = KeyPair.generate();
|
|
75
|
+
* console.log('Public key:', keyPair.publicKey);
|
|
76
|
+
*/
|
|
77
|
+
static generate() {
|
|
78
|
+
const { publicKey, secretKey } = x25519GenerateKeyPair();
|
|
79
|
+
return new KeyPair(publicKey, secretKey);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Creates a KeyPair from an existing secret key.
|
|
84
|
+
* Derives the public key from the secret key.
|
|
85
|
+
* @param {Uint8Array} secretKey - 32-byte secret key
|
|
86
|
+
* @returns {KeyPair} Key pair with derived public key
|
|
87
|
+
* @throws {Error} If secret key is invalid
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* const restored = KeyPair.fromSecretKey(storedSecretKey);
|
|
91
|
+
*/
|
|
92
|
+
static fromSecretKey(secretKey) {
|
|
93
|
+
if (!(secretKey instanceof Uint8Array) || secretKey.length !== KEY_SIZE) {
|
|
94
|
+
throw new Error(`Secret key must be ${KEY_SIZE} bytes`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const publicKey = scalarMultBase(secretKey);
|
|
98
|
+
return new KeyPair(publicKey, secretKey);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Creates a KeyPair from exported key material.
|
|
103
|
+
* @param {object} exported - Exported key object
|
|
104
|
+
* @param {number[]} exported.publicKey - Public key as byte array
|
|
105
|
+
* @param {number[]} exported.secretKey - Secret key as byte array
|
|
106
|
+
* @returns {KeyPair} Restored key pair
|
|
107
|
+
* @throws {Error} If exported data is invalid
|
|
108
|
+
*/
|
|
109
|
+
static fromExported(exported) {
|
|
110
|
+
if (!exported || typeof exported !== 'object') {
|
|
111
|
+
throw new Error('Invalid exported key data');
|
|
112
|
+
}
|
|
113
|
+
if (!Array.isArray(exported.publicKey) || !Array.isArray(exported.secretKey)) {
|
|
114
|
+
throw new Error('Exported data must contain publicKey and secretKey arrays');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const publicKey = new Uint8Array(exported.publicKey);
|
|
118
|
+
const secretKey = new Uint8Array(exported.secretKey);
|
|
119
|
+
|
|
120
|
+
return new KeyPair(publicKey, secretKey);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Exports the key pair for storage.
|
|
125
|
+
* WARNING: The exported data contains sensitive key material.
|
|
126
|
+
* @returns {object} Exportable key object
|
|
127
|
+
*/
|
|
128
|
+
export() {
|
|
129
|
+
this._checkDestroyed();
|
|
130
|
+
return {
|
|
131
|
+
publicKey: Array.from(this._publicKey),
|
|
132
|
+
secretKey: Array.from(this._secretKey)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Exports only the public key (safe to share).
|
|
138
|
+
* @returns {object} Object containing only the public key
|
|
139
|
+
*/
|
|
140
|
+
exportPublic() {
|
|
141
|
+
this._checkDestroyed();
|
|
142
|
+
return {
|
|
143
|
+
publicKey: Array.from(this._publicKey)
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Checks if this key pair matches another by public key.
|
|
149
|
+
* @param {KeyPair} other - Another key pair to compare
|
|
150
|
+
* @returns {boolean} True if public keys match
|
|
151
|
+
*/
|
|
152
|
+
matches(other) {
|
|
153
|
+
this._checkDestroyed();
|
|
154
|
+
if (!(other instanceof KeyPair)) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const otherPublic = other.publicKey;
|
|
159
|
+
if (otherPublic.length !== this._publicKey.length) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Constant-time comparison
|
|
164
|
+
let diff = 0;
|
|
165
|
+
for (let i = 0; i < this._publicKey.length; i++) {
|
|
166
|
+
diff |= this._publicKey[i] ^ otherPublic[i];
|
|
167
|
+
}
|
|
168
|
+
return diff === 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Gets the public key as a hex string (useful for display/logging).
|
|
173
|
+
* @returns {string} Hex-encoded public key
|
|
174
|
+
*/
|
|
175
|
+
getPublicKeyHex() {
|
|
176
|
+
this._checkDestroyed();
|
|
177
|
+
return Array.from(this._publicKey)
|
|
178
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
179
|
+
.join('');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Securely destroys the key pair, zeroing sensitive material.
|
|
184
|
+
* After destruction, the key pair cannot be used.
|
|
185
|
+
*/
|
|
186
|
+
destroy() {
|
|
187
|
+
if (!this._destroyed) {
|
|
188
|
+
this._secretKey.fill(0);
|
|
189
|
+
this._publicKey.fill(0);
|
|
190
|
+
this._destroyed = true;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Checks if the key pair has been destroyed.
|
|
196
|
+
* @returns {boolean} True if destroyed
|
|
197
|
+
*/
|
|
198
|
+
isDestroyed() {
|
|
199
|
+
return this._destroyed;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Throws if the key pair has been destroyed.
|
|
204
|
+
* @private
|
|
205
|
+
*/
|
|
206
|
+
_checkDestroyed() {
|
|
207
|
+
if (this._destroyed) {
|
|
208
|
+
throw new Error('Key pair has been destroyed');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
module.exports = {
|
|
214
|
+
KeyPair,
|
|
215
|
+
KEY_SIZE
|
|
216
|
+
};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SecureStorage - Abstract storage interface for sensitive key material.
|
|
5
|
+
* Implementations should use platform-specific secure storage mechanisms.
|
|
6
|
+
* @module crypto/keys/SecureStorage
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* SecureStorage defines the interface for secure key storage.
|
|
11
|
+
* This is an abstract class - use platform-specific implementations.
|
|
12
|
+
*
|
|
13
|
+
* Platform implementations:
|
|
14
|
+
* - React Native: Use react-native-keychain or expo-secure-store
|
|
15
|
+
* - Node.js: Use encrypted file storage or keytar
|
|
16
|
+
* - Browser: Use IndexedDB with encryption
|
|
17
|
+
*
|
|
18
|
+
* @abstract
|
|
19
|
+
* @class
|
|
20
|
+
*/
|
|
21
|
+
class SecureStorage {
|
|
22
|
+
/**
|
|
23
|
+
* Stores a value securely.
|
|
24
|
+
* @param {string} key - Storage key
|
|
25
|
+
* @param {string} value - Value to store (should be serialized JSON)
|
|
26
|
+
* @returns {Promise<void>}
|
|
27
|
+
* @abstract
|
|
28
|
+
*/
|
|
29
|
+
async set(_key, _value) {
|
|
30
|
+
throw new Error('SecureStorage.set() must be implemented');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Retrieves a stored value.
|
|
35
|
+
* @param {string} key - Storage key
|
|
36
|
+
* @returns {Promise<string|null>} Stored value or null if not found
|
|
37
|
+
* @abstract
|
|
38
|
+
*/
|
|
39
|
+
async get(_key) {
|
|
40
|
+
throw new Error('SecureStorage.get() must be implemented');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Deletes a stored value.
|
|
45
|
+
* @param {string} key - Storage key
|
|
46
|
+
* @returns {Promise<void>}
|
|
47
|
+
* @abstract
|
|
48
|
+
*/
|
|
49
|
+
async delete(_key) {
|
|
50
|
+
throw new Error('SecureStorage.delete() must be implemented');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Checks if a key exists in storage.
|
|
55
|
+
* @param {string} key - Storage key
|
|
56
|
+
* @returns {Promise<boolean>} True if key exists
|
|
57
|
+
*/
|
|
58
|
+
async has(key) {
|
|
59
|
+
const value = await this.get(key);
|
|
60
|
+
return value !== null && value !== undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Clears all stored values.
|
|
65
|
+
* @returns {Promise<void>}
|
|
66
|
+
* @abstract
|
|
67
|
+
*/
|
|
68
|
+
async clear() {
|
|
69
|
+
throw new Error('SecureStorage.clear() must be implemented');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* MemorySecureStorage - In-memory implementation for testing.
|
|
75
|
+
* WARNING: Not secure for production use - keys are not persisted
|
|
76
|
+
* and are stored in plain memory.
|
|
77
|
+
*
|
|
78
|
+
* @class
|
|
79
|
+
* @extends SecureStorage
|
|
80
|
+
*/
|
|
81
|
+
class MemorySecureStorage extends SecureStorage {
|
|
82
|
+
constructor() {
|
|
83
|
+
super();
|
|
84
|
+
/** @type {Map<string, string>} */
|
|
85
|
+
this._store = new Map();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Stores a value in memory.
|
|
90
|
+
* @param {string} key - Storage key
|
|
91
|
+
* @param {string} value - Value to store
|
|
92
|
+
* @returns {Promise<void>}
|
|
93
|
+
*/
|
|
94
|
+
async set(key, value) {
|
|
95
|
+
if (typeof key !== 'string') {
|
|
96
|
+
throw new Error('Key must be a string');
|
|
97
|
+
}
|
|
98
|
+
if (typeof value !== 'string') {
|
|
99
|
+
throw new Error('Value must be a string');
|
|
100
|
+
}
|
|
101
|
+
this._store.set(key, value);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Retrieves a value from memory.
|
|
106
|
+
* @param {string} key - Storage key
|
|
107
|
+
* @returns {Promise<string|null>} Stored value or null
|
|
108
|
+
*/
|
|
109
|
+
async get(key) {
|
|
110
|
+
if (typeof key !== 'string') {
|
|
111
|
+
throw new Error('Key must be a string');
|
|
112
|
+
}
|
|
113
|
+
return this._store.get(key) || null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Deletes a value from memory.
|
|
118
|
+
* @param {string} key - Storage key
|
|
119
|
+
* @returns {Promise<void>}
|
|
120
|
+
*/
|
|
121
|
+
async delete(key) {
|
|
122
|
+
if (typeof key !== 'string') {
|
|
123
|
+
throw new Error('Key must be a string');
|
|
124
|
+
}
|
|
125
|
+
this._store.delete(key);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Clears all stored values.
|
|
130
|
+
* @returns {Promise<void>}
|
|
131
|
+
*/
|
|
132
|
+
async clear() {
|
|
133
|
+
this._store.clear();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Gets the number of stored items.
|
|
138
|
+
* @returns {number} Number of items
|
|
139
|
+
*/
|
|
140
|
+
get size() {
|
|
141
|
+
return this._store.size;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates a SecureStorage adapter for React Native AsyncStorage.
|
|
147
|
+
* Note: AsyncStorage is NOT secure - consider using expo-secure-store
|
|
148
|
+
* or react-native-keychain for production.
|
|
149
|
+
*
|
|
150
|
+
* @param {object} asyncStorage - AsyncStorage instance
|
|
151
|
+
* @returns {SecureStorage} Storage adapter
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
155
|
+
* const storage = createAsyncStorageAdapter(AsyncStorage);
|
|
156
|
+
*/
|
|
157
|
+
function createAsyncStorageAdapter(asyncStorage) {
|
|
158
|
+
return {
|
|
159
|
+
async set(key, value) {
|
|
160
|
+
await asyncStorage.setItem(key, value);
|
|
161
|
+
},
|
|
162
|
+
async get(key) {
|
|
163
|
+
return await asyncStorage.getItem(key);
|
|
164
|
+
},
|
|
165
|
+
async delete(key) {
|
|
166
|
+
await asyncStorage.removeItem(key);
|
|
167
|
+
},
|
|
168
|
+
async has(key) {
|
|
169
|
+
const value = await asyncStorage.getItem(key);
|
|
170
|
+
return value !== null;
|
|
171
|
+
},
|
|
172
|
+
async clear() {
|
|
173
|
+
// Only clear mesh-related keys
|
|
174
|
+
const keys = await asyncStorage.getAllKeys();
|
|
175
|
+
const meshKeys = keys.filter(k => k.startsWith('mesh_'));
|
|
176
|
+
await asyncStorage.multiRemove(meshKeys);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Creates a SecureStorage adapter for expo-secure-store.
|
|
183
|
+
* This provides actual secure storage on iOS/Android.
|
|
184
|
+
*
|
|
185
|
+
* @param {object} secureStore - SecureStore module from expo-secure-store
|
|
186
|
+
* @returns {SecureStorage} Storage adapter
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* import * as SecureStore from 'expo-secure-store';
|
|
190
|
+
* const storage = createExpoSecureStoreAdapter(SecureStore);
|
|
191
|
+
*/
|
|
192
|
+
function createExpoSecureStoreAdapter(secureStore) {
|
|
193
|
+
return {
|
|
194
|
+
async set(key, value) {
|
|
195
|
+
await secureStore.setItemAsync(key, value);
|
|
196
|
+
},
|
|
197
|
+
async get(key) {
|
|
198
|
+
return await secureStore.getItemAsync(key);
|
|
199
|
+
},
|
|
200
|
+
async delete(key) {
|
|
201
|
+
await secureStore.deleteItemAsync(key);
|
|
202
|
+
},
|
|
203
|
+
async has(key) {
|
|
204
|
+
const value = await secureStore.getItemAsync(key);
|
|
205
|
+
return value !== null;
|
|
206
|
+
},
|
|
207
|
+
async clear() {
|
|
208
|
+
// expo-secure-store doesn't have getAllKeys, so we track known keys
|
|
209
|
+
console.warn('SecureStore clear() requires manual key tracking');
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
module.exports = {
|
|
215
|
+
SecureStorage,
|
|
216
|
+
MemorySecureStorage,
|
|
217
|
+
createAsyncStorageAdapter,
|
|
218
|
+
createExpoSecureStoreAdapter
|
|
219
|
+
};
|