mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-06-03 16:02:34 +02:00
Merge 23362 via importfromcoldcard
This commit is contained in:
commit
f81f980843
@ -50,6 +50,7 @@ static void SetupWalletToolArgs(ArgsManager& argsman)
|
||||
argsman.AddCommand("salvage", "Attempt to recover private keys from a corrupt wallet. Warning: 'salvage' is experimental.");
|
||||
argsman.AddCommand("dump", "Print out all of the wallet key-value records");
|
||||
argsman.AddCommand("createfromdump", "Create new wallet file from dumped records");
|
||||
argsman.AddCommand("importfromcoldcard", "Create new wallet file and import descriptors from Coldcard wallet");
|
||||
}
|
||||
|
||||
static std::optional<int> WalletAppInit(ArgsManager& args, int argc, char* argv[])
|
||||
|
@ -1447,7 +1447,7 @@ RPCHelpMan importmulti()
|
||||
};
|
||||
}
|
||||
|
||||
static UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||
UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||
{
|
||||
UniValue warnings(UniValue::VARR);
|
||||
UniValue result(UniValue::VOBJ);
|
||||
|
@ -9,6 +9,8 @@
|
||||
#include <wallet/wallettool.h>
|
||||
|
||||
#include <common/args.h>
|
||||
#include <tinyformat.h>
|
||||
#include <univalue.h>
|
||||
#include <util/fs.h>
|
||||
#include <util/translation.h>
|
||||
#include <wallet/dump.h>
|
||||
@ -16,7 +18,15 @@
|
||||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletutil.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace wallet {
|
||||
|
||||
UniValue ProcessDescriptorImport(CWallet& wallet, const UniValue& data, const int64_t timestamp)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||
|
||||
namespace WalletTool {
|
||||
|
||||
// The standard wallet deleter function blocks on the validation interface
|
||||
@ -36,6 +46,10 @@ static void WalletCreate(CWallet* wallet_instance, uint64_t wallet_creation_flag
|
||||
wallet_instance->SetMinVersion(FEATURE_LATEST);
|
||||
wallet_instance->InitWalletFlags(wallet_creation_flags);
|
||||
|
||||
if (wallet_instance->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!wallet_instance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
|
||||
auto spk_man = wallet_instance->GetOrCreateLegacyScriptPubKeyMan();
|
||||
spk_man->SetupGeneration(false);
|
||||
@ -112,14 +126,40 @@ static void WalletShowInfo(CWallet* wallet_instance)
|
||||
tfm::format(std::cout, "Address Book: %zu\n", wallet_instance->m_address_book.size());
|
||||
}
|
||||
|
||||
static bool ReadAndParseColdcardFile(const fs::path& path, UniValue& decriptors)
|
||||
{
|
||||
std::ifstream file;
|
||||
file.open(path);
|
||||
if (!file.is_open()) {
|
||||
tfm::format(std::cerr, "%s. Please check permissions.\n", fs::PathToString(path));
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
while (std::getline(file, line)) {
|
||||
if (line.substr(0, 22) == "importdescriptors \'[{\"") break;
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
decriptors.clear();
|
||||
if (!decriptors.read(line.substr(19, line.size() - 20))) {
|
||||
tfm::format(std::cerr, "Unable to parse %s\n", fs::PathToString(path));
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(decriptors.isArray());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
|
||||
{
|
||||
if (args.IsArgSet("-format") && command != "createfromdump") {
|
||||
tfm::format(std::cerr, "The -format option can only be used with the \"createfromdump\" command.\n");
|
||||
return false;
|
||||
}
|
||||
if (args.IsArgSet("-dumpfile") && command != "dump" && command != "createfromdump") {
|
||||
tfm::format(std::cerr, "The -dumpfile option can only be used with the \"dump\" and \"createfromdump\" commands.\n");
|
||||
if (args.IsArgSet("-dumpfile") && command != "dump" && command != "createfromdump" && command != "importfromcoldcard") {
|
||||
tfm::format(std::cerr, "The -dumpfile option can only be used with the \"dump\", \"createfromdump\" and \"importfromcoldcard\" commands.\n");
|
||||
return false;
|
||||
}
|
||||
if (args.IsArgSet("-descriptors") && command != "create") {
|
||||
@ -228,6 +268,45 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
|
||||
tfm::format(std::cerr, "%s\n", error.original);
|
||||
}
|
||||
return ret;
|
||||
} else if (command == "importfromcoldcard") {
|
||||
tfm::format(std::cerr, "WARNING: The \"importfromcoldcard\" command is experimental and will likely be removed or changed incompatibly in a future version.\n");
|
||||
|
||||
std::string filename = gArgs.GetArg("-dumpfile", "");
|
||||
if (filename.empty()) {
|
||||
tfm::format(std::cerr, "To use importfromcoldcard, -dumpfile=<filename> must be provided.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const fs::path import_file_path{fs::absolute(fs::PathFromString(filename))};
|
||||
if (!fs::exists(import_file_path)) {
|
||||
tfm::format(std::cerr, "File %s does not exist.\n", fs::PathToString(import_file_path));
|
||||
return false;
|
||||
}
|
||||
|
||||
UniValue descriptors;
|
||||
if (!ReadAndParseColdcardFile(import_file_path, descriptors)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DatabaseOptions options;
|
||||
options.require_create = true;
|
||||
options.create_flags |= WALLET_FLAG_DESCRIPTORS;
|
||||
options.create_flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
|
||||
options.create_flags |= WALLET_FLAG_BLANK_WALLET;
|
||||
options.require_format = DatabaseFormat::SQLITE;
|
||||
std::shared_ptr<CWallet> wallet_instance = MakeWallet(name, path, options);
|
||||
if (!wallet_instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LOCK(wallet_instance->cs_wallet);
|
||||
for (const UniValue& descriptor : descriptors.getValues()) {
|
||||
const UniValue result = ProcessDescriptorImport(*wallet_instance, descriptor, 0);
|
||||
tfm::format(std::cerr, "%s\n", result.write(2));
|
||||
}
|
||||
|
||||
WalletShowInfo(wallet_instance.get());
|
||||
wallet_instance->Close();
|
||||
} else {
|
||||
tfm::format(std::cerr, "Invalid command: %s\n", command);
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user