diff --git a/Bitkit/Services/LightningService.swift b/Bitkit/Services/LightningService.swift index bf9fdd93..4798268d 100644 --- a/Bitkit/Services/LightningService.swift +++ b/Bitkit/Services/LightningService.swift @@ -368,12 +368,8 @@ class LightningService { return false } - // When geoblocked, only count non-LSP channels - let isGeoblocked = GeoService.shared.isGeoBlocked - let channelsToUse = isGeoblocked ? getNonLspChannels() : channels - let totalNextOutboundHtlcLimitSats = - channelsToUse + channels .filter(\.isUsable) .map(\.nextOutboundHtlcLimitMsat) .reduce(0, +) / 1000 @@ -436,16 +432,6 @@ class LightningService { throw AppError(serviceError: .nodeNotSetup) } - // When geoblocked, verify we have external (non-LSP) peers - let isGeoblocked = GeoService.shared.isGeoBlocked - if isGeoblocked && !hasExternalPeers() { - Logger.error("Cannot send Lightning payment when geoblocked without external peers") - throw AppError( - message: "Lightning send unavailable", - debugMessage: "You need channels with non-Blocktank nodes to send Lightning payments." - ) - } - Logger.info("Paying bolt11: \(bolt11)") do { @@ -657,31 +643,6 @@ extension LightningService { try node.getAddressBalance(addressStr: address) } } - - /// Returns LSP (Blocktank) peer node IDs - func getLspPeerNodeIds() -> [String] { - return Env.trustedLnPeers.map(\.nodeId) - } - - /// Checks if there are connected peers other than LSP peers - /// Used for geoblocking to determine if Lightning operations can proceed - func hasExternalPeers() -> Bool { - guard let peers else { return false } - let lspNodeIds = Set(getLspPeerNodeIds()) - return peers.contains { peer in - !lspNodeIds.contains(peer.nodeId) - } - } - - /// Filters channels to exclude LSP channels - /// Used for geoblocking to only allow operations through non-Blocktank channels - func getNonLspChannels() -> [ChannelDetails] { - guard let channels else { return [] } - let lspNodeIds = Set(getLspPeerNodeIds()) - return channels.filter { channel in - !lspNodeIds.contains(channel.counterpartyNodeId) - } - } } // MARK: Events diff --git a/Bitkit/ViewModels/WalletViewModel.swift b/Bitkit/ViewModels/WalletViewModel.swift index 83b620dc..f055dd20 100644 --- a/Bitkit/ViewModels/WalletViewModel.swift +++ b/Bitkit/ViewModels/WalletViewModel.swift @@ -544,25 +544,8 @@ class WalletViewModel: ObservableObject { return capacity } - /// Total inbound Lightning capacity excluding LSP (Blocktank) channels - /// Used when geoblocked to show only non-Blocktank receiving capacity - var totalNonLspInboundLightningSats: UInt64? { - let nonLspChannels = lightningService.getNonLspChannels() - guard !nonLspChannels.isEmpty else { - return nil - } - - var capacity: UInt64 = 0 - for channel in nonLspChannels { - capacity += channel.inboundCapacityMsat / 1000 - } - return capacity - } - - /// Check if there are non-LSP (non-Blocktank) channels available - /// Used for geoblocking to determine if Lightning operations can proceed - func hasNonLspChannels() -> Bool { - return !lightningService.getNonLspChannels().isEmpty + var hasUsableChannels: Bool { + return channels?.contains(where: \.isChannelReady) ?? false } func refreshBip21(forceRefreshBolt11: Bool = false) async throws { @@ -591,14 +574,6 @@ class WalletViewModel: ObservableObject { let amountSats = invoiceAmountSats > 0 ? invoiceAmountSats : nil - // When geoblocked, only create Lightning invoice if we have non-LSP channels - let isGeoblocked = GeoService.shared.isGeoBlocked - let hasUsableChannels: Bool = if isGeoblocked { - hasNonLspChannels() - } else { - channels?.count ?? 0 > 0 - } - if hasUsableChannels { if forceRefreshBolt11 || bolt11.isEmpty { bolt11 = try await createInvoice(amountSats: amountSats, note: invoiceNote) diff --git a/Bitkit/Views/Wallets/Receive/ReceiveEdit.swift b/Bitkit/Views/Wallets/Receive/ReceiveEdit.swift index e6b63a2d..f2c02ba1 100644 --- a/Bitkit/Views/Wallets/Receive/ReceiveEdit.swift +++ b/Bitkit/Views/Wallets/Receive/ReceiveEdit.swift @@ -177,10 +177,7 @@ struct ReceiveEdit: View { private func needsAdditionalCjit() -> Bool { let isGeoBlocked = GeoService.shared.isGeoBlocked let minimumAmount = blocktank.minCjitSats ?? 0 - // When geoblocked, only count non-LSP inbound capacity - let inboundCapacity = isGeoBlocked - ? (wallet.totalNonLspInboundLightningSats ?? 0) - : (wallet.totalInboundLightningSats ?? 0) + let inboundCapacity = wallet.totalInboundLightningSats ?? 0 let invoiceAmount = amountViewModel.amountSats // Calculate maxClientBalance using TransferViewModel diff --git a/Bitkit/Views/Wallets/Receive/ReceiveQr.swift b/Bitkit/Views/Wallets/Receive/ReceiveQr.swift index c1e415e2..e7085213 100644 --- a/Bitkit/Views/Wallets/Receive/ReceiveQr.swift +++ b/Bitkit/Views/Wallets/Receive/ReceiveQr.swift @@ -42,17 +42,9 @@ struct ReceiveQr: View { } } - private var hasUsableChannels: Bool { - if GeoService.shared.isGeoBlocked { - return wallet.hasNonLspChannels() - } else { - return wallet.channelCount != 0 - } - } - private var availableTabItems: [TabItem] { // Only show unified tab if there are usable channels - if hasUsableChannels { + if wallet.hasUsableChannels { return [ TabItem(.savings), TabItem(.unified, activeColor: .white), @@ -67,12 +59,7 @@ struct ReceiveQr: View { } var showingCjitOnboarding: Bool { - // Show CJIT onboarding when: - // 1. No channels at all, OR - // 2. Geoblocked with only Blocktank channels (treat as no usable channels) - let hasNoUsableChannels = (wallet.channelCount == 0) || - (GeoService.shared.isGeoBlocked && !wallet.hasNonLspChannels()) - return hasNoUsableChannels && cjitInvoice == nil && selectedTab == .spending + return !wallet.hasUsableChannels && cjitInvoice == nil && selectedTab == .spending } var body: some View { @@ -88,7 +75,7 @@ struct ReceiveQr: View { TabView(selection: $selectedTab) { tabContent(for: .savings) - if hasUsableChannels { + if wallet.hasUsableChannels { tabContent(for: .unified) } @@ -109,10 +96,10 @@ struct ReceiveQr: View { .foregroundColor(.purpleAccent), isDisabled: wallet.nodeLifecycleState != .running ) { - if GeoService.shared.isGeoBlocked && !wallet.hasNonLspChannels() { - navigationPath.append(.cjitGeoBlocked) - } else { + if !wallet.hasUsableChannels && !GeoService.shared.isGeoBlocked { navigationPath.append(.cjitAmount) + } else if GeoService.shared.isGeoBlocked { + navigationPath.append(.cjitGeoBlocked) } } } else {