38 std::stringstream
ret;
39 for (
const unsigned char c : str) {
40 if (c <= 32 || c >= 128 || c ==
'%') {
50 std::stringstream
ret;
51 for (
unsigned int pos = 0; pos < str.length(); pos++) {
52 unsigned char c = str[pos];
53 if (c ==
'%' && pos+2 < str.length()) {
54 c = (((str[pos+1]>>6)*9+((str[pos+1]-
'0')&15)) << 4) |
55 ((str[pos+2]>>6)*9+((str[pos+2]-
'0')&15));
65 bool fLabelFound =
false;
67 spk_man->GetKey(keyid, key);
69 const auto* address_book_entry =
wallet.FindAddressBookEntry(dest);
70 if (address_book_entry) {
71 if (!strAddr.empty()) {
89 int64_t scanned_time =
wallet.RescanFromTime(time_begin, reserver, update);
90 if (
wallet.IsAbortingRescan()) {
92 }
else if (scanned_time > time_begin) {
99 auto& chain{
wallet.chain()};
100 if (!chain.havePruned()) {
108 if (found && !chain.hasBlocks(tip_hash, height)) {
116 "\nAdds a private key (as returned by dumpprivkey) to your wallet. Requires a new wallet backup.\n" 117 "Hint: use importmulti to import more than one private key.\n" 118 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 119 "may report that the imported key exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\n" 120 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 121 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 122 "Note: Use \"getwalletinfo\" to query the scanning progress.\n" 123 "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" with \"combo(X)\" for descriptor wallets.\n",
131 "\nDump a private key\n" 133 "\nImport the private key with rescan\n" 135 "\nImport using a label and without rescan\n" 136 +
HelpExampleCli(
"importprivkey",
"\"mykey\" \"testing\" false") +
137 "\nImport using default blank label and without rescan\n" 139 "\nAs a JSON-RPC call\n" 140 +
HelpExampleRpc(
"importprivkey",
"\"mykey\", \"testing\", false")
156 LOCK(pwallet->cs_wallet);
160 std::string strSecret = request.params[0].get_str();
164 if (!request.params[2].isNull())
165 fRescan = request.params[2].get_bool();
167 if (fRescan && pwallet->chain().havePruned()) {
174 if (fRescan && !reserver.
reserve()) {
185 pwallet->MarkDirty();
191 if (!request.params[1].isNull() || !pwallet->FindAddressBookEntry(dest)) {
197 if (!pwallet->ImportPrivKeys({{vchAddress, key}}, 1)) {
219 "\nAdds an address or script (in hex) that can be watched as if it were in your wallet but cannot be used to spend. Requires a new wallet backup.\n" 220 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 221 "may report that the imported address exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\n" 222 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 223 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 224 "If you have the full public key, you should call importpubkey instead of this.\n" 225 "Hint: use importmulti to import more than one address.\n" 226 "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n" 227 "as change, and not show up in many RPCs.\n" 228 "Note: Use \"getwalletinfo\" to query the scanning progress.\n" 229 "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" for descriptor wallets.\n",
238 "\nImport an address with rescan\n" 240 "\nImport using a label without rescan\n" 241 +
HelpExampleCli(
"importaddress",
"\"myaddress\" \"testing\" false") +
242 "\nAs a JSON-RPC call\n" 243 +
HelpExampleRpc(
"importaddress",
"\"myaddress\", \"testing\", false")
256 if (!request.params[2].isNull())
257 fRescan = request.params[2].get_bool();
259 if (fRescan && pwallet->chain().havePruned()) {
267 if (fRescan && !reserver.
reserve()) {
273 if (!request.params[3].isNull())
274 fP2SH = request.params[3].get_bool();
277 LOCK(pwallet->cs_wallet);
288 pwallet->MarkDirty();
291 }
else if (
IsHex(request.params[0].get_str())) {
292 std::vector<unsigned char> data(
ParseHex(request.params[0].get_str()));
293 CScript redeem_script(data.begin(), data.end());
295 std::set<CScript> scripts = {redeem_script};
296 pwallet->ImportScripts(scripts, 0);
302 pwallet->ImportScriptPubKeys(strLabel, scripts,
false,
true, 1);
310 pwallet->ResubmitWalletTransactions(
false,
true);
321 "\nImports funds without rescan. Corresponding address or script must previously be included in wallet. Aimed towards pruned wallets. The end-user is responsible to import additional transactions that subsequently spend the imported outputs or rescan after the point in the blockchain the transaction is included.\n",
334 if (!
DecodeHexTx(tx, request.params[0].get_str())) {
344 std::vector<uint256> vMatch;
345 std::vector<unsigned int> vIndex;
346 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) {
350 LOCK(pwallet->cs_wallet);
352 if (!pwallet->chain().findAncestorByHash(pwallet->GetLastBlockHash(), merkleBlock.header.GetHash(),
FoundBlock().
height(height))) {
356 std::vector<uint256>::const_iterator it;
357 if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx)) == vMatch.end()) {
361 unsigned int txnIndex = vIndex[it - vMatch.begin()];
364 if (pwallet->IsMine(*tx_ref)) {
365 pwallet->AddToWallet(std::move(tx_ref),
TxStateConfirmed{merkleBlock.header.GetHash(), height,
static_cast<int>(txnIndex)});
377 "\nDeletes the specified transaction from the wallet. Meant for use with pruned wallets and as a companion to importprunedfunds. This will affect wallet balances.\n",
383 HelpExampleCli(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
384 "\nAs a JSON-RPC call\n" 385 +
HelpExampleRpc(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
392 LOCK(pwallet->cs_wallet);
395 std::vector<uint256> vHash;
396 vHash.push_back(hash);
397 std::vector<uint256> vHashOut;
399 if (pwallet->ZapSelectTx(vHash, vHashOut) != DBErrors::LOAD_OK) {
403 if(vHashOut.empty()) {
415 "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend. Requires a new wallet backup.\n" 416 "Hint: use importmulti to import more than one public key.\n" 417 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 418 "may report that the imported pubkey exists but related transactions are still missing, leading to temporarily incorrect/bogus balances and unspent outputs until rescan completes.\n" 419 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 420 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 421 "Note: Use \"getwalletinfo\" to query the scanning progress.\n" 422 "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" with \"combo(X)\" for descriptor wallets.\n",
430 "\nImport a public key with rescan\n" 432 "\nImport using a label without rescan\n" 433 +
HelpExampleCli(
"importpubkey",
"\"mypubkey\" \"testing\" false") +
434 "\nAs a JSON-RPC call\n" 435 +
HelpExampleRpc(
"importpubkey",
"\"mypubkey\", \"testing\", false")
448 if (!request.params[2].isNull())
449 fRescan = request.params[2].get_bool();
451 if (fRescan && pwallet->chain().havePruned()) {
459 if (fRescan && !reserver.
reserve()) {
463 if (!
IsHex(request.params[0].get_str()))
465 std::vector<unsigned char> data(
ParseHex(request.params[0].get_str()));
471 LOCK(pwallet->cs_wallet);
473 std::set<CScript> script_pub_keys;
478 pwallet->MarkDirty();
480 pwallet->ImportScriptPubKeys(strLabel, script_pub_keys,
true,
true, 1);
482 pwallet->ImportPubKeys({pubKey.
GetID()}, {{pubKey.
GetID(), pubKey}} , {},
false,
false, 1);
487 pwallet->ResubmitWalletTransactions(
false,
true);
499 "\nImports keys from a wallet dump file (see dumpwallet). Requires a new wallet backup to include imported keys.\n" 500 "Note: Blockchain and Mempool will be rescanned after a successful import. Use \"getwalletinfo\" to query the scanning progress.\n" 501 "Note: This command is only compatible with legacy wallets.\n",
507 "\nDump the wallet\n" 509 "\nImport the wallet\n" 511 "\nImport using the json rpc call\n" 526 int64_t nTimeBegin = 0;
529 LOCK(pwallet->cs_wallet);
534 file.open(
fs::u8path(request.params[0].get_str()), std::ios::in | std::ios::ate);
535 if (!file.is_open()) {
540 int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
541 file.seekg(0, file.beg);
545 pwallet->chain().showProgress(
strprintf(
"%s " +
_(
"Importing…").translated, pwallet->GetDisplayName()), 0,
false);
546 std::vector<std::tuple<CKey, int64_t, bool, std::string>> keys;
547 std::vector<std::pair<CScript, int64_t>> scripts;
548 while (file.good()) {
549 pwallet->chain().showProgress(
"", std::max(1, std::min(50, (
int)(((
double)file.tellg() / (double)nFilesize) * 100))),
false);
551 std::getline(file, line);
552 if (line.empty() || line[0] ==
'#')
555 std::vector<std::string> vstr =
SplitString(line,
' ');
561 std::string strLabel;
563 for (
unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
564 if (vstr[nStr].front() ==
'#')
566 if (vstr[nStr] ==
"change=1")
568 if (vstr[nStr] ==
"reserve=1")
570 if (vstr[nStr].substr(0,6) ==
"label=") {
575 nTimeBegin = std::min(nTimeBegin, nTime);
576 keys.emplace_back(key, nTime, fLabel, strLabel);
577 }
else if(
IsHex(vstr[0])) {
578 std::vector<unsigned char> vData(
ParseHex(vstr[0]));
581 if (birth_time > 0) nTimeBegin = std::min(nTimeBegin, birth_time);
582 scripts.emplace_back(script, birth_time);
589 pwallet->chain().showProgress(
"", 100,
false);
592 double total = (double)(keys.size() + scripts.size());
594 for (
const auto& key_tuple : keys) {
595 pwallet->chain().showProgress(
"", std::max(50, std::min(75, (
int)((progress / total) * 100) + 50)),
false);
596 const CKey& key = std::get<0>(key_tuple);
597 int64_t time = std::get<1>(key_tuple);
598 bool has_label = std::get<2>(key_tuple);
599 std::string label = std::get<3>(key_tuple);
603 CKeyID keyid = pubkey.GetID();
607 if (!pwallet->ImportPrivKeys({{keyid, key}}, time)) {
614 pwallet->SetAddressBook(
PKHash(keyid), label, AddressPurpose::RECEIVE);
617 for (
const auto& script_pair : scripts) {
618 pwallet->chain().showProgress(
"", std::max(50, std::min(75, (
int)((progress / total) * 100) + 50)),
false);
619 const CScript& script = script_pair.first;
620 int64_t time = script_pair.second;
622 if (!pwallet->ImportScripts({script}, time)) {
623 pwallet->WalletLogPrintf(
"Error importing script %s\n",
HexStr(script));
630 pwallet->chain().showProgress(
"", 100,
false);
632 pwallet->chain().showProgress(
"", 100,
false);
634 pwallet->MarkDirty();
647 "\nReveals the private key corresponding to 'address'.\n" 648 "Then the importprivkey can be used with this output\n" 649 "Note: This command is only compatible with legacy wallets.\n",
672 std::string strAddress = request.params[0].get_str();
678 if (keyid.IsNull()) {
682 if (!spk_man.
GetKey(keyid, vchSecret)) {
694 "\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n" 695 "Imported scripts are included in the dumpfile, but corresponding BIP173 addresses, etc. may not be added automatically by importwallet.\n" 696 "Note that if your wallet contains keys which are not derived from your HD seed (e.g. imported keys), these are not covered by\n" 697 "only backing up the seed itself, and must be backed up too (e.g. ensure you back up the whole dumpfile).\n" 698 "Note: This command is only compatible with legacy wallets.\n",
722 wallet.BlockUntilSyncedToCurrentChain();
745 std::map<CKeyID, int64_t> mapKeyBirth;
746 wallet.GetKeyBirthTimes(mapKeyBirth);
748 int64_t block_time = 0;
756 std::set<CScriptID> scripts = spk_man.
GetCScripts();
759 std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
760 vKeyBirth.reserve(mapKeyBirth.size());
761 for (
const auto& entry : mapKeyBirth) {
762 vKeyBirth.emplace_back(entry.second, entry.first);
765 std::sort(vKeyBirth.begin(), vKeyBirth.end());
770 file <<
strprintf(
"# * Best block at time of backup was %i (%s),\n",
wallet.GetLastBlockHeight(),
wallet.GetLastBlockHash().ToString());
779 if (spk_man.
GetKey(seed_id, seed)) {
783 file <<
"# extended private masterkey: " <<
EncodeExtKey(masterKey) <<
"\n\n";
786 for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
787 const CKeyID &keyid = it->second;
790 std::string strLabel;
792 if (spk_man.
GetKey(keyid, key)) {
794 const auto it{spk_man.mapKeyMetadata.find(keyid)};
795 if (it != spk_man.mapKeyMetadata.end()) metadata = it->second;
799 }
else if (keyid == seed_id) {
801 }
else if (mapKeyPool.count(keyid)) {
804 file <<
"inactivehdseed=1";
812 for (
const CScriptID &scriptid : scripts) {
814 std::string create_time =
"0";
817 auto it = spk_man.m_script_metadata.find(scriptid);
818 if (it != spk_man.m_script_metadata.end()) {
823 file <<
strprintf(
" # addr=%s\n", address);
827 file <<
"# End of dump\n";
831 reply.
pushKV(
"filename", filepath.u8string());
862 std::vector<std::vector<unsigned char>> solverdata;
865 switch (script_type) {
882 if (!subscript)
return "missing redeemscript";
883 if (
CScriptID(*subscript) !=
id)
return "redeemScript does not match the scriptPubKey";
888 for (
size_t i = 1; i + 1< solverdata.size(); ++i) {
898 if (!subscript)
return "missing witnessscript";
899 if (
CScriptID(*subscript) !=
id)
return "witnessScript does not match the scriptPubKey or redeemScript";
900 if (script_ctx == ScriptContext::TOP) {
910 if (script_ctx == ScriptContext::TOP) {
916 return "unspendable script";
920 return "unrecognized script";
925 static UniValue ProcessImportLegacy(
ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys,
bool& have_solving_data,
const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)
930 const UniValue& scriptPubKey = data[
"scriptPubKey"];
935 const std::string& output = isScript ? scriptPubKey.
get_str() : scriptPubKey[
"address"].
get_str();
938 const std::string& strRedeemScript = data.
exists(
"redeemscript") ? data[
"redeemscript"].
get_str() :
"";
939 const std::string& witness_script_hex = data.
exists(
"witnessscript") ? data[
"witnessscript"].
get_str() :
"";
942 const bool internal = data.
exists(
"internal") ? data[
"internal"].
get_bool() :
false;
943 const bool watchOnly = data.
exists(
"watchonly") ? data[
"watchonly"].
get_bool() :
false;
945 if (data.
exists(
"range")) {
961 if (!
IsHex(output)) {
964 std::vector<unsigned char> vData(
ParseHex(output));
965 script =
CScript(vData.begin(), vData.end());
971 script_pub_keys.emplace(script);
974 if (strRedeemScript.size()) {
975 if (!
IsHex(strRedeemScript)) {
978 auto parsed_redeemscript =
ParseHex(strRedeemScript);
979 import_data.
redeemscript = std::make_unique<CScript>(parsed_redeemscript.begin(), parsed_redeemscript.end());
981 if (witness_script_hex.size()) {
982 if (!
IsHex(witness_script_hex)) {
985 auto parsed_witnessscript =
ParseHex(witness_script_hex);
986 import_data.
witnessscript = std::make_unique<CScript>(parsed_witnessscript.begin(), parsed_witnessscript.end());
988 for (
size_t i = 0; i < pubKeys.
size(); ++i) {
989 const auto& str = pubKeys[i].
get_str();
998 pubkey_map.emplace(pubkey.
GetID(), pubkey);
999 ordered_pubkeys.push_back(pubkey.
GetID());
1001 for (
size_t i = 0; i < keys.
size(); ++i) {
1002 const auto& str = keys[i].
get_str();
1009 if (pubkey_map.count(
id)) {
1010 pubkey_map.erase(
id);
1012 privkey_map.emplace(
id, key);
1018 if (have_solving_data) {
1023 bool spendable = std::all_of(import_data.
used_keys.begin(), import_data.
used_keys.end(), [&](
const std::pair<CKeyID, bool>& used_key){
return privkey_map.count(used_key.first) > 0; });
1024 if (!watchOnly && !spendable) {
1025 warnings.
push_back(
"Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.");
1027 if (watchOnly && spendable) {
1028 warnings.
push_back(
"All private keys are provided, outputs will be considered spendable. If this is intentional, do not specify the watchonly flag.");
1032 if (
error.empty()) {
1033 for (
const auto& require_key : import_data.
used_keys) {
1034 if (!require_key.second)
continue;
1035 if (pubkey_map.count(require_key.first) == 0 && privkey_map.count(require_key.first) == 0) {
1036 error =
"some required keys are missing";
1041 if (!
error.empty()) {
1042 warnings.
push_back(
"Importing as non-solvable: " +
error +
". If this is intentional, don't provide any keys, pubkeys, witnessscript, or redeemscript.");
1045 privkey_map.clear();
1046 have_solving_data =
false;
1049 if (import_data.
redeemscript) warnings.
push_back(
"Ignoring redeemscript as this is not a P2SH script.");
1050 if (import_data.
witnessscript) warnings.
push_back(
"Ignoring witnessscript as this is not a (P2SH-)P2WSH script.");
1051 for (
auto it = privkey_map.begin(); it != privkey_map.end(); ) {
1053 if (import_data.
used_keys.count(oldit->first) == 0) {
1054 warnings.
push_back(
"Ignoring irrelevant private key.");
1055 privkey_map.erase(oldit);
1058 for (
auto it = pubkey_map.begin(); it != pubkey_map.end(); ) {
1060 auto key_data_it = import_data.
used_keys.find(oldit->first);
1061 if (key_data_it == import_data.
used_keys.end() || !key_data_it->second) {
1062 warnings.
push_back(
"Ignoring public key \"" +
HexStr(oldit->first) +
"\" as it doesn't appear inside P2PKH or P2WPKH.");
1063 pubkey_map.erase(oldit);
1072 static UniValue ProcessImportDescriptor(
ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys,
bool& have_solving_data,
const UniValue& data, std::vector<CKeyID>& ordered_pubkeys)
1076 const std::string& descriptor = data[
"desc"].
get_str();
1079 auto parsed_desc =
Parse(descriptor, keys,
error,
true);
1087 have_solving_data = parsed_desc->IsSolvable();
1088 const bool watch_only = data.
exists(
"watchonly") ? data[
"watchonly"].
get_bool() :
false;
1090 int64_t range_start = 0, range_end = 0;
1091 if (!parsed_desc->IsRange() && data.
exists(
"range")) {
1093 }
else if (parsed_desc->IsRange()) {
1094 if (!data.
exists(
"range")) {
1103 for (
int i = range_start; i <= range_end; ++i) {
1105 std::vector<CScript> scripts_temp;
1106 parsed_desc->Expand(i, keys, scripts_temp, out_keys);
1107 std::copy(scripts_temp.begin(), scripts_temp.end(), std::inserter(script_pub_keys, script_pub_keys.end()));
1108 for (
const auto& key_pair : out_keys.
pubkeys) {
1109 ordered_pubkeys.push_back(key_pair.first);
1112 for (
const auto& x : out_keys.
scripts) {
1116 parsed_desc->ExpandPrivate(i, keys, out_keys);
1118 std::copy(out_keys.
pubkeys.begin(), out_keys.
pubkeys.end(), std::inserter(pubkey_map, pubkey_map.end()));
1119 std::copy(out_keys.
keys.begin(), out_keys.
keys.end(), std::inserter(privkey_map, privkey_map.end()));
1123 for (
size_t i = 0; i < priv_keys.
size(); ++i) {
1124 const auto& str = priv_keys[i].
get_str();
1133 if (!pubkey_map.count(
id)) {
1134 warnings.
push_back(
"Ignoring irrelevant private key.");
1136 privkey_map.emplace(
id, key);
1144 bool spendable = std::all_of(pubkey_map.begin(), pubkey_map.end(),
1145 [&](
const std::pair<CKeyID, CPubKey>& used_key) {
1146 return privkey_map.count(used_key.first) > 0;
1148 [&](
const std::pair<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& entry) {
1149 return privkey_map.count(entry.first) > 0;
1151 if (!watch_only && !spendable) {
1152 warnings.
push_back(
"Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.");
1154 if (watch_only && spendable) {
1155 warnings.
push_back(
"All private keys are provided, outputs will be considered spendable. If this is intentional, do not specify the watchonly flag.");
1167 const bool internal = data.exists(
"internal") ? data[
"internal"].get_bool() :
false;
1169 if (
internal && data.exists(
"label")) {
1173 const bool add_keypool = data.exists(
"keypool") ? data[
"keypool"].get_bool() :
false;
1181 std::map<CKeyID, CPubKey> pubkey_map;
1182 std::map<CKeyID, CKey> privkey_map;
1183 std::set<CScript> script_pub_keys;
1184 std::vector<CKeyID> ordered_pubkeys;
1185 bool have_solving_data;
1187 if (data.exists(
"scriptPubKey") && data.exists(
"desc")) {
1189 }
else if (data.exists(
"scriptPubKey")) {
1190 warnings =
ProcessImportLegacy(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys);
1191 }
else if (data.exists(
"desc")) {
1192 warnings =
ProcessImportDescriptor(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys);
1203 for (
const CScript& script : script_pub_keys) {
1214 if (!
wallet.ImportPrivKeys(privkey_map, timestamp)) {
1217 if (!
wallet.ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.
key_origins, add_keypool,
internal, timestamp)) {
1220 if (!
wallet.ImportScriptPubKeys(label, script_pub_keys, have_solving_data, !
internal, timestamp)) {
1227 result.
pushKV(
"error", e);
1239 if (data.
exists(
"timestamp")) {
1240 const UniValue& timestamp = data[
"timestamp"];
1241 if (timestamp.
isNum()) {
1242 return timestamp.
getInt<int64_t>();
1243 }
else if (timestamp.
isStr() && timestamp.
get_str() ==
"now") {
1254 "\nImport addresses/scripts (with private or public keys, redeem script (P2SH)), optionally rescanning the blockchain from the earliest creation time of the imported scripts. Requires a new wallet backup.\n" 1255 "If an address/script is imported without all of the private keys required to spend from that address, it will be watchonly. The 'watchonly' option must be set to true in this case or a warning will be returned.\n" 1256 "Conversely, if all the private keys are provided and the address/script is spendable, the watchonly option must be set to false, or a warning will be returned.\n" 1257 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 1258 "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n" 1259 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 1260 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 1261 "Note: Use \"getwalletinfo\" to query the scanning progress.\n" 1262 "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" for descriptor wallets.\n",
1273 "or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n" 1274 "key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n" 1275 "\"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n" 1276 "0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n" 1277 "creation time of all keys being imported by the importmulti call will be scanned.",
1282 {
"pubkeys",
RPCArg::Type::ARR,
RPCArg::Default{
UniValue::VARR},
"Array of strings giving pubkeys to import. They must occur in P2PKH or P2WPKH scripts. They are not required when the private key is also provided (see the \"keys\" argument).",
1296 {
"keypool",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Stating whether imported public keys should be added to the keypool for when users request new addresses. Only allowed when wallet private keys are disabled"},
1308 RPCResult::Type::ARR,
"",
"Response is an array with the same size as the input that has the execution result",
1325 HelpExampleCli(
"importmulti",
"'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }, " 1326 "{ \"scriptPubKey\": { \"address\": \"<my 2nd address>\" }, \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
1327 HelpExampleCli(
"importmulti",
"'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }]' '{ \"rescan\": false}'")
1337 wallet.BlockUntilSyncedToCurrentChain();
1341 const UniValue& requests = mainRequest.params[0];
1344 bool fRescan =
true;
1346 if (!mainRequest.params[1].isNull()) {
1347 const UniValue& options = mainRequest.params[1];
1349 if (options.
exists(
"rescan")) {
1350 fRescan = options[
"rescan"].
get_bool();
1355 if (fRescan && !reserver.
reserve()) {
1360 bool fRunScan =
false;
1361 int64_t nLowestTimestamp = 0;
1364 LOCK(pwallet->cs_wallet);
1367 bool is_watchonly{
true};
1368 for (
size_t i = 0; i < requests.
size(); ++i) {
1369 const UniValue& request = requests[i];
1370 if (!request.
exists(
"watchonly") || !request[
"watchonly"].
get_bool()) {
1371 is_watchonly =
false;
1384 const int64_t minimumTimestamp = 1;
1396 if (result[
"success"].get_bool()) {
1401 if (timestamp < nLowestTimestamp) {
1402 nLowestTimestamp = timestamp;
1406 if (fRescan && fRunScan && requests.
size()) {
1407 int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, reserver,
true);
1408 pwallet->ResubmitWalletTransactions(
false,
true);
1410 if (pwallet->IsAbortingRescan()) {
1413 if (scannedTime > nLowestTimestamp) {
1414 std::vector<UniValue> results = response.
getValues();
1423 if (scannedTime <=
GetImportTimestamp(request, now) || results.at(i).exists(
"error")) {
1432 strprintf(
"Rescan failed for key with creation timestamp %d. There was an error reading a " 1433 "block from time %d, which is after or within %d seconds of key creation, and " 1434 "could contain transactions pertaining to the key. As a result, transactions " 1435 "and coins using this key may not appear in the wallet. This error could be " 1436 "caused by pruning or data corruption (see bitcoind log for details) and could " 1437 "be dealt with by downloading and rescanning the relevant blocks (see -reindex " 1438 "option and rescanblockchain RPC).",
1458 if (!data.exists(
"desc")) {
1462 const std::string& descriptor = data[
"desc"].get_str();
1463 const bool active = data.exists(
"active") ? data[
"active"].get_bool() :
false;
1464 const bool internal = data.exists(
"internal") ? data[
"internal"].get_bool() :
false;
1470 auto parsed_desc =
Parse(descriptor, keys,
error,
true);
1476 int64_t range_start = 0, range_end = 1, next_index = 0;
1477 if (!parsed_desc->IsRange() && data.exists(
"range")) {
1479 }
else if (parsed_desc->IsRange()) {
1480 if (data.exists(
"range")) {
1482 range_start = range.first;
1483 range_end = range.second + 1;
1485 warnings.
push_back(
"Range not given, using default keypool range");
1487 range_end =
wallet.m_keypool_size;
1489 next_index = range_start;
1491 if (data.exists(
"next_index")) {
1492 next_index = data[
"next_index"].getInt<int64_t>();
1494 if (next_index < range_start || next_index >= range_end) {
1501 if (active && !parsed_desc->IsRange()) {
1506 if (data.exists(
"range") && data.exists(
"label")) {
1511 if (
internal && data.exists(
"label")) {
1516 if (active && !parsed_desc->IsSingleType()) {
1527 std::vector<CScript> scripts;
1528 if (!parsed_desc->Expand(0, keys, scripts, expand_keys)) {
1529 throw JSONRPCError(
RPC_WALLET_ERROR,
"Cannot expand descriptor. Probably because of hardened derivations without private keys provided");
1531 parsed_desc->ExpandPrivate(0, keys, expand_keys);
1534 bool have_all_privkeys = !expand_keys.
keys.empty();
1535 for (
const auto& entry : expand_keys.
origins) {
1536 const CKeyID& key_id = entry.first;
1538 if (!expand_keys.
GetKey(key_id, key)) {
1539 have_all_privkeys =
false;
1546 if (keys.
keys.empty()) {
1549 if (!have_all_privkeys) {
1550 warnings.
push_back(
"Not all private keys provided. Some wallet functionality may return unexpected errors");
1554 WalletDescriptor w_desc(std::move(parsed_desc), timestamp, range_start, range_end, next_index);
1557 auto existing_spk_manager =
wallet.GetDescriptorScriptPubKeyMan(w_desc);
1558 if (existing_spk_manager) {
1559 if (!existing_spk_manager->CanUpdateToWalletDescriptor(w_desc,
error)) {
1565 auto spk_manager =
wallet.AddWalletDescriptor(w_desc, keys, label,
internal);
1566 if (spk_manager ==
nullptr) {
1573 warnings.
push_back(
"Unknown output type, cannot set descriptor to active.");
1575 wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.
descriptor->GetOutputType(),
internal);
1579 wallet.DeactivateScriptPubKeyMan(spk_manager->GetID(), *w_desc.
descriptor->GetOutputType(),
internal);
1586 result.
pushKV(
"error", e);
1595 "\nImport descriptors. This will trigger a rescan of the blockchain based on the earliest timestamp of all descriptors being imported. Requires a new wallet backup.\n" 1596 "\nNote: This call can take over an hour to complete if using an early timestamp; during that time, other rpc calls\n" 1597 "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n" 1598 "The rescan is significantly faster if block filters are available (using startup option \"-blockfilterindex=1\").\n",
1609 "Use the string \"now\" to substitute the current synced blockchain time.\n" 1610 "\"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n" 1611 "0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n" 1612 "of all descriptors being imported will be scanned as well as the mempool.",
1623 RPCResult::Type::ARR,
"",
"Response is an array with the same size as the input that has the execution result",
1640 HelpExampleCli(
"importdescriptors",
"'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"internal\": true }, " 1641 "{ \"desc\": \"<my descriptor 2>\", \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
1642 HelpExampleCli(
"importdescriptors",
"'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"active\": true, \"range\": [0,100], \"label\": \"<my bech32 wallet>\" }]'")
1652 wallet.BlockUntilSyncedToCurrentChain();
1660 if (!reserver.
reserve(
true)) {
1666 LOCK(pwallet->m_relock_mutex);
1668 const UniValue& requests = main_request.params[0];
1669 const int64_t minimum_timestamp = 1;
1671 int64_t lowest_timestamp = 0;
1672 bool rescan =
false;
1675 LOCK(pwallet->cs_wallet);
1683 const int64_t timestamp = std::max(
GetImportTimestamp(request, now), minimum_timestamp);
1687 if (lowest_timestamp > timestamp ) {
1688 lowest_timestamp = timestamp;
1692 if (!rescan && result[
"success"].get_bool()) {
1696 pwallet->ConnectScriptPubKeyManNotifiers();
1701 int64_t scanned_time = pwallet->RescanFromTime(lowest_timestamp, reserver,
true);
1702 pwallet->ResubmitWalletTransactions(
false,
true);
1704 if (pwallet->IsAbortingRescan()) {
1708 if (scanned_time > lowest_timestamp) {
1709 std::vector<UniValue> results = response.
getValues();
1714 for (
unsigned int i = 0; i < requests.
size(); ++i) {
1721 if (scanned_time <=
GetImportTimestamp(request, now) || results.at(i).exists(
"error")) {
1730 strprintf(
"Rescan failed for descriptor with timestamp %d. There was an error reading a " 1731 "block from time %d, which is after or within %d seconds of key creation, and " 1732 "could contain transactions pertaining to the desc. As a result, transactions " 1733 "and coins using this desc may not appear in the wallet. This error could be " 1734 "caused by pruning or data corruption (see bitcoind log for details) and could " 1735 "be dealt with by downloading and rescanning the relevant blocks (see -reindex " 1736 "option and rescanblockchain RPC).",
1753 "\nList descriptors imported into a descriptor-enabled wallet.\n",
1759 {
RPCResult::Type::ARR,
"descriptors",
"Array of descriptor objects (sorted by descriptor string representation)",
1764 {
RPCResult::Type::BOOL,
"active",
"Whether this descriptor is currently used to generate new addresses"},
1765 {
RPCResult::Type::BOOL,
"internal",
true,
"True if this descriptor is used to generate change addresses. False if this descriptor is used to generate receiving addresses; defined only for active descriptors"},
1770 {
RPCResult::Type::NUM,
"next",
true,
"Same as next_index field. Kept for compatibility reason."},
1771 {
RPCResult::Type::NUM,
"next_index",
true,
"The next index to generate addresses from; defined only for ranged descriptors"},
1788 const bool priv = !request.params[0].isNull() && request.params[0].get_bool();
1795 const auto active_spk_mans =
wallet->GetActiveScriptPubKeyMans();
1797 struct WalletDescInfo {
1798 std::string descriptor;
1799 uint64_t creation_time;
1801 std::optional<bool>
internal;
1802 std::optional<std::pair<int64_t,int64_t>> range;
1806 std::vector<WalletDescInfo> wallet_descriptors;
1807 for (
const auto& spk_man :
wallet->GetAllScriptPubKeyMans()) {
1809 if (!desc_spk_man) {
1812 LOCK(desc_spk_man->cs_desc_man);
1813 const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor();
1814 std::string descriptor;
1815 if (!desc_spk_man->GetDescriptorString(descriptor, priv)) {
1818 const bool is_range = wallet_descriptor.descriptor->IsRange();
1819 wallet_descriptors.push_back({
1821 wallet_descriptor.creation_time,
1822 active_spk_mans.count(desc_spk_man) != 0,
1823 wallet->IsInternalScriptPubKeyMan(desc_spk_man),
1824 is_range ? std::optional(std::make_pair(wallet_descriptor.range_start, wallet_descriptor.range_end)) : std::nullopt,
1825 wallet_descriptor.next_index
1829 std::sort(wallet_descriptors.begin(), wallet_descriptors.end(), [](
const auto& a,
const auto& b) {
1830 return a.descriptor < b.descriptor;
1834 for (
const WalletDescInfo& info : wallet_descriptors) {
1836 spk.
pushKV(
"desc", info.descriptor);
1837 spk.
pushKV(
"timestamp", info.creation_time);
1838 spk.
pushKV(
"active", info.active);
1839 if (info.internal.has_value()) {
1840 spk.
pushKV(
"internal", info.internal.value());
1842 if (info.range.has_value()) {
1845 range.
push_back(info.range->second - 1);
1846 spk.
pushKV(
"range", range);
1847 spk.
pushKV(
"next", info.next_index);
1848 spk.
pushKV(
"next_index", info.next_index);
1850 descriptors.push_back(spk);
1855 response.
pushKV(
"descriptors", descriptors);
1865 "\nSafely copies the current wallet file to the specified destination, which can either be a directory or a path with a filename.\n",
1881 pwallet->BlockUntilSyncedToCurrentChain();
1883 LOCK(pwallet->cs_wallet);
1885 std::string strDest = request.params[0].get_str();
1886 if (!pwallet->BackupWallet(strDest)) {
1900 "\nRestores and loads a wallet from backup.\n" 1901 "\nThe rescan is significantly faster if a descriptor wallet is restored" 1902 "\nand block filters are available (using startup option \"-blockfilterindex=1\").\n",
1912 {
RPCResult::Type::ARR,
"warnings",
true,
"Warning messages, if any, related to restoring and loading the wallet.",
1919 HelpExampleCli(
"restorewallet",
"\"testwallet\" \"home\\backups\\backup-file.bak\"")
1920 +
HelpExampleRpc(
"restorewallet",
"\"testwallet\" \"home\\backups\\backup-file.bak\"")
1921 +
HelpExampleCliNamed(
"restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak\""}, {
"load_on_startup",
true}})
1922 +
HelpExampleRpcNamed(
"restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak\""}, {
"load_on_startup",
true}})
1929 auto backup_file =
fs::u8path(request.params[1].get_str());
1931 std::string wallet_name = request.params[0].get_str();
1933 std::optional<bool> load_on_start = request.params[2].isNull() ? std::nullopt : std::optional<bool>(request.params[2].get_bool());
1937 std::vector<bilingual_str> warnings;
std::shared_ptr< const CTransaction > CTransactionRef
RPCHelpMan importaddress()
Witness v0 (P2WPKH and P2WSH); see BIP 141.
Helper for findBlock to selectively return pieces of block data.
RPCHelpMan importwallet()
static UniValue Parse(std::string_view raw)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
void push_back(UniValue val)
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_opts.type_str.at(0) will override the type of the value in a key-value pair, m_opts.type_str.at(1) will override the type in the argument description.
const std::vector< UniValue > & getValues() const
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
const CHDChain & GetHDChain() const
std::vector< Byte > ParseHex(std::string_view hex_str)
Like TryParseHex, but returns an empty vector on invalid input.
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination corresponds to one with an address.
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath, bool apostrophe)
Write HD keypaths as strings.
iterator insert(iterator pos, const T &value)
RPCHelpMan restorewallet()
RecursiveMutex cs_KeyStore
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
std::vector< unsigned char > ParseHexV(const UniValue &v, std::string strName)
CPubKey GetPubKey() const
Compute the public key from a private key.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
std::map< CKeyID, CKey > keys
static void EnsureBlockDataFromTime(const CWallet &wallet, int64_t timestamp)
#define CHECK_NONFATAL(condition)
Identity function.
bool IsHex(std::string_view str)
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
virtual std::set< CScriptID > GetCScripts() const
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
const std::string & get_str() const
enum VType getType() const
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
const UniValue & get_array() const
RAII object to check and reserve a wallet rescan.
bool reserve(bool with_passphrase=false)
static int64_t GetImportTimestamp(const UniValue &data, int64_t now)
bool GetKey(const CKeyID &address, CKey &keyOut) const override
State of transaction confirmed in a block.
uint160 RIPEMD160(Span< const unsigned char > data)
Compute the 160-bit RIPEMD-160 hash of an array.
std::vector< std::string > SplitString(std::string_view str, char sep)
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
std::map< CKeyID, bool > used_keys
Import these private keys if available (the value indicates whether if the key is required for solvab...
Invalid, missing or duplicate parameter.
std::vector< CTxDestination > GetAllDestinationsForKey(const CPubKey &key)
Get all destinations (potentially) supported by the wallet for the given key.
static const int64_t TIMESTAMP_MIN
static UniValue ProcessDescriptorImport(CWallet &wallet, const UniValue &data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
void HandleWalletError(const std::shared_ptr< CWallet > wallet, DatabaseStatus &status, bilingual_str &error)
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
Special type that is a STR with only hex chars.
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
const char * uvTypeName(UniValue::VType t)
Used to relay blocks as header + vector<merkle branch> to filtered nodes.
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > key_origins
UniValue JSONRPCError(int code, const std::string &message)
std::string LabelFromValue(const UniValue &value)
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a scriptPubKey for the destination.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::map< CScriptID, CScript > scripts
Double ended buffer combining vector and stream-like interfaces.
bool exists(const std::string &key) const
bilingual_str _(const char *psz)
Translation function.
Special array that has a fixed number of entries.
std::shared_ptr< Descriptor > descriptor
An encapsulated public key.
std::map< CKeyID, CPubKey > pubkeys
WalletContext & EnsureWalletContext(const std::any &context)
Unexpected type was passed as parameter.
RPCHelpMan listdescriptors()
Indicate that this wallet supports DescriptorScriptPubKeyMan.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
General application defined errors.
std::string DefaultHint
Hint for default value.
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
void PushWarnings(const UniValue &warnings, UniValue &obj)
Push warning messages to an RPC "warnings" field as a JSON array of strings.
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
constexpr bool IsNull() const
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
static UniValue ProcessImportLegacy(ImportData &import_data, std::map< CKeyID, CPubKey > &pubkey_map, std::map< CKeyID, CKey > &privkey_map, std::set< CScript > &script_pub_keys, bool &have_solving_data, const UniValue &data, std::vector< CKeyID > &ordered_pubkeys)
std::string FormatFullVersion()
RPCHelpMan importdescriptors()
Descriptor with some wallet metadata.
LegacyScriptPubKeyMan & EnsureLegacyScriptPubKeyMan(CWallet &wallet, bool also_create)
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static CTransactionRef MakeTransactionRef(Tx &&txIn)
static UniValue ProcessImportDescriptor(ImportData &import_data, std::map< CKeyID, CPubKey > &pubkey_map, std::map< CKeyID, CKey > &privkey_map, std::set< CScript > &script_pub_keys, bool &have_solving_data, const UniValue &data, std::vector< CKeyID > &ordered_pubkeys)
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Special type that is a NUM or [NUM,NUM].
std::variant< CNoDestination, PubKeyDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script categorized into standard templates.
RPCHelpMan importpubkey()
Optional argument for which the default value is omitted from help text for one of two reasons: ...
#define EXCLUSIVE_LOCKS_REQUIRED(...)
bool GetKey(const CKeyID &keyid, CKey &key) const override
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
void SetSeed(Span< const std::byte > seed)
RPCHelpMan importprunedfunds()
static std::string RecurseImportData(const CScript &script, ImportData &import_data, const ScriptContext script_ctx)
static bool GetWalletAddressesForKey(const LegacyScriptPubKeyMan *spk_man, const CWallet &wallet, const CKeyID &keyid, std::string &strAddr, std::string &strLabel) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
bool error(const char *fmt, const Args &... args)
void pushKV(std::string key, UniValue val)
Serialized script, used inside transaction inputs and outputs.
#define NONFATAL_UNREACHABLE()
NONFATAL_UNREACHABLE() is a macro that is used to mark unreachable code.
RPCHelpMan importprivkey()
A reference to a CKey: the Hash160 of its serialized public key.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
WalletContext struct containing references to state shared between CWallet instances, like the reference to the chain interface, and the list of opened wallets.
std::set< CScript > import_scripts
static void RescanWallet(CWallet &wallet, const WalletRescanReserver &reserver, int64_t time_begin=TIMESTAMP_MIN, bool update=true)
void EnsureWalletIsUnlocked(const CWallet &wallet)
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
A reference to a CScript: the Hash160 of its serialization.
std::string EncodeDestination(const CTxDestination &dest)
static std::string EncodeDumpString(const std::string &str)
A mutable version of CTransaction.
FoundBlock & height(int &height)
RPCHelpMan removeprunedfunds()
An encapsulated private key.
std::unique_ptr< CScript > witnessscript
Provided witnessScript; will be moved to import_scripts if relevant.
FoundBlock & mtpTime(int64_t &mtp_time)
RPCHelpMan backupwallet()
std::optional< OutputType > OutputTypeFromDestination(const CTxDestination &dest)
Get the OutputType for a CTxDestination.
static UniValue ProcessImport(CWallet &wallet, const UniValue &data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
CKey DecodeSecret(const std::string &str)
static bool exists(const path &p)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
const LegacyScriptPubKeyMan & EnsureConstLegacyScriptPubKeyMan(const CWallet &wallet)
static path u8path(const std::string &utf8_str)
std::shared_ptr< CWallet > RestoreWallet(WalletContext &context, const fs::path &backup_file, const std::string &wallet_name, std::optional< bool > load_on_start, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
std::unique_ptr< CScript > redeemscript
Provided redeemScript; will be moved to import_scripts if relevant.
int64_t ParseISO8601DateTime(const std::string &str)
int64_t GetTime()
DEPRECATED, see GetTime.
std::string EncodeSecret(const CKey &key)
std::vector< uint32_t > path
Only for Witness versions not already defined above.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
static path absolute(const path &p)
CKeyID seed_id
seed hash160
const std::map< CKeyID, int64_t > & GetAllReserveKeys() const
std::string EncodeExtKey(const CExtKey &key)
static std::string DecodeDumpString(const std::string &str)
FoundBlock & time(int64_t &time)
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Error parsing or validating structure in raw format.
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency...
Special type to denote elision (...)
bool IsValid() const
Check whether this private key is valid.
unspendable OP_RETURN script that carries data
bool IsCompressed() const
Check whether this is a compressed public key.