feat: implement NIP-BE Nostr BLE Communications Protocol in Quartz

Adds full NIP-BE implementation for BLE-based Nostr peer-to-peer
messaging and synchronization with KMP support across all targets.

Protocol layer (commonMain):
- BleConfig: NIP-BE constants (service UUID, characteristic UUIDs)
- BleMessageChunker: DEFLATE compression + chunk splitting/joining
- BleRole/assignRole: Role assignment based on UUID comparison
- BleTransport: Platform-agnostic BLE transport interface
- BleNostrClient: IRelayClient implementation over BLE
- BleNostrServer: Relay server over BLE with notification support
- BleMeshManager: High-level mesh manager with auto-discovery,
  role assignment, and event broadcasting
- BleChunkAssembler: Thread-safe chunk reassembly

Platform support:
- Deflate expect/actual for jvmAndroid, apple, and linux targets
- AndroidBleTransport: Full Android BLE implementation using GATT
  server/client APIs with scanning, advertising, and MTU negotiation

Tests: Deflate compression, message chunking, role assignment,
and chunk assembly (25 tests passing).

https://claude.ai/code/session_01Tz5E73Rj7tL48A3qUGS5DT
This commit is contained in:
Claude
2026-03-30 01:58:26 +00:00
parent 207fc6beba
commit fb78c1a4c4
18 changed files with 2379 additions and 0 deletions
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2025 Vitor Pamplona
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
* Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.vitorpamplona.quartz.utils
import java.io.ByteArrayOutputStream
import java.util.zip.Deflater
import java.util.zip.Inflater
actual object Deflate {
actual fun compress(input: ByteArray): ByteArray {
val deflater = Deflater(Deflater.DEFAULT_COMPRESSION, true)
try {
deflater.setInput(input)
deflater.finish()
val bos = ByteArrayOutputStream(input.size)
val buffer = ByteArray(4096)
while (!deflater.finished()) {
val count = deflater.deflate(buffer)
bos.write(buffer, 0, count)
}
return bos.toByteArray()
} finally {
deflater.end()
}
}
actual fun decompress(input: ByteArray): ByteArray {
val inflater = Inflater(true)
try {
inflater.setInput(input)
val bos = ByteArrayOutputStream(input.size * 2)
val buffer = ByteArray(4096)
while (!inflater.finished()) {
val count = inflater.inflate(buffer)
if (count == 0 && inflater.needsInput()) break
bos.write(buffer, 0, count)
}
return bos.toByteArray()
} finally {
inflater.end()
}
}
}