@@ -17,7 +17,7 @@ use crate::{
1717} ;
1818
1919use cove_macros:: impl_default_for;
20- use tracing:: warn;
20+ use tracing:: { info , warn} ;
2121
2222#[ derive( Debug , Copy , Clone , Hash , Eq , PartialEq , uniffi:: Enum ) ]
2323pub enum ImportWalletManagerReconcileMessage {
@@ -122,58 +122,62 @@ impl RustImportWalletManager {
122122 . into_iter ( )
123123 . find ( |wallet_metadata| wallet_metadata. matches_fingerprint ( fingerprint) ) ;
124124
125- if let Some ( mut metadata) = existing_wallet {
126- let id = metadata. id . clone ( ) ;
127- let keychain = Keychain :: global ( ) ;
128-
129- if metadata. wallet_type == WalletType :: Hot {
130- if keychain. get_wallet_key ( & id) ?. is_none ( ) {
131- warn ! ( "hot wallet {id} is missing private key, restoring from imported words" ) ;
132- } else {
133- warn ! (
134- "attempted to import words for existing hot wallet {id}, showing duplicate alert"
135- ) ;
136- Database :: global ( ) . global_config . select_wallet ( id. clone ( ) ) ?;
137- return Err ( ImportWalletError :: WalletAlreadyExists ( id) ) ;
138- }
139- }
125+ // new wallet, create it and return
126+ if existing_wallet. is_none ( ) {
127+ // get current number of wallets and add one;
128+ let number_of_wallets = Database :: global ( ) . wallets . len ( network, mode) . unwrap_or ( 0 ) ;
129+
130+ let name = format ! ( "Wallet {}" , number_of_wallets + 1 ) ;
131+ let wallet_metadata =
132+ WalletMetadata :: new_imported_from_mnemonic ( name, network, fingerprint) ;
133+
134+ Wallet :: try_new_persisted_and_selected ( wallet_metadata. clone ( ) , mnemonic. clone ( ) , None )
135+ . map_err_str ( ImportWalletError :: WalletImportError ) ?;
136+
137+ return Ok ( wallet_metadata) ;
138+ }
140139
141- // Restore the private key material for an existing wallet.
142- keychain. save_wallet_key ( & id, mnemonic. clone ( ) ) ?;
143-
144- // Keep xpub/descriptors in sync with the imported mnemonic.
145- let xpub = mnemonic. xpub ( network. into ( ) ) ;
146- keychain. save_wallet_xpub ( & id, xpub) ?;
147-
148- let descriptors =
149- mnemonic. clone ( ) . into_descriptors ( None , network, metadata. address_type ) ;
150- keychain. save_public_descriptor (
151- & id,
152- descriptors. external . extended_descriptor ,
153- descriptors. internal . extended_descriptor ,
154- ) ?;
155-
156- // Imported mnemonic means this wallet can now sign locally.
157- metadata. wallet_type = WalletType :: Hot ;
158- metadata. hardware_metadata = None ;
159- metadata. verified = true ;
160- Database :: global ( ) . wallets . update_wallet_metadata ( metadata. clone ( ) ) ?;
161- Database :: global ( ) . global_config . select_wallet ( id) ?;
162-
163- return Ok ( metadata) ;
140+ // existing wallet
141+ let mut metadata = existing_wallet. expect ( "wallet exists, just checked above" ) ;
142+ let id = metadata. id . clone ( ) ;
143+ let keychain = Keychain :: global ( ) ;
144+
145+ // hot wallets with private key already in keychain, don't do anything else
146+ if metadata. wallet_type == WalletType :: Hot && keychain. get_wallet_key ( & id) ?. is_some ( ) {
147+ warn ! (
148+ "attempted to import words for existing hot wallet {id}, showing duplicate alert"
149+ ) ;
150+
151+ Database :: global ( ) . global_config . select_wallet ( id. clone ( ) ) ?;
152+ return Err ( ImportWalletError :: WalletAlreadyExists ( id) ) ;
164153 }
165154
166- // get current number of wallets and add one;
167- let number_of_wallets = Database :: global ( ) . wallets . len ( network, mode) . unwrap_or ( 0 ) ;
155+ info ! ( "adding mnemonic to existing wallet {id}" ) ;
156+
157+ // save the private key material for an existing wallet.
158+ keychain. save_wallet_key ( & id, mnemonic. clone ( ) ) ?;
159+
160+ // save xpub/descriptors in keychain too
161+ let xpub = mnemonic. xpub ( network. into ( ) ) ;
162+ keychain. save_wallet_xpub ( & id, xpub) ?;
163+
164+ // save public descriptors in keychain too
165+ let descriptors = mnemonic. clone ( ) . into_descriptors ( None , network, metadata. address_type ) ;
166+ keychain. save_public_descriptor (
167+ & id,
168+ descriptors. external . extended_descriptor ,
169+ descriptors. internal . extended_descriptor ,
170+ ) ?;
168171
169- let name = format ! ( "Wallet {}" , number_of_wallets + 1 ) ;
170- let wallet_metadata =
171- WalletMetadata :: new_imported_from_mnemonic ( name, network, fingerprint) ;
172+ // imported mnemonic means this wallet can now sign locally.
173+ metadata. wallet_type = WalletType :: Hot ;
174+ metadata. hardware_metadata = None ;
175+ metadata. verified = true ;
172176
173- Wallet :: try_new_persisted_and_selected ( wallet_metadata . clone ( ) , mnemonic . clone ( ) , None )
174- . map_err_str ( ImportWalletError :: WalletImportError ) ?;
177+ Database :: global ( ) . wallets . update_wallet_metadata ( metadata . clone ( ) ) ? ;
178+ Database :: global ( ) . global_config . select_wallet ( id ) ?;
175179
176- Ok ( wallet_metadata )
180+ Ok ( metadata )
177181 }
178182
179183 /// Action from the frontend to change the state of the view model
0 commit comments