diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h index 8c31112fc9..54eb720d02 100644 --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -50,6 +50,7 @@ struct WalletBalances; struct WalletTx; struct WalletTxOut; struct WalletTxStatus; +struct WalletMigrationResult; using WalletOrderForm = std::vector>; using WalletValueMap = std::map; @@ -332,6 +333,9 @@ public: //! Restore backup wallet virtual util::Result> restoreWallet(const fs::path& backup_file, const std::string& wallet_name, std::vector& warnings) = 0; + //! Migrate a wallet + virtual util::Result migrateWallet(const std::string& name, const SecureString& passphrase) = 0; + //! Return available wallets in wallet directory. virtual std::vector listWalletDir() = 0; @@ -423,6 +427,15 @@ struct WalletTxOut bool is_spent = false; }; +//! Migrated wallet info +struct WalletMigrationResult +{ + std::unique_ptr wallet; + std::optional watchonly_wallet_name; + std::optional solvables_wallet_name; + fs::path backup_path; +}; + //! Return implementation of Wallet interface. This function is defined in //! dummywallet.cpp and throws if the wallet component is not compiled. std::unique_ptr MakeWallet(wallet::WalletContext& context, const std::shared_ptr& wallet); diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp index cd438cfe2f..463d169b46 100644 --- a/src/wallet/interfaces.cpp +++ b/src/wallet/interfaces.cpp @@ -42,6 +42,7 @@ using interfaces::Wallet; using interfaces::WalletAddress; using interfaces::WalletBalances; using interfaces::WalletLoader; +using interfaces::WalletMigrationResult; using interfaces::WalletOrderForm; using interfaces::WalletTx; using interfaces::WalletTxOut; @@ -631,6 +632,18 @@ public: return util::Error{error}; } } + util::Result migrateWallet(const std::string& name, const SecureString& passphrase) override + { + auto res = wallet::MigrateLegacyToDescriptor(name, passphrase, m_context); + if (!res) return util::Error{util::ErrorString(res)}; + WalletMigrationResult out{ + .wallet = MakeWallet(m_context, res->wallet), + .watchonly_wallet_name = res->watchonly_wallet ? std::make_optional(res->watchonly_wallet->GetName()) : std::nullopt, + .solvables_wallet_name = res->solvables_wallet ? std::make_optional(res->solvables_wallet->GetName()) : std::nullopt, + .backup_path = res->backup_path, + }; + return {std::move(out)}; // std::move to work around clang bug + } std::string getWalletDir() override { return fs::PathToString(GetWalletDir()); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 62f0f53b01..b153c3f60a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4253,7 +4253,7 @@ util::Result MigrateLegacyToDescriptor(const std::string& walle // Migration successful, unload the wallet locally, then reload it. assert(local_wallet.use_count() == 1); local_wallet.reset(); - LoadWallet(context, wallet_name, /*load_on_start=*/std::nullopt, options, status, error, warnings); + res.wallet = LoadWallet(context, wallet_name, /*load_on_start=*/std::nullopt, options, status, error, warnings); res.wallet_name = wallet_name; } else { // Migration failed, cleanup diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index cbd5008366..25752a3849 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1068,6 +1068,7 @@ bool FillInputToWeight(CTxIn& txin, int64_t target_weight); struct MigrationResult { std::string wallet_name; + std::shared_ptr wallet; std::shared_ptr watchonly_wallet; std::shared_ptr solvables_wallet; fs::path backup_path;