@@ -48,7 +48,9 @@ class SettingsViewModel: NSObject, ObservableObject {
4848
4949 private let defaults = UserDefaults . standard
5050
51- private var isChangingAddressType = false
51+ @Published private( set) var isChangingAddressType = false
52+ /// Set during restore when backup contained explicit monitored address types.
53+ private( set) var restoredMonitoredTypesFromBackup = false
5254 private var observedKeys : Set < String > = [ ]
5355
5456 // Reactive publishers for settings changes (used by BackupService)
@@ -211,6 +213,7 @@ class SettingsViewModel: NSObject, ObservableObject {
211213 _addressTypesToMonitor = " nativeSegwit "
212214 pinEnabled = false
213215 isChangingAddressType = false
216+ restoredMonitoredTypesFromBackup = false
214217 }
215218
216219 // MARK: - Computed Properties
@@ -275,6 +278,9 @@ class SettingsViewModel: NSObject, ObservableObject {
275278 }
276279
277280 // Address Type Settings
281+ /// Address types that support native SegWit scripts (required for Lightning).
282+ private static let nativeWitnessTypes : [ AddressScriptType ] = [ . nativeSegwit, . taproot]
283+
278284 @AppStorage ( " selectedAddressType " ) private var _selectedAddressType : String = " nativeSegwit "
279285
280286 @AppStorage ( " addressTypesToMonitor " ) private var _addressTypesToMonitor : String = " nativeSegwit "
@@ -337,8 +343,7 @@ class SettingsViewModel: NSObject, ObservableObject {
337343 return false
338344 }
339345
340- let nativeWitnessTypes : [ AddressScriptType ] = [ . nativeSegwit, . taproot]
341- let remainingNativeWitness = current. filter { $0 != addressType && nativeWitnessTypes. contains ( $0) }
346+ let remainingNativeWitness = current. filter { $0 != addressType && Self . nativeWitnessTypes. contains ( $0) }
342347 if remainingNativeWitness. isEmpty {
343348 return false
344349 }
@@ -372,6 +377,14 @@ class SettingsViewModel: NSObject, ObservableObject {
372377 addressTypesToMonitor = AddressScriptType . allAddressTypes
373378 }
374379
380+ /// Syncs monitored address types from ldk-node's runtime state into UserDefaults.
381+ func syncMonitoredTypesFromNode( ) {
382+ let nodeMonitored = lightningService. listMonitoredAddressTypes ( )
383+ var combined = Set ( nodeMonitored)
384+ combined. insert ( selectedAddressType)
385+ addressTypesToMonitor = AddressScriptType . allAddressTypes. filter { combined. contains ( $0) }
386+ }
387+
375388 private static let pendingRestoreAddressTypePruneKey = " pendingRestoreAddressTypePrune "
376389
377390 /// Tracks whether to prune empty address types after restore (set when user taps Get Started; cleared when prune runs).
@@ -385,7 +398,6 @@ class SettingsViewModel: NSObject, ObservableObject {
385398 func pruneEmptyAddressTypesAfterRestore( ) async {
386399 guard !isChangingAddressType else { return }
387400
388- let nativeWitnessTypes : [ AddressScriptType ] = [ . nativeSegwit, . taproot]
389401 var newMonitored = addressTypesToMonitor
390402 var changed = false
391403
@@ -407,7 +419,7 @@ class SettingsViewModel: NSObject, ObservableObject {
407419 }
408420
409421 // Ensure at least one native witness type
410- if !newMonitored. contains ( where: { nativeWitnessTypes. contains ( $0) } ) {
422+ if !newMonitored. contains ( where: { Self . nativeWitnessTypes. contains ( $0) } ) {
411423 if !newMonitored. contains ( . nativeSegwit) {
412424 newMonitored. append ( . nativeSegwit)
413425 changed = true
@@ -438,10 +450,9 @@ class SettingsViewModel: NSObject, ObservableObject {
438450
439451 /// True if disabling this would leave no native witness wallet (required for Lightning).
440452 func isLastRequiredNativeWitnessWallet( _ addressType: AddressScriptType ) -> Bool {
441- let nativeWitnessTypes : [ AddressScriptType ] = [ . nativeSegwit, . taproot]
442- guard nativeWitnessTypes. contains ( addressType) else { return false }
453+ guard Self . nativeWitnessTypes. contains ( addressType) else { return false }
443454
444- let remainingNativeWitness = addressTypesToMonitor. filter { $0 != addressType && nativeWitnessTypes. contains ( $0) }
455+ let remainingNativeWitness = addressTypesToMonitor. filter { $0 != addressType && Self . nativeWitnessTypes. contains ( $0) }
445456 return remainingNativeWitness. isEmpty
446457 }
447458
@@ -471,6 +482,7 @@ class SettingsViewModel: NSObject, ObservableObject {
471482
472483 do {
473484 try await lightningService. setPrimaryAddressType ( addressType)
485+ syncMonitoredTypesFromNode ( )
474486 try await lightningService. sync ( )
475487 await generateAndUpdateAddress ( addressType: addressType, wallet: wallet)
476488 } catch {
@@ -727,6 +739,39 @@ class SettingsViewModel: NSObject, ObservableObject {
727739 if let rgsServerUrl = dict [ " rgsServerUrl " ] as? String , !rgsServerUrl. isEmpty {
728740 rgsConfigService. saveServerUrl ( rgsServerUrl)
729741 }
742+
743+ syncAppStorageFromDefaults ( )
744+
745+ let restoredMonitored = addressTypesToMonitor
746+ let restoredPrimary = selectedAddressType
747+ restoredMonitoredTypesFromBackup = restoredMonitored. count > 1
748+ || ( restoredMonitored. count == 1 && restoredMonitored. first != restoredPrimary)
749+
750+ Logger . debug (
751+ " Restored settings: selectedAddressType= \( _selectedAddressType) , addressTypesToMonitor= \( _addressTypesToMonitor) , fromBackup= \( restoredMonitoredTypesFromBackup) " ,
752+ context: " SettingsRestore "
753+ )
754+ }
755+
756+ /// Re-read UserDefaults into @AppStorage properties after a direct defaults write.
757+ private func syncAppStorageFromDefaults( ) {
758+ _swipeBalanceToHide = defaults. object ( forKey: " swipeBalanceToHide " ) as? Bool ?? true
759+ defaultTransactionSpeed = TransactionSpeed ( rawValue: defaults. string ( forKey: " defaultTransactionSpeed " ) ?? " " ) ?? . normal
760+ hideBalance = defaults. bool ( forKey: " hideBalance " )
761+ hideBalanceOnOpen = defaults. bool ( forKey: " hideBalanceOnOpen " )
762+ readClipboard = defaults. bool ( forKey: " readClipboard " )
763+ warnWhenSendingOver100 = defaults. bool ( forKey: " warnWhenSendingOver100 " )
764+ enableQuickpay = defaults. bool ( forKey: " enableQuickpay " )
765+ quickpayAmount = defaults. double ( forKey: " quickpayAmount " )
766+ enableNotifications = defaults. bool ( forKey: " enableNotifications " )
767+ requirePinForPayments = defaults. bool ( forKey: " requirePinForPayments " )
768+ useBiometrics = defaults. bool ( forKey: " useBiometrics " )
769+ showWidgets = defaults. object ( forKey: " showWidgets " ) as? Bool ?? true
770+ showWidgetTitles = defaults. bool ( forKey: " showWidgetTitles " )
771+ _coinSelectionMethod = defaults. string ( forKey: " coinSelectionMethod " ) ?? CoinSelectionMethod . autopilot. rawValue
772+ _coinSelectionAlgorithm = defaults. string ( forKey: " coinSelectionAlgorithm " ) ?? CoinSelectionAlgorithm . branchAndBound. stringValue
773+ _selectedAddressType = defaults. string ( forKey: " selectedAddressType " ) ?? " nativeSegwit "
774+ _addressTypesToMonitor = defaults. string ( forKey: " addressTypesToMonitor " ) ?? " nativeSegwit "
730775 }
731776
732777 /// Gets the current app cache data for backup
0 commit comments