Bitcoin Core  27.1.0
P2P Digital Currency
wallet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
8 #endif
9 
10 #include <core_io.h>
11 #include <key_io.h>
12 #include <rpc/server.h>
13 #include <rpc/util.h>
14 #include <util/translation.h>
15 #include <wallet/context.h>
16 #include <wallet/receive.h>
17 #include <wallet/rpc/wallet.h>
18 #include <wallet/rpc/util.h>
19 #include <wallet/wallet.h>
20 #include <wallet/walletutil.h>
21 
22 #include <optional>
23 
24 #include <univalue.h>
25 
26 
27 namespace wallet {
28 
29 static const std::map<uint64_t, std::string> WALLET_FLAG_CAVEATS{
31  "You need to rescan the blockchain in order to correctly mark used "
32  "destinations in the past. Until this is done, some destinations may "
33  "be considered unused, even if the opposite is the case."},
34 };
35 
37 bool HaveKey(const SigningProvider& wallet, const CKey& key)
38 {
39  CKey key2;
40  key2.Set(key.begin(), key.end(), !key.IsCompressed());
41  return wallet.HaveKey(key.GetPubKey().GetID()) || wallet.HaveKey(key2.GetPubKey().GetID());
42 }
43 
45 {
46  return RPCHelpMan{"getwalletinfo",
47  "Returns an object containing various wallet state info.\n",
48  {},
49  RPCResult{
50  RPCResult::Type::OBJ, "", "",
51  {
52  {
53  {RPCResult::Type::STR, "walletname", "the wallet name"},
54  {RPCResult::Type::NUM, "walletversion", "the wallet version"},
55  {RPCResult::Type::STR, "format", "the database format (bdb or sqlite)"},
56  {RPCResult::Type::STR_AMOUNT, "balance", "DEPRECATED. Identical to getbalances().mine.trusted"},
57  {RPCResult::Type::STR_AMOUNT, "unconfirmed_balance", "DEPRECATED. Identical to getbalances().mine.untrusted_pending"},
58  {RPCResult::Type::STR_AMOUNT, "immature_balance", "DEPRECATED. Identical to getbalances().mine.immature"},
59  {RPCResult::Type::NUM, "txcount", "the total number of transactions in the wallet"},
60  {RPCResult::Type::NUM_TIME, "keypoololdest", /*optional=*/true, "the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool. Legacy wallets only."},
61  {RPCResult::Type::NUM, "keypoolsize", "how many new keys are pre-generated (only counts external keys)"},
62  {RPCResult::Type::NUM, "keypoolsize_hd_internal", /*optional=*/true, "how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)"},
63  {RPCResult::Type::NUM_TIME, "unlocked_until", /*optional=*/true, "the " + UNIX_EPOCH_TIME + " until which the wallet is unlocked for transfers, or 0 if the wallet is locked (only present for passphrase-encrypted wallets)"},
64  {RPCResult::Type::STR_AMOUNT, "paytxfee", "the transaction fee configuration, set in " + CURRENCY_UNIT + "/kvB"},
65  {RPCResult::Type::STR_HEX, "hdseedid", /*optional=*/true, "the Hash160 of the HD seed (only present when HD is enabled)"},
66  {RPCResult::Type::BOOL, "private_keys_enabled", "false if privatekeys are disabled for this wallet (enforced watch-only wallet)"},
67  {RPCResult::Type::BOOL, "avoid_reuse", "whether this wallet tracks clean/dirty coins in terms of reuse"},
68  {RPCResult::Type::OBJ, "scanning", "current scanning details, or false if no scan is in progress",
69  {
70  {RPCResult::Type::NUM, "duration", "elapsed seconds since scan start"},
71  {RPCResult::Type::NUM, "progress", "scanning progress percentage [0.0, 1.0]"},
72  }, /*skip_type_check=*/true},
73  {RPCResult::Type::BOOL, "descriptors", "whether this wallet uses descriptors for scriptPubKey management"},
74  {RPCResult::Type::BOOL, "external_signer", "whether this wallet is configured to use an external signer such as a hardware wallet"},
75  {RPCResult::Type::BOOL, "blank", "Whether this wallet intentionally does not contain any keys, scripts, or descriptors"},
76  {RPCResult::Type::NUM_TIME, "birthtime", /*optional=*/true, "The start time for blocks scanning. It could be modified by (re)importing any descriptor with an earlier timestamp."},
78  }},
79  },
81  HelpExampleCli("getwalletinfo", "")
82  + HelpExampleRpc("getwalletinfo", "")
83  },
84  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
85 {
86  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
87  if (!pwallet) return UniValue::VNULL;
88 
89  // Make sure the results are valid at least up to the most recent block
90  // the user could have gotten from another RPC command prior to now
91  pwallet->BlockUntilSyncedToCurrentChain();
92 
93  LOCK(pwallet->cs_wallet);
94 
96 
97  size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
98  const auto bal = GetBalance(*pwallet);
99  obj.pushKV("walletname", pwallet->GetName());
100  obj.pushKV("walletversion", pwallet->GetVersion());
101  obj.pushKV("format", pwallet->GetDatabase().Format());
102  obj.pushKV("balance", ValueFromAmount(bal.m_mine_trusted));
103  obj.pushKV("unconfirmed_balance", ValueFromAmount(bal.m_mine_untrusted_pending));
104  obj.pushKV("immature_balance", ValueFromAmount(bal.m_mine_immature));
105  obj.pushKV("txcount", (int)pwallet->mapWallet.size());
106  const auto kp_oldest = pwallet->GetOldestKeyPoolTime();
107  if (kp_oldest.has_value()) {
108  obj.pushKV("keypoololdest", kp_oldest.value());
109  }
110  obj.pushKV("keypoolsize", (int64_t)kpExternalSize);
111 
112  LegacyScriptPubKeyMan* spk_man = pwallet->GetLegacyScriptPubKeyMan();
113  if (spk_man) {
114  CKeyID seed_id = spk_man->GetHDChain().seed_id;
115  if (!seed_id.IsNull()) {
116  obj.pushKV("hdseedid", seed_id.GetHex());
117  }
118  }
119 
120  if (pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) {
121  obj.pushKV("keypoolsize_hd_internal", (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize));
122  }
123  if (pwallet->IsCrypted()) {
124  obj.pushKV("unlocked_until", pwallet->nRelockTime);
125  }
126  obj.pushKV("paytxfee", ValueFromAmount(pwallet->m_pay_tx_fee.GetFeePerK()));
127  obj.pushKV("private_keys_enabled", !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
128  obj.pushKV("avoid_reuse", pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE));
129  if (pwallet->IsScanning()) {
130  UniValue scanning(UniValue::VOBJ);
131  scanning.pushKV("duration", Ticks<std::chrono::seconds>(pwallet->ScanningDuration()));
132  scanning.pushKV("progress", pwallet->ScanningProgress());
133  obj.pushKV("scanning", scanning);
134  } else {
135  obj.pushKV("scanning", false);
136  }
137  obj.pushKV("descriptors", pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
138  obj.pushKV("external_signer", pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER));
139  obj.pushKV("blank", pwallet->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET));
140  if (int64_t birthtime = pwallet->GetBirthTime(); birthtime != UNKNOWN_TIME) {
141  obj.pushKV("birthtime", birthtime);
142  }
143 
144  AppendLastProcessedBlock(obj, *pwallet);
145  return obj;
146 },
147  };
148 }
149 
151 {
152  return RPCHelpMan{"listwalletdir",
153  "Returns a list of wallets in the wallet directory.\n",
154  {},
155  RPCResult{
156  RPCResult::Type::OBJ, "", "",
157  {
158  {RPCResult::Type::ARR, "wallets", "",
159  {
160  {RPCResult::Type::OBJ, "", "",
161  {
162  {RPCResult::Type::STR, "name", "The wallet name"},
163  }},
164  }},
165  }
166  },
167  RPCExamples{
168  HelpExampleCli("listwalletdir", "")
169  + HelpExampleRpc("listwalletdir", "")
170  },
171  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
172 {
173  UniValue wallets(UniValue::VARR);
174  for (const auto& path : ListDatabases(GetWalletDir())) {
176  wallet.pushKV("name", path.utf8string());
177  wallets.push_back(wallet);
178  }
179 
180  UniValue result(UniValue::VOBJ);
181  result.pushKV("wallets", wallets);
182  return result;
183 },
184  };
185 }
186 
188 {
189  return RPCHelpMan{"listwallets",
190  "Returns a list of currently loaded wallets.\n"
191  "For full information on the wallet, use \"getwalletinfo\"\n",
192  {},
193  RPCResult{
194  RPCResult::Type::ARR, "", "",
195  {
196  {RPCResult::Type::STR, "walletname", "the wallet name"},
197  }
198  },
199  RPCExamples{
200  HelpExampleCli("listwallets", "")
201  + HelpExampleRpc("listwallets", "")
202  },
203  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
204 {
206 
207  WalletContext& context = EnsureWalletContext(request.context);
208  for (const std::shared_ptr<CWallet>& wallet : GetWallets(context)) {
209  LOCK(wallet->cs_wallet);
210  obj.push_back(wallet->GetName());
211  }
212 
213  return obj;
214 },
215  };
216 }
217 
219 {
220  return RPCHelpMan{"loadwallet",
221  "\nLoads a wallet from a wallet file or directory."
222  "\nNote that all wallet command-line options used when starting bitcoind will be"
223  "\napplied to the new wallet.\n",
224  {
225  {"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The wallet directory or .dat file."},
226  {"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
227  },
228  RPCResult{
229  RPCResult::Type::OBJ, "", "",
230  {
231  {RPCResult::Type::STR, "name", "The wallet name if loaded successfully."},
232  {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to loading the wallet.",
233  {
234  {RPCResult::Type::STR, "", ""},
235  }},
236  }
237  },
238  RPCExamples{
239  HelpExampleCli("loadwallet", "\"test.dat\"")
240  + HelpExampleRpc("loadwallet", "\"test.dat\"")
241  },
242  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
243 {
244  WalletContext& context = EnsureWalletContext(request.context);
245  const std::string name(request.params[0].get_str());
246 
247  DatabaseOptions options;
248  DatabaseStatus status;
249  ReadDatabaseArgs(*context.args, options);
250  options.require_existing = true;
252  std::vector<bilingual_str> warnings;
253  std::optional<bool> load_on_start = request.params[1].isNull() ? std::nullopt : std::optional<bool>(request.params[1].get_bool());
254 
255  {
256  LOCK(context.wallets_mutex);
257  if (std::any_of(context.wallets.begin(), context.wallets.end(), [&name](const auto& wallet) { return wallet->GetName() == name; })) {
258  throw JSONRPCError(RPC_WALLET_ALREADY_LOADED, "Wallet \"" + name + "\" is already loaded.");
259  }
260  }
261 
262  std::shared_ptr<CWallet> const wallet = LoadWallet(context, name, load_on_start, options, status, error, warnings);
263 
264  HandleWalletError(wallet, status, error);
265 
267  obj.pushKV("name", wallet->GetName());
268  PushWarnings(warnings, obj);
269 
270  return obj;
271 },
272  };
273 }
274 
276 {
277  std::string flags;
278  for (auto& it : WALLET_FLAG_MAP)
279  if (it.second & MUTABLE_WALLET_FLAGS)
280  flags += (flags == "" ? "" : ", ") + it.first;
281 
282  return RPCHelpMan{"setwalletflag",
283  "\nChange the state of the given wallet flag for a wallet.\n",
284  {
285  {"flag", RPCArg::Type::STR, RPCArg::Optional::NO, "The name of the flag to change. Current available flags: " + flags},
286  {"value", RPCArg::Type::BOOL, RPCArg::Default{true}, "The new state."},
287  },
288  RPCResult{
289  RPCResult::Type::OBJ, "", "",
290  {
291  {RPCResult::Type::STR, "flag_name", "The name of the flag that was modified"},
292  {RPCResult::Type::BOOL, "flag_state", "The new state of the flag"},
293  {RPCResult::Type::STR, "warnings", /*optional=*/true, "Any warnings associated with the change"},
294  }
295  },
296  RPCExamples{
297  HelpExampleCli("setwalletflag", "avoid_reuse")
298  + HelpExampleRpc("setwalletflag", "\"avoid_reuse\"")
299  },
300  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
301 {
302  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
303  if (!pwallet) return UniValue::VNULL;
304 
305  std::string flag_str = request.params[0].get_str();
306  bool value = request.params[1].isNull() || request.params[1].get_bool();
307 
308  if (!WALLET_FLAG_MAP.count(flag_str)) {
309  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unknown wallet flag: %s", flag_str));
310  }
311 
312  auto flag = WALLET_FLAG_MAP.at(flag_str);
313 
314  if (!(flag & MUTABLE_WALLET_FLAGS)) {
315  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is immutable: %s", flag_str));
316  }
317 
319 
320  if (pwallet->IsWalletFlagSet(flag) == value) {
321  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is already set to %s: %s", value ? "true" : "false", flag_str));
322  }
323 
324  res.pushKV("flag_name", flag_str);
325  res.pushKV("flag_state", value);
326 
327  if (value) {
328  pwallet->SetWalletFlag(flag);
329  } else {
330  pwallet->UnsetWalletFlag(flag);
331  }
332 
333  if (flag && value && WALLET_FLAG_CAVEATS.count(flag)) {
334  res.pushKV("warnings", WALLET_FLAG_CAVEATS.at(flag));
335  }
336 
337  return res;
338 },
339  };
340 }
341 
343 {
344  return RPCHelpMan{
345  "createwallet",
346  "\nCreates and loads a new wallet.\n",
347  {
348  {"wallet_name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name for the new wallet. If this is a path, the wallet will be created at the path location."},
349  {"disable_private_keys", RPCArg::Type::BOOL, RPCArg::Default{false}, "Disable the possibility of private keys (only watchonlys are possible in this mode)."},
350  {"blank", RPCArg::Type::BOOL, RPCArg::Default{false}, "Create a blank wallet. A blank wallet has no keys or HD seed. One can be set using sethdseed."},
351  {"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Encrypt the wallet with this passphrase."},
352  {"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{false}, "Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind."},
353  {"descriptors", RPCArg::Type::BOOL, RPCArg::Default{true}, "Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation."
354  " Setting to \"false\" will create a legacy wallet; This is only possible with the -deprecatedrpc=create_bdb setting because, the legacy wallet type is being deprecated and"
355  " support for creating and opening legacy wallets will be removed in the future."},
356  {"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
357  {"external_signer", RPCArg::Type::BOOL, RPCArg::Default{false}, "Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true."},
358  },
359  RPCResult{
360  RPCResult::Type::OBJ, "", "",
361  {
362  {RPCResult::Type::STR, "name", "The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path."},
363  {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to creating and loading the wallet.",
364  {
365  {RPCResult::Type::STR, "", ""},
366  }},
367  }
368  },
369  RPCExamples{
370  HelpExampleCli("createwallet", "\"testwallet\"")
371  + HelpExampleRpc("createwallet", "\"testwallet\"")
372  + HelpExampleCliNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}})
373  + HelpExampleRpcNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}})
374  },
375  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
376 {
377  WalletContext& context = EnsureWalletContext(request.context);
378  uint64_t flags = 0;
379  if (!request.params[1].isNull() && request.params[1].get_bool()) {
381  }
382 
383  if (!request.params[2].isNull() && request.params[2].get_bool()) {
385  }
386  SecureString passphrase;
387  passphrase.reserve(100);
388  std::vector<bilingual_str> warnings;
389  if (!request.params[3].isNull()) {
390  passphrase = std::string_view{request.params[3].get_str()};
391  if (passphrase.empty()) {
392  // Empty string means unencrypted
393  warnings.emplace_back(Untranslated("Empty string given as passphrase, wallet will not be encrypted."));
394  }
395  }
396 
397  if (!request.params[4].isNull() && request.params[4].get_bool()) {
399  }
400  if (self.Arg<bool>(5)) {
401 #ifndef USE_SQLITE
402  throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without sqlite support (required for descriptor wallets)");
403 #endif
405  } else {
406  if (!context.chain->rpcEnableDeprecated("create_bdb")) {
407  throw JSONRPCError(RPC_WALLET_ERROR, "BDB wallet creation is deprecated and will be removed in a future release."
408  " In this release it can be re-enabled temporarily with the -deprecatedrpc=create_bdb setting.");
409  }
410  }
411  if (!request.params[7].isNull() && request.params[7].get_bool()) {
412 #ifdef ENABLE_EXTERNAL_SIGNER
414 #else
415  throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without external signing support (required for external signing)");
416 #endif
417  }
418 
419 #ifndef USE_BDB
420  if (!(flags & WALLET_FLAG_DESCRIPTORS)) {
421  throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without bdb support (required for legacy wallets)");
422  }
423 #endif
424 
425  DatabaseOptions options;
426  DatabaseStatus status;
427  ReadDatabaseArgs(*context.args, options);
428  options.require_create = true;
429  options.create_flags = flags;
430  options.create_passphrase = passphrase;
432  std::optional<bool> load_on_start = request.params[6].isNull() ? std::nullopt : std::optional<bool>(request.params[6].get_bool());
433  const std::shared_ptr<CWallet> wallet = CreateWallet(context, request.params[0].get_str(), load_on_start, options, status, error, warnings);
434  if (!wallet) {
435  RPCErrorCode code = status == DatabaseStatus::FAILED_ENCRYPT ? RPC_WALLET_ENCRYPTION_FAILED : RPC_WALLET_ERROR;
436  throw JSONRPCError(code, error.original);
437  }
438 
440  obj.pushKV("name", wallet->GetName());
441  PushWarnings(warnings, obj);
442 
443  return obj;
444 },
445  };
446 }
447 
449 {
450  return RPCHelpMan{"unloadwallet",
451  "Unloads the wallet referenced by the request endpoint, otherwise unloads the wallet specified in the argument.\n"
452  "Specifying the wallet name on a wallet endpoint is invalid.",
453  {
454  {"wallet_name", RPCArg::Type::STR, RPCArg::DefaultHint{"the wallet name from the RPC endpoint"}, "The name of the wallet to unload. If provided both here and in the RPC endpoint, the two must be identical."},
455  {"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
456  },
458  {RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to unloading the wallet.",
459  {
460  {RPCResult::Type::STR, "", ""},
461  }},
462  }},
463  RPCExamples{
464  HelpExampleCli("unloadwallet", "wallet_name")
465  + HelpExampleRpc("unloadwallet", "wallet_name")
466  },
467  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
468 {
469  std::string wallet_name;
470  if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
471  if (!(request.params[0].isNull() || request.params[0].get_str() == wallet_name)) {
472  throw JSONRPCError(RPC_INVALID_PARAMETER, "RPC endpoint wallet and wallet_name parameter specify different wallets");
473  }
474  } else {
475  wallet_name = request.params[0].get_str();
476  }
477 
478  WalletContext& context = EnsureWalletContext(request.context);
479  std::shared_ptr<CWallet> wallet = GetWallet(context, wallet_name);
480  if (!wallet) {
481  throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
482  }
483 
484  std::vector<bilingual_str> warnings;
485  {
486  WalletRescanReserver reserver(*wallet);
487  if (!reserver.reserve()) {
488  throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
489  }
490 
491  // Release the "main" shared pointer and prevent further notifications.
492  // Note that any attempt to load the same wallet would fail until the wallet
493  // is destroyed (see CheckUniqueFileid).
494  std::optional<bool> load_on_start{self.MaybeArg<bool>(1)};
495  if (!RemoveWallet(context, wallet, load_on_start, warnings)) {
496  throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");
497  }
498  }
499 
500  UnloadWallet(std::move(wallet));
501 
502  UniValue result(UniValue::VOBJ);
503  PushWarnings(warnings, result);
504 
505  return result;
506 },
507  };
508 }
509 
511 {
512  return RPCHelpMan{"sethdseed",
513  "\nSet or generate a new HD wallet seed. Non-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n"
514  "HD will have a new HD seed set so that new keys added to the keypool will be derived from this new seed.\n"
515  "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed." + HELP_REQUIRING_PASSPHRASE +
516  "Note: This command is only compatible with legacy wallets.\n",
517  {
518  {"newkeypool", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to flush old unused addresses, including change addresses, from the keypool and regenerate it.\n"
519  "If true, the next address from getnewaddress and change address from getrawchangeaddress will be from this new seed.\n"
520  "If false, addresses (including change addresses if the wallet already had HD Chain Split enabled) from the existing\n"
521  "keypool will be used until it has been depleted."},
522  {"seed", RPCArg::Type::STR, RPCArg::DefaultHint{"random seed"}, "The WIF private key to use as the new HD seed.\n"
523  "The seed value can be retrieved using the dumpwallet command. It is the private key marked hdseed=1"},
524  },
526  RPCExamples{
527  HelpExampleCli("sethdseed", "")
528  + HelpExampleCli("sethdseed", "false")
529  + HelpExampleCli("sethdseed", "true \"wifkey\"")
530  + HelpExampleRpc("sethdseed", "true, \"wifkey\"")
531  },
532  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
533 {
534  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
535  if (!pwallet) return UniValue::VNULL;
536 
537  LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet, true);
538 
539  if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
540  throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set a HD seed to a wallet with private keys disabled");
541  }
542 
543  LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
544 
545  // Do not do anything to non-HD wallets
546  if (!pwallet->CanSupportFeature(FEATURE_HD)) {
547  throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set an HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD");
548  }
549 
550  EnsureWalletIsUnlocked(*pwallet);
551 
552  bool flush_key_pool = true;
553  if (!request.params[0].isNull()) {
554  flush_key_pool = request.params[0].get_bool();
555  }
556 
557  CPubKey master_pub_key;
558  if (request.params[1].isNull()) {
559  master_pub_key = spk_man.GenerateNewSeed();
560  } else {
561  CKey key = DecodeSecret(request.params[1].get_str());
562  if (!key.IsValid()) {
563  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
564  }
565 
566  if (HaveKey(spk_man, key)) {
567  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Already have this key (either as an HD seed or as a loose private key)");
568  }
569 
570  master_pub_key = spk_man.DeriveNewSeed(key);
571  }
572 
573  spk_man.SetHDSeed(master_pub_key);
574  if (flush_key_pool) spk_man.NewKeyPool();
575 
576  return UniValue::VNULL;
577 },
578  };
579 }
580 
582 {
583  return RPCHelpMan{"upgradewallet",
584  "\nUpgrade the wallet. Upgrades to the latest version if no version number is specified.\n"
585  "New keys may be generated and a new wallet backup will need to be made.",
586  {
587  {"version", RPCArg::Type::NUM, RPCArg::Default{int{FEATURE_LATEST}}, "The version number to upgrade to. Default is the latest wallet version."}
588  },
589  RPCResult{
590  RPCResult::Type::OBJ, "", "",
591  {
592  {RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"},
593  {RPCResult::Type::NUM, "previous_version", "Version of wallet before this operation"},
594  {RPCResult::Type::NUM, "current_version", "Version of wallet after this operation"},
595  {RPCResult::Type::STR, "result", /*optional=*/true, "Description of result, if no error"},
596  {RPCResult::Type::STR, "error", /*optional=*/true, "Error message (if there is one)"}
597  },
598  },
599  RPCExamples{
600  HelpExampleCli("upgradewallet", "169900")
601  + HelpExampleRpc("upgradewallet", "169900")
602  },
603  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
604 {
605  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
606  if (!pwallet) return UniValue::VNULL;
607 
608  EnsureWalletIsUnlocked(*pwallet);
609 
610  int version = 0;
611  if (!request.params[0].isNull()) {
612  version = request.params[0].getInt<int>();
613  }
615  const int previous_version{pwallet->GetVersion()};
616  const bool wallet_upgraded{pwallet->UpgradeWallet(version, error)};
617  const int current_version{pwallet->GetVersion()};
618  std::string result;
619 
620  if (wallet_upgraded) {
621  if (previous_version == current_version) {
622  result = "Already at latest version. Wallet version unchanged.";
623  } else {
624  result = strprintf("Wallet upgraded successfully from version %i to version %i.", previous_version, current_version);
625  }
626  }
627 
629  obj.pushKV("wallet_name", pwallet->GetName());
630  obj.pushKV("previous_version", previous_version);
631  obj.pushKV("current_version", current_version);
632  if (!result.empty()) {
633  obj.pushKV("result", result);
634  } else {
635  CHECK_NONFATAL(!error.empty());
636  obj.pushKV("error", error.original);
637  }
638  return obj;
639 },
640  };
641 }
642 
644 {
645  return RPCHelpMan{"simulaterawtransaction",
646  "\nCalculate the balance change resulting in the signing and broadcasting of the given transaction(s).\n",
647  {
648  {"rawtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "An array of hex strings of raw transactions.\n",
649  {
651  },
652  },
654  {
655  {"include_watchonly", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Whether to include watch-only addresses (see RPC importaddress)"},
656  },
657  },
658  },
659  RPCResult{
660  RPCResult::Type::OBJ, "", "",
661  {
662  {RPCResult::Type::STR_AMOUNT, "balance_change", "The wallet balance change (negative means decrease)."},
663  }
664  },
665  RPCExamples{
666  HelpExampleCli("simulaterawtransaction", "[\"myhex\"]")
667  + HelpExampleRpc("simulaterawtransaction", "[\"myhex\"]")
668  },
669  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
670 {
671  const std::shared_ptr<const CWallet> rpc_wallet = GetWalletForJSONRPCRequest(request);
672  if (!rpc_wallet) return UniValue::VNULL;
673  const CWallet& wallet = *rpc_wallet;
674 
675  LOCK(wallet.cs_wallet);
676 
677  UniValue include_watchonly(UniValue::VNULL);
678  if (request.params[1].isObject()) {
679  UniValue options = request.params[1];
680  RPCTypeCheckObj(options,
681  {
682  {"include_watchonly", UniValueType(UniValue::VBOOL)},
683  },
684  true, true);
685 
686  include_watchonly = options["include_watchonly"];
687  }
688 
690  if (ParseIncludeWatchonly(include_watchonly, wallet)) {
691  filter |= ISMINE_WATCH_ONLY;
692  }
693 
694  const auto& txs = request.params[0].get_array();
695  CAmount changes{0};
696  std::map<COutPoint, CAmount> new_utxos; // UTXO:s that were made available in transaction array
697  std::set<COutPoint> spent;
698 
699  for (size_t i = 0; i < txs.size(); ++i) {
701  if (!DecodeHexTx(mtx, txs[i].get_str(), /* try_no_witness */ true, /* try_witness */ true)) {
702  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Transaction hex string decoding failure.");
703  }
704 
705  // Fetch previous transactions (inputs)
706  std::map<COutPoint, Coin> coins;
707  for (const CTxIn& txin : mtx.vin) {
708  coins[txin.prevout]; // Create empty map entry keyed by prevout.
709  }
710  wallet.chain().findCoins(coins);
711 
712  // Fetch debit; we are *spending* these; if the transaction is signed and
713  // broadcast, we will lose everything in these
714  for (const auto& txin : mtx.vin) {
715  const auto& outpoint = txin.prevout;
716  if (spent.count(outpoint)) {
717  throw JSONRPCError(RPC_INVALID_PARAMETER, "Transaction(s) are spending the same output more than once");
718  }
719  if (new_utxos.count(outpoint)) {
720  changes -= new_utxos.at(outpoint);
721  new_utxos.erase(outpoint);
722  } else {
723  if (coins.at(outpoint).IsSpent()) {
724  throw JSONRPCError(RPC_INVALID_PARAMETER, "One or more transaction inputs are missing or have been spent already");
725  }
726  changes -= wallet.GetDebit(txin, filter);
727  }
728  spent.insert(outpoint);
729  }
730 
731  // Iterate over outputs; we are *receiving* these, if the wallet considers
732  // them "mine"; if the transaction is signed and broadcast, we will receive
733  // everything in these
734  // Also populate new_utxos in case these are spent in later transactions
735 
736  const auto& hash = mtx.GetHash();
737  for (size_t i = 0; i < mtx.vout.size(); ++i) {
738  const auto& txout = mtx.vout[i];
739  bool is_mine = 0 < (wallet.IsMine(txout) & filter);
740  changes += new_utxos[COutPoint(hash, i)] = is_mine ? txout.nValue : 0;
741  }
742  }
743 
744  UniValue result(UniValue::VOBJ);
745  result.pushKV("balance_change", ValueFromAmount(changes));
746 
747  return result;
748 }
749  };
750 }
751 
753 {
754  return RPCHelpMan{"migratewallet",
755  "\nMigrate the wallet to a descriptor wallet.\n"
756  "A new wallet backup will need to be made.\n"
757  "\nThe migration process will create a backup of the wallet before migrating. This backup\n"
758  "file will be named <wallet name>-<timestamp>.legacy.bak and can be found in the directory\n"
759  "for this wallet. In the event of an incorrect migration, the backup can be restored using restorewallet."
760  "\nEncrypted wallets must have the passphrase provided as an argument to this call.\n"
761  "\nThis RPC may take a long time to complete. Increasing the RPC client timeout is recommended.",
762  {
763  {"wallet_name", RPCArg::Type::STR, RPCArg::DefaultHint{"the wallet name from the RPC endpoint"}, "The name of the wallet to migrate. If provided both here and in the RPC endpoint, the two must be identical."},
764  {"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "The wallet passphrase"},
765  },
766  RPCResult{
767  RPCResult::Type::OBJ, "", "",
768  {
769  {RPCResult::Type::STR, "wallet_name", "The name of the primary migrated wallet"},
770  {RPCResult::Type::STR, "watchonly_name", /*optional=*/true, "The name of the migrated wallet containing the watchonly scripts"},
771  {RPCResult::Type::STR, "solvables_name", /*optional=*/true, "The name of the migrated wallet containing solvable but not watched scripts"},
772  {RPCResult::Type::STR, "backup_path", "The location of the backup of the original wallet"},
773  }
774  },
775  RPCExamples{
776  HelpExampleCli("migratewallet", "")
777  + HelpExampleRpc("migratewallet", "")
778  },
779  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
780  {
781  std::string wallet_name;
782  if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
783  if (!(request.params[0].isNull() || request.params[0].get_str() == wallet_name)) {
784  throw JSONRPCError(RPC_INVALID_PARAMETER, "RPC endpoint wallet and wallet_name parameter specify different wallets");
785  }
786  } else {
787  if (request.params[0].isNull()) {
788  throw JSONRPCError(RPC_INVALID_PARAMETER, "Either RPC endpoint wallet or wallet_name parameter must be provided");
789  }
790  wallet_name = request.params[0].get_str();
791  }
792 
793  SecureString wallet_pass;
794  wallet_pass.reserve(100);
795  if (!request.params[1].isNull()) {
796  wallet_pass = std::string_view{request.params[1].get_str()};
797  }
798 
799  WalletContext& context = EnsureWalletContext(request.context);
800  util::Result<MigrationResult> res = MigrateLegacyToDescriptor(wallet_name, wallet_pass, context);
801  if (!res) {
802  throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(res).original);
803  }
804 
806  r.pushKV("wallet_name", res->wallet_name);
807  if (res->watchonly_wallet) {
808  r.pushKV("watchonly_name", res->watchonly_wallet->GetName());
809  }
810  if (res->solvables_wallet) {
811  r.pushKV("solvables_name", res->solvables_wallet->GetName());
812  }
813  r.pushKV("backup_path", res->backup_path.utf8string());
814 
815  return r;
816  },
817  };
818 }
819 
820 // addresses
831 #ifdef ENABLE_EXTERNAL_SIGNER
833 #endif // ENABLE_EXTERNAL_SIGNER
834 
835 // backup
849 
850 // coins
859 
860 // encryption
865 
866 // spend
873 RPCHelpMan send();
878 
879 // signmessage
881 
882 // transactions
891 
893 {
894  static const CRPCCommand commands[]{
895  {"rawtransactions", &fundrawtransaction},
896  {"wallet", &abandontransaction},
897  {"wallet", &abortrescan},
898  {"wallet", &addmultisigaddress},
899  {"wallet", &backupwallet},
900  {"wallet", &bumpfee},
901  {"wallet", &psbtbumpfee},
902  {"wallet", &createwallet},
903  {"wallet", &restorewallet},
904  {"wallet", &dumpprivkey},
905  {"wallet", &dumpwallet},
906  {"wallet", &encryptwallet},
907  {"wallet", &getaddressesbylabel},
908  {"wallet", &getaddressinfo},
909  {"wallet", &getbalance},
910  {"wallet", &getnewaddress},
911  {"wallet", &getrawchangeaddress},
912  {"wallet", &getreceivedbyaddress},
913  {"wallet", &getreceivedbylabel},
914  {"wallet", &gettransaction},
915  {"wallet", &getunconfirmedbalance},
916  {"wallet", &getbalances},
917  {"wallet", &getwalletinfo},
918  {"wallet", &importaddress},
919  {"wallet", &importdescriptors},
920  {"wallet", &importmulti},
921  {"wallet", &importprivkey},
922  {"wallet", &importprunedfunds},
923  {"wallet", &importpubkey},
924  {"wallet", &importwallet},
925  {"wallet", &keypoolrefill},
926  {"wallet", &listaddressgroupings},
927  {"wallet", &listdescriptors},
928  {"wallet", &listlabels},
929  {"wallet", &listlockunspent},
930  {"wallet", &listreceivedbyaddress},
931  {"wallet", &listreceivedbylabel},
932  {"wallet", &listsinceblock},
933  {"wallet", &listtransactions},
934  {"wallet", &listunspent},
935  {"wallet", &listwalletdir},
936  {"wallet", &listwallets},
937  {"wallet", &loadwallet},
938  {"wallet", &lockunspent},
939  {"wallet", &migratewallet},
940  {"wallet", &newkeypool},
941  {"wallet", &removeprunedfunds},
942  {"wallet", &rescanblockchain},
943  {"wallet", &send},
944  {"wallet", &sendmany},
945  {"wallet", &sendtoaddress},
946  {"wallet", &sethdseed},
947  {"wallet", &setlabel},
948  {"wallet", &settxfee},
949  {"wallet", &setwalletflag},
950  {"wallet", &signmessage},
951  {"wallet", &signrawtransactionwithwallet},
952  {"wallet", &simulaterawtransaction},
953  {"wallet", &sendall},
954  {"wallet", &unloadwallet},
955  {"wallet", &upgradewallet},
956  {"wallet", &walletcreatefundedpsbt},
957 #ifdef ENABLE_EXTERNAL_SIGNER
958  {"wallet", &walletdisplayaddress},
959 #endif // ENABLE_EXTERNAL_SIGNER
960  {"wallet", &walletlock},
961  {"wallet", &walletpassphrase},
962  {"wallet", &walletpassphrasechange},
963  {"wallet", &walletprocesspsbt},
964  };
965  return commands;
966 }
967 } // namespace wallet
RPCHelpMan walletlock()
Definition: encrypt.cpp:174
RPCHelpMan importaddress()
Definition: backup.cpp:220
RPCHelpMan importwallet()
Definition: backup.cpp:494
void push_back(UniValue val)
Definition: univalue.cpp:104
void ReadDatabaseArgs(const ArgsManager &args, DatabaseOptions &options)
Definition: db.cpp:142
RPCHelpMan listlockunspent()
Definition: coins.cpp:377
static RPCHelpMan listwalletdir()
Definition: wallet.cpp:150
RPCHelpMan simulaterawtransaction()
Definition: wallet.cpp:643
static RPCHelpMan setwalletflag()
Definition: wallet.cpp:275
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:179
const CHDChain & GetHDChain() const
RPCHelpMan importmulti()
Definition: backup.cpp:1249
RPCHelpMan sendmany()
Definition: spend.cpp:317
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: util.cpp:43
Required arg.
RPCHelpMan restorewallet()
Definition: backup.cpp:1894
Bilingual messages:
Definition: translation.h:18
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
static RPCHelpMan loadwallet()
Definition: wallet.cpp:218
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
RecursiveMutex cs_KeyStore
RPCHelpMan walletpassphrase()
Definition: encrypt.cpp:11
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:188
RPCHelpMan sendtoaddress()
Definition: spend.cpp:223
std::vector< CTxIn > vin
Definition: transaction.h:379
RPCHelpMan getreceivedbylabel()
Definition: coins.cpp:122
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:48
std::shared_ptr< CWallet > LoadWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:360
RPCHelpMan listtransactions()
RPCHelpMan abandontransaction()
#define CHECK_NONFATAL(condition)
Identity function.
Definition: check.h:73
RPCHelpMan psbtbumpfee()
Definition: spend.cpp:1186
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
RPCHelpMan lockunspent()
Definition: coins.cpp:241
static RPCHelpMan sethdseed()
Definition: wallet.cpp:510
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:58
bool ParseIncludeWatchonly(const UniValue &include_watchonly, const CWallet &wallet)
Used by RPC commands that have an include_watchonly parameter.
Definition: util.cpp:51
void SetHDSeed(const CPubKey &key)
const std::byte * end() const
Definition: key.h:116
RAII object to check and reserve a wallet rescan.
Definition: wallet.h:1065
Balance GetBalance(const CWallet &wallet, const int min_depth, bool avoid_reuse)
Definition: receive.cpp:293
static const RPCResult RESULT_LAST_PROCESSED_BLOCK
Definition: util.h:28
bool reserve(bool with_passphrase=false)
Definition: wallet.h:1076
RPCHelpMan getaddressinfo()
Definition: addresses.cpp:497
RPCHelpMan send()
Definition: spend.cpp:1188
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:11
RPCHelpMan sendall()
Definition: spend.cpp:1302
This same wallet is already loaded.
Definition: protocol.h:82
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:164
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses, and other watch only things, and is therefore "blank.".
Definition: walletutil.h:71
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
static constexpr uint64_t MUTABLE_WALLET_FLAGS
Definition: wallet.h:160
static RPCHelpMan getwalletinfo()
Definition: wallet.cpp:44
static RPCHelpMan unloadwallet()
Definition: wallet.cpp:448
RPCHelpMan rescanblockchain()
RPCHelpMan walletdisplayaddress()
Definition: addresses.cpp:759
RPCHelpMan signmessage()
Definition: signmessage.cpp:14
void HandleWalletError(const std::shared_ptr< CWallet > wallet, DatabaseStatus &status, bilingual_str &error)
Definition: util.cpp:154
RPCHelpMan walletcreatefundedpsbt()
Definition: spend.cpp:1637
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
Special type that is a STR with only hex chars.
RPCHelpMan walletpassphrasechange()
Definition: encrypt.cpp:115
Indicates that the wallet needs an external signer.
Definition: walletutil.h:77
#define LOCK2(cs1, cs2)
Definition: sync.h:258
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:173
RPCHelpMan fundrawtransaction()
Definition: spend.cpp:732
static constexpr int64_t UNKNOWN_TIME
Constant representing an unknown spkm creation time.
std::underlying_type< isminetype >::type isminefilter
used for bitflags of isminetype
Definition: wallet.h:43
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:58
RPCHelpMan signrawtransactionwithwallet()
Definition: spend.cpp:864
Special string with only hex chars.
SecureString create_passphrase
Definition: db.h:187
RPCHelpMan setlabel()
Definition: addresses.cpp:122
RPCHelpMan listsinceblock()
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start)
Definition: wallet.cpp:172
RPCHelpMan walletprocesspsbt()
Definition: spend.cpp:1554
uint64_t create_flags
Definition: db.h:186
An input of a transaction.
Definition: transaction.h:66
static RPCHelpMan createwallet()
Definition: wallet.cpp:342
#define LOCK(cs)
Definition: sync.h:257
const char * name
Definition: rest.cpp:49
RPCHelpMan listreceivedbylabel()
An encapsulated public key.
Definition: pubkey.h:33
RPCHelpMan listunspent()
Definition: coins.cpp:500
RPCHelpMan newkeypool()
Definition: addresses.cpp:361
WalletContext & EnsureWalletContext(const std::any &context)
Definition: util.cpp:103
RPCHelpMan listdescriptors()
Definition: backup.cpp:1747
Indicate that this wallet supports DescriptorScriptPubKeyMan.
Definition: walletutil.h:74
const std::string CURRENCY_UNIT
Definition: feerate.h:17
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:300
General application defined errors.
Definition: protocol.h:39
std::string DefaultHint
Hint for default value.
Definition: util.h:199
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
Definition: util.cpp:160
void PushWarnings(const UniValue &warnings, UniValue &obj)
Push warning messages to an RPC "warnings" field as a JSON array of strings.
Definition: util.cpp:1331
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
Definition: key.h:122
void ReadDatabaseArgs(const ArgsManager &args, DBOptions &options)
Invalid address or key.
Definition: protocol.h:41
Txid GetHash() const
Compute the hash of this CMutableTransaction.
Definition: transaction.cpp:69
Invalid wallet specified.
Definition: protocol.h:80
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:28
static const std::map< std::string, WalletFlags > WALLET_FLAG_MAP
Definition: wallet.h:163
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:155
std::vector< CTxOut > vout
Definition: transaction.h:380
constexpr bool IsNull() const
Definition: uint256.h:42
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition: key.h:99
RPCHelpMan dumpprivkey()
Definition: backup.cpp:642
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
Definition: wallet.cpp:239
const std::string HELP_REQUIRING_PASSPHRASE
Definition: util.cpp:20
util::Result< MigrationResult > MigrateLegacyToDescriptor(const std::string &wallet_name, const SecureString &passphrase, WalletContext &context)
Do all steps to migrate a legacy wallet to a descriptor wallet.
Definition: wallet.cpp:4286
Special numeric to denote unix epoch time.
RPCHelpMan listreceivedbyaddress()
RPCHelpMan importdescriptors()
Definition: backup.cpp:1590
LegacyScriptPubKeyMan & EnsureLegacyScriptPubKeyMan(CWallet &wallet, bool also_create)
Definition: util.cpp:113
RPCHelpMan encryptwallet()
Definition: encrypt.cpp:216
int flags
Definition: bitcoin-tx.cpp:530
std::shared_ptr< CWallet > GetWallet(WalletContext &context, const std::string &name)
Definition: wallet.cpp:191
RPCHelpMan importpubkey()
Definition: backup.cpp:410
Failed to encrypt the wallet.
Definition: protocol.h:78
DatabaseStatus
Definition: db.h:196
Optional argument for which the default value is omitted from help text for one of two reasons: ...
CPubKey DeriveNewSeed(const CKey &key)
RPCHelpMan getunconfirmedbalance()
Definition: coins.cpp:218
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
Definition: wallet.cpp:178
RPCHelpMan listlabels()
Definition: addresses.cpp:703
An interface to be implemented by keystores that support signing.
RPCHelpMan importprunedfunds()
Definition: backup.cpp:322
Special string to represent a floating point amount.
void AppendLastProcessedBlock(UniValue &entry, const CWallet &wallet) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
Definition: util.cpp:181
bool error(const char *fmt, const Args &... args)
Definition: logging.h:267
void pushKV(std::string key, UniValue val)
Definition: univalue.cpp:126
RPCHelpMan dumpwallet()
Definition: backup.cpp:689
RPCHelpMan gettransaction()
const std::byte * begin() const
Definition: key.h:115
RPCHelpMan getaddressesbylabel()
Definition: addresses.cpp:643
RPCHelpMan importprivkey()
Definition: backup.cpp:117
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:23
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
Definition: core_read.cpp:194
std::string GetHex() const
Definition: uint256.cpp:11
bool HaveKey(const SigningProvider &wallet, const CKey &key)
Checks if a CKey is in the given CWallet compressed or otherwise.
Definition: wallet.cpp:37
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:26
WalletContext struct containing references to state shared between CWallet instances, like the reference to the chain interface, and the list of opened wallets.
Definition: context.h:36
RPCHelpMan abortrescan()
void EnsureWalletIsUnlocked(const CWallet &wallet)
Definition: util.cpp:96
bilingual_str ErrorString(const Result< T > &result)
Definition: result.h:81
RPCHelpMan keypoolrefill()
Definition: addresses.cpp:317
interfaces::Chain * chain
Definition: context.h:37
A mutable version of CTransaction.
Definition: transaction.h:377
Wallet errors.
Definition: protocol.h:71
RPCHelpMan getreceivedbyaddress()
Definition: coins.cpp:81
std::vector< fs::path > ListDatabases(const fs::path &wallet_dir)
Recursively list database paths in directory.
Definition: db.cpp:19
RPCHelpMan getbalance()
Definition: coins.cpp:163
RPCHelpMan listaddressgroupings()
Definition: addresses.cpp:160
RPCHelpMan removeprunedfunds()
Definition: backup.cpp:378
An encapsulated private key.
Definition: key.h:32
Span< const CRPCCommand > GetWalletRPCCommands()
Definition: wallet.cpp:892
A Span is an object that can refer to a contiguous sequence of objects.
Definition: solver.h:20
std::shared_ptr< CWallet > wallet
RPCErrorCode
Bitcoin RPC error codes.
Definition: protocol.h:23
RPCHelpMan backupwallet()
Definition: backup.cpp:1860
CKey DecodeSecret(const std::string &str)
Definition: key_io.cpp:209
RPCHelpMan bumpfee()
Definition: spend.cpp:1185
static RPCHelpMan migratewallet()
Definition: wallet.cpp:752
std::shared_ptr< CWallet > CreateWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: wallet.cpp:373
RPCHelpMan getnewaddress()
Definition: addresses.cpp:23
RPCHelpMan getbalances()
Definition: coins.cpp:430
virtual bool rpcEnableDeprecated(const std::string &method)=0
Check if deprecated RPC is enabled.
static RPCHelpMan listwallets()
Definition: wallet.cpp:187
COutPoint prevout
Definition: transaction.h:69
ArgsManager * args
Definition: context.h:39
CKeyID seed_id
seed hash160
Definition: walletdb.h:102
RPCHelpMan getrawchangeaddress()
Definition: addresses.cpp:75
static RPCHelpMan upgradewallet()
Definition: wallet.cpp:581
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: util.h:74
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: util.cpp:72
static const std::map< uint64_t, std::string > WALLET_FLAG_CAVEATS
Definition: wallet.cpp:29
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest &request, std::string &wallet_name)
Definition: util.cpp:62
Error parsing or validating structure in raw format.
Definition: protocol.h:45
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency...
Definition: util.cpp:30
RPCHelpMan addmultisigaddress()
Definition: addresses.cpp:220
bool IsValid() const
Check whether this private key is valid.
Definition: key.h:119
RPCHelpMan settxfee()
Definition: spend.cpp:411