mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-24 23:45:18 +00:00
PeerID 21/n: UnifiedPeerService (#772)
This commit is contained in:
@@ -18,14 +18,14 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
// MARK: - Published Properties
|
||||
|
||||
@Published private(set) var peers: [BitchatPeer] = []
|
||||
@Published private(set) var connectedPeerIDs: Set<String> = []
|
||||
@Published private(set) var connectedPeerIDs: Set<PeerID> = []
|
||||
@Published private(set) var favorites: [BitchatPeer] = []
|
||||
@Published private(set) var mutualFavorites: [BitchatPeer] = []
|
||||
|
||||
// MARK: - Private Properties
|
||||
|
||||
private var peerIndex: [String: BitchatPeer] = [:]
|
||||
private var fingerprintCache: [String: String] = [:] // peerID -> fingerprint
|
||||
private var peerIndex: [PeerID: BitchatPeer] = [:]
|
||||
private var fingerprintCache: [PeerID: String] = [:]
|
||||
private let meshService: Transport
|
||||
private let identityManager: SecureIdentityStateManagerProtocol
|
||||
weak var messageRouter: MessageRouter?
|
||||
@@ -97,7 +97,7 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
|
||||
// Update fingerprint cache
|
||||
if let publicKey = peerInfo.noisePublicKey {
|
||||
fingerprintCache[peerID.id] = publicKey.sha256Fingerprint()
|
||||
fingerprintCache[peerID] = publicKey.sha256Fingerprint()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,12 +114,12 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
}
|
||||
if isConnectedByNickname { continue }
|
||||
|
||||
let peer = buildPeerFromFavorite(favorite: favorite, peerID: peerID.id)
|
||||
let peer = buildPeerFromFavorite(favorite: favorite, peerID: peerID)
|
||||
enrichedPeers.append(peer)
|
||||
addedPeerIDs.insert(peerID)
|
||||
|
||||
// Update fingerprint cache
|
||||
fingerprintCache[peerID.id] = favoriteKey.sha256Fingerprint()
|
||||
fingerprintCache[peerID] = favoriteKey.sha256Fingerprint()
|
||||
}
|
||||
|
||||
// Phase 3: Sort peers
|
||||
@@ -137,10 +137,10 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
// Phase 4: Build subsets and indices
|
||||
var favoritesList: [BitchatPeer] = []
|
||||
var mutualsList: [BitchatPeer] = []
|
||||
var newIndex: [String: BitchatPeer] = [:]
|
||||
var newIndex: [PeerID: BitchatPeer] = [:]
|
||||
|
||||
for peer in enrichedPeers {
|
||||
newIndex[peer.peerID.id] = peer
|
||||
newIndex[peer.peerID] = peer
|
||||
|
||||
if peer.isFavorite {
|
||||
favoritesList.append(peer)
|
||||
@@ -155,7 +155,7 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
p.isConnected || p.isReachable || p.isMutualFavorite
|
||||
}
|
||||
self.peers = filtered
|
||||
self.connectedPeerIDs = Set(connected.map(\.id))
|
||||
self.connectedPeerIDs = connected
|
||||
self.favorites = favoritesList
|
||||
self.mutualFavorites = mutualsList
|
||||
self.peerIndex = newIndex
|
||||
@@ -204,10 +204,10 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
|
||||
private func buildPeerFromFavorite(
|
||||
favorite: FavoritesPersistenceService.FavoriteRelationship,
|
||||
peerID: String
|
||||
peerID: PeerID
|
||||
) -> BitchatPeer {
|
||||
var peer = BitchatPeer(
|
||||
peerID: PeerID(str: peerID),
|
||||
peerID: peerID,
|
||||
noisePublicKey: favorite.peerNoisePublicKey,
|
||||
nickname: favorite.peerNickname,
|
||||
lastSeen: favorite.lastUpdated,
|
||||
@@ -224,8 +224,8 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
// MARK: - Public Methods
|
||||
|
||||
/// Get peer by ID
|
||||
func getPeer(by id: String) -> BitchatPeer? {
|
||||
return peerIndex[id]
|
||||
func getPeer(by peerID: PeerID) -> BitchatPeer? {
|
||||
return peerIndex[peerID]
|
||||
}
|
||||
|
||||
/// Get peer ID for nickname
|
||||
@@ -238,13 +238,8 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Check if peer is online
|
||||
func isOnline(_ peerID: String) -> Bool {
|
||||
return connectedPeerIDs.contains(peerID)
|
||||
}
|
||||
|
||||
/// Check if peer is blocked
|
||||
func isBlocked(_ peerID: String) -> Bool {
|
||||
func isBlocked(_ peerID: PeerID) -> Bool {
|
||||
// Get fingerprint
|
||||
guard let fingerprint = getFingerprint(for: peerID) else { return false }
|
||||
|
||||
@@ -257,8 +252,8 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
}
|
||||
|
||||
/// Toggle favorite status
|
||||
func toggleFavorite(_ peerID: String) {
|
||||
guard let peer = getPeer(by: peerID) else {
|
||||
func toggleFavorite(_ peerID: PeerID) {
|
||||
guard let peer = getPeer(by: peerID) else {
|
||||
SecureLogger.warning("⚠️ Cannot toggle favorite - peer not found: \(peerID)", category: .session)
|
||||
return
|
||||
}
|
||||
@@ -273,7 +268,7 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
|
||||
if actualNickname.isEmpty {
|
||||
// Try to get from mesh service's current peer list
|
||||
if let meshPeerNickname = meshService.peerNickname(peerID: PeerID(str: peerID)) {
|
||||
if let meshPeerNickname = meshService.peerNickname(peerID: peerID) {
|
||||
actualNickname = meshPeerNickname
|
||||
SecureLogger.debug("🔍 Got nickname from mesh service: '\(actualNickname)'", category: .session)
|
||||
}
|
||||
@@ -306,10 +301,10 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
|
||||
// Send favorite notification to the peer via router (mesh or Nostr)
|
||||
if let router = messageRouter {
|
||||
router.sendFavoriteNotification(to: PeerID(str: peerID), isFavorite: !wasFavorite)
|
||||
router.sendFavoriteNotification(to: peerID, isFavorite: !wasFavorite)
|
||||
} else {
|
||||
// Fallback to mesh-only if router not yet wired
|
||||
meshService.sendFavoriteNotification(to: PeerID(str: peerID), isFavorite: !wasFavorite)
|
||||
meshService.sendFavoriteNotification(to: peerID, isFavorite: !wasFavorite)
|
||||
}
|
||||
|
||||
// Force update of peers to reflect the change
|
||||
@@ -321,46 +316,14 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
/// Toggle blocked status
|
||||
func toggleBlocked(_ peerID: String) {
|
||||
guard let fingerprint = getFingerprint(for: peerID) else { return }
|
||||
|
||||
// Get or create social identity
|
||||
var identity = identityManager.getSocialIdentity(for: fingerprint)
|
||||
?? SocialIdentity(
|
||||
fingerprint: fingerprint,
|
||||
localPetname: nil,
|
||||
claimedNickname: getPeer(by: peerID)?.displayName ?? "Unknown",
|
||||
trustLevel: .unknown,
|
||||
isFavorite: false,
|
||||
isBlocked: false,
|
||||
notes: nil
|
||||
)
|
||||
|
||||
// Toggle blocked status
|
||||
identity.isBlocked = !identity.isBlocked
|
||||
|
||||
// Can't be both favorite and blocked
|
||||
if identity.isBlocked {
|
||||
identity.isFavorite = false
|
||||
// Also remove from favorites service
|
||||
if let peer = getPeer(by: peerID) {
|
||||
favoritesService.removeFavorite(peerNoisePublicKey: peer.noisePublicKey)
|
||||
}
|
||||
}
|
||||
|
||||
identityManager.updateSocialIdentity(identity)
|
||||
}
|
||||
|
||||
/// Get fingerprint for peer ID
|
||||
func getFingerprint(for peerID: String) -> String? {
|
||||
func getFingerprint(for peerID: PeerID) -> String? {
|
||||
// Check cache first
|
||||
if let cached = fingerprintCache[peerID] {
|
||||
return cached
|
||||
}
|
||||
|
||||
// Try to get from mesh service
|
||||
if let fingerprint = meshService.getFingerprint(for: PeerID(str: peerID)) {
|
||||
if let fingerprint = meshService.getFingerprint(for: peerID) {
|
||||
fingerprintCache[peerID] = fingerprint
|
||||
return fingerprint
|
||||
}
|
||||
@@ -378,13 +341,13 @@ final class UnifiedPeerService: ObservableObject, TransportPeerEventsDelegate {
|
||||
// MARK: - Compatibility Methods (for easy migration)
|
||||
|
||||
var allPeers: [BitchatPeer] { peers }
|
||||
var connectedPeers: [String] { Array(connectedPeerIDs) }
|
||||
var favoritePeers: Set<String> {
|
||||
Set(favorites.compactMap { getFingerprint(for: $0.peerID.id) })
|
||||
var connectedPeers: [PeerID] { Array(connectedPeerIDs) }
|
||||
var favoritePeers: Set<String> {
|
||||
Set(favorites.compactMap { getFingerprint(for: $0.peerID) })
|
||||
}
|
||||
var blockedUsers: Set<String> {
|
||||
Set(peers.compactMap { peer in
|
||||
isBlocked(peer.peerID.id) ? getFingerprint(for: peer.peerID.id) : nil
|
||||
isBlocked(peer.peerID) ? getFingerprint(for: peer.peerID) : nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
|
||||
// Computed properties for compatibility
|
||||
@MainActor
|
||||
var connectedPeers: [String] { Array(unifiedPeerService.connectedPeerIDs) }
|
||||
var connectedPeers: [String] { Array(unifiedPeerService.connectedPeerIDs.map(\.id)) }
|
||||
@Published var allPeers: [BitchatPeer] = []
|
||||
var privateChats: [String: [BitchatMessage]] {
|
||||
get { privateChatManager.privateChats }
|
||||
@@ -1186,7 +1186,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
}
|
||||
|
||||
// Check if messages are stored under the stable Noise key hex
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
let noiseKeyHex = peer.noisePublicKey.hexEncodedString()
|
||||
if unreadPrivateMessages.contains(noiseKeyHex) {
|
||||
return true
|
||||
@@ -1233,7 +1233,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
|
||||
if let ephemeralID = ephemeralPeerID {
|
||||
// Found the ephemeral peer, use normal toggle
|
||||
unifiedPeerService.toggleFavorite(ephemeralID.id)
|
||||
unifiedPeerService.toggleFavorite(ephemeralID)
|
||||
// Also trigger UI update
|
||||
objectWillChange.send()
|
||||
} else {
|
||||
@@ -1278,7 +1278,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
}
|
||||
} else {
|
||||
// This is an ephemeral peer ID (16 hex chars), use normal toggle
|
||||
unifiedPeerService.toggleFavorite(peerID)
|
||||
unifiedPeerService.toggleFavorite(PeerID(str: peerID))
|
||||
// Trigger UI update
|
||||
objectWillChange.send()
|
||||
}
|
||||
@@ -1294,7 +1294,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
}
|
||||
} else {
|
||||
// This is an ephemeral peer ID - check with UnifiedPeerService
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
return peer.isFavorite
|
||||
}
|
||||
}
|
||||
@@ -1306,7 +1306,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
|
||||
@MainActor
|
||||
func isPeerBlocked(_ peerID: String) -> Bool {
|
||||
return unifiedPeerService.isBlocked(peerID)
|
||||
return unifiedPeerService.isBlocked(PeerID(str: peerID))
|
||||
}
|
||||
|
||||
// Helper method to find current peer ID for a fingerprint
|
||||
@@ -2206,7 +2206,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
guard !content.isEmpty else { return }
|
||||
|
||||
// Check if blocked
|
||||
if unifiedPeerService.isBlocked(peerID) {
|
||||
if unifiedPeerService.isBlocked(PeerID(str: peerID)) {
|
||||
let nickname = meshService.peerNickname(peerID: PeerID(str: peerID)) ?? "user"
|
||||
addSystemMessage(
|
||||
String(
|
||||
@@ -2458,7 +2458,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
let peerNickname = meshService.peerNickname(peerID: PeerID(str: peerID)) ?? "unknown"
|
||||
|
||||
// Check if the peer is blocked
|
||||
if unifiedPeerService.isBlocked(peerID) {
|
||||
if unifiedPeerService.isBlocked(PeerID(str: peerID)) {
|
||||
addSystemMessage(
|
||||
String(
|
||||
format: String(localized: "system.chat.blocked", comment: "System message when starting chat fails because peer is blocked"),
|
||||
@@ -2470,7 +2470,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
}
|
||||
|
||||
// Check mutual favorites for offline messaging
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID),
|
||||
if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)),
|
||||
peer.isFavorite && !peer.theyFavoritedUs && !peer.isConnected {
|
||||
addSystemMessage(
|
||||
String(
|
||||
@@ -2484,7 +2484,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
|
||||
// Consolidate messages from stable Noise key if needed
|
||||
// This ensures Nostr messages appear when opening a chat with an ephemeral peer ID
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
let noiseKeyHex = peer.noisePublicKey.hexEncodedString()
|
||||
|
||||
// If we have messages stored under the stable Noise key hex but not under the ephemeral ID,
|
||||
@@ -3045,7 +3045,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
peerNostrPubkey = favoriteStatus.peerNostrPublicKey
|
||||
}
|
||||
// Otherwise get the Noise key from the peer info
|
||||
else if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
else if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
noiseKeyHex = peer.noisePublicKey.hexEncodedString()
|
||||
let favoriteStatus = FavoritesPersistenceService.shared.getFavoriteStatus(for: peer.noisePublicKey)
|
||||
peerNostrPubkey = favoriteStatus?.peerNostrPublicKey
|
||||
@@ -3068,7 +3068,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
// Skip if we already sent an ACK for this message
|
||||
if !sentReadReceipts.contains(message.id) {
|
||||
// Use stable Noise key hex if available; else fall back to peerID
|
||||
let recipPeer = (Data(hexString: peerID) != nil) ? peerID : (unifiedPeerService.getPeer(by: peerID)?.noisePublicKey.hexEncodedString() ?? peerID)
|
||||
let recipPeer = (Data(hexString: peerID) != nil) ? peerID : (unifiedPeerService.getPeer(by: PeerID(str: peerID))?.noisePublicKey.hexEncodedString() ?? peerID)
|
||||
let receipt = ReadReceipt(originalMessageID: message.id, readerID: meshService.myPeerID.id, readerNickname: nickname)
|
||||
messageRouter.sendReadReceipt(receipt, to: PeerID(str: recipPeer))
|
||||
sentReadReceipts.insert(message.id)
|
||||
@@ -3088,7 +3088,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
}
|
||||
|
||||
// Also include messages stored under the stable Noise key (Nostr path)
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
let noiseKeyHex = peer.noisePublicKey.hexEncodedString()
|
||||
if noiseKeyHex != peerID, let nostrMessages = privateChats[noiseKeyHex] {
|
||||
combined.append(contentsOf: nostrMessages)
|
||||
@@ -4247,7 +4247,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
|
||||
@MainActor
|
||||
func getFingerprint(for peerID: String) -> String? {
|
||||
return unifiedPeerService.getFingerprint(for: peerID)
|
||||
return unifiedPeerService.getFingerprint(for: PeerID(str: peerID))
|
||||
}
|
||||
|
||||
//
|
||||
@@ -4337,7 +4337,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
// Also log any offline favorites and whether we consider them verified
|
||||
let offlineFavorites = unifiedPeerService.favorites.filter { !$0.isConnected }
|
||||
for fav in offlineFavorites {
|
||||
let fp = unifiedPeerService.getFingerprint(for: fav.peerID.id)
|
||||
let fp = unifiedPeerService.getFingerprint(for: fav.peerID)
|
||||
let isVer = fp.flatMap { verifiedFingerprints.contains($0) } ?? false
|
||||
let fpShort = fp?.prefix(8) ?? "nil"
|
||||
SecureLogger.info("⭐️ Favorite offline: \(fav.nickname) fp=\(fpShort) verified=\(isVer)", category: .security)
|
||||
@@ -4454,7 +4454,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
switch type {
|
||||
case .privateMessage:
|
||||
guard let pm = PrivateMessagePacket.decode(from: payload) else { return }
|
||||
let senderName = unifiedPeerService.getPeer(by: peerID.id)?.nickname ?? "Unknown"
|
||||
let senderName = unifiedPeerService.getPeer(by: peerID)?.nickname ?? "Unknown"
|
||||
let pmMentions = parseMentions(from: pm.content)
|
||||
let msg = BitchatMessage(
|
||||
id: pm.messageID,
|
||||
@@ -4474,7 +4474,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
|
||||
case .delivered:
|
||||
guard let messageID = String(data: payload, encoding: .utf8) else { return }
|
||||
if let name = unifiedPeerService.getPeer(by: peerID.id)?.nickname {
|
||||
if let name = unifiedPeerService.getPeer(by: peerID)?.nickname {
|
||||
if let messages = privateChats[peerID.id], let idx = messages.firstIndex(where: { $0.id == messageID }) {
|
||||
privateChats[peerID.id]?[idx].deliveryStatus = .delivered(to: name, at: Date())
|
||||
objectWillChange.send()
|
||||
@@ -4483,7 +4483,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
|
||||
case .readReceipt:
|
||||
guard let messageID = String(data: payload, encoding: .utf8) else { return }
|
||||
if let name = unifiedPeerService.getPeer(by: peerID.id)?.nickname {
|
||||
if let name = unifiedPeerService.getPeer(by: peerID)?.nickname {
|
||||
if let messages = privateChats[peerID.id], let idx = messages.firstIndex(where: { $0.id == messageID }) {
|
||||
privateChats[peerID.id]?[idx].deliveryStatus = .read(by: name, at: Date())
|
||||
objectWillChange.send()
|
||||
@@ -4507,7 +4507,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
let last = lastMutualToastAt[fp] ?? .distantPast
|
||||
if now.timeIntervalSince(last) > 60 { // 1-minute throttle
|
||||
lastMutualToastAt[fp] = now
|
||||
let name = unifiedPeerService.getPeer(by: peerID.id)?.nickname ?? resolveNickname(for: peerID.id)
|
||||
let name = unifiedPeerService.getPeer(by: peerID)?.nickname ?? resolveNickname(for: peerID.id)
|
||||
NotificationService.shared.sendLocalNotification(
|
||||
title: "Mutual verification",
|
||||
body: "You and \(name) verified each other",
|
||||
@@ -4533,7 +4533,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
identityManager.setVerified(fingerprint: fp, verified: true)
|
||||
identityManager.forceSave()
|
||||
verifiedFingerprints.insert(fp)
|
||||
let name = unifiedPeerService.getPeer(by: peerID.id)?.nickname ?? resolveNickname(for: peerID.id)
|
||||
let name = unifiedPeerService.getPeer(by: peerID)?.nickname ?? resolveNickname(for: peerID.id)
|
||||
NotificationService.shared.sendLocalNotification(
|
||||
title: "Verified",
|
||||
body: "You verified \(name)",
|
||||
@@ -4639,7 +4639,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
objectWillChange.send()
|
||||
|
||||
// Cache mapping to full Noise key for session continuity on disconnect
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID.id) {
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
let noiseKeyHex = peer.noisePublicKey.hexEncodedString()
|
||||
shortIDToNoiseKey[peerID.id] = noiseKeyHex
|
||||
}
|
||||
@@ -5193,7 +5193,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
if selectedPrivateChatPeer == targetPeerID {
|
||||
isViewingThisChat = true
|
||||
} else if let selectedPeer = selectedPrivateChatPeer,
|
||||
let selectedPeerData = unifiedPeerService.getPeer(by: selectedPeer),
|
||||
let selectedPeerData = unifiedPeerService.getPeer(by: PeerID(str: selectedPeer)),
|
||||
let key = actualSenderNoiseKey,
|
||||
selectedPeerData.noisePublicKey == key {
|
||||
isViewingThisChat = true
|
||||
@@ -5458,7 +5458,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
}
|
||||
|
||||
// If not a hex key, get from peer service (ephemeral ID)
|
||||
if noiseKey == nil, let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
if noiseKey == nil, let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
noiseKey = peer.noisePublicKey
|
||||
}
|
||||
|
||||
@@ -5651,7 +5651,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
noiseKey = hexKey
|
||||
} else {
|
||||
// It's an ephemeral peer ID, get the Noise key from UnifiedPeerService
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
noiseKey = peer.noisePublicKey
|
||||
}
|
||||
}
|
||||
@@ -5841,7 +5841,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
||||
// IMPORTANT: Also consolidate messages from stable Noise key if this is an ephemeral peer
|
||||
// This ensures Nostr messages appear in BLE chats
|
||||
if peerID.count == 16 { // This is an ephemeral peer ID (8 bytes = 16 hex chars)
|
||||
if let peer = unifiedPeerService.getPeer(by: peerID) {
|
||||
if let peer = unifiedPeerService.getPeer(by: PeerID(str: peerID)) {
|
||||
let stableKeyHex = peer.noisePublicKey.hexEncodedString()
|
||||
|
||||
// If we have messages stored under the stable key, merge them
|
||||
|
||||
Reference in New Issue
Block a user