Skip to content

Commit 8ab0069

Browse files
committed
revert Swift-side filtering + bump ldk-node to v0.7.0-rc.33 which includes the migration-aware write protection
1 parent 86be5df commit 8ab0069

21 files changed

Lines changed: 68 additions & 74 deletions

Bitkit.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,7 @@
928928
repositoryURL = "https://github.com/synonymdev/ldk-node";
929929
requirement = {
930930
kind = revision;
931-
revision = c5698d00066e0e50f33696afc562d71023da2373;
931+
revision = 1531af727811f03ec0542aec3befb5a26198b192;
932932
};
933933
};
934934
96DEA0382DE8BBA1009932BF /* XCRemoteSwiftPackageReference "bitkit-core" */ = {

Bitkit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import UIKit
2+
3+
/// Shared state for swipe-back gesture. Views can set this via the `.allowSwipeBack(_:)` modifier
4+
/// to disable the gesture on screens that don't show a back button (e.g. SheetHeader without back).
5+
enum SwipeBackState {
6+
/// When false, the interactive pop gesture is disabled. Set by views that hide the back button.
7+
static var allowSwipeBack: Bool = true
8+
}
9+
10+
/// Re-enables the interactive swipe-back gesture when the navigation bar is hidden
11+
/// (e.g. when using a custom NavigationBar with `.navigationBarHidden(true)`).
12+
/// Without this, the system disables the gesture when the bar is hidden.
13+
/// Use `.allowSwipeBack(false)` on views that don't show a back button to disable the gesture there.
14+
extension UINavigationController: @retroactive UIGestureRecognizerDelegate {
15+
override open func viewDidLoad() {
16+
super.viewDidLoad()
17+
interactivePopGestureRecognizer?.delegate = self
18+
}
19+
20+
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
21+
// Only allow swipe-back when not at root — avoids iOS 17+ freeze when re-pushing after swiping to root
22+
guard viewControllers.count > 1 else { return false }
23+
return SwipeBackState.allowSwipeBack
24+
}
25+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import SwiftUI
2+
3+
extension View {
4+
/// Controls whether the interactive swipe-back gesture is enabled on this screen.
5+
/// Use `.allowSwipeBack(false)` on screens that use a custom header without a back button
6+
/// (e.g. `SheetHeader` with default `showBackButton: false`) so users can't swipe to dismiss.
7+
/// Default is `true`; only apply this modifier when you want to disable the gesture.
8+
func allowSwipeBack(_ allowed: Bool) -> some View {
9+
modifier(AllowSwipeBackModifier(allowed: allowed))
10+
}
11+
}
12+
13+
private struct AllowSwipeBackModifier: ViewModifier {
14+
let allowed: Bool
15+
16+
func body(content: Content) -> some View {
17+
content
18+
.onAppear { SwipeBackState.allowSwipeBack = allowed }
19+
.onDisappear { SwipeBackState.allowSwipeBack = true }
20+
}
21+
}

Bitkit/Services/MigrationsService.swift

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,6 @@ enum RNKeychainKey {
311311
struct PendingChannelMigration: Codable {
312312
let channelManager: Data
313313
let channelMonitors: [Data]
314-
/// Parallel array of channel monitor IDs in "{txid}_{output_index}" format.
315-
/// Used to filter out monitors that already exist locally before applying migration.
316-
let channelMonitorIds: [String]
317314
}
318315

319316
/// Peer entry from backup peers.json: [{"pubKey":"...","address":"...","port":9735}, ...]
@@ -682,7 +679,6 @@ extension MigrationsService {
682679

683680
let managerData = try Data(contentsOf: managerPath)
684681
var monitors: [Data] = []
685-
var monitorIds: [String] = []
686682

687683
let channelsPath = accountPath.appendingPathComponent("channels")
688684
let monitorsPath = accountPath.appendingPathComponent("monitors")
@@ -693,14 +689,12 @@ extension MigrationsService {
693689
for file in monitorFiles where file.hasSuffix(".bin") {
694690
let monitorData = try Data(contentsOf: monitorDir.appendingPathComponent(file))
695691
monitors.append(monitorData)
696-
monitorIds.append(file.replacingOccurrences(of: ".bin", with: ""))
697692
}
698693
}
699694

700695
pendingChannelMigration = PendingChannelMigration(
701696
channelManager: managerData,
702-
channelMonitors: monitors,
703-
channelMonitorIds: monitorIds
697+
channelMonitors: monitors
704698
)
705699
Logger.info("Prepared \(monitors.count) channel monitors for migration", context: "Migration")
706700
}
@@ -2138,12 +2132,7 @@ extension MigrationsService {
21382132
)
21392133
}
21402134

2141-
let successfulResults = monitorResults.compactMap { id, data -> (String, Data)? in
2142-
guard let data else { return nil }
2143-
return (id, data)
2144-
}
2145-
let monitorIds = successfulResults.map(\.0)
2146-
let monitors = successfulResults.map(\.1)
2135+
let monitors = monitorResults.compactMap(\.1)
21472136

21482137
if monitors.count < expectedCount {
21492138
Logger.warn(
@@ -2155,8 +2144,7 @@ extension MigrationsService {
21552144
if !monitors.isEmpty {
21562145
pendingChannelMigration = PendingChannelMigration(
21572146
channelManager: managerData,
2158-
channelMonitors: monitors,
2159-
channelMonitorIds: monitorIds
2147+
channelMonitors: monitors
21602148
)
21612149
Logger.info("Prepared \(monitors.count)/\(expectedCount) channel monitors for migration", context: "Migration")
21622150
}

Bitkit/ViewModels/WalletViewModel.swift

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,7 @@ class WalletViewModel: ObservableObject {
282282
"Found \(migration.channelMonitors.count) monitors on RN backup for pre-startup recovery",
283283
context: "WalletViewModel"
284284
)
285-
let filtered = filterMigrationMonitors(migration, walletIndex: walletIndex)
286-
return (filtered, allRetrieved)
285+
return (migration, allRetrieved)
287286
} else {
288287
Logger.info("No channel monitors found on RN backup", context: "WalletViewModel")
289288
return (nil, allRetrieved)
@@ -294,56 +293,6 @@ class WalletViewModel: ObservableObject {
294293
}
295294
}
296295

297-
/// Filters out migration monitors for channels that already have local monitors.
298-
/// Prevents old RN monitors from overwriting newer local ones during orphaned channel recovery.
299-
private func filterMigrationMonitors(_ migration: PendingChannelMigration, walletIndex: Int) -> PendingChannelMigration? {
300-
let monitorsDir = Env.ldkStorage(walletIndex: walletIndex)
301-
.appendingPathComponent("channel_monitors")
302-
.appendingPathComponent("0")
303-
304-
guard FileManager.default.fileExists(atPath: monitorsDir.path) else {
305-
Logger.debug("No local monitors directory, keeping all migration monitors", context: "WalletViewModel")
306-
return migration
307-
}
308-
309-
let localFiles = (try? FileManager.default.contentsOfDirectory(atPath: monitorsDir.path)) ?? []
310-
guard !localFiles.isEmpty else {
311-
Logger.debug("No local monitor files, keeping all migration monitors", context: "WalletViewModel")
312-
return migration
313-
}
314-
315-
let localMonitorIds = Set(localFiles)
316-
var filteredMonitors: [Data] = []
317-
var filteredIds: [String] = []
318-
319-
for (index, monitorId) in migration.channelMonitorIds.enumerated() {
320-
if localMonitorIds.contains(monitorId) {
321-
Logger.info("Skipping migration monitor \(monitorId) — already exists locally", context: "WalletViewModel")
322-
} else {
323-
filteredMonitors.append(migration.channelMonitors[index])
324-
filteredIds.append(monitorId)
325-
}
326-
}
327-
328-
if filteredMonitors.isEmpty {
329-
Logger.info(
330-
"All \(migration.channelMonitors.count) migration monitors already exist locally, skipping migration",
331-
context: "WalletViewModel"
332-
)
333-
return nil
334-
}
335-
336-
Logger.info(
337-
"Filtered migration monitors: \(filteredMonitors.count) kept, \(migration.channelMonitors.count - filteredMonitors.count) skipped (already local)",
338-
context: "WalletViewModel"
339-
)
340-
return PendingChannelMigration(
341-
channelManager: migration.channelManager,
342-
channelMonitors: filteredMonitors,
343-
channelMonitorIds: filteredIds
344-
)
345-
}
346-
347296
private func fetchTrustedPeersFromBlocktank() async -> [LnPeer]? {
348297
switch Self.peerSimulation {
349298
case .apiFailure:

Bitkit/Views/Backup/BackupMnemonic.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ struct BackupMnemonicView: View {
9999
.padding(.horizontal, 16)
100100
}
101101
.navigationBarHidden(true)
102+
.allowSwipeBack(false)
102103
.padding(.horizontal, 16)
103104
.sheetBackground()
104105
.frame(maxWidth: .infinity, maxHeight: .infinity)

Bitkit/Views/Backup/BackupPassphrase.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct BackupPassphrase: View {
77

88
var body: some View {
99
VStack(alignment: .leading, spacing: 0) {
10-
SheetHeader(title: t("security__pass_your"))
10+
SheetHeader(title: t("security__pass_your"), showBackButton: true)
1111

1212
VStack(spacing: 0) {
1313
BodyMText(t("security__pass_text"))

Bitkit/Views/Gift/GiftError.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct GiftFailed: View {
3030
}
3131
}
3232
.navigationBarHidden(true)
33+
.allowSwipeBack(false)
3334
.padding(.horizontal, 16)
3435
.sheetBackground()
3536
.accessibilityIdentifier("GiftError")

Bitkit/Views/Gift/GiftUsed.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct GiftUsed: View {
3030
}
3131
}
3232
.navigationBarHidden(true)
33+
.allowSwipeBack(false)
3334
.padding(.horizontal, 16)
3435
.sheetBackground()
3536
.accessibilityIdentifier("GiftUsed")

0 commit comments

Comments
 (0)