* Fix fragmentation + BLE long-write + padding
- Accumulate CBATTRequest long writes by offset and decode once per central
- Decode original packet after fragment reassembly (preserve flags/compression)
- Switch MessagePadding to strict PKCS#7 and validate before unpadding
- Make BinaryProtocol.decode robust: try raw first, then unpad fallback
- Unpad frames before BLE notify; fragment when exceeding centrals' max update length
- Skip notify path when max update length < 21 bytes (protocol minimum)
Verified large PMs and announces route without decode errors and peers show reliably.
* Tests: fix weak delegate lifetime, legacy constants, and unused vars; fragment unpadded frames
- BLEServiceTests: hold strong reference to MockBitchatDelegate
- IntegrationTests: fix inline comment braces; replace removed types with test-safe values; use numeric 0x06 for legacy handshake resp checks
- BinaryProtocolTests: remove unused minResult variable
- BLEService: fragment the unpadded frame so fragments are efficient
* tests: add Noise rehandshake recovery test; document in-memory test bus and autoFlood; stabilize large-network broadcast
* tests: align suite with current behavior (compression, padding, routing, nonce); deflake and stabilize
---------
Co-authored-by: jack <jackjackbits@users.noreply.github.com>
* Refactor: move Nostr embedding and TLVs out of BLE; add NostrEmbeddedBitChat, Packets, PeerIDUtils; centralize MessageDeduplicator; update ChatViewModel to use new helpers; remove AI_CONTEXT.md and CLAUDE.md
* Rename class to BLEService with compatibility alias; move mention parsing out of BLE; emit low-level BLE events to delegate; unify hex helpers; accept 64-hex in isPeerConnected; add PeerIDResolver
* Project: rename file to BLEService.swift and update Xcode project; keep typealias SimplifiedBluetoothService = BLEService for compatibility
* Remove SimplifiedBluetoothService alias; update app code to use BLEService explicitly
* Tests: rename MockSimplifiedBluetoothService to MockBLEService; update typealiases and Xcode project
* Docs: update comments to refer to BLEService (tests, protocol, noise service)
* Tests: rename SimplifiedBluetoothServiceTests to BLEServiceTests; update project references and class names
* Introduce Transport protocol; BLEService conforms; document delegate-only event pattern in BLEService; keep publishers internal for UnifiedPeerService
* Adopt Transport end-to-end: add TransportPeerSnapshot + publishers; BLEService maps to Transport snapshots; UnifiedPeerService consumes Transport; ChatViewModel holds Transport
* Fix Transport integration: replace getPeerFingerprint with getFingerprint(for:); update PrivateChatManager and CommandProcessor to use Transport; add BLEService.getFingerprint(for:); update PeerManager to use Transport
* Refactor transport and BLE/Nostr layers; unify UI events; fix MainActor isolation
- Rename SimplifiedBluetoothService to BLEService and slim responsibilities
- Introduce Transport protocol and peerEventsDelegate for UI updates
- Add NostrTransport and MessageRouter to route PM/read/favorite via BLE or Nostr
- Centralize TLVs, PeerID utils, and MessageDeduplicator outside BLE
- Update UnifiedPeerService and ChatViewModel to use Transport and delegate events
- Fix MainActor isolation: route delegate calls via Task on MainActor; update notifyUI helper
- Adjust related files and tests accordingly
* BLEService: remove internal publishers; switch to delegate-only events
- Drop legacy messages/peers/fullPeers publishers
- Provide lightweight peerSnapshotSubject only to satisfy Transport
- Rework publishFullPeerData to build snapshots from internal state and notify delegate + subject
- Remove all peersPublisher.send call sites
- Keep UnifiedPeerService on delegate updates exclusively
* Remove inlined Nostr send helpers from ChatViewModel; route via MessageRouter
- Replace direct Nostr sends (PM, ACKs, favorites) with MessageRouter
- Add router method for delivery ACKs and implement NostrTransport.sendDeliveryAck
- Simplify ChatViewModel favorite notification path to use router
- Keep Nostr receive handling intact; reduce duplication
* Fix ReadReceipt initializer usage in ChatViewModel (readerID + readerNickname)
* Fix unused variable warning: replace shadowed 'nostrPubkey' bind with boolean check in ChatViewModel
* Fix queued PM format: use TLV for pending messages after Noise handshake
- Pending messages (including first-time favorite notifications) now use the same TLV encoding as normal sends
- Ensures ChatViewModel can decode on first send, even if handshake completes after queuing
---------
Co-authored-by: jack <jackjackbits@users.noreply.github.com>