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