37 std::stringstream
ret;
38 for (
const unsigned char c : str) {
39 if (c <= 32 || c >= 128 || c ==
'%') {
49 std::stringstream
ret;
50 for (
unsigned int pos = 0; pos < str.length(); pos++) {
51 unsigned char c = str[pos];
52 if (c ==
'%' && pos+2 < str.length()) {
53 c = (((str[pos+1]>>6)*9+((str[pos+1]-
'0')&15)) << 4) |
54 ((str[pos+2]>>6)*9+((str[pos+2]-
'0')&15));
64 bool fLabelFound =
false;
66 spk_man->GetKey(keyid, key);
68 const auto* address_book_entry =
wallet.FindAddressBookEntry(dest);
69 if (address_book_entry) {
70 if (!strAddr.empty()) {
88 int64_t scanned_time =
wallet.RescanFromTime(time_begin, reserver, update);
89 if (
wallet.IsAbortingRescan()) {
91 }
else if (scanned_time > time_begin) {
99 "\nAdds a private key (as returned by dumpprivkey) to your wallet. Requires a new wallet backup.\n" 100 "Hint: use importmulti to import more than one private key.\n" 101 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 102 "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" 103 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 104 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 105 "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
113 "\nDump a private key\n" 115 "\nImport the private key with rescan\n" 117 "\nImport using a label and without rescan\n" 118 +
HelpExampleCli(
"importprivkey",
"\"mykey\" \"testing\" false") +
119 "\nImport using default blank label and without rescan\n" 121 "\nAs a JSON-RPC call\n" 122 +
HelpExampleRpc(
"importprivkey",
"\"mykey\", \"testing\", false")
138 LOCK(pwallet->cs_wallet);
142 std::string strSecret = request.params[0].get_str();
143 std::string strLabel;
144 if (!request.params[1].isNull())
145 strLabel = request.params[1].get_str();
148 if (!request.params[2].isNull())
149 fRescan = request.params[2].get_bool();
151 if (fRescan && pwallet->chain().havePruned()) {
158 if (fRescan && !reserver.
reserve()) {
169 pwallet->MarkDirty();
175 if (!request.params[1].isNull() || !pwallet->FindAddressBookEntry(dest)) {
176 pwallet->SetAddressBook(dest, strLabel,
"receive");
181 if (!pwallet->ImportPrivKeys({{vchAddress, key}}, 1)) {
203 "\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" 204 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 205 "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" 206 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 207 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 208 "If you have the full public key, you should call importpubkey instead of this.\n" 209 "Hint: use importmulti to import more than one address.\n" 210 "\nNote: If you import a non-standard raw script in hex form, outputs sending to it will be treated\n" 211 "as change, and not show up in many RPCs.\n" 212 "Note: Use \"getwalletinfo\" to query the scanning progress.\n" 213 "Note: This command is only compatible with legacy wallets. Use \"importdescriptors\" with \"addr(X)\" for descriptor wallets.\n",
222 "\nImport an address with rescan\n" 224 "\nImport using a label without rescan\n" 225 +
HelpExampleCli(
"importaddress",
"\"myaddress\" \"testing\" false") +
226 "\nAs a JSON-RPC call\n" 227 +
HelpExampleRpc(
"importaddress",
"\"myaddress\", \"testing\", false")
236 std::string strLabel;
237 if (!request.params[1].isNull())
238 strLabel = request.params[1].get_str();
242 if (!request.params[2].isNull())
243 fRescan = request.params[2].get_bool();
245 if (fRescan && pwallet->chain().havePruned()) {
253 if (fRescan && !reserver.
reserve()) {
259 if (!request.params[3].isNull())
260 fP2SH = request.params[3].get_bool();
263 LOCK(pwallet->cs_wallet);
274 pwallet->MarkDirty();
277 }
else if (
IsHex(request.params[0].get_str())) {
278 std::vector<unsigned char> data(
ParseHex(request.params[0].get_str()));
279 CScript redeem_script(data.begin(), data.end());
281 std::set<CScript> scripts = {redeem_script};
282 pwallet->ImportScripts(scripts, 0 );
288 pwallet->ImportScriptPubKeys(strLabel, scripts,
false ,
true , 1 );
296 pwallet->ResubmitWalletTransactions(
false,
true);
307 "\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",
320 if (!
DecodeHexTx(tx, request.params[0].get_str())) {
330 std::vector<uint256> vMatch;
331 std::vector<unsigned int> vIndex;
332 if (merkleBlock.txn.ExtractMatches(vMatch, vIndex) != merkleBlock.header.hashMerkleRoot) {
336 LOCK(pwallet->cs_wallet);
338 if (!pwallet->chain().findAncestorByHash(pwallet->GetLastBlockHash(), merkleBlock.header.GetHash(),
FoundBlock().
height(height))) {
342 std::vector<uint256>::const_iterator it;
343 if ((it = std::find(vMatch.begin(), vMatch.end(), hashTx)) == vMatch.end()) {
347 unsigned int txnIndex = vIndex[it - vMatch.begin()];
350 if (pwallet->IsMine(*tx_ref)) {
351 pwallet->AddToWallet(std::move(tx_ref),
TxStateConfirmed{merkleBlock.header.GetHash(), height,
static_cast<int>(txnIndex)});
363 "\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",
369 HelpExampleCli(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"") +
370 "\nAs a JSON-RPC call\n" 371 +
HelpExampleRpc(
"removeprunedfunds",
"\"a8d0c0184dde994a09ec054286f1ce581bebf46446a512166eae7628734ea0a5\"")
378 LOCK(pwallet->cs_wallet);
381 std::vector<uint256> vHash;
382 vHash.push_back(hash);
383 std::vector<uint256> vHashOut;
385 if (pwallet->ZapSelectTx(vHash, vHashOut) != DBErrors::LOAD_OK) {
389 if(vHashOut.empty()) {
401 "\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" 402 "Hint: use importmulti to import more than one public key.\n" 403 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 404 "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" 405 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 406 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 407 "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
415 "\nImport a public key with rescan\n" 417 "\nImport using a label without rescan\n" 418 +
HelpExampleCli(
"importpubkey",
"\"mypubkey\" \"testing\" false") +
419 "\nAs a JSON-RPC call\n" 420 +
HelpExampleRpc(
"importpubkey",
"\"mypubkey\", \"testing\", false")
429 std::string strLabel;
430 if (!request.params[1].isNull())
431 strLabel = request.params[1].get_str();
435 if (!request.params[2].isNull())
436 fRescan = request.params[2].get_bool();
438 if (fRescan && pwallet->chain().havePruned()) {
446 if (fRescan && !reserver.
reserve()) {
450 if (!
IsHex(request.params[0].get_str()))
452 std::vector<unsigned char> data(
ParseHex(request.params[0].get_str()));
458 LOCK(pwallet->cs_wallet);
460 std::set<CScript> script_pub_keys;
465 pwallet->MarkDirty();
467 pwallet->ImportScriptPubKeys(strLabel, script_pub_keys,
true ,
true , 1 );
469 pwallet->ImportPubKeys({pubKey.
GetID()}, {{pubKey.
GetID(), pubKey}} , {} ,
false ,
false , 1 );
474 pwallet->ResubmitWalletTransactions(
false,
true);
486 "\nImports keys from a wallet dump file (see dumpwallet). Requires a new wallet backup to include imported keys.\n" 487 "Note: Blockchain and Mempool will be rescanned after a successful import. Use \"getwalletinfo\" to query the scanning progress.\n",
493 "\nDump the wallet\n" 495 "\nImport the wallet\n" 497 "\nImport using the json rpc call\n" 507 if (pwallet->chain().havePruned()) {
519 int64_t nTimeBegin = 0;
522 LOCK(pwallet->cs_wallet);
527 file.open(
fs::u8path(request.params[0].get_str()), std::ios::in | std::ios::ate);
528 if (!file.is_open()) {
533 int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
534 file.seekg(0, file.beg);
538 pwallet->chain().showProgress(
strprintf(
"%s " +
_(
"Importing…").translated, pwallet->GetDisplayName()), 0,
false);
539 std::vector<std::tuple<CKey, int64_t, bool, std::string>> keys;
540 std::vector<std::pair<CScript, int64_t>> scripts;
541 while (file.good()) {
542 pwallet->chain().showProgress(
"", std::max(1, std::min(50, (
int)(((
double)file.tellg() / (double)nFilesize) * 100))),
false);
544 std::getline(file, line);
545 if (line.empty() || line[0] ==
'#')
548 std::vector<std::string> vstr =
SplitString(line,
' ');
554 std::string strLabel;
556 for (
unsigned int nStr = 2; nStr < vstr.size(); nStr++) {
557 if (vstr[nStr].front() ==
'#')
559 if (vstr[nStr] ==
"change=1")
561 if (vstr[nStr] ==
"reserve=1")
563 if (vstr[nStr].substr(0,6) ==
"label=") {
568 keys.push_back(std::make_tuple(key, nTime, fLabel, strLabel));
569 }
else if(
IsHex(vstr[0])) {
570 std::vector<unsigned char> vData(
ParseHex(vstr[0]));
573 scripts.push_back(std::pair<CScript, int64_t>(script, birth_time));
579 pwallet->chain().showProgress(
"", 100,
false);
582 double total = (double)(keys.size() + scripts.size());
584 for (
const auto& key_tuple : keys) {
585 pwallet->chain().showProgress(
"", std::max(50, std::min(75, (
int)((progress / total) * 100) + 50)),
false);
586 const CKey& key = std::get<0>(key_tuple);
587 int64_t time = std::get<1>(key_tuple);
588 bool has_label = std::get<2>(key_tuple);
589 std::string label = std::get<3>(key_tuple);
593 CKeyID keyid = pubkey.GetID();
597 if (!pwallet->ImportPrivKeys({{keyid, key}}, time)) {
604 pwallet->SetAddressBook(
PKHash(keyid), label,
"receive");
606 nTimeBegin = std::min(nTimeBegin, time);
609 for (
const auto& script_pair : scripts) {
610 pwallet->chain().showProgress(
"", std::max(50, std::min(75, (
int)((progress / total) * 100) + 50)),
false);
611 const CScript& script = script_pair.first;
612 int64_t time = script_pair.second;
614 if (!pwallet->ImportScripts({script}, time)) {
615 pwallet->WalletLogPrintf(
"Error importing script %s\n",
HexStr(script));
620 nTimeBegin = std::min(nTimeBegin, time);
625 pwallet->chain().showProgress(
"", 100,
false);
627 pwallet->chain().showProgress(
"", 100,
false);
629 pwallet->MarkDirty();
642 "\nReveals the private key corresponding to 'address'.\n" 643 "Then the importprivkey can be used with this output\n",
666 std::string strAddress = request.params[0].get_str();
672 if (keyid.IsNull()) {
676 if (!spk_man.
GetKey(keyid, vchSecret)) {
688 "\nDumps all wallet keys in a human-readable format to a server-side file. This does not allow overwriting existing files.\n" 689 "Imported scripts are included in the dumpfile, but corresponding BIP173 addresses, etc. may not be added automatically by importwallet.\n" 690 "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" 691 "only backing up the seed itself, and must be backed up too (e.g. ensure you back up the whole dumpfile).\n",
715 wallet.BlockUntilSyncedToCurrentChain();
738 std::map<CKeyID, int64_t> mapKeyBirth;
739 wallet.GetKeyBirthTimes(mapKeyBirth);
741 int64_t block_time = 0;
749 std::set<CScriptID> scripts = spk_man.
GetCScripts();
752 std::vector<std::pair<int64_t, CKeyID> > vKeyBirth;
753 for (
const auto& entry : mapKeyBirth) {
754 vKeyBirth.push_back(std::make_pair(entry.second, entry.first));
757 std::sort(vKeyBirth.begin(), vKeyBirth.end());
762 file <<
strprintf(
"# * Best block at time of backup was %i (%s),\n",
wallet.GetLastBlockHeight(),
wallet.GetLastBlockHash().ToString());
771 if (spk_man.
GetKey(seed_id, seed)) {
775 file <<
"# extended private masterkey: " <<
EncodeExtKey(masterKey) <<
"\n\n";
778 for (std::vector<std::pair<int64_t, CKeyID> >::const_iterator it = vKeyBirth.begin(); it != vKeyBirth.end(); it++) {
779 const CKeyID &keyid = it->second;
782 std::string strLabel;
784 if (spk_man.
GetKey(keyid, key)) {
786 const auto it{spk_man.mapKeyMetadata.find(keyid)};
787 if (it != spk_man.mapKeyMetadata.end()) metadata = it->second;
791 }
else if (keyid == seed_id) {
793 }
else if (mapKeyPool.count(keyid)) {
796 file <<
"inactivehdseed=1";
804 for (
const CScriptID &scriptid : scripts) {
806 std::string create_time =
"0";
809 auto it = spk_man.m_script_metadata.find(scriptid);
810 if (it != spk_man.m_script_metadata.end()) {
815 file <<
strprintf(
" # addr=%s\n", address);
819 file <<
"# End of dump\n";
823 reply.
pushKV(
"filename", filepath.u8string());
854 std::vector<std::vector<unsigned char>> solverdata;
857 switch (script_type) {
874 if (!subscript)
return "missing redeemscript";
875 if (
CScriptID(*subscript) !=
id)
return "redeemScript does not match the scriptPubKey";
880 for (
size_t i = 1; i + 1< solverdata.size(); ++i) {
892 if (!subscript)
return "missing witnessscript";
893 if (
CScriptID(*subscript) !=
id)
return "witnessScript does not match the scriptPubKey or redeemScript";
894 if (script_ctx == ScriptContext::TOP) {
904 if (script_ctx == ScriptContext::TOP) {
910 return "unspendable script";
914 return "unrecognized script";
919 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)
924 const UniValue& scriptPubKey = data[
"scriptPubKey"];
929 const std::string& output = isScript ? scriptPubKey.
get_str() : scriptPubKey[
"address"].
get_str();
932 const std::string& strRedeemScript = data.
exists(
"redeemscript") ? data[
"redeemscript"].
get_str() :
"";
933 const std::string& witness_script_hex = data.
exists(
"witnessscript") ? data[
"witnessscript"].
get_str() :
"";
936 const bool internal = data.
exists(
"internal") ? data[
"internal"].
get_bool() :
false;
937 const bool watchOnly = data.
exists(
"watchonly") ? data[
"watchonly"].
get_bool() :
false;
939 if (data.
exists(
"range")) {
955 if (!
IsHex(output)) {
958 std::vector<unsigned char> vData(
ParseHex(output));
959 script =
CScript(vData.begin(), vData.end());
965 script_pub_keys.emplace(script);
968 if (strRedeemScript.size()) {
969 if (!
IsHex(strRedeemScript)) {
972 auto parsed_redeemscript =
ParseHex(strRedeemScript);
973 import_data.
redeemscript = std::make_unique<CScript>(parsed_redeemscript.begin(), parsed_redeemscript.end());
975 if (witness_script_hex.size()) {
976 if (!
IsHex(witness_script_hex)) {
979 auto parsed_witnessscript =
ParseHex(witness_script_hex);
980 import_data.
witnessscript = std::make_unique<CScript>(parsed_witnessscript.begin(), parsed_witnessscript.end());
982 for (
size_t i = 0; i < pubKeys.
size(); ++i) {
983 const auto& str = pubKeys[i].
get_str();
992 pubkey_map.emplace(pubkey.
GetID(), pubkey);
993 ordered_pubkeys.push_back(pubkey.
GetID());
995 for (
size_t i = 0; i < keys.
size(); ++i) {
996 const auto& str = keys[i].
get_str();
1003 if (pubkey_map.count(
id)) {
1004 pubkey_map.erase(
id);
1006 privkey_map.emplace(
id, key);
1012 if (have_solving_data) {
1017 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; });
1018 if (!watchOnly && !spendable) {
1019 warnings.
push_back(
"Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.");
1021 if (watchOnly && spendable) {
1022 warnings.
push_back(
"All private keys are provided, outputs will be considered spendable. If this is intentional, do not specify the watchonly flag.");
1026 if (
error.empty()) {
1027 for (
const auto& require_key : import_data.
used_keys) {
1028 if (!require_key.second)
continue;
1029 if (pubkey_map.count(require_key.first) == 0 && privkey_map.count(require_key.first) == 0) {
1030 error =
"some required keys are missing";
1035 if (!
error.empty()) {
1036 warnings.
push_back(
"Importing as non-solvable: " +
error +
". If this is intentional, don't provide any keys, pubkeys, witnessscript, or redeemscript.");
1039 privkey_map.clear();
1040 have_solving_data =
false;
1043 if (import_data.
redeemscript) warnings.
push_back(
"Ignoring redeemscript as this is not a P2SH script.");
1044 if (import_data.
witnessscript) warnings.
push_back(
"Ignoring witnessscript as this is not a (P2SH-)P2WSH script.");
1045 for (
auto it = privkey_map.begin(); it != privkey_map.end(); ) {
1047 if (import_data.
used_keys.count(oldit->first) == 0) {
1048 warnings.
push_back(
"Ignoring irrelevant private key.");
1049 privkey_map.erase(oldit);
1052 for (
auto it = pubkey_map.begin(); it != pubkey_map.end(); ) {
1054 auto key_data_it = import_data.
used_keys.find(oldit->first);
1055 if (key_data_it == import_data.
used_keys.end() || !key_data_it->second) {
1056 warnings.
push_back(
"Ignoring public key \"" +
HexStr(oldit->first) +
"\" as it doesn't appear inside P2PKH or P2WPKH.");
1057 pubkey_map.erase(oldit);
1066 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)
1070 const std::string& descriptor = data[
"desc"].
get_str();
1073 auto parsed_desc =
Parse(descriptor, keys,
error,
true);
1081 have_solving_data = parsed_desc->IsSolvable();
1082 const bool watch_only = data.
exists(
"watchonly") ? data[
"watchonly"].
get_bool() :
false;
1084 int64_t range_start = 0, range_end = 0;
1085 if (!parsed_desc->IsRange() && data.
exists(
"range")) {
1087 }
else if (parsed_desc->IsRange()) {
1088 if (!data.
exists(
"range")) {
1097 for (
int i = range_start; i <= range_end; ++i) {
1099 std::vector<CScript> scripts_temp;
1100 parsed_desc->Expand(i, keys, scripts_temp, out_keys);
1101 std::copy(scripts_temp.begin(), scripts_temp.end(), std::inserter(script_pub_keys, script_pub_keys.end()));
1102 for (
const auto& key_pair : out_keys.
pubkeys) {
1103 ordered_pubkeys.push_back(key_pair.first);
1106 for (
const auto& x : out_keys.
scripts) {
1110 parsed_desc->ExpandPrivate(i, keys, out_keys);
1112 std::copy(out_keys.
pubkeys.begin(), out_keys.
pubkeys.end(), std::inserter(pubkey_map, pubkey_map.end()));
1113 std::copy(out_keys.
keys.begin(), out_keys.
keys.end(), std::inserter(privkey_map, privkey_map.end()));
1117 for (
size_t i = 0; i < priv_keys.
size(); ++i) {
1118 const auto& str = priv_keys[i].
get_str();
1127 if (!pubkey_map.count(
id)) {
1128 warnings.
push_back(
"Ignoring irrelevant private key.");
1130 privkey_map.emplace(
id, key);
1138 bool spendable = std::all_of(pubkey_map.begin(), pubkey_map.end(),
1139 [&](
const std::pair<CKeyID, CPubKey>& used_key) {
1140 return privkey_map.count(used_key.first) > 0;
1142 [&](
const std::pair<CKeyID, std::pair<CPubKey, KeyOriginInfo>>& entry) {
1143 return privkey_map.count(entry.first) > 0;
1145 if (!watch_only && !spendable) {
1146 warnings.
push_back(
"Some private keys are missing, outputs will be considered watchonly. If this is intentional, specify the watchonly flag.");
1148 if (watch_only && spendable) {
1149 warnings.
push_back(
"All private keys are provided, outputs will be considered spendable. If this is intentional, do not specify the watchonly flag.");
1161 const bool internal = data.exists(
"internal") ? data[
"internal"].get_bool() :
false;
1163 if (
internal && data.exists(
"label")) {
1166 const std::string& label = data.exists(
"label") ? data[
"label"].get_str() :
"";
1167 const bool add_keypool = data.exists(
"keypool") ? data[
"keypool"].get_bool() :
false;
1175 std::map<CKeyID, CPubKey> pubkey_map;
1176 std::map<CKeyID, CKey> privkey_map;
1177 std::set<CScript> script_pub_keys;
1178 std::vector<CKeyID> ordered_pubkeys;
1179 bool have_solving_data;
1181 if (data.exists(
"scriptPubKey") && data.exists(
"desc")) {
1183 }
else if (data.exists(
"scriptPubKey")) {
1184 warnings =
ProcessImportLegacy(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys);
1185 }
else if (data.exists(
"desc")) {
1186 warnings =
ProcessImportDescriptor(import_data, pubkey_map, privkey_map, script_pub_keys, have_solving_data, data, ordered_pubkeys);
1197 for (
const CScript& script : script_pub_keys) {
1208 if (!
wallet.ImportPrivKeys(privkey_map, timestamp)) {
1211 if (!
wallet.ImportPubKeys(ordered_pubkeys, pubkey_map, import_data.
key_origins, add_keypool,
internal, timestamp)) {
1214 if (!
wallet.ImportScriptPubKeys(label, script_pub_keys, have_solving_data, !
internal, timestamp)) {
1221 result.
pushKV(
"error", e);
1227 if (warnings.
size()) result.
pushKV(
"warnings", warnings);
1233 if (data.
exists(
"timestamp")) {
1234 const UniValue& timestamp = data[
"timestamp"];
1235 if (timestamp.
isNum()) {
1236 return timestamp.
getInt<int64_t>();
1237 }
else if (timestamp.
isStr() && timestamp.
get_str() ==
"now") {
1248 "\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" 1249 "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" 1250 "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" 1251 "\nNote: This call can take over an hour to complete if rescan is true, during that time, other rpc calls\n" 1252 "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n" 1253 "The rescan parameter can be set to false if the key was never used to create transactions. If it is set to false,\n" 1254 "but the key was used to create transactions, rescanblockchain needs to be called with the appropriate block range.\n" 1255 "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
1263 "", {
"\"<script>\" | { \"address\":\"<address>\" }",
"string / json"}
1266 " or the string \"now\" to substitute the current synced blockchain time. The timestamp of the oldest\n" 1267 " key will determine how far back blockchain rescans need to begin for missing wallet transactions.\n" 1268 " \"now\" can be specified to bypass scanning, for keys which are known to never have been used, and\n" 1269 " 0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest key\n" 1270 " creation time of all keys being imported by the importmulti call will be scanned.",
1271 "", {
"timestamp | \"now\"",
"integer / string"}
1275 {
"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).",
1289 {
"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"},
1301 RPCResult::Type::ARR,
"",
"Response is an array with the same size as the input that has the execution result",
1318 HelpExampleCli(
"importmulti",
"'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }, " 1319 "{ \"scriptPubKey\": { \"address\": \"<my 2nd address>\" }, \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
1320 HelpExampleCli(
"importmulti",
"'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }]' '{ \"rescan\": false}'")
1330 wallet.BlockUntilSyncedToCurrentChain();
1332 RPCTypeCheck(mainRequest.params, {UniValue::VARR, UniValue::VOBJ});
1336 const UniValue& requests = mainRequest.params[0];
1339 bool fRescan =
true;
1341 if (!mainRequest.params[1].isNull()) {
1342 const UniValue& options = mainRequest.params[1];
1344 if (options.
exists(
"rescan")) {
1345 fRescan = options[
"rescan"].
get_bool();
1350 if (fRescan && !reserver.
reserve()) {
1355 bool fRunScan =
false;
1356 int64_t nLowestTimestamp = 0;
1359 LOCK(pwallet->cs_wallet);
1368 const int64_t minimumTimestamp = 1;
1380 if (result[
"success"].get_bool()) {
1385 if (timestamp < nLowestTimestamp) {
1386 nLowestTimestamp = timestamp;
1390 if (fRescan && fRunScan && requests.
size()) {
1391 int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp, reserver,
true );
1392 pwallet->ResubmitWalletTransactions(
false,
true);
1394 if (pwallet->IsAbortingRescan()) {
1397 if (scannedTime > nLowestTimestamp) {
1398 std::vector<UniValue> results = response.
getValues();
1407 if (scannedTime <=
GetImportTimestamp(request, now) || results.at(i).exists(
"error")) {
1416 strprintf(
"Rescan failed for key with creation timestamp %d. There was an error reading a " 1417 "block from time %d, which is after or within %d seconds of key creation, and " 1418 "could contain transactions pertaining to the key. As a result, transactions " 1419 "and coins using this key may not appear in the wallet. This error could be " 1420 "caused by pruning or data corruption (see bitcoind log for details) and could " 1421 "be dealt with by downloading and rescanning the relevant blocks (see -reindex " 1422 "option and rescanblockchain RPC).",
1442 if (!data.exists(
"desc")) {
1446 const std::string& descriptor = data[
"desc"].get_str();
1447 const bool active = data.exists(
"active") ? data[
"active"].get_bool() :
false;
1448 const bool internal = data.exists(
"internal") ? data[
"internal"].get_bool() :
false;
1449 const std::string& label = data.exists(
"label") ? data[
"label"].get_str() :
"";
1454 auto parsed_desc =
Parse(descriptor, keys,
error,
true);
1460 int64_t range_start = 0, range_end = 1, next_index = 0;
1461 if (!parsed_desc->IsRange() && data.exists(
"range")) {
1463 }
else if (parsed_desc->IsRange()) {
1464 if (data.exists(
"range")) {
1466 range_start = range.first;
1467 range_end = range.second + 1;
1469 warnings.
push_back(
"Range not given, using default keypool range");
1473 next_index = range_start;
1475 if (data.exists(
"next_index")) {
1476 next_index = data[
"next_index"].getInt<int64_t>();
1478 if (next_index < range_start || next_index >= range_end) {
1485 if (active && !parsed_desc->IsRange()) {
1490 if (data.exists(
"range") && data.exists(
"label")) {
1495 if (
internal && data.exists(
"label")) {
1500 if (active && !parsed_desc->IsSingleType()) {
1511 std::vector<CScript> scripts;
1512 if (!parsed_desc->Expand(0, keys, scripts, expand_keys)) {
1513 throw JSONRPCError(
RPC_WALLET_ERROR,
"Cannot expand descriptor. Probably because of hardened derivations without private keys provided");
1515 parsed_desc->ExpandPrivate(0, keys, expand_keys);
1518 bool have_all_privkeys = !expand_keys.
keys.empty();
1519 for (
const auto& entry : expand_keys.
origins) {
1520 const CKeyID& key_id = entry.first;
1522 if (!expand_keys.
GetKey(key_id, key)) {
1523 have_all_privkeys =
false;
1530 if (keys.
keys.empty()) {
1533 if (!have_all_privkeys) {
1534 warnings.
push_back(
"Not all private keys provided. Some wallet functionality may return unexpected errors");
1538 WalletDescriptor w_desc(std::move(parsed_desc), timestamp, range_start, range_end, next_index);
1541 auto existing_spk_manager =
wallet.GetDescriptorScriptPubKeyMan(w_desc);
1542 if (existing_spk_manager) {
1543 if (!existing_spk_manager->CanUpdateToWalletDescriptor(w_desc,
error)) {
1549 auto spk_manager =
wallet.AddWalletDescriptor(w_desc, keys, label,
internal);
1550 if (spk_manager ==
nullptr) {
1557 warnings.
push_back(
"Unknown output type, cannot set descriptor to active.");
1559 wallet.AddActiveScriptPubKeyMan(spk_manager->GetID(), *w_desc.
descriptor->GetOutputType(),
internal);
1563 wallet.DeactivateScriptPubKeyMan(spk_manager->GetID(), *w_desc.
descriptor->GetOutputType(),
internal);
1570 result.
pushKV(
"error", e);
1572 if (warnings.
size()) result.
pushKV(
"warnings", warnings);
1579 "\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" 1580 "\nNote: This call can take over an hour to complete if using an early timestamp; during that time, other rpc calls\n" 1581 "may report that the imported keys, addresses or scripts exist but related transactions are still missing.\n",
1592 " Use the string \"now\" to substitute the current synced blockchain time.\n" 1593 " \"now\" can be specified to bypass scanning, for outputs which are known to never have been used, and\n" 1594 " 0 can be specified to scan the entire blockchain. Blocks up to 2 hours before the earliest timestamp\n" 1595 "of all descriptors being imported will be scanned as well as the mempool.",
1596 "", {
"timestamp | \"now\"",
"integer / string"}
1606 RPCResult::Type::ARR,
"",
"Response is an array with the same size as the input that has the execution result",
1623 HelpExampleCli(
"importdescriptors",
"'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"internal\": true }, " 1624 "{ \"desc\": \"<my descriptor 2>\", \"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
1625 HelpExampleCli(
"importdescriptors",
"'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, \"active\": true, \"range\": [0,100], \"label\": \"<my bech32 wallet>\" }]'")
1635 wallet.BlockUntilSyncedToCurrentChain();
1642 RPCTypeCheck(main_request.params, {UniValue::VARR, UniValue::VOBJ});
1649 const UniValue& requests = main_request.params[0];
1650 const int64_t minimum_timestamp = 1;
1652 int64_t lowest_timestamp = 0;
1653 bool rescan =
false;
1656 LOCK(pwallet->cs_wallet);
1664 const int64_t timestamp = std::max(
GetImportTimestamp(request, now), minimum_timestamp);
1668 if (lowest_timestamp > timestamp ) {
1669 lowest_timestamp = timestamp;
1673 if (!rescan && result[
"success"].get_bool()) {
1677 pwallet->ConnectScriptPubKeyManNotifiers();
1682 int64_t scanned_time = pwallet->RescanFromTime(lowest_timestamp, reserver,
true );
1683 pwallet->ResubmitWalletTransactions(
false,
true);
1685 if (pwallet->IsAbortingRescan()) {
1689 if (scanned_time > lowest_timestamp) {
1690 std::vector<UniValue> results = response.
getValues();
1695 for (
unsigned int i = 0; i < requests.
size(); ++i) {
1702 if (scanned_time <=
GetImportTimestamp(request, now) || results.at(i).exists(
"error")) {
1711 strprintf(
"Rescan failed for descriptor with timestamp %d. There was an error reading a " 1712 "block from time %d, which is after or within %d seconds of key creation, and " 1713 "could contain transactions pertaining to the desc. As a result, transactions " 1714 "and coins using this desc may not appear in the wallet. This error could be " 1715 "caused by pruning or data corruption (see bitcoind log for details) and could " 1716 "be dealt with by downloading and rescanning the relevant blocks (see -reindex " 1717 "option and rescanblockchain RPC).",
1734 "\nList descriptors imported into a descriptor-enabled wallet.\n",
1745 {
RPCResult::Type::BOOL,
"active",
"Whether this descriptor is currently used to generate new addresses"},
1746 {
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"},
1751 {
RPCResult::Type::NUM,
"next",
true,
"The next index to generate addresses from; defined only for ranged descriptors"},
1768 const bool priv = !request.params[0].isNull() && request.params[0].get_bool();
1775 const auto active_spk_mans =
wallet->GetActiveScriptPubKeyMans();
1777 struct WalletDescInfo {
1778 std::string descriptor;
1779 uint64_t creation_time;
1781 std::optional<bool>
internal;
1782 std::optional<std::pair<int64_t,int64_t>> range;
1786 std::vector<WalletDescInfo> wallet_descriptors;
1787 for (
const auto& spk_man :
wallet->GetAllScriptPubKeyMans()) {
1789 if (!desc_spk_man) {
1792 LOCK(desc_spk_man->cs_desc_man);
1793 const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor();
1794 std::string descriptor;
1795 if (!desc_spk_man->GetDescriptorString(descriptor, priv)) {
1798 const bool is_range = wallet_descriptor.descriptor->IsRange();
1799 wallet_descriptors.push_back({
1801 wallet_descriptor.creation_time,
1802 active_spk_mans.count(desc_spk_man) != 0,
1803 wallet->IsInternalScriptPubKeyMan(desc_spk_man),
1804 is_range ? std::optional(std::make_pair(wallet_descriptor.range_start, wallet_descriptor.range_end)) : std::nullopt,
1805 wallet_descriptor.next_index
1809 std::sort(wallet_descriptors.begin(), wallet_descriptors.end(), [](
const auto& a,
const auto& b) {
1810 return a.descriptor < b.descriptor;
1814 for (
const WalletDescInfo& info : wallet_descriptors) {
1816 spk.
pushKV(
"desc", info.descriptor);
1817 spk.
pushKV(
"timestamp", info.creation_time);
1818 spk.
pushKV(
"active", info.active);
1819 if (info.internal.has_value()) {
1820 spk.
pushKV(
"internal", info.internal.value());
1822 if (info.range.has_value()) {
1825 range.
push_back(info.range->second - 1);
1826 spk.
pushKV(
"range", range);
1827 spk.
pushKV(
"next", info.next_index);
1829 descriptors.push_back(spk);
1834 response.
pushKV(
"descriptors", descriptors);
1844 "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n",
1860 pwallet->BlockUntilSyncedToCurrentChain();
1862 LOCK(pwallet->cs_wallet);
1864 std::string strDest = request.params[0].get_str();
1865 if (!pwallet->BackupWallet(strDest)) {
1879 "\nRestore and loads a wallet from backup.\n",
1889 {
RPCResult::Type::STR,
"warning",
"Warning messages, if any, related to restoring the wallet. Multiple messages will be delimited by newlines."},
1893 HelpExampleCli(
"restorewallet",
"\"testwallet\" \"home\\backups\\backup-file.bak\"")
1894 +
HelpExampleRpc(
"restorewallet",
"\"testwallet\" \"home\\backups\\backup-file.bak\"")
1895 +
HelpExampleCliNamed(
"restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak\""}, {
"load_on_startup",
true}})
1896 +
HelpExampleRpcNamed(
"restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak\""}, {
"load_on_startup",
true}})
1903 auto backup_file =
fs::u8path(request.params[1].get_str());
1905 std::string wallet_name = request.params[0].get_str();
1907 std::optional<bool> load_on_start = request.params[2].isNull() ? std::nullopt : std::optional<bool>(request.params[2].get_bool());
1911 std::vector<bilingual_str> warnings;
std::shared_ptr< const CTransaction > CTransactionRef
Witness v0 (P2WPKH and P2WSH); see BIP 141.
Helper for findBlock to selectively return pieces of block data.
RPCHelpMan importwallet()
void push_back(UniValue val)
const std::vector< UniValue > & getValues() const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
const CHDChain & GetHDChain() const
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
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.
std::map< CKeyID, CKey > keys
static constexpr unsigned int size()
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
#define CHECK_NONFATAL(condition)
Identity function.
bool IsHex(std::string_view str)
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
virtual std::set< CScriptID > GetCScripts() const
static const unsigned int DEFAULT_KEYPOOL_SIZE
Default for -keypool.
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.
Double ended buffer combining vector and stream-like interfaces.
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.
std::vector< std::string > SplitString(std::string_view str, char sep)
int64_t ParseISO8601DateTime(const std::string &str)
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
unspendable OP_RETURN script that carries data
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::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
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)
std::vector< Byte > ParseHex(std::string_view str)
Parse the hex string into bytes (uint8_t or std::byte).
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)
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
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
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...
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
General application defined errors.
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
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()
Optional arg that is a named argument and has a default value of null.
Descriptor with some wallet metadata.
LegacyScriptPubKeyMan & EnsureLegacyScriptPubKeyMan(CWallet &wallet, bool also_create)
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)
CRIPEMD160 & Write(const unsigned char *data, size_t len)
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].
RPCHelpMan importpubkey()
Optional argument with default value omitted because they are implicitly clear.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
void importaddress(wallet::CWallet &wallet, const std::string &address)
Import the address to the wallet.
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)
void pushKV(std::string key, UniValue val)
Serialized script, used inside transaction inputs and outputs.
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
static const int PROTOCOL_VERSION
network protocol versioning
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath)
Write HD keypaths as strings.
#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.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char >> &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
Only for Witness versions not already defined above.
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 (see script.h)
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 GetTime()
DEPRECATED, see GetTime.
std::string EncodeSecret(const CKey &key)
std::vector< uint32_t > path
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
bool error(const char *fmt, const Args &... args)
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...
A hasher class for RIPEMD-160.
Special type to denote elision (...)
bool IsValid() const
Check whether this private key is valid.
void RPCTypeCheck(const UniValue ¶ms, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
bool IsCompressed() const
Check whether this is a compressed public key.