@@ -17,6 +17,7 @@ use crate::{
1717 xpub:: { self , XpubError } ,
1818} ;
1919use balance:: Balance ;
20+ use bdk_wallet:: bitcoin:: bip32:: Xpub ;
2021use bdk_wallet:: chain:: rusqlite:: Connection ;
2122use bdk_wallet:: { KeychainKind , descriptor:: ExtendedDescriptor , keys:: DescriptorPublicKey } ;
2223use bip39:: Mnemonic ;
@@ -296,39 +297,18 @@ impl Wallet {
296297 let fingerprint: Fingerprint = ( * fingerprint) . into ( ) ;
297298 metadata. master_fingerprint = Some ( fingerprint. into ( ) ) ;
298299
299- let existing = database
300- . wallets
301- . get_all ( network, mode) ?
302- . into_iter ( )
303- . filter_map ( |wm| {
304- let fp = wm. master_fingerprint . as_ref ( ) ?;
305- ( fp. as_ref ( ) == & fingerprint) . then_some ( wm)
306- } )
307- . next ( ) ;
308-
309- if let Some ( mut existing_metadata) = existing {
310- if existing_metadata. wallet_type != WalletType :: WatchOnly {
311- return Err ( WalletError :: WalletAlreadyExists ( existing_metadata. id ) ) ;
312- }
313-
314- let existing_id = existing_metadata. id . clone ( ) ;
315-
316- keychain. save_wallet_xpub ( & existing_id, xpub) ?;
317-
318- existing_metadata. wallet_type = WalletType :: Cold ;
319- existing_metadata. origin = descriptors. origin ( ) . ok ( ) ;
320-
321- keychain. save_public_descriptor (
322- & existing_id,
323- descriptors. external . extended_descriptor ,
324- descriptors. internal . extended_descriptor ,
325- ) ?;
326- database. wallets . update_wallet_metadata ( existing_metadata. clone ( ) ) ?;
327- database. global_config . select_wallet ( existing_id. clone ( ) ) ?;
328-
329- Updater :: send_update ( Update :: ClearCachedWalletManager ( existing_id. clone ( ) ) ) ;
330-
331- return Self :: try_load_persisted ( existing_id) ;
300+ let existing = database. wallets . get_all ( network, mode) ?. into_iter ( ) . find ( |wm| {
301+ wm. master_fingerprint . as_ref ( ) . is_some_and ( |fp| fp. as_ref ( ) == & fingerprint)
302+ } ) ;
303+
304+ if let Some ( existing_metadata) = existing {
305+ return Self :: upgrade_to_cold (
306+ existing_metadata,
307+ xpub,
308+ descriptors,
309+ keychain,
310+ & database,
311+ ) ;
332312 }
333313 }
334314
@@ -663,6 +643,37 @@ impl Wallet {
663643
664644 Ok ( ( ) )
665645 }
646+
647+ /// Upgrade an existing watch-only wallet to cold by saving the xpub and descriptors
648+ fn upgrade_to_cold (
649+ mut metadata : WalletMetadata ,
650+ xpub : Xpub ,
651+ descriptors : Descriptors ,
652+ keychain : & Keychain ,
653+ database : & Database ,
654+ ) -> Result < Self , WalletError > {
655+ if metadata. wallet_type != WalletType :: WatchOnly {
656+ return Err ( WalletError :: WalletAlreadyExists ( metadata. id ) ) ;
657+ }
658+
659+ let id = metadata. id . clone ( ) ;
660+ keychain. save_wallet_xpub ( & id, xpub) ?;
661+
662+ metadata. wallet_type = WalletType :: Cold ;
663+ metadata. origin = descriptors. origin ( ) . ok ( ) ;
664+
665+ keychain. save_public_descriptor (
666+ & id,
667+ descriptors. external . extended_descriptor ,
668+ descriptors. internal . extended_descriptor ,
669+ ) ?;
670+
671+ database. wallets . update_wallet_metadata ( metadata. clone ( ) ) ?;
672+ database. global_config . select_wallet ( id. clone ( ) ) ?;
673+
674+ Updater :: send_update ( Update :: ClearCachedWalletManager ( id. clone ( ) ) ) ;
675+ Self :: try_load_persisted ( id)
676+ }
666677}
667678
668679fn check_for_duplicate_wallet (
0 commit comments