43 std::stringstream ret;
44 for (
const uint8_t c : str) {
45 if (c <= 32 || c >= 128 || c ==
'%') {
46 ret <<
'%' <<
HexStr({&c, 1});
55 std::stringstream ret;
56 for (
unsigned int pos = 0; pos < str.length(); pos++) {
58 if (c ==
'%' && pos + 2 < str.length()) {
59 c = (((str[pos + 1] >> 6) * 9 + ((str[pos + 1] -
'0') & 15)) << 4) |
60 ((str[pos + 2] >> 6) * 9 + ((str[pos + 2] -
'0') & 15));
71 std::string &strAddr, std::string &strLabel)
73 bool fLabelFound =
false;
75 spk_man->GetKey(keyid, key);
77 const auto *address_book_entry = pwallet->FindAddressBookEntry(dest);
78 if (address_book_entry) {
79 if (!strAddr.empty()) {
90 pwallet->m_default_address_type),
100 bool update =
true) {
101 int64_t scanned_time =
wallet.RescanFromTime(time_begin, reserver, update);
102 if (
wallet.IsAbortingRescan()) {
104 }
else if (scanned_time > time_begin) {
106 "Rescan was unable to fully rescan the blockchain. "
107 "Some transactions may be missing.");
112 auto &chain{
wallet.chain()};
113 if (!chain.havePruned()) {
118 const bool found{chain.findFirstBlockWithTimeAndHeight(
123 if (found && !chain.hasBlocks(tip_hash, height)) {
127 "Pruned blocks from height %d required to import keys. Use RPC "
128 "call getblockchaininfo to determine your pruned height.",
136 "Adds a private key (as returned by dumpprivkey) to your wallet. "
137 "Requires a new wallet backup.\n"
138 "Hint: use importmulti to import more than one private key.\n"
139 "\nNote: This call can take minutes to complete if rescan is true, "
140 "during that time, other rpc calls\n"
141 "may report that the imported key exists but related transactions are "
142 "still missing, leading to temporarily incorrect/bogus balances and "
143 "unspent outputs until rescan completes.\n"
144 "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
145 "Note: This command is only compatible with legacy wallets. Use "
146 "\"importdescriptors\" with \"combo(X)\" for descriptor wallets.\n",
149 "The private key (see dumpprivkey)"},
152 "current label if address exists, otherwise \"\""},
153 "An optional label"},
155 "Rescan the wallet for transactions"},
159 "\nDump a private key\n" +
161 "\nImport the private key with rescan\n" +
163 "\nImport using a label and without rescan\n" +
165 "\nImport using default blank label and without rescan\n" +
167 "\nAs a JSON-RPC call\n" +
168 HelpExampleRpc(
"importprivkey",
"\"mykey\", \"testing\", false")},
171 std::shared_ptr<CWallet>
const wallet =
181 "Cannot import private keys to a wallet with "
182 "private keys disabled");
194 std::string strSecret = request.params[0].get_str();
195 std::string strLabel =
"";
196 if (!request.params[1].isNull()) {
197 strLabel = request.params[1].get_str();
201 if (!request.params[2].isNull()) {
202 fRescan = request.params[2].get_bool();
211 "Rescan is disabled when blocks are pruned");
214 if (fRescan && !reserver.
reserve()) {
217 "Wallet is currently rescanning. Abort existing "
224 "Invalid private key encoding");
237 if (!request.params[1].isNull() ||
246 "Error adding key to wallet");
262 "Stops current wallet rescan triggered by an RPC call, e.g. by an "
263 "importprivkey call.\n"
264 "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
267 "Whether the abort was successful"},
270 "\nAbort the running wallet rescan\n" +
272 "\nAs a JSON-RPC call\n" +
276 std::shared_ptr<CWallet>
const wallet =
295 "Adds an address or script (in hex) that can be watched as if it "
296 "were in your wallet but cannot be used to spend. Requires a new "
298 "\nNote: This call can take minutes to complete if rescan is true, "
299 "during that time, other rpc calls\n"
300 "may report that the imported address exists but related transactions "
301 "are still missing, leading to temporarily incorrect/bogus balances "
302 "and unspent outputs until rescan completes.\n"
303 "If you have the full public key, you should call importpubkey instead "
305 "Hint: use importmulti to import more than one address.\n"
306 "\nNote: If you import a non-standard raw script in hex form, outputs "
307 "sending to it will be treated\n"
308 "as change, and not show up in many RPCs.\n"
309 "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
310 "Note: This command is only compatible with legacy wallets. Use "
311 "\"importdescriptors\" for descriptor wallets.\n",
314 "The Bitcoin address (or hex-encoded script)"},
316 "An optional label"},
318 "Rescan the wallet for transactions"},
320 "Add the P2SH version of the script as well"},
324 "\nImport an address with rescan\n" +
326 "\nImport using a label without rescan\n" +
327 HelpExampleCli(
"importaddress",
"\"myaddress\" \"testing\" false") +
328 "\nAs a JSON-RPC call\n" +
330 "\"myaddress\", \"testing\", false")},
333 std::shared_ptr<CWallet>
const wallet =
342 std::string strLabel;
343 if (!request.params[1].isNull()) {
344 strLabel = request.params[1].get_str();
349 if (!request.params[2].isNull()) {
350 fRescan = request.params[2].get_bool();
358 "Rescan is disabled when blocks are pruned");
362 if (fRescan && !reserver.
reserve()) {
364 "Wallet is currently rescanning. Abort "
365 "existing rescan or wait.");
370 if (!request.params[3].isNull()) {
371 fP2SH = request.params[3].get_bool();
378 request.params[0].get_str(),
wallet->GetChainParams());
383 "Cannot use the p2sh flag with an address - "
384 "use a script instead");
393 }
else if (
IsHex(request.params[0].get_str())) {
394 std::vector<uint8_t> data(
395 ParseHex(request.params[0].get_str()));
396 CScript redeem_script(data.begin(), data.end());
398 std::set<CScript> scripts = {redeem_script};
407 strLabel, scripts,
false ,
411 "Invalid Bitcoin address or script");
430 "Imports funds without rescan. Corresponding address or script must "
431 "previously be included in wallet. Aimed towards pruned wallets. The "
432 "end-user is responsible to import additional transactions that "
433 "subsequently spend the imported outputs or rescan after the point in "
434 "the blockchain the transaction is included.\n",
437 "A raw transaction in hex funding an already-existing address in "
440 "The hex output from gettxoutproof that contains the transaction"},
446 std::shared_ptr<CWallet>
const wallet =
454 if (!
DecodeHexTx(tx, request.params[0].get_str())) {
466 std::vector<uint256> vMatch;
467 std::vector<size_t> vIndex;
471 "Something wrong with merkleblock");
480 "Block not found in chain");
483 std::vector<uint256>::const_iterator it;
484 if ((it = std::find(vMatch.begin(), vMatch.end(), txid)) ==
487 "Transaction given doesn't exist in proof");
490 size_t txnIndex = vIndex[it - vMatch.begin()];
493 CWalletTx::Status::CONFIRMED, height,
497 if (pwallet->
IsMine(*tx_ref)) {
504 "No addresses in wallet correspond to included transaction");
512 "Deletes the specified transaction from the wallet. Meant for use "
513 "with pruned wallets and as a companion to importprunedfunds. This "
514 "will affect wallet balances.\n",
517 "The hex-encoded id of the transaction you are deleting"},
521 "\"a8d0c0184dde994a09ec054286f1ce581bebf4644"
522 "6a512166eae7628734ea0a5\"") +
523 "\nAs a JSON-RPC call\n" +
525 "\"a8d0c0184dde994a09ec054286f1ce581bebf4644"
526 "6a512166eae7628734ea0a5\"")},
529 std::shared_ptr<CWallet>
const wallet =
539 std::vector<TxId> txIds;
540 txIds.push_back(txid);
541 std::vector<TxId> txIdsOut;
546 "Could not properly delete the transaction.");
549 if (txIdsOut.empty()) {
551 "Transaction does not exist in wallet.");
562 "Adds a public key (in hex) that can be watched as if it were in "
563 "your wallet but cannot be used to spend. Requires a new wallet "
565 "Hint: use importmulti to import more than one public key.\n"
566 "\nNote: This call can take minutes to complete if rescan is true, "
567 "during that time, other rpc calls\n"
568 "may report that the imported pubkey exists but related transactions "
569 "are still missing, leading to temporarily incorrect/bogus balances "
570 "and unspent outputs until rescan completes.\n"
571 "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
572 "Note: This command is only compatible with legacy wallets. Use "
573 "\"importdescriptors\" with \"combo(X)\" for descriptor wallets.\n",
576 "The hex-encoded public key"},
578 "An optional label"},
580 "Rescan the wallet for transactions"},
584 "\nImport a public key with rescan\n" +
586 "\nImport using a label without rescan\n" +
587 HelpExampleCli(
"importpubkey",
"\"mypubkey\" \"testing\" false") +
588 "\nAs a JSON-RPC call\n" +
589 HelpExampleRpc(
"importpubkey",
"\"mypubkey\", \"testing\", false")},
592 std::shared_ptr<CWallet>
const wallet =
601 std::string strLabel;
602 if (!request.params[1].isNull()) {
603 strLabel = request.params[1].get_str();
608 if (!request.params[2].isNull()) {
609 fRescan = request.params[2].get_bool();
617 "Rescan is disabled when blocks are pruned");
621 if (fRescan && !reserver.
reserve()) {
623 "Wallet is currently rescanning. Abort "
624 "existing rescan or wait.");
627 if (!
IsHex(request.params[0].get_str())) {
629 "Pubkey must be a hex string");
631 std::vector<uint8_t> data(
ParseHex(request.params[0].get_str()));
635 "Pubkey is not a valid public key");
641 std::set<CScript> script_pub_keys;
649 strLabel, script_pub_keys,
true ,
673 "Imports keys from a wallet dump file (see dumpwallet). Requires a "
674 "new wallet backup to include imported keys.\n"
675 "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
676 "Note: This command is only compatible with legacy wallets.\n",
684 "\nImport the wallet\n" +
686 "\nImport using the json rpc call\n" +
690 std::shared_ptr<CWallet>
const wallet =
702 "Wallet is currently rescanning. Abort "
703 "existing rescan or wait.");
706 int64_t nTimeBegin = 0;
714 file.open(
fs::u8path(request.params[0].get_str()),
715 std::ios::in | std::ios::ate);
716 if (!file.is_open()) {
718 "Cannot open wallet dump file");
724 int64_t nFilesize = std::max<int64_t>(1, file.tellg());
725 file.seekg(0, file.beg);
735 strprintf(
"%s " +
_(
"Importing...").translated,
738 std::vector<std::tuple<CKey, int64_t, bool, std::string>> keys;
739 std::vector<std::pair<CScript, int64_t>> scripts;
740 while (file.good()) {
744 std::min<int>(50, 100 *
double(file.tellg()) /
748 std::getline(file, line);
749 if (line.empty() || line[0] ==
'#') {
753 std::vector<std::string> vstr =
SplitString(line,
' ');
754 if (vstr.size() < 2) {
761 std::string strLabel;
763 for (
size_t nStr = 2; nStr < vstr.size(); nStr++) {
764 if (vstr[nStr].front() ==
'#') {
767 if (vstr[nStr] ==
"change=1") {
770 if (vstr[nStr] ==
"reserve=1") {
773 if (vstr[nStr].substr(0, 6) ==
"label=") {
779 nTimeBegin = std::min(nTimeBegin, nTime);
781 std::make_tuple(key, nTime, fLabel, strLabel));
782 }
else if (
IsHex(vstr[0])) {
783 std::vector<uint8_t> vData(
ParseHex(vstr[0]));
784 CScript
script = CScript(vData.begin(), vData.end());
787 if (birth_time > 0) {
788 nTimeBegin = std::min(nTimeBegin, birth_time);
791 std::pair<CScript, int64_t>(
script, birth_time));
803 "Importing wallets is disabled when "
804 "private keys are disabled");
806 double total = double(keys.size() + scripts.size());
808 for (
const auto &key_tuple : keys) {
811 std::max(50, std::min<int>(75, 100 * progress / total) +
814 const CKey &key = std::get<0>(key_tuple);
815 int64_t time = std::get<1>(key_tuple);
816 bool has_label = std::get<2>(key_tuple);
817 std::string label = std::get<3>(key_tuple);
829 "Error importing key for %s\n",
841 for (
const auto &script_pair : scripts) {
844 std::max(50, std::min<int>(75, 100 * progress / total) +
847 const CScript &
script = script_pair.first;
848 int64_t time = script_pair.second;
864 pwallet->chain().showProgress(
"", 100,
false);
866 pwallet->MarkDirty();
870 "Error adding some keys/scripts to wallet");
881 "Reveals the private key corresponding to 'address'.\n"
882 "Then the importprivkey can be used with this output\n"
883 "Note: This command is only compatible with legacy wallets.\n",
886 "The bitcoin address for the private key"},
894 std::shared_ptr<CWallet>
const wallet =
908 std::string strAddress = request.params[0].get_str();
913 "Invalid Bitcoin address");
916 if (keyid.IsNull()) {
918 "Address does not refer to a key");
921 if (!spk_man.
GetKey(keyid, vchSecret)) {
923 "Private key for address " + strAddress +
934 "Dumps all wallet keys in a human-readable format to a server-side "
935 "file. This does not allow overwriting existing files.\n"
936 "Imported scripts are included in the dumpsfile, but corresponding "
937 "addresses may not be added automatically by importwallet.\n"
938 "Note that if your wallet contains keys which are not derived from "
939 "your HD seed (e.g. imported keys), these are not covered by\n"
940 "only backing up the seed itself, and must be backed up too (e.g. "
941 "ensure you back up the whole dumpfile).\n"
942 "Note: This command is only compatible with legacy wallets.\n",
945 "The filename with path (absolute path recommended)"},
952 "The filename with full absolute path"},
958 std::shared_ptr<CWallet>
const pwallet =
971 wallet.BlockUntilSyncedToCurrentChain();
989 " already exists. If you are "
990 "sure this is what you want, "
991 "move it out of the way first");
996 if (!file.is_open()) {
998 "Cannot open wallet dump file");
1001 std::map<CKeyID, int64_t> mapKeyBirth;
1002 wallet.GetKeyBirthTimes(mapKeyBirth);
1004 int64_t block_time = 0;
1014 const std::map<CKeyID, int64_t> &mapKeyPool =
1016 std::set<CScriptID> scripts = spk_man.
GetCScripts();
1019 std::vector<std::pair<int64_t, CKeyID>> vKeyBirth;
1020 vKeyBirth.reserve(mapKeyBirth.size());
1021 for (
const auto &entry : mapKeyBirth) {
1022 vKeyBirth.push_back(std::make_pair(entry.second, entry.first));
1024 mapKeyBirth.clear();
1025 std::sort(vKeyBirth.begin(), vKeyBirth.end());
1030 file <<
strprintf(
"# * Created on %s\n",
1032 file <<
strprintf(
"# * Best block at time of backup was %i (%s),\n",
1033 wallet.GetLastBlockHeight(),
1034 wallet.GetLastBlockHash().ToString());
1043 if (spk_man.
GetKey(seed_id, seed)) {
1047 file <<
"# extended private masterkey: "
1051 for (std::vector<std::pair<int64_t, CKeyID>>::const_iterator it =
1053 it != vKeyBirth.end(); it++) {
1054 const CKeyID &keyid = it->second;
1056 std::string strAddr;
1057 std::string strLabel;
1059 if (spk_man.
GetKey(keyid, key)) {
1062 keyid, strAddr, strLabel)) {
1063 file <<
strprintf(
"label=%s", strLabel);
1064 }
else if (keyid == seed_id) {
1066 }
else if (mapKeyPool.count(keyid)) {
1067 file <<
"reserve=1";
1068 }
else if (spk_man.mapKeyMetadata[keyid].hdKeypath ==
"s") {
1069 file <<
"inactivehdseed=1";
1074 " # addr=%s%s\n", strAddr,
1075 (spk_man.mapKeyMetadata[keyid].has_key_origin
1083 for (
const CScriptID &scriptid : scripts) {
1085 std::string create_time =
"0";
1086 std::string address =
1089 auto it = spk_man.m_script_metadata.find(scriptid);
1090 if (it != spk_man.m_script_metadata.end()) {
1096 file <<
strprintf(
" # addr=%s\n", address);
1100 file <<
"# End of dump\n";
1114 "dump all the UTXO tracked by the wallet.\n",
1123 "The list of UTXO corresponding to this address.",
1130 "The transaction id"},
1134 "The output's amount"},
1143 std::shared_ptr<CWallet>
const pwallet =
1154 wallet.BlockUntilSyncedToCurrentChain();
1163 for (
const auto &o : p.second) {
1165 utxo.
pushKV(
"txid", o.tx->GetId().ToString());
1166 utxo.
pushKV(
"vout", o.i);
1167 utxo.
pushKV(
"depth", o.nDepth);
1168 utxo.
pushKV(
"value", o.tx->tx->vout[o.i].nValue);
1208 std::vector<std::vector<uint8_t>> solverdata;
1211 switch (script_type) {
1213 CPubKey pubkey(solverdata[0]);
1225 "Trying to nest P2SH inside another P2SH");
1233 return "missing redeemscript";
1236 return "redeemScript does not match the scriptPubKey";
1243 for (
size_t i = 1; i + 1 < solverdata.size(); ++i) {
1244 CPubKey pubkey(solverdata[i]);
1250 return "unspendable script";
1253 return "unrecognized script";
1259 std::map<CKeyID, CPubKey> &pubkey_map, std::map<CKeyID, CKey> &privkey_map,
1260 std::set<CScript> &script_pub_keys,
bool &have_solving_data,
1261 const UniValue &data, std::vector<CKeyID> &ordered_pubkeys) {
1266 const UniValue &scriptPubKey = data[
"scriptPubKey"];
1269 scriptPubKey.
exists(
"address"))) {
1271 "scriptPubKey must be string with script or JSON "
1272 "with address string");
1274 const std::string &output =
1275 isScript ? scriptPubKey.
get_str() : scriptPubKey[
"address"].
get_str();
1278 const std::string &strRedeemScript =
1279 data.
exists(
"redeemscript") ? data[
"redeemscript"].
get_str() :
"";
1284 const bool internal =
1286 const bool watchOnly =
1289 if (data.
exists(
"range")) {
1292 "Range should not be specified for a non-descriptor import");
1302 "Invalid address \"" + output +
"\"");
1306 if (!
IsHex(output)) {
1308 "Invalid scriptPubKey \"" + output +
"\"");
1310 std::vector<uint8_t> vData(
ParseHex(output));
1311 script = CScript(vData.begin(), vData.end());
1315 "Internal must be set to true for "
1316 "nonstandard scriptPubKey imports.");
1319 script_pub_keys.emplace(
script);
1322 if (strRedeemScript.size()) {
1323 if (!
IsHex(strRedeemScript)) {
1325 "Invalid redeem script \"" + strRedeemScript +
1326 "\": must be hex string");
1328 auto parsed_redeemscript =
ParseHex(strRedeemScript);
1330 parsed_redeemscript.begin(), parsed_redeemscript.end());
1332 for (
size_t i = 0; i < pubKeys.
size(); ++i) {
1333 const auto &str = pubKeys[i].
get_str();
1336 "Pubkey \"" + str +
"\" must be a hex string");
1338 auto parsed_pubkey =
ParseHex(str);
1339 CPubKey pubkey(parsed_pubkey);
1343 "\" is not a valid public key");
1345 pubkey_map.emplace(pubkey.
GetID(), pubkey);
1346 ordered_pubkeys.push_back(pubkey.
GetID());
1348 for (
size_t i = 0; i < keys.
size(); ++i) {
1349 const auto &str = keys[i].
get_str();
1353 "Invalid private key encoding");
1357 if (pubkey_map.count(
id)) {
1358 pubkey_map.erase(
id);
1360 privkey_map.emplace(
id, key);
1365 import_data.
redeemscript || pubkey_map.size() || privkey_map.size();
1366 if (have_solving_data) {
1372 bool spendable = std::all_of(
1374 [&](
const std::pair<CKeyID, bool> &used_key) {
1375 return privkey_map.count(used_key.first) > 0;
1377 if (!watchOnly && !spendable) {
1378 warnings.
push_back(
"Some private keys are missing, outputs "
1379 "will be considered watchonly. If this is "
1380 "intentional, specify the watchonly flag.");
1382 if (watchOnly && spendable) {
1384 "All private keys are provided, outputs will be considered "
1385 "spendable. If this is intentional, do not specify the "
1390 if (error.empty()) {
1391 for (
const auto &require_key : import_data.
used_keys) {
1392 if (!require_key.second) {
1397 if (pubkey_map.count(require_key.first) == 0 &&
1398 privkey_map.count(require_key.first) == 0) {
1399 error =
"some required keys are missing";
1404 if (!error.empty()) {
1405 warnings.
push_back(
"Importing as non-solvable: " + error +
1406 ". If this is intentional, don't provide "
1407 "any keys, pubkeys or redeemscript.");
1410 privkey_map.clear();
1411 have_solving_data =
false;
1418 "Ignoring redeemscript as this is not a P2SH script.");
1420 for (
auto it = privkey_map.begin(); it != privkey_map.end();) {
1422 if (import_data.
used_keys.count(oldit->first) == 0) {
1423 warnings.
push_back(
"Ignoring irrelevant private key.");
1424 privkey_map.erase(oldit);
1427 for (
auto it = pubkey_map.begin(); it != pubkey_map.end();) {
1429 auto key_data_it = import_data.
used_keys.find(oldit->first);
1430 if (key_data_it == import_data.
used_keys.end() ||
1431 !key_data_it->second) {
1432 warnings.
push_back(
"Ignoring public key \"" +
1434 "\" as it doesn't appear inside P2PKH.");
1435 pubkey_map.erase(oldit);
1445 std::map<CKeyID, CPubKey> &pubkey_map,
1446 std::map<CKeyID, CKey> &privkey_map,
1447 std::set<CScript> &script_pub_keys,
1448 bool &have_solving_data,
1450 std::vector<CKeyID> &ordered_pubkeys) {
1453 const std::string &descriptor = data[
"desc"].
get_str();
1457 Parse(descriptor, keys, error,
true);
1462 have_solving_data = parsed_desc->IsSolvable();
1463 const bool watch_only =
1466 int64_t range_start = 0, range_end = 0;
1467 if (!parsed_desc->IsRange() && data.
exists(
"range")) {
1470 "Range should not be specified for an un-ranged descriptor");
1471 }
else if (parsed_desc->IsRange()) {
1472 if (!data.
exists(
"range")) {
1475 "Descriptor is ranged, please specify the range");
1485 for (
int i = range_start; i <= range_end; ++i) {
1487 std::vector<CScript> scripts_temp;
1488 parsed_desc->Expand(i, keys, scripts_temp, out_keys);
1489 std::copy(scripts_temp.begin(), scripts_temp.end(),
1490 std::inserter(script_pub_keys, script_pub_keys.end()));
1491 for (
const auto &key_pair : out_keys.
pubkeys) {
1492 ordered_pubkeys.push_back(key_pair.first);
1495 for (
const auto &x : out_keys.
scripts) {
1499 parsed_desc->ExpandPrivate(i, keys, out_keys);
1502 std::inserter(pubkey_map, pubkey_map.end()));
1503 std::copy(out_keys.
keys.begin(), out_keys.
keys.end(),
1504 std::inserter(privkey_map, privkey_map.end()));
1509 for (
size_t i = 0; i < priv_keys.
size(); ++i) {
1510 const auto &str = priv_keys[i].
get_str();
1514 "Invalid private key encoding");
1521 if (!pubkey_map.count(
id)) {
1522 warnings.
push_back(
"Ignoring irrelevant private key.");
1524 privkey_map.emplace(
id, key);
1535 std::all_of(pubkey_map.begin(), pubkey_map.end(),
1536 [&](
const std::pair<CKeyID, CPubKey> &used_key) {
1537 return privkey_map.count(used_key.first) > 0;
1541 [&](
const std::pair<
CKeyID, std::pair<CPubKey, KeyOriginInfo>>
1542 &entry) { return privkey_map.count(entry.first) > 0; });
1543 if (!watch_only && !spendable) {
1545 "Some private keys are missing, outputs will be considered "
1546 "watchonly. If this is intentional, specify the watchonly flag.");
1548 if (watch_only && spendable) {
1549 warnings.
push_back(
"All private keys are provided, outputs will be "
1550 "considered spendable. If this is intentional, do "
1551 "not specify the watchonly flag.");
1558 const int64_t timestamp)
1564 const bool internal =
1565 data.exists(
"internal") ? data[
"internal"].get_bool() :
false;
1567 if (internal && data.exists(
"label")) {
1569 "Internal addresses should not have a label");
1571 const std::string &label =
1572 data.exists(
"label") ? data[
"label"].get_str() :
"";
1573 const bool add_keypool =
1574 data.exists(
"keypool") ? data[
"keypool"].get_bool() :
false;
1580 "Keys can only be imported to the keypool when "
1581 "private keys are disabled");
1585 std::map<CKeyID, CPubKey> pubkey_map;
1586 std::map<CKeyID, CKey> privkey_map;
1587 std::set<CScript> script_pub_keys;
1588 std::vector<CKeyID> ordered_pubkeys;
1589 bool have_solving_data;
1591 if (data.exists(
"scriptPubKey") && data.exists(
"desc")) {
1594 "Both a descriptor and a scriptPubKey should not be provided.");
1595 }
else if (data.exists(
"scriptPubKey")) {
1597 pwallet, import_data, pubkey_map, privkey_map, script_pub_keys,
1598 have_solving_data, data, ordered_pubkeys);
1599 }
else if (data.exists(
"desc")) {
1601 import_data, pubkey_map, privkey_map, script_pub_keys,
1602 have_solving_data, data, ordered_pubkeys);
1606 "Either a descriptor or scriptPubKey must be provided.");
1612 !privkey_map.empty()) {
1614 "Cannot import private keys to a wallet with "
1615 "private keys disabled");
1619 for (
const CScript &
script : script_pub_keys) {
1622 "The wallet already contains the private "
1623 "key for this address or script (\"" +
1629 pwallet->MarkDirty();
1630 if (!pwallet->ImportScripts(import_data.
import_scripts, timestamp)) {
1632 "Error adding script to wallet");
1634 if (!pwallet->ImportPrivKeys(privkey_map, timestamp)) {
1637 if (!pwallet->ImportPubKeys(ordered_pubkeys, pubkey_map,
1639 internal, timestamp)) {
1641 "Error adding address to wallet");
1643 if (!pwallet->ImportScriptPubKeys(label, script_pub_keys,
1644 have_solving_data, !internal,
1647 "Error adding address to wallet");
1653 result.
pushKV(
"error", e);
1660 if (warnings.
size()) {
1661 result.
pushKV(
"warnings", warnings);
1667 if (data.
exists(
"timestamp")) {
1668 const UniValue ×tamp = data[
"timestamp"];
1669 if (timestamp.
isNum()) {
1670 return timestamp.
getInt<int64_t>();
1671 }
else if (timestamp.
isStr() && timestamp.
get_str() ==
"now") {
1675 strprintf(
"Expected number or \"now\" timestamp "
1676 "value for key. got type %s",
1680 "Missing required timestamp field for key");
1684 const int64_t objectTimestamp,
1685 const int64_t blockTimestamp,
1686 const bool have_pruned,
1687 const bool has_assumed_valid_chain) {
1688 std::string error_msg{
1689 strprintf(
"Rescan failed for %s with creation timestamp %d. There "
1690 "was an error reading a block from time %d, which is after "
1691 "or within %d seconds of key creation, and could contain "
1692 "transactions pertaining to the %s. As a result, "
1693 "transactions and coins using this %s may not appear "
1699 "This error could be caused by pruning or data corruption "
1700 "(see bitcoind log for details) and could be dealt with by "
1701 "downloading and rescanning the relevant blocks (see -reindex "
1702 "option and rescanblockchain RPC).");
1703 }
else if (has_assumed_valid_chain) {
1705 "This error is likely caused by an in-progress assumeutxo "
1706 "background sync. Check logs or getchainstates RPC for assumeutxo "
1707 "background sync progress and try again later.");
1710 "This error could potentially be caused by data corruption. If "
1711 "the issue persists you may want to reindex (see -reindex "
1720 "Import addresses/scripts (with private or public keys, redeem "
1721 "script (P2SH)), optionally rescanning the blockchain from the "
1722 "earliest creation time of the imported scripts. Requires a new wallet "
1724 "If an address/script is imported without all of the private keys "
1725 "required to spend from that address, it will be watchonly. The "
1726 "'watchonly' option must be set to true in this case or a warning will "
1728 "Conversely, if all the private keys are provided and the "
1729 "address/script is spendable, the watchonly option must be set to "
1730 "false, or a warning will be returned.\n"
1731 "Note: Use \"getwalletinfo\" to query the scanning progress.\n"
1732 "Note: This command is only compatible with legacy wallets. Use "
1733 "\"importdescriptors\" for descriptor wallets.\n",
1738 "Data to be imported",
1747 "Descriptor to import. If using descriptor, do not "
1748 "also provide address/scriptPubKey, scripts, or "
1752 "Type of scriptPubKey (string for script, json for "
1753 "address). Should not be provided if using a "
1757 "\"address\":\"<address>\" }",
1760 "Creation time of the key expressed in " +
1763 "or the string \"now\" to substitute the current "
1764 "synced blockchain time. The timestamp of the "
1766 "key will determine how far back blockchain "
1767 "rescans need to begin for missing wallet "
1769 "\"now\" can be specified to bypass scanning, "
1770 "for keys which are known to never have been "
1772 "0 can be specified to scan the entire "
1773 "blockchain. Blocks up to 2 hours before the "
1775 "creation time of all keys being imported by the "
1776 "importmulti call will be scanned.",
1778 "integer / string"}}},
1781 "Allowed only if the scriptPubKey is a P2SH "
1782 "address/scriptPubKey"},
1786 "Array of strings giving pubkeys to import. They "
1787 "must occur in P2PKH scripts. They are not required "
1788 "when the private key is also provided (see the "
1789 "\"keys\" argument).",
1797 "Array of strings giving private keys to import. The "
1798 "corresponding public keys must occur in the output "
1806 "If a ranged descriptor is used, this specifies the "
1807 "end or the range (in the form [begin,end]) to "
1811 "Stating whether matching outputs should be treated "
1812 "as not incoming payments (also known as change)"},
1815 "Stating whether matching outputs should be "
1816 "considered watchonly."},
1818 "Label to assign to the address, only allowed with "
1821 "Stating whether imported public keys should be "
1822 "added to the keypool for when users request new "
1823 "addresses. Only allowed when wallet private keys "
1835 "Stating if should rescan the blockchain after all imports"},
1841 "Response is an array with the same size as the input that "
1842 "has the execution result",
1868 "'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, "
1869 "\"timestamp\":1455191478 }, "
1870 "{ \"scriptPubKey\": { \"address\": \"<my 2nd address>\" "
1872 "\"label\": \"example 2\", \"timestamp\": 1455191480 }]'") +
1875 "'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, "
1876 "\"timestamp\":1455191478 }]' '{ \"rescan\": false}'")
1881 std::shared_ptr<CWallet>
const wallet =
1890 const UniValue &requests = mainRequest.params[0];
1893 bool fRescan =
true;
1895 if (!mainRequest.params[1].isNull()) {
1896 const UniValue &options = mainRequest.params[1];
1898 if (options.
exists(
"rescan")) {
1899 fRescan = options[
"rescan"].
get_bool();
1904 if (fRescan && !reserver.
reserve()) {
1906 "Wallet is currently rescanning. Abort "
1907 "existing rescan or wait.");
1911 bool fRunScan =
false;
1912 int64_t nLowestTimestamp = 0;
1921 FoundBlock().time(nLowestTimestamp).mtpTime(now)));
1926 const int64_t minimumTimestamp = 1;
1929 const int64_t timestamp = std::max(
1940 if (result[
"success"].get_bool()) {
1945 if (timestamp < nLowestTimestamp) {
1946 nLowestTimestamp = timestamp;
1950 if (fRescan && fRunScan && requests.
size()) {
1952 nLowestTimestamp, reserver,
true );
1960 "Rescan aborted by user.");
1962 if (scannedTime > nLowestTimestamp) {
1963 std::vector<UniValue> results =
response.getValues();
1973 results.at(i).exists(
"error")) {
1988 response.push_back(std::move(result));
2002 const int64_t timestamp)
2008 if (!data.exists(
"desc")) {
2012 const std::string &descriptor = data[
"desc"].get_str();
2014 data.exists(
"active") ? data[
"active"].get_bool() :
false;
2015 const bool internal =
2016 data.exists(
"internal") ? data[
"internal"].get_bool() :
false;
2017 const std::string &label =
2018 data.exists(
"label") ? data[
"label"].get_str() :
"";
2024 Parse(descriptor, keys, error,
true);
2030 int64_t range_start = 0, range_end = 1, next_index = 0;
2031 if (!parsed_desc->IsRange() && data.exists(
"range")) {
2034 "Range should not be specified for an un-ranged descriptor");
2035 }
else if (parsed_desc->IsRange()) {
2036 if (data.exists(
"range")) {
2038 range_start = range.first;
2041 range_end = range.second + 1;
2044 "Range not given, using default keypool range");
2048 next_index = range_start;
2050 if (data.exists(
"next_index")) {
2051 next_index = data[
"next_index"].getInt<int64_t>();
2053 if (next_index < range_start || next_index >= range_end) {
2055 "next_index is out of range");
2061 if (active && !parsed_desc->IsRange()) {
2063 "Active descriptors must be ranged");
2067 if (data.exists(
"range") && data.exists(
"label")) {
2069 "Ranged descriptors should not have a label");
2073 if (internal && data.exists(
"label")) {
2075 "Internal addresses should not have a label");
2079 if (active && !parsed_desc->IsSingleType()) {
2081 "Combo descriptors cannot be set to active");
2086 !keys.
keys.empty()) {
2088 "Cannot import private keys to a wallet with "
2089 "private keys disabled");
2095 std::vector<CScript> scripts;
2096 if (!parsed_desc->Expand(0, keys, scripts, expand_keys)) {
2099 "Cannot expand descriptor. Probably because of hardened "
2100 "derivations without private keys provided");
2102 parsed_desc->ExpandPrivate(0, keys, expand_keys);
2105 bool have_all_privkeys = !expand_keys.
keys.empty();
2106 for (
const auto &entry : expand_keys.
origins) {
2107 const CKeyID &key_id = entry.first;
2109 if (!expand_keys.
GetKey(key_id, key)) {
2110 have_all_privkeys =
false;
2117 if (keys.
keys.empty()) {
2120 "Cannot import descriptor without private keys to a wallet "
2121 "with private keys enabled");
2123 if (!have_all_privkeys) {
2125 "Not all private keys provided. Some wallet functionality "
2126 "may return unexpected errors");
2131 range_end, next_index);
2134 auto existing_spk_manager =
2135 pwallet->GetDescriptorScriptPubKeyMan(w_desc);
2136 if (existing_spk_manager &&
2137 !existing_spk_manager->CanUpdateToWalletDescriptor(w_desc, error)) {
2143 pwallet->AddWalletDescriptor(w_desc, keys, label, internal);
2144 if (spk_manager ==
nullptr) {
2147 strprintf(
"Could not add descriptor '%s'", descriptor));
2154 "Unknown output type, cannot set descriptor to active.");
2156 pwallet->AddActiveScriptPubKeyMan(
2157 spk_manager->GetID(), *w_desc.
descriptor->GetOutputType(),
2162 pwallet->DeactivateScriptPubKeyMan(
2163 spk_manager->GetID(), *w_desc.
descriptor->GetOutputType(),
2171 result.
pushKV(
"error", e);
2173 if (warnings.
size()) {
2174 result.
pushKV(
"warnings", warnings);
2181 "importdescriptors",
2182 "Import descriptors. This will trigger a rescan of the blockchain "
2183 "based on the earliest timestamp of all descriptors being imported. "
2184 "Requires a new wallet backup.\n"
2185 "\nNote: This call can take over an hour to complete if using an early "
2186 "timestamp; during that time, other rpc calls\n"
2187 "may report that the imported keys, addresses or scripts exist but "
2188 "related transactions are still missing.\n",
2193 "Data to be imported",
2202 "Descriptor to import."},
2204 "Set this descriptor to be the active descriptor for "
2205 "the corresponding output type/externality"},
2208 "If a ranged descriptor is used, this specifies the "
2209 "end or the range (in the form [begin,end]) to "
2213 "If a ranged descriptor is set to active, this "
2214 "specifies the next index to generate addresses "
2217 "Time from which to start rescanning the blockchain "
2218 "for this descriptor, in " +
2221 "Use the string \"now\" to substitute the "
2222 "current synced blockchain time.\n"
2223 "\"now\" can be specified to bypass scanning, "
2224 "for outputs which are known to never have been "
2226 "0 can be specified to scan the entire "
2227 "blockchain. Blocks up to 2 hours before the "
2228 "earliest timestamp\n"
2229 "of all descriptors being imported will be "
2232 "integer / string"}}},
2235 "Whether matching outputs should be treated as not "
2236 "incoming payments (e.g. change)"},
2238 "Label to assign to the address, only allowed with "
2247 "Response is an array with the same size as the input that "
2248 "has the execution result",
2273 "'[{ \"desc\": \"<my descriptor>\", "
2274 "\"timestamp\":1455191478, \"internal\": true }, "
2275 "{ \"desc\": \"<my desccriptor 2>\", \"label\": "
2276 "\"example 2\", \"timestamp\": 1455191480 }]'") +
2278 "importdescriptors",
2279 "'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, "
2280 "\"active\": true, \"range\": [0,100], \"label\": \"<my "
2281 "cashaddr wallet>\" }]'")},
2284 std::shared_ptr<CWallet>
const wallet =
2294 "importdescriptors is not available for "
2295 "non-descriptor wallets");
2301 "Wallet is currently rescanning. Abort "
2302 "existing rescan or wait.");
2305 const UniValue &requests = main_request.params[0];
2306 const int64_t minimum_timestamp = 1;
2308 int64_t lowest_timestamp = 0;
2309 bool rescan =
false;
2317 FoundBlock().time(lowest_timestamp).mtpTime(now)));
2322 const int64_t timestamp = std::max(
2328 if (lowest_timestamp > timestamp) {
2329 lowest_timestamp = timestamp;
2334 if (!rescan && result[
"success"].get_bool()) {
2344 lowest_timestamp, reserver,
true );
2352 "Rescan aborted by user.");
2355 if (scanned_time > lowest_timestamp) {
2356 std::vector<UniValue> results =
response.getValues();
2361 for (
unsigned int i = 0; i < requests.
size(); ++i) {
2370 results.at(i).exists(
"error")) {
2386 response.push_back(std::move(result));
2400 "Safely copies current wallet file to destination, which can be a "
2401 "directory or a path with filename.\n",
2404 "The destination directory or file"},
2411 std::shared_ptr<CWallet>
const wallet =
2421 pwallet->BlockUntilSyncedToCurrentChain();
2425 std::string strDest = request.params[0].get_str();
2428 "Error: Wallet backup failed!");
2439 "\nRestore and loads a wallet from backup.\n",
2442 "The name that will be applied to the restored wallet"},
2444 "The backup file that will be used to restore the wallet."},
2446 "Save wallet name to persistent settings and load on startup. "
2447 "True to add wallet to startup list, false to remove, null to "
2448 "leave unchanged."},
2455 "The wallet name if restored successfully."},
2457 "Warning message if wallet was not loaded cleanly."},
2461 "\"testwallet\" \"home\\backups\\backup-file.bak\"") +
2464 "\"testwallet\" \"home\\backups\\backup-file.bak\"") +
2467 {{
"wallet_name",
"testwallet"},
2468 {
"backup_file",
"home\\backups\\backup-file.bak\""},
2469 {
"load_on_startup",
true}}) +
2472 {{
"wallet_name",
"testwallet"},
2473 {
"backup_file",
"home\\backups\\backup-file.bak\""},
2474 {
"load_on_startup",
true}})},
2482 std::string wallet_name = request.params[0].get_str();
2484 std::optional<bool> load_on_start =
2485 request.params[2].isNull()
2487 : std::optional<bool>(request.params[2].get_bool());
2491 std::vector<bilingual_str> warnings;
2493 const std::shared_ptr<CWallet>
wallet =
2494 RestoreWallet(context, backup_file, wallet_name, load_on_start,
2495 status, error, warnings);
static RPCHelpMan dumpcoins()
RPCHelpMan importprivkey()
static const int64_t TIMESTAMP_MIN
RPCHelpMan importdescriptors()
static void RescanWallet(CWallet &wallet, const WalletRescanReserver &reserver, int64_t time_begin=TIMESTAMP_MIN, bool update=true)
static std::string RecurseImportData(const CScript &script, ImportData &import_data, const ScriptContext script_ctx)
RPCHelpMan importaddress()
RPCHelpMan importwallet()
Span< const CRPCCommand > GetWalletDumpRPCCommands()
static std::string GetRescanErrorMessage(const std::string &object, const int64_t objectTimestamp, const int64_t blockTimestamp, const bool have_pruned, const bool has_assumed_valid_chain)
static UniValue ProcessImportLegacy(CWallet *const pwallet, 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)
RPCHelpMan importpubkey()
static std::string EncodeDumpString(const std::string &str)
static bool GetWalletAddressesForKey(const Config &config, LegacyScriptPubKeyMan *spk_man, const CWallet *const pwallet, const CKeyID &keyid, std::string &strAddr, std::string &strLabel) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static std::string DecodeDumpString(const std::string &str)
RPCHelpMan importprunedfunds()
RPCHelpMan restorewallet()
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)
@ TOP
Top-level scriptPubKey.
static UniValue ProcessImport(CWallet *const pwallet, const UniValue &data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
static void EnsureBlockDataFromTime(const CWallet &wallet, int64_t timestamp)
RPCHelpMan backupwallet()
static UniValue ProcessDescriptorImport(CWallet *const pwallet, const UniValue &data, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)
RPCHelpMan removeprunedfunds()
static int64_t GetImportTimestamp(const UniValue &data, int64_t now)
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath)
Write HD keypaths as strings.
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
#define CHECK_NONFATAL(condition)
Identity function.
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
CKeyID seed_id
seed hash160
An encapsulated secp256k1 private key.
bool IsValid() const
Check whether this private key is valid.
CPubKey GetPubKey() const
Compute the public key from a private key.
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
A reference to a CKey: the Hash160 of its serialized public key.
Used to create a Merkle proof (usually from a subset of transactions), which consists of a block head...
CBlockHeader header
Public only for unit testing.
A mutable version of CTransaction.
TxId GetId() const
Compute the id and hash of this CMutableTransaction.
uint256 ExtractMatches(std::vector< uint256 > &vMatch, std::vector< size_t > &vnIndex)
Extract the matching txid's represented by this partial merkle tree and their respective indices with...
An encapsulated public key.
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
A reference to a CScript: the Hash160 of its serialization (see script.h)
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
BlockHash GetLastBlockHash() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
void ConnectScriptPubKeyManNotifiers()
Connect the signals from ScriptPubKeyMans to the signals in CWallet.
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
bool IsAbortingRescan() const
interfaces::Chain & chain() const
Interface for accessing chain state.
bool BackupWallet(const std::string &strDest) const
std::string GetDisplayName() const override
Returns a bracketed wallet name for displaying in logs, will return [default wallet] if the wallet ha...
const CAddressBookData * FindAddressBookEntry(const CTxDestination &, bool allow_change=false) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Double ended buffer combining vector and stream-like interfaces.
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
virtual std::set< CScriptID > GetCScripts() const
RecursiveMutex cs_KeyStore
const CHDChain & GetHDChain() const
bool GetKey(const CKeyID &address, CKey &keyOut) const override
const std::map< CKeyID, int64_t > & GetAllReserveKeys() const
A Span is an object that can refer to a contiguous sequence of objects.
void push_back(UniValue val)
const std::string & get_str() const
enum VType getType() const
const std::vector< UniValue > & getValues() const
const UniValue & get_array() const
bool exists(const std::string &key) const
void pushKV(std::string key, UniValue val)
Descriptor with some wallet metadata.
std::shared_ptr< Descriptor > descriptor
RAII object to check and reserve a wallet rescan.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
std::string u8string() const
virtual bool findAncestorByHash(const BlockHash &block_hash, const BlockHash &ancestor_hash, const FoundBlock &ancestor_out={})=0
Return whether block descends from a specified ancestor, and optionally return ancestor information.
virtual bool findBlock(const BlockHash &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
virtual void showProgress(const std::string &title, int progress, bool resume_possible)=0
Send progress indicator.
virtual bool havePruned()=0
Check if any block has been pruned.
virtual bool hasAssumedValidChain()=0
Return true if an assumed-valid chain is in use.
Helper for findBlock to selectively return pieces of block data.
static UniValue Parse(std::string_view raw)
Parse string to UniValue or throw runtime_error if string contains invalid JSON.
const std::string CLIENT_BUILD
const std::string CLIENT_NAME
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
DBErrors ZapSelectTx(std::vector< TxId > &txIdsIn, std::vector< TxId > &txIdsOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool ImportPubKeys(const std::vector< CKeyID > &ordered_pubkeys, const std::map< CKeyID, CPubKey > &pubkey_map, const std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > &key_origins, const bool add_keypool, const bool internal, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool ImportScripts(const std::set< CScript > scripts, int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
CWalletTx * AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation &confirm, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true)
bool ImportPrivKeys(const std::map< CKeyID, CKey > &privkey_map, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
isminetype IsMine(const CTxDestination &dest) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool ImportScriptPubKeys(const std::string &label, const std::set< CScript > &script_pub_keys, const bool have_solving_data, const bool apply_label, const int64_t timestamp) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
const CChainParams & GetChainParams() const override
void ReacceptWalletTransactions() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
bool IsWalletFlagSet(uint64_t flag) const override
Check if a certain wallet flag is set.
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver &reserver, bool update)
Scan active chain for relevant transactions after importing keys.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string EncodeDestination(const CTxDestination &dest, const Config &config)
std::string EncodeExtKey(const CExtKey &key)
std::string EncodeSecret(const CKey &key)
CTxDestination DecodeDestination(const std::string &addr, const CChainParams ¶ms)
CKey DecodeSecret(const std::string &str)
static path absolute(const path &p)
static path u8path(const std::string &utf8_str)
static bool exists(const path &p)
static path PathFromString(const std::string &string)
Convert byte string to path object.
std::vector< std::string > SplitString(std::string_view str, char sep)
auto Join(const std::vector< T > &list, const BaseType &separator, UnaryOp unary_op) -> decltype(unary_op(list.at(0)))
Join a list of items.
CTxDestination GetDestinationForKey(const CPubKey &key, OutputType type)
Get a destination of the requested type (if possible) to the specified key.
std::vector< CTxDestination > GetAllDestinationsForKey(const CPubKey &key)
Get all destinations (potentially) supported by the wallet for the given key.
static CTransactionRef MakeTransactionRef()
std::shared_ptr< const CTransaction > CTransactionRef
UniValue JSONRPCError(int code, const std::string &message)
@ RPC_MISC_ERROR
General application defined errors std::exception thrown in command handling.
@ RPC_TYPE_ERROR
Unexpected type was passed as parameter.
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
@ RPC_WALLET_ERROR
Wallet errors Unspecified problem with wallet (key not found etc.)
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
std::pair< int64_t, int64_t > ParseDescriptorRange(const UniValue &value)
Parse a JSON range specified as int64, or [int64, int64].
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
std::vector< uint8_t > ParseHexV(const UniValue &v, std::string strName)
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency.
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded values (throws error if not hex).
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
static const unsigned int DEFAULT_KEYPOOL_SIZE
Default for -keypool.
CKeyID GetKeyForDestination(const SigningProvider &store, const CTxDestination &dest)
Return the CKeyID of the key involved in a script (if there is a unique one).
std::map< CTxDestination, std::vector< COutput > > ListCoins(const CWallet &wallet)
Return list of available coins and locked coins grouped by non-change output address.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< uint8_t > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
A BlockHash is a unqiue identifier for a block.
void SetSeed(Span< const std::byte > seed)
Confirmation includes tx status and a triplet of {block height/block hash/tx index in block} at which...
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > origins
bool GetKey(const CKeyID &keyid, CKey &key) const override
std::map< CKeyID, CPubKey > pubkeys
std::map< CKeyID, CKey > keys
std::map< CScriptID, CScript > scripts
std::unique_ptr< CScript > redeemscript
Provided redeemScript; will be moved to import_scripts if relevant.
std::map< CKeyID, bool > used_keys
Import these private keys if available (the value indicates whether if the key is required for solvab...
std::set< CScript > import_scripts
std::map< CKeyID, std::pair< CPubKey, KeyOriginInfo > > key_origins
@ RANGE
Special type that is a NUM or [NUM,NUM].
@ STR_HEX
Special type that is a STR with only hex chars.
@ OBJ_NAMED_PARAMS
Special type that behaves almost exactly like OBJ, defining an options object with a list of pre-defi...
std::string DefaultHint
Hint for default value.
@ OMITTED
Optional argument for which the default value is omitted from help text for one of two reasons:
std::vector< std::string > type_str
Should be empty unless it is supposed to override the auto-generated type strings.
std::string oneline_description
Should be empty unless it is supposed to override the auto-generated summary line.
@ ELISION
Special type to denote elision (...)
@ OBJ_DYN
Special dictionary with keys that are not literals.
@ STR_HEX
Special string with only hex chars.
@ STR_AMOUNT
Special string to represent a floating point amount.
A TxId is the identifier of a transaction.
WalletContext struct containing references to state shared between CWallet instances,...
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
std::optional< int64_t > ParseISO8601DateTime(std::string_view str)
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
bilingual_str _(const char *psz)
Translation function.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
const UniValue NullUniValue
const char * uvTypeName(UniValue::VType t)
template std::vector< std::byte > ParseHex(std::string_view)
bool IsHex(std::string_view str)
Returns true if each character in str is a hex character, and has an even number of hex digits.
void EnsureWalletIsUnlocked(const CWallet *pwallet)
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
LegacyScriptPubKeyMan & EnsureLegacyScriptPubKeyMan(CWallet &wallet, bool also_create)
void HandleWalletError(const std::shared_ptr< CWallet > wallet, DatabaseStatus &status, bilingual_str &error)
WalletContext & EnsureWalletContext(const std::any &context)
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)
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.