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