Refactor/robustness (#446)

* Refactor BitChat for improved robustness and performance

Major refactoring to simplify architecture and fix critical issues:

Architecture Improvements:
- Replace complex BluetoothMeshService with simplified SimplifiedBluetoothService
- Consolidate message routing and peer management into unified services
- Remove redundant caching layers and optimize performance

Bug Fixes:
- Fix critical BLE peer mapping corruption in mesh networks
- Fix encrypted message routing failures in multi-peer scenarios
- Fix app freezes and Main Thread Checker warnings
- Fix BLE message delivery in dual-role connections
- Fix favorite toggle UI not updating instantly
- Fix Nostr offline messaging with 24-hour message filtering

Features:
- Add command processor for chat commands
- Add autocomplete service for mentions and commands
- Improve private chat management with dedicated service
- Add unified peer service for consistent state management

Performance:
- Optimize BLE reconnection speed
- Reduce excessive logging throughout codebase
- Improve message deduplication efficiency
- Optimize UI updates and state management

* Improvements refactor robust (#441)

* remove unused code

* remove more

* TLV for announcement

* restore

* restore

* restore?

* messages tlv too (#442)

* Fix Nostr notification and read receipt issues, add TLV encoding, cleanup unused code

## Notification & Read Receipt Fixes
- Fixed toolbar notification icon appearing incorrectly on app restart for already-read messages
- Fixed read receipts being incorrectly deleted on startup when privateChats was empty
- Fixed messages not being marked as read when opening chat for first time
- Fixed senderPeerID not being updated during message consolidation
- Added startup phase logic to block old messages (>30s) while allowing recent ones
- Fixed unread status checking across all storage locations (ephemeral, stable Noise keys, temporary Nostr IDs)

## TLV Encoding Implementation
- Implemented Type-Length-Value encoding for private message payloads
- Added PrivateMessagePacket struct with TLV encode/decode methods
- Enhanced message structure for better extensibility and robustness

## Code Cleanup
- Removed unused PeerStateManager class and related dependencies
- Removed dead protocol types (DeliveryAck, ProtocolAck/Nack, NoiseIdentityAnnouncement)
- Cleaned up BitchatDelegate by removing unused methods
- Removed excessive debug logging throughout ChatViewModel
- Added test-only ProtocolNack helper for integration tests

## Technical Details
- Messages stored under three ID types: ephemeral peer IDs, stable Noise key hexes, temporary Nostr IDs
- Fixed cleanupOldReadReceipts() to skip when privateChats is empty or during startup
- Updated message consolidation to properly update senderPeerID
- Restored NIP-17 timestamp randomization (±15 minutes) for privacy

---------

Co-authored-by: jack <jackjackbits@users.noreply.github.com>
Co-authored-by: callebtc <93376500+callebtc@users.noreply.github.com>
This commit is contained in:
jack
2025-08-17 01:51:54 +02:00
committed by GitHub
co-authored by jack callebtc
parent 47b0829685
commit 845ffc601b
38 changed files with 6423 additions and 12246 deletions
+10 -6
View File
@@ -13,8 +13,7 @@ final class NostrProtocolTests: XCTestCase {
override func setUp() {
super.setUp()
// Enable secure logging for tests
SecureLogger.enableLogging()
// SecureLogger is always enabled
}
func testNIP17MessageRoundTrip() throws {
@@ -39,7 +38,7 @@ final class NostrProtocolTests: XCTestCase {
print("Gift wrap pubkey: \(giftWrap.pubkey)")
// Decrypt the gift wrap
let (decryptedContent, senderPubkey) = try NostrProtocol.decryptPrivateMessage(
let (decryptedContent, senderPubkey, timestamp) = try NostrProtocol.decryptPrivateMessage(
giftWrap: giftWrap,
recipientIdentity: recipient
)
@@ -48,7 +47,12 @@ final class NostrProtocolTests: XCTestCase {
XCTAssertEqual(decryptedContent, originalContent)
XCTAssertEqual(senderPubkey, sender.publicKeyHex)
print("✅ Successfully decrypted message: '\(decryptedContent)' from \(senderPubkey)")
// Verify timestamp is reasonable (within last minute)
let messageDate = Date(timeIntervalSince1970: TimeInterval(timestamp))
let timeDiff = abs(messageDate.timeIntervalSinceNow)
XCTAssertLessThan(timeDiff, 60, "Message timestamp should be recent")
print("✅ Successfully decrypted message: '\(decryptedContent)' from \(senderPubkey) at \(messageDate)")
}
func testGiftWrapUsesUniqueEphemeralKeys() throws {
@@ -75,11 +79,11 @@ final class NostrProtocolTests: XCTestCase {
print("Message 2 gift wrap pubkey: \(message2.pubkey)")
// Both should decrypt successfully
let (content1, _) = try NostrProtocol.decryptPrivateMessage(
let (content1, _, _) = try NostrProtocol.decryptPrivateMessage(
giftWrap: message1,
recipientIdentity: recipient
)
let (content2, _) = try NostrProtocol.decryptPrivateMessage(
let (content2, _, _) = try NostrProtocol.decryptPrivateMessage(
giftWrap: message2,
recipientIdentity: recipient
)