20 std::vector<WalletDescInfo> wallet_descriptors;
21 for (
const auto& spk_man :
wallet.GetAllScriptPubKeyMans()) {
26 LOCK(desc_spk_man->cs_desc_man);
27 const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor();
28 std::string descriptor;
29 if (!
Assume(desc_spk_man->GetDescriptorString(descriptor, export_private))) {
32 const bool is_range = wallet_descriptor.descriptor->IsRange();
33 wallet_descriptors.emplace_back(
35 wallet_descriptor.creation_time,
36 wallet.IsActiveScriptPubKeyMan(*desc_spk_man),
37 wallet.IsInternalScriptPubKeyMan(desc_spk_man),
38 is_range ? std::optional(std::make_pair(wallet_descriptor.range_start, wallet_descriptor.range_end)) : std::nullopt,
39 wallet_descriptor.next_index
42 return wallet_descriptors;
49 if (destination.empty()) {
50 return util::Error{
_(
"Error: Export destination cannot be empty")};
60 if (!success) fs::remove(destination);
68 if (exported->empty()) {
69 return util::Error{
_(
"Error: Wallet has no descriptors to export")};
83 std::vector<bilingual_str> warnings;
84 std::string wallet_name =
wallet.GetName() +
"_watchonly_temp";
86 std::unique_ptr<WalletDatabase> database =
MakeWalletDatabase(wallet_name, options, status, error);
92 std::shared_ptr<CWallet> watchonly_wallet;
94 std::vector<fs::path> cleanup_files = database->Files();
96 if (watchonly_wallet) watchonly_wallet.reset();
97 for (
const auto& file : cleanup_files) {
100 fs::remove(wallet_path);
106 if (!watchonly_wallet) {
111 LOCK(watchonly_wallet->cs_wallet);
117 std::string dummy_err;
118 std::vector<std::unique_ptr<Descriptor>> descs =
Parse(desc_info.descriptor, dummy_keys, dummy_err,
true);
123 int32_t range_start = 0;
124 int32_t range_end = 0;
125 if (desc_info.range) {
126 range_start = desc_info.range->first;
127 range_end = desc_info.range->second;
130 WalletDescriptor w_desc(std::move(descs.at(0)), desc_info.creation_time, range_start, range_end, desc_info.next_index);
140 if (
auto spkm_res = watchonly_wallet->AddWalletDescriptor(w_desc, dummy_keys,
"",
false); !spkm_res) {
145 if (desc_info.active) {
148 bool internal =
false;
149 if (desc_info.internal) {
150 internal = *desc_info.internal;
152 watchonly_wallet->AddActiveScriptPubKeyMan(desc_id, *
Assert(w_desc.
descriptor->GetOutputType()), internal);
157 for (
const auto& [coin, persisted] :
wallet.m_locked_coins) {
158 if (!persisted)
continue;
159 watchonly_wallet->LockCoin(coin, persisted);
164 WalletBatch watchonly_batch(watchonly_wallet->GetDatabase());
166 return util::Error{
strprintf(
_(
"Error: database transaction cannot be executed for new watchonly wallet %s"), watchonly_wallet->GetName())};
177 return util::Error{
_(
"Error: Unable to read wallet's best block locator record")};
181 return util::Error{
_(
"Error: Unable to write watchonly wallet best block locator record")};
185 for (
const auto& [txid, wtx] :
wallet.mapWallet) {
187 if (!new_tx) return false;
188 ins_wtx.SetTx(wtx.tx);
189 ins_wtx.CopyFrom(wtx);
194 watchonly_batch.
WriteTx(watchonly_wallet->mapWallet.at(txid));
198 for (
const auto& [dest, entry] :
wallet.m_address_book) {
201 if (entry.label) watchonly_batch.
WriteName(address, *entry.label);
202 for (
const auto& [
id, request] : entry.receive_requests) {
209 return util::Error{
_(
"Error: cannot commit db transaction for watchonly wallet export")};
215 return util::Error{
_(
"Error: Unable to write the exported wallet")};
#define CHECK_NONFATAL(condition)
Identity function.
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
The util::Expected class provides a standard way for low-level functions to return either error value...
The util::Unexpected class represents an unexpected value stored in util::Expected.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
static std::shared_ptr< CWallet > CreateNew(WalletContext &context, const std::string &name, std::unique_ptr< WalletDatabase > database, uint64_t wallet_creation_flags, bool born_encrypted, bilingual_str &error, std::vector< bilingual_str > &warnings)
A transaction with a bunch of additional info that only the owner cares about.
WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man)
RecursiveMutex cs_desc_man
Access to the wallet database.
bool WriteBestBlock(const CBlockLocator &locator)
bool ReadBestBlock(CBlockLocator &locator)
bool TxnBegin()
Begin a new transaction.
bool WriteAddressPreviouslySpent(const CTxDestination &dest, bool previously_spent)
bool TxnCommit()
Commit current transaction.
bool WriteName(const std::string &strAddress, const std::string &strName)
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
bool WriteOrderPosNext(int64_t nOrderPosNext)
bool WriteTx(const CWalletTx &wtx)
bool WriteAddressReceiveRequest(const CTxDestination &dest, const std::string &id, const std::string &receive_request)
Descriptor with some wallet metadata.
std::shared_ptr< Descriptor > descriptor
static UniValue Parse(std::string_view raw, ParamFormat format=ParamFormat::JSON)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
static bool exists(const path &p)
static std::string PathToString(const path &path)
Convert path object to a byte string.
static path PathFromString(const std::string &string)
Convert byte string to path object.
std::string EncodeDestination(const CTxDestination &dest)
std::unique_ptr< Handler > MakeCleanupHandler(std::function< void()> cleanup)
Return handler wrapping a cleanup function.
bilingual_str ErrorString(const Result< T > &result)
std::unique_ptr< WalletDatabase > MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error_string)
std::string PurposeToString(AddressPurpose p)
util::Result< std::string > ExportWatchOnlyWallet(const CWallet &wallet, const fs::path &destination, WalletContext &context)
Make a new watchonly wallet file containing the public descriptors from this wallet The exported watc...
util::Expected< std::vector< WalletDescInfo >, std::string > ExportDescriptors(const CWallet &wallet, bool export_private)
Export the descriptors from a wallet so that they can be imported elsewhere.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::map< CKeyID, CKey > keys
std::optional< DatabaseFormat > require_format
WalletContext struct containing references to state shared between CWallet instances,...
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
for(size_t start{0};start< num_entries;start+=SEED_BATCH_SIZE)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
consteval auto _(util::TranslatedLiteral str)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.