46 "Imports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n",
59 if (!
DecodeHexTx(tx, request.params[0].get_str())) {
67 std::vector<Txid> vMatch;
68 std::vector<unsigned int> vIndex;
73 LOCK(pwallet->cs_wallet);
75 if (!pwallet->chain().findAncestorByHash(pwallet->GetLastBlockHash(), merkleBlock.
header.
GetHash(),
FoundBlock().height(height))) {
79 std::vector<Txid>::const_iterator it;
80 if ((it = std::find(vMatch.begin(), vMatch.end(), tx.
GetHash())) == vMatch.end()) {
84 unsigned int txnIndex = vIndex[it - vMatch.begin()];
87 if (pwallet->IsMine(*tx_ref)) {
101 "(DEPRECATED) This feature will be removed in the next major release. Start bitcoind with the `-deprecatedrpc=removeprunedfunds` option in order to use this.\n"
102 "Deletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will affect wallet balances.\n",
108 HelpExampleCli(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
109 "\nAs a JSON-RPC call\n"
110 +
HelpExampleRpc(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
117 if (!pwallet->chain().rpcEnableDeprecated(
"removeprunedfunds")) {
118 throw JSONRPCError(
RPC_METHOD_DEPRECATED,
"DEPRECATION WARNING: This feature will be removed in the next major release. Start bitcoind with the `-deprecatedrpc=removeprunedfunds` option in order to use this.");
121 LOCK(pwallet->cs_wallet);
124 std::vector<Txid> vHash;
125 vHash.push_back(hash);
126 if (
auto res = pwallet->RemoveTxs(vHash); !res) {
143 if (
data.exists(
"timestamp")) {
145 if (timestamp.
isNum()) {
146 const int64_t value{timestamp.
getInt<int64_t>()};
151 }
else if (timestamp.
isStr() && timestamp.
get_str() ==
"now") {
162 if (!
data.exists(
"desc")) {
168 if (
data.exists(
"active")) request.
active =
data[
"active"].get_bool();
169 if (
data.exists(
"internal")) request.
internal =
data[
"internal"].get_bool();
171 if (
data.exists(
"next_index")) request.
next_index =
data[
"next_index"].getInt<int64_t>();
179 "Import descriptors. This will trigger a rescan of the blockchain based on the earliest timestamp of all descriptors being imported. Requires a new wallet backup.\n"
180 "When importing descriptors with multipath key expressions, if the multipath specifier contains exactly two elements, the descriptor produced from the second element will be imported as an internal descriptor.\n"
181 "\nNote: This call can take over an hour to complete if using an early timestamp; during that time, other rpc calls\n"
182 "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n"
183 "The rescan is significantly faster if block filters are available (using startup option \"-blockfilterindex=1\").\n",
194 "Use the string \"now\" to substitute the current synced blockchain time.\n"
195 "\"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n"
196 "0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n"
197 "of all descriptors being imported will be scanned as well as the mempool.",
208 RPCResult::Type::ARR,
"",
"Response is an array with the same size as the input that has the execution result",
226 HelpExampleCli(
"importdescriptors",
"'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"internal\": true }, "
227 "{ \"desc\": \"<my descriptor 2>\", \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
228 HelpExampleCli(
"importdescriptors",
"'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"active\": true, \"range\": [0,100], \"label\": \"<my bech32 wallet>\" }]'")
236 const UniValue& univalue_requests = main_request.params[0];
238 std::vector<UniValue> results(univalue_requests.
size());
240 struct ParsedRequest {
244 std::vector<ParsedRequest> requests;
247 for (
size_t i = 0; i < univalue_requests.
size(); ++i) {
254 results[i].pushKV(
"success",
UniValue(
false));
255 results[i].pushKV(
"error", e);
261 std::vector<ImportDescriptorRequest> descriptor_requests;
262 descriptor_requests.reserve(requests.size());
263 for (
auto& parsed : requests) {
264 descriptor_requests.push_back(std::move(parsed.request));
271 if (import_results.size() == 1 && import_results[0].has_error() && import_results[0].error->is_general_error) {
272 const ImportError& import_error = import_results[0].error.value();
282 for (
size_t k = 0;
k < requests.size(); ++
k) {
283 UniValue& result = results[requests[
k].input_index];
289 auto write_error = [&result, &error](
int code) {
290 result.
pushKV(
"success",
false);
296 result.
pushKV(
"success",
true);
298 for (
const auto& w : import_result.
warnings) {
317 "List all descriptors present in a wallet.\n",
323 {
RPCResult::Type::ARR,
"descriptors",
"Array of descriptor objects (sorted by descriptor string representation)",
328 {
RPCResult::Type::BOOL,
"active",
"Whether this descriptor is currently used to generate new addresses"},
329 {
RPCResult::Type::BOOL,
"internal",
true,
"True if this descriptor is used to generate change addresses. False if this descriptor is used to generate receiving addresses; defined only for active descriptors"},
334 {
RPCResult::Type::NUM,
"next",
true,
"Same as next_index field. Kept for compatibility reason."},
335 {
RPCResult::Type::NUM,
"next_index",
true,
"The next index to generate addresses from; defined only for ranged descriptors"},
348 const bool priv = !request.params[0].isNull() && request.params[0].get_bool();
361 std::vector<WalletDescInfo> wallet_descriptors = *exported;
363 std::sort(wallet_descriptors.begin(), wallet_descriptors.end(), [](
const auto& a,
const auto& b) {
364 return a.descriptor < b.descriptor;
370 spk.
pushKV(
"desc", info.descriptor);
371 spk.
pushKV(
"timestamp", info.creation_time);
372 spk.
pushKV(
"active", info.active);
373 if (info.internal.has_value()) {
374 spk.
pushKV(
"internal", info.internal.value());
376 if (info.range.has_value()) {
380 spk.
pushKV(
"range", std::move(range));
381 spk.
pushKV(
"next", info.next_index);
382 spk.
pushKV(
"next_index", info.next_index);
389 response.
pushKV(
"descriptors", std::move(descriptors));
400 "Safely copies the current wallet file to the specified destination, which can either be a directory or a path with a filename.\n",
416 pwallet->BlockUntilSyncedToCurrentChain();
418 LOCK(pwallet->cs_wallet);
420 std::string strDest = request.params[0].get_str();
421 if (!pwallet->BackupWallet(strDest)) {
435 "Restores and loads a wallet from backup.\n"
436 "\nThe rescan is significantly faster if block filters are available"
437 "\n(using startup option \"-blockfilterindex=1\").\n",
447 {
RPCResult::Type::ARR,
"warnings",
true,
"Warning messages, if any, related to restoring and loading the wallet.",
454 HelpExampleCli(
"restorewallet",
"\"testwallet\" \"home\\backups\\backup-file.bak\"")
455 +
HelpExampleRpc(
"restorewallet", R
"("testwallet", "home\\backups\\backup-file.bak")")
456 + HelpExampleCliNamed("restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak"}, {
"load_on_startup",
true}})
457 +
HelpExampleRpcNamed(
"restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak"}, {
"load_on_startup",
true}})
464 auto backup_file =
fs::u8path(request.params[1].get_str());
466 std::string wallet_name = request.params[0].get_str();
468 std::optional<bool> load_on_start = request.params[2].isNull() ? std::nullopt : std::optional<bool>(request.params[2].get_bool());
472 std::vector<bilingual_str> warnings;
474 const std::shared_ptr<CWallet>
wallet =
RestoreWallet(context, backup_file, wallet_name, load_on_start, status, error, warnings);
#define CHECK_NONFATAL(condition)
Identity function.
#define NONFATAL_UNREACHABLE()
NONFATAL_UNREACHABLE() is a macro that is used to mark unreachable code.
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
CBlockHeader header
Public only for unit testing.
uint256 ExtractMatches(std::vector< Txid > &vMatch, std::vector< unsigned int > &vnIndex)
extract the matching txid's represented by this partial merkle tree and their respective indices with...
Minimal stream for reading from an existing byte array by std::span.
void push_back(UniValue val)
const std::string & get_str() const
void pushKV(std::string key, UniValue val)
Helper for findBlock to selectively return pieces of block data.
static transaction_identifier FromUint256(const uint256 &id)
The util::Expected class provides a standard way for low-level functions to return either error value...
constexpr const E & error() const &noexcept LIFETIMEBOUND
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
static const PrecomputedData data
Precomputed COutPoint and CCoins values.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness, bool try_witness)
static path u8path(std::string_view utf8_str)
bilingual_str ErrorString(const Result< T > &result)
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
void HandleWalletError(const std::shared_ptr< CWallet > &wallet, DatabaseStatus &status, bilingual_str &error)
RPCMethod importdescriptors()
static ImportDescriptorRequest ProcessUniValueDescriptor(const UniValue &data, std::optional< int64_t > timestamp)
void EnsureWalletIsUnlocked(const CWallet &wallet)
std::vector< ImportResult > ProcessDescriptorsImport(CWallet &wallet, std::vector< ImportDescriptorRequest > &requests)
@ UnlockNeeded
The wallet is locked and the operation requires access to private keys.
RPCErrorCode HandleWalletErrorCode(const WalletErrorCode code)
WalletContext & EnsureWalletContext(const std::any &context)
RPCMethod removeprunedfunds()
RPCMethod importprunedfunds()
std::string LabelFromValue(const UniValue &value)
std::shared_ptr< CWallet > RestoreWallet(WalletContext &context, const fs::path &backup_file, const std::string &wallet_name, std::optional< bool > load_on_start, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings, bool load_after_restore, bool allow_unnamed)
RPCMethod listdescriptors()
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
RPCMethod restorewallet()
static std::optional< int64_t > GetImportTimestamp(const UniValue &data)
Converts the timestamp from UniValue data to an int64_t.
is a home for public enum and struct type definitions that are used internally by node code,...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
UniValue JSONRPCError(int code, const std::string &message)
RPCErrorCode
Bitcoin RPC error codes.
@ RPC_TYPE_ERROR
Unexpected type was passed as parameter.
@ RPC_METHOD_DEPRECATED
RPC method is deprecated.
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
@ RPC_WALLET_ERROR
Wallet errors.
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string_view name)
void PushWarnings(const UniValue &warnings, UniValue &obj)
Push warning messages to an RPC "warnings" field as a JSON array of strings.
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
uint256 ParseHashV(const UniValue &v, std::string_view name)
Utilities: convert hex-encoded Values (throws error if not hex).
A mutable version of CTransaction.
Txid GetHash() const
Compute the hash of this CMutableTransaction.
@ RANGE
Special type that is a NUM or [NUM,NUM].
@ STR_HEX
Special type that is a STR with only hex chars.
@ OMITTED
Optional argument for which the default value is omitted from help text for one of two reasons:
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings....
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
@ ARR_FIXED
Special array that has a fixed number of entries.
Information about a descriptor to be imported.
std::optional< int64_t > timestamp
std::optional< int64_t > next_index
std::optional< bool > internal
std::optional< std::pair< int64_t, int64_t > > range
std::optional< ImportError > error
std::vector< std::string > warnings
State of transaction confirmed in a block.
WalletContext struct containing references to state shared between CWallet instances,...
Wallet-layer error with both programmatic and user-facing information.
bilingual_str message
User-facing translated error message.
WalletErrorCode code
Machine-readable error code for callers that need programmatic handling.
const char * uvTypeName(UniValue::VType t)