11use std:: str:: FromStr ;
22
33pub use :: bitcoin:: util:: address:: Address ;
4- use anyhow:: Result ;
4+ use anyhow:: { anyhow , Result } ;
55pub use bdk:: { wallet:: AddressIndex , FeeRate , LocalUtxo , TransactionDetails } ;
66pub use bitcoin_hashes:: { sha256, Hash } ;
77use serde_encrypt:: {
@@ -16,6 +16,7 @@ mod payment;
1616mod psbt;
1717mod wallet;
1818
19+ use crate :: structs:: EncryptedWalletDataV04 ;
1920pub use crate :: {
2021 bitcoin:: {
2122 assets:: dust_tx,
@@ -33,7 +34,11 @@ pub use crate::{
3334} ;
3435
3536impl SerdeEncryptSharedKey for EncryptedWalletData {
36- type S = BincodeSerializer < Self > ; // you can specify serializer implementation (or implement it by yourself).
37+ type S = BincodeSerializer < Self > ;
38+ }
39+
40+ impl SerdeEncryptSharedKey for EncryptedWalletDataV04 {
41+ type S = BincodeSerializer < Self > ;
3742}
3843
3944/// Bitcoin Wallet Operations
@@ -47,12 +52,45 @@ pub fn get_encrypted_wallet(
4752 let shared_key: [ u8 ; 32 ] = hash. into_inner ( ) ;
4853 let encrypted_descriptors: Vec < u8 > = hex:: decode ( encrypted_descriptors) ?;
4954 let encrypted_message = EncryptedMessage :: deserialize ( encrypted_descriptors) ?;
55+
5056 Ok ( EncryptedWalletData :: decrypt_owned (
5157 & encrypted_message,
5258 & SharedKey :: from_array ( shared_key) ,
5359 ) ?)
5460}
5561
62+ pub async fn upgrade_wallet (
63+ password : & str ,
64+ encrypted_descriptors : & str ,
65+ seed_password : & str ,
66+ ) -> Result < String > {
67+ // read hash digest and consume hasher
68+ let hash = sha256:: Hash :: hash ( password. as_bytes ( ) ) ;
69+ let shared_key: [ u8 ; 32 ] = hash. into_inner ( ) ;
70+ let encrypted_descriptors: Vec < u8 > = hex:: decode ( encrypted_descriptors) ?;
71+ let encrypted_message = EncryptedMessage :: deserialize ( encrypted_descriptors) ?;
72+
73+ match EncryptedWalletData :: decrypt_owned ( & encrypted_message, & SharedKey :: from_array ( shared_key) )
74+ {
75+ Ok ( _data) => Err ( anyhow ! ( "Descriptor does not need to be upgraded" ) ) ,
76+ Err ( _err) => {
77+ // If there's a deserialization error, attempt to recover just the mnemnonic.
78+ let recovered_wallet_data = EncryptedWalletDataV04 :: decrypt_owned (
79+ & encrypted_message,
80+ & SharedKey :: from_array ( shared_key) ,
81+ ) ?;
82+
83+ // println!("Recovered wallet data: {recovered_wallet_data:?}"); // Keep commented out for security
84+
85+ let upgraded_descriptor =
86+ save_mnemonic_seed ( & recovered_wallet_data. mnemonic , password, seed_password)
87+ . await ?;
88+
89+ Ok ( upgraded_descriptor. serialized_encrypted_message )
90+ }
91+ }
92+ }
93+
5694pub async fn new_mnemonic_seed (
5795 encryption_password : & str ,
5896 seed_password : & str ,
@@ -64,7 +102,7 @@ pub async fn new_mnemonic_seed(
64102 let encrypted_message = encrypted_wallet_data. encrypt ( & SharedKey :: from_array ( shared_key) ) ?;
65103 let serialized_encrypted_message = hex:: encode ( encrypted_message. serialize ( ) ) ;
66104 let mnemonic_seed_data = MnemonicSeedData {
67- mnemonic : encrypted_wallet_data. private . mnemonic ,
105+ mnemonic : encrypted_wallet_data. mnemonic ,
68106 serialized_encrypted_message,
69107 } ;
70108
@@ -83,7 +121,7 @@ pub async fn save_mnemonic_seed(
83121 let encrypted_message = vault_data. encrypt ( & SharedKey :: from_array ( shared_key) ) ?;
84122 let serialized_encrypted_message = hex:: encode ( encrypted_message. serialize ( ) ) ;
85123 let mnemonic_seed_data = MnemonicSeedData {
86- mnemonic : vault_data. private . mnemonic ,
124+ mnemonic : vault_data. mnemonic ,
87125 serialized_encrypted_message,
88126 } ;
89127
0 commit comments