diff --git a/bitchat/ViewModels/ChatViewModel.swift b/bitchat/ViewModels/ChatViewModel.swift index 8af4e045..e153232c 100644 --- a/bitchat/ViewModels/ChatViewModel.swift +++ b/bitchat/ViewModels/ChatViewModel.swift @@ -363,6 +363,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate { private var geoSubscriptionID: String? = nil private var geoDmSubscriptionID: String? = nil private var currentGeohash: String? = nil + private var cachedGeohashIdentity: (geohash: String, identity: NostrIdentity)? = nil // Cache current geohash identity private var geoNicknames: [String: String] = [:] // pubkeyHex(lowercased) -> nickname // Show Tor status once per app launch private var torStatusAnnounced = false @@ -3763,7 +3764,19 @@ final class ChatViewModel: ObservableObject, BitchatDelegate { if let spid = message.senderPeerID?.id { // In geohash channels, compare against our per-geohash nostr short ID if case .location(let ch) = activeChannel, spid.hasPrefix("nostr:") { - if let myGeo = try? idBridge.deriveIdentity(forGeohash: ch.geohash) { + // Use cached identity to avoid crypto during rendering + let myGeo: NostrIdentity? = { + if let cached = cachedGeohashIdentity, cached.geohash == ch.geohash { + return cached.identity + } + // Fallback: derive and cache (should rarely happen) + if let identity = try? NostrIdentityBridge.deriveIdentity(forGeohash: ch.geohash) { + cachedGeohashIdentity = (ch.geohash, identity) + return identity + } + return nil + }() + if let myGeo = myGeo { return spid == "nostr:\(myGeo.publicKeyHex.prefix(TransportConfig.nostrShortKeyDisplayLength))" } }