51static const std::string
HELP_REQUIRING_PASSPHRASE{
"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"};
55 bool avoid_reuse = param.
isNull() ? can_avoid_reuse : param.
get_bool();
57 if (avoid_reuse && !can_avoid_reuse) {
71 if (include_watchonly.
isNull()) {
104 std::string wallet_name;
106 const std::shared_ptr<CWallet> pwallet =
GetWallet(context, wallet_name);
111 std::vector<std::shared_ptr<CWallet>> wallets =
GetWallets(context);
112 if (wallets.size() == 1) {
116 if (wallets.empty()) {
118 RPC_WALLET_NOT_FOUND,
"No wallet is loaded. Load a wallet using loadwallet or create a new one with createwallet. (Note: A default wallet is no longer automatically created)");
121 "Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
133 auto wallet_context = util::AnyPtr<WalletContext>(context);
134 if (!wallet_context) {
137 return *wallet_context;
144 if (!spk_man && also_create) {
145 spk_man =
wallet.GetOrCreateLegacyScriptPubKeyMan();
156 int confirms =
wallet.GetTxDepthInMainChain(wtx);
157 entry.
pushKV(
"confirmations", confirms);
159 entry.
pushKV(
"generated",
true);
167 entry.
pushKV(
"blocktime", block_time);
176 entry.
pushKV(
"walletconflicts", conflicts);
181 std::string rbfStatus =
"no";
185 rbfStatus =
"unknown";
189 entry.
pushKV(
"bip125-replaceable", rbfStatus);
191 for (
const std::pair<const std::string, std::string>& item : wtx.
mapValue)
192 entry.
pushKV(item.first, item.second);
197 std::string label = value.
get_str();
219 if (!conf_target.
isNull()) {
220 throw JSONRPCError(
RPC_INVALID_PARAMETER,
"Cannot specify both conf_target and fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate.");
222 if (!estimate_mode.
isNull() && estimate_mode.
get_str() !=
"unset") {
235 if (!conf_target.
isNull()) {
243 "\nReturns a new Bitcoin address for receiving payments.\n"
244 "If 'label' is specified, it is added to the address book \n"
245 "so payments received with the address will be associated with 'label'.\n",
247 {
"label",
RPCArg::Type::STR,
RPCArg::Default{
""},
"The label name for the address to be linked to. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created if there is no label by the given name."},
262 LOCK(pwallet->cs_wallet);
264 if (!pwallet->CanGetAddresses()) {
270 if (!request.params[0].isNull())
273 OutputType output_type = pwallet->m_default_address_type;
274 if (!request.params[1].isNull()) {
275 std::optional<OutputType> parsed =
ParseOutputType(request.params[1].get_str());
281 output_type = parsed.value();
286 if (!pwallet->GetNewDestination(output_type, label, dest,
error)) {
298 "\nReturns a new Bitcoin address, for receiving change.\n"
299 "This is for use with raw transactions, NOT normal use.\n",
315 LOCK(pwallet->cs_wallet);
317 if (!pwallet->CanGetAddresses(
true)) {
321 OutputType output_type = pwallet->m_default_change_type.value_or(pwallet->m_default_address_type);
322 if (!request.params[0].isNull()) {
323 std::optional<OutputType> parsed =
ParseOutputType(request.params[0].get_str());
329 output_type = parsed.value();
334 if (!pwallet->GetNewChangeDestination(output_type, dest,
error)) {
346 "\nSets the label associated with the given address.\n",
361 LOCK(pwallet->cs_wallet);
370 if (pwallet->IsMine(dest)) {
371 pwallet->SetAddressBook(dest, label,
"receive");
373 pwallet->SetAddressBook(dest, label,
"send");
382 std::set<CTxDestination> destinations;
384 for (
const std::string& address: address_amounts.
getKeys()) {
390 if (destinations.count(dest)) {
393 destinations.insert(dest);
398 bool subtract_fee =
false;
399 for (
unsigned int idx = 0; idx < subtract_fee_outputs.
size(); idx++) {
400 const UniValue& addr = subtract_fee_outputs[idx];
401 if (addr.
get_str() == address) {
406 CRecipient recipient = {script_pub_key, amount, subtract_fee};
426 int nChangePosRet = -1;
434 wallet.CommitTransaction(tx, std::move(map_value), {} );
437 entry.
pushKV(
"txid", tx->GetHash().GetHex());
441 return tx->GetHash().GetHex();
447 "\nSend an amount to a given address." +
453 "This is not part of the transaction, just kept in your wallet."},
455 "to which you're sending the transaction. This is not part of the \n"
456 "transaction, just kept in your wallet."},
458 "The recipient will receive less bitcoins than you enter in the amount field."},
463 {
"avoid_reuse",
RPCArg::Type::BOOL,
RPCArg::Default{
true},
"(only available if avoid_reuse wallet flag is set) Avoid spending from dirty addresses; addresses are considered\n"
464 "dirty if they have previously been used in a transaction. If true, this also activates avoidpartialspends, grouping outputs by their addresses."},
469 RPCResult{
"if verbose is not set or set to false",
483 "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode using positional arguments\n"
485 "\nSend 0.1 BTC with a fee rate of 1.1 " +
CURRENCY_ATOM +
"/vB, subtract fee from amount, BIP125-replaceable, using positional arguments\n"
487 "\nSend 0.2 BTC with a confirmation target of 6 blocks in economical fee estimate mode using named arguments\n"
489 "\nSend 0.5 BTC with a fee rate of 25 " +
CURRENCY_ATOM +
"/vB using named arguments\n"
491 +
HelpExampleCli(
"-named sendtoaddress",
"address=\"" +
EXAMPLE_ADDRESS[0] +
"\" amount=0.5 fee_rate=25 subtractfeefromamount=false replaceable=true avoid_reuse=true comment=\"2 pizzas\" comment_to=\"jeremy\" verbose=true")
500 pwallet->BlockUntilSyncedToCurrentChain();
502 LOCK(pwallet->cs_wallet);
506 if (!request.params[2].isNull() && !request.params[2].get_str().empty())
507 mapValue[
"comment"] = request.params[2].get_str();
508 if (!request.params[3].isNull() && !request.params[3].get_str().empty())
509 mapValue[
"to"] = request.params[3].get_str();
511 bool fSubtractFeeFromAmount =
false;
512 if (!request.params[4].isNull()) {
513 fSubtractFeeFromAmount = request.params[4].get_bool();
517 if (!request.params[5].isNull()) {
525 SetFeeEstimateMode(*pwallet, coin_control, request.params[6], request.params[7], request.params[9],
false);
530 const std::string address = request.params[0].get_str();
531 address_amounts.
pushKV(address, request.params[1]);
533 if (fSubtractFeeFromAmount) {
534 subtractFeeFromAmount.
push_back(address);
537 std::vector<CRecipient> recipients;
539 const bool verbose{request.params[10].isNull() ? false : request.params[10].get_bool()};
541 return SendMoney(*pwallet, coin_control, recipients, mapValue, verbose);
549 "\nLists groups of addresses which have had their common ownership\n"
550 "made public by common use as inputs or as the resulting change\n"
551 "in past transactions\n",
578 pwallet->BlockUntilSyncedToCurrentChain();
580 LOCK(pwallet->cs_wallet);
592 const auto* address_book_entry = pwallet->FindAddressBookEntry(address);
593 if (address_book_entry) {
594 addressInfo.
push_back(address_book_entry->GetLabel());
601 return jsonGroupings;
609 "\nSign a message with the private key of an address" +
619 "\nUnlock the wallet for 30 seconds\n"
621 "\nCreate the signature\n"
622 +
HelpExampleCli(
"signmessage",
"\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
623 "\nVerify the signature\n"
624 +
HelpExampleCli(
"verifymessage",
"\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
625 "\nAs a JSON-RPC call\n"
626 +
HelpExampleRpc(
"signmessage",
"\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
633 LOCK(pwallet->cs_wallet);
637 std::string strAddress = request.params[0].get_str();
638 std::string strMessage = request.params[1].get_str();
645 const PKHash* pkhash = std::get_if<PKHash>(&dest);
650 std::string signature;
651 SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature);
665 std::set<CTxDestination> address_set;
670 address_set =
wallet.GetLabelAddresses(label);
678 if (!
wallet.IsMine(script_pub_key)) {
681 address_set.insert(dest);
686 if (!params[1].isNull())
687 min_depth = params[1].get_int();
691 for (
const std::pair<const uint256, CWalletTx>& wtx_pair :
wallet.mapWallet) {
697 for (
const CTxOut& txout : wtx.
tx->vout) {
712 "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n",
721 "\nThe amount from transactions with at least 1 confirmation\n"
723 "\nThe amount including unconfirmed transactions, zero confirmations\n"
725 "\nThe amount with at least 6 confirmations\n"
727 "\nAs a JSON-RPC call\n"
737 pwallet->BlockUntilSyncedToCurrentChain();
739 LOCK(pwallet->cs_wallet);
750 "\nReturns the total amount received by addresses with <label> in transactions with at least [minconf] confirmations.\n",
759 "\nAmount received by the default label with at least 1 confirmation\n"
761 "\nAmount received at the tabby label including unconfirmed amounts with zero confirmations\n"
763 "\nThe amount with at least 6 confirmations\n"
765 "\nAs a JSON-RPC call\n"
775 pwallet->BlockUntilSyncedToCurrentChain();
777 LOCK(pwallet->cs_wallet);
788 "\nReturns the total available balance.\n"
789 "The available balance is what the wallet considers currently spendable, and is\n"
790 "thus affected by options which limit spendability such as -spendzeroconfchange.\n",
794 {
"include_watchonly",
RPCArg::Type::BOOL,
RPCArg::DefaultHint{
"true for watch-only wallets, otherwise false"},
"Also include balance in watch-only addresses (see 'importaddress')"},
795 {
"avoid_reuse",
RPCArg::Type::BOOL,
RPCArg::Default{
true},
"(only available if avoid_reuse wallet flag is set) Do not include balance in dirty outputs; addresses are considered dirty if they have previously been used in a transaction."},
801 "\nThe total amount in the wallet with 0 or more confirmations\n"
803 "\nThe total amount in the wallet with at least 6 confirmations\n"
805 "\nAs a JSON-RPC call\n"
815 pwallet->BlockUntilSyncedToCurrentChain();
817 LOCK(pwallet->cs_wallet);
819 const UniValue& dummy_value = request.params[0];
825 if (!request.params[1].isNull()) {
826 min_depth = request.params[1].get_int();
833 const auto bal =
GetBalance(*pwallet, min_depth, avoid_reuse);
835 return ValueFromAmount(bal.m_mine_trusted + (include_watchonly ? bal.m_watchonly_trusted : 0));
843 "DEPRECATED\nIdentical to getbalances().mine.untrusted_pending\n",
854 pwallet->BlockUntilSyncedToCurrentChain();
856 LOCK(pwallet->cs_wallet);
867 "\nSend multiple times. Amounts are double-precision floating point numbers." +
879 "The fee will be equally deducted from the amount of each selected address.\n"
880 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
881 "If no addresses are specified here, the sender pays the fee.",
894 RPCResult{
"if verbose is not set or set to false",
896 "the number of addresses."
902 "the number of addresses."},
908 "\nSend two amounts to two different addresses:\n"
910 "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
912 "\nSend two amounts to two different addresses, subtract fee from amount:\n"
914 "\nAs a JSON-RPC call\n"
924 pwallet->BlockUntilSyncedToCurrentChain();
926 LOCK(pwallet->cs_wallet);
928 if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
934 if (!request.params[3].isNull() && !request.params[3].get_str().empty())
935 mapValue[
"comment"] = request.params[3].
get_str();
938 if (!request.params[4].isNull())
939 subtractFeeFromAmount = request.params[4].
get_array();
942 if (!request.params[5].isNull()) {
946 SetFeeEstimateMode(*pwallet, coin_control, request.params[6], request.params[7], request.params[8],
false);
948 std::vector<CRecipient> recipients;
950 const bool verbose{request.params[9].isNull() ? false : request.params[9].get_bool()};
952 return SendMoney(*pwallet, coin_control, recipients, std::move(mapValue), verbose);
961 "\nAdd an nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup.\n"
962 "Each key is a Bitcoin address or hex-encoded public key.\n"
963 "This functionality is only intended for use with non-watchonly addresses.\n"
964 "See `importaddress` for watchonly p2sh address support.\n"
965 "If 'label' is specified, assign address to that label.\n",
985 "\nAdd a multisig address from 2 addresses\n"
987 "\nAs a JSON-RPC call\n"
1000 if (!request.params[2].isNull())
1003 int required = request.params[0].get_int();
1007 std::vector<CPubKey> pubkeys;
1008 for (
unsigned int i = 0; i < keys_or_addrs.
size(); ++i) {
1009 if (
IsHex(keys_or_addrs[i].get_str()) && (keys_or_addrs[i].get_str().length() == 66 || keys_or_addrs[i].get_str().length() == 130)) {
1012 pubkeys.push_back(
AddrToPubKey(spk_man, keys_or_addrs[i].get_str()));
1016 OutputType output_type = pwallet->m_default_address_type;
1017 if (!request.params[3].isNull()) {
1018 std::optional<OutputType> parsed =
ParseOutputType(request.params[3].get_str());
1024 output_type = parsed.value();
1030 pwallet->SetAddressBook(dest, label,
"send");
1038 result.
pushKV(
"descriptor", descriptor->ToString());
1047 int nConf{std::numeric_limits<int>::max()};
1059 if (!params[0].isNull())
1060 nMinDepth = params[0].get_int();
1063 bool fIncludeEmpty =
false;
1064 if (!params[1].isNull())
1065 fIncludeEmpty = params[1].get_bool();
1073 bool has_filtered_address =
false;
1075 if (!by_label && params.size() > 3) {
1080 has_filtered_address =
true;
1084 std::map<CTxDestination, tallyitem> mapTally;
1085 for (
const std::pair<const uint256, CWalletTx>& pairWtx :
wallet.mapWallet) {
1092 int nDepth =
wallet.GetTxDepthInMainChain(wtx);
1093 if (nDepth < nMinDepth)
1096 for (
const CTxOut& txout : wtx.
tx->vout)
1102 if (has_filtered_address && !(filtered_address == address)) {
1107 if(!(mine & filter))
1121 std::map<std::string, tallyitem> label_tally;
1125 auto start =
wallet.m_address_book.begin();
1126 auto end =
wallet.m_address_book.end();
1128 if (has_filtered_address) {
1129 start =
wallet.m_address_book.find(filtered_address);
1131 end = std::next(start);
1135 for (
auto item_it = start; item_it != end; ++item_it)
1137 if (item_it->second.IsChange())
continue;
1139 const std::string& label = item_it->second.GetLabel();
1140 auto it = mapTally.find(address);
1141 if (it == mapTally.end() && !fIncludeEmpty)
1145 int nConf = std::numeric_limits<int>::max();
1146 bool fIsWatchonly =
false;
1147 if (it != mapTally.end())
1149 nAmount = (*it).second.nAmount;
1150 nConf = (*it).second.nConf;
1151 fIsWatchonly = (*it).second.fIsWatchonly;
1165 obj.
pushKV(
"involvesWatchonly",
true);
1168 obj.
pushKV(
"confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf));
1169 obj.
pushKV(
"label", label);
1171 if (it != mapTally.end())
1173 for (
const uint256& _item : (*it).second.txids)
1178 obj.
pushKV(
"txids", transactions);
1185 for (
const auto& entry : label_tally)
1187 CAmount nAmount = entry.second.nAmount;
1188 int nConf = entry.second.nConf;
1190 if (entry.second.fIsWatchonly)
1191 obj.
pushKV(
"involvesWatchonly",
true);
1193 obj.
pushKV(
"confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf));
1194 obj.
pushKV(
"label", entry.first);
1205 "\nList balances by receiving address.\n",
1217 {
RPCResult::Type::BOOL,
"involvesWatchonly",
true,
"Only returns true if imported addresses were involved in transaction"},
1220 {
RPCResult::Type::NUM,
"confirmations",
"The number of confirmations of the most recent transaction included"},
1221 {
RPCResult::Type::STR,
"label",
"The label of the receiving address. The default label is \"\""},
1242 pwallet->BlockUntilSyncedToCurrentChain();
1244 LOCK(pwallet->cs_wallet);
1254 "\nList received transactions by label.\n",
1265 {
RPCResult::Type::BOOL,
"involvesWatchonly",
true,
"Only returns true if imported addresses were involved in transaction"},
1267 {
RPCResult::Type::NUM,
"confirmations",
"The number of confirmations of the most recent transaction included"},
1268 {
RPCResult::Type::STR,
"label",
"The label of the receiving address. The default label is \"\""},
1284 pwallet->BlockUntilSyncedToCurrentChain();
1286 LOCK(pwallet->cs_wallet);
1314 std::list<COutputEntry> listReceived;
1315 std::list<COutputEntry> listSent;
1328 entry.
pushKV(
"involvesWatchonly",
true);
1331 entry.
pushKV(
"category",
"send");
1333 const auto* address_book_entry =
wallet.FindAddressBookEntry(s.destination);
1334 if (address_book_entry) {
1335 entry.
pushKV(
"label", address_book_entry->GetLabel());
1337 entry.
pushKV(
"vout", s.vout);
1341 entry.
pushKV(
"abandoned", wtx.isAbandoned());
1342 ret.push_back(entry);
1347 if (listReceived.size() > 0 &&
wallet.GetTxDepthInMainChain(wtx) >= nMinDepth) {
1351 const auto* address_book_entry =
wallet.FindAddressBookEntry(r.destination);
1352 if (address_book_entry) {
1353 label = address_book_entry->GetLabel();
1355 if (filter_label && label != *filter_label) {
1360 entry.
pushKV(
"involvesWatchonly",
true);
1363 if (wtx.IsCoinBase())
1365 if (
wallet.GetTxDepthInMainChain(wtx) < 1)
1366 entry.
pushKV(
"category",
"orphan");
1367 else if (
wallet.IsTxImmatureCoinBase(wtx))
1368 entry.
pushKV(
"category",
"immature");
1370 entry.
pushKV(
"category",
"generate");
1374 entry.
pushKV(
"category",
"receive");
1377 if (address_book_entry) {
1378 entry.
pushKV(
"label", label);
1380 entry.
pushKV(
"vout", r.vout);
1383 ret.push_back(entry);
1390 return{{
RPCResult::Type::NUM,
"confirmations",
"The number of confirmations for the transaction. Negative confirmations means the\n"
1391 "transaction conflicted that many blocks ago."},
1392 {
RPCResult::Type::BOOL,
"generated",
true,
"Only present if the transaction's only input is a coinbase one."},
1393 {
RPCResult::Type::BOOL,
"trusted",
true,
"Whether we consider the transaction to be trusted and safe to spend from.\n"
1394 "Only present when the transaction has 0 confirmations (or negative confirmations, if conflicted)."},
1397 {
RPCResult::Type::NUM,
"blockindex",
true,
"The index of the transaction in the block that includes it."},
1410 {
RPCResult::Type::STR,
"comment",
true,
"If a comment is associated with the transaction, only present if not empty."},
1411 {
RPCResult::Type::STR,
"bip125-replaceable",
"(\"yes|no|unknown\") Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1412 "may be unknown for unconfirmed transactions not in the mempool."}};
1418 "\nIf a label name is provided, this will return only incoming transactions paying to addresses with the specified label.\n"
1419 "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions.\n",
1422 "with the specified label, or \"*\" to disable filtering and return all transactions."},
1425 {
"include_watchonly",
RPCArg::Type::BOOL,
RPCArg::DefaultHint{
"true for watch-only wallets, otherwise false"},
"Include transactions to watch-only addresses (see 'importaddress')"},
1432 {
RPCResult::Type::BOOL,
"involvesWatchonly",
true,
"Only returns true if imported addresses were involved in transaction."},
1435 "\"send\" Transactions sent.\n"
1436 "\"receive\" Non-coinbase transactions received.\n"
1437 "\"generate\" Coinbase transactions received with more than 100 confirmations.\n"
1438 "\"immature\" Coinbase transactions received with 100 or fewer confirmations.\n"
1439 "\"orphan\" Orphaned coinbase transactions received."},
1441 "for all other categories"},
1445 "'send' category of transactions."},
1449 {
RPCResult::Type::BOOL,
"abandoned",
true,
"'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1450 "'send' category of transactions."},
1455 "\nList the most recent 10 transactions in the systems\n"
1457 "\nList transactions 100 to 120\n"
1459 "\nAs a JSON-RPC call\n"
1469 pwallet->BlockUntilSyncedToCurrentChain();
1471 const std::string* filter_label =
nullptr;
1472 if (!request.params[0].isNull() && request.params[0].get_str() !=
"*") {
1473 filter_label = &request.params[0].
get_str();
1474 if (filter_label->empty()) {
1479 if (!request.params[1].isNull())
1480 nCount = request.params[1].get_int();
1482 if (!request.params[2].isNull())
1483 nFrom = request.params[2].get_int();
1498 LOCK(pwallet->cs_wallet);
1503 for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1507 if ((
int)ret.
size() >= (nCount+nFrom))
break;
1513 if (nFrom > (
int)ret.
size())
1515 if ((nFrom + nCount) > (
int)ret.
size())
1516 nCount = ret.
size() - nFrom;
1518 const std::vector<UniValue>& txs = ret.
getValues();
1520 result.push_backV({ txs.rend() - nFrom - nCount, txs.rend() - nFrom });
1529 "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
1530 "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
1531 "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n",
1534 {
"target_confirmations",
RPCArg::Type::NUM,
RPCArg::Default{1},
"Return the nth block hash from the main chain. e.g. 1 would mean the best block hash. Note: this is not used as a filter, but only affects [lastblock] in the return value"},
1535 {
"include_watchonly",
RPCArg::Type::BOOL,
RPCArg::DefaultHint{
"true for watch-only wallets, otherwise false"},
"Include transactions to watch-only addresses (see 'importaddress')"},
1537 "(not guaranteed to work on pruned nodes)"},
1546 {
RPCResult::Type::BOOL,
"involvesWatchonly",
true,
"Only returns true if imported addresses were involved in transaction."},
1549 "\"send\" Transactions sent.\n"
1550 "\"receive\" Non-coinbase transactions received.\n"
1551 "\"generate\" Coinbase transactions received with more than 100 confirmations.\n"
1552 "\"immature\" Coinbase transactions received with 100 or fewer confirmations.\n"
1553 "\"orphan\" Orphaned coinbase transactions received."},
1555 "for all other categories"},
1558 "'send' category of transactions."},
1562 {
RPCResult::Type::BOOL,
"abandoned",
true,
"'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1563 "'send' category of transactions."},
1567 {
RPCResult::Type::ARR,
"removed",
true,
"<structure is the same as \"transactions\" above, only present if include_removed=true>\n"
1568 "Note: transactions that were re-added in the active chain will appear as-is in this array, and may thus have a positive confirmation count."
1570 {
RPCResult::Type::STR_HEX,
"lastblock",
"The hash of the block (target_confirmations-1) from the best block on the main chain, or the genesis hash if the referenced block does not exist yet. This is typically used to feed back into listsinceblock the next time you call it. So you would generally use a target_confirmations of say 6, so you will be continually re-notified of transactions until they've reached 6 confirmations plus any new ones"},
1575 +
HelpExampleCli(
"listsinceblock",
"\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1576 +
HelpExampleRpc(
"listsinceblock",
"\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1586 wallet.BlockUntilSyncedToCurrentChain();
1590 std::optional<int> height;
1591 std::optional<int> altheight;
1592 int target_confirms = 1;
1596 if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
1597 blockId =
ParseHashV(request.params[0],
"blockhash");
1605 if (!request.params[1].isNull()) {
1606 target_confirms = request.params[1].get_int();
1608 if (target_confirms < 1) {
1617 bool include_removed = (request.params[3].isNull() || request.params[3].get_bool());
1619 int depth = height ?
wallet.GetLastBlockHeight() + 1 - *height : -1;
1623 for (
const std::pair<const uint256, CWalletTx>& pairWtx :
wallet.mapWallet) {
1626 if (depth == -1 || abs(
wallet.GetTxDepthInMainChain(tx)) < depth) {
1634 while (include_removed && altheight && *altheight > *height) {
1640 auto it =
wallet.mapWallet.find(tx->GetHash());
1641 if (it !=
wallet.mapWallet.end()) {
1652 target_confirms = std::min(target_confirms,
wallet.GetLastBlockHeight() + 1);
1656 ret.
pushKV(
"transactions", transactions);
1657 if (include_removed) ret.
pushKV(
"removed", removed);
1668 "\nGet detailed information about in-wallet transaction <txid>\n",
1672 "Whether to include watch-only addresses in balance calculation and details[]"},
1674 "Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction)"},
1681 "'send' category of transactions."},
1689 {
RPCResult::Type::BOOL,
"involvesWatchonly",
true,
"Only returns true if imported addresses were involved in transaction."},
1692 "\"send\" Transactions sent.\n"
1693 "\"receive\" Non-coinbase transactions received.\n"
1694 "\"generate\" Coinbase transactions received with more than 100 confirmations.\n"
1695 "\"immature\" Coinbase transactions received with 100 or fewer confirmations.\n"
1696 "\"orphan\" Orphaned coinbase transactions received."},
1701 "'send' category of transactions."},
1702 {
RPCResult::Type::BOOL,
"abandoned",
true,
"'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1703 "'send' category of transactions."},
1707 {
RPCResult::Type::OBJ,
"decoded",
true,
"The decoded transaction (only present when `verbose` is passed)",
1709 {
RPCResult::Type::ELISION,
"",
"Equivalent to the RPC decoderawtransaction method, or the RPC getrawtransaction method when `verbose` is passed."},
1714 HelpExampleCli(
"gettransaction",
"\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1715 +
HelpExampleCli(
"gettransaction",
"\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
1716 +
HelpExampleCli(
"gettransaction",
"\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" false true")
1717 +
HelpExampleRpc(
"gettransaction",
"\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1726 pwallet->BlockUntilSyncedToCurrentChain();
1728 LOCK(pwallet->cs_wallet);
1738 bool verbose = request.params[2].isNull() ? false : request.params[2].get_bool();
1741 auto it = pwallet->mapWallet.find(hash);
1742 if (it == pwallet->mapWallet.end()) {
1749 CAmount nNet = nCredit - nDebit;
1760 entry.
pushKV(
"details", details);
1762 std::string strHex =
EncodeHexTx(*wtx.
tx, pwallet->chain().rpcSerializationFlags());
1763 entry.
pushKV(
"hex", strHex);
1768 entry.
pushKV(
"decoded", decoded);
1779 "\nMark in-wallet transaction <txid> as abandoned\n"
1780 "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
1781 "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
1782 "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
1783 "It has no effect on transactions which are already abandoned.\n",
1789 HelpExampleCli(
"abandontransaction",
"\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1790 +
HelpExampleRpc(
"abandontransaction",
"\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
1799 pwallet->BlockUntilSyncedToCurrentChain();
1801 LOCK(pwallet->cs_wallet);
1805 if (!pwallet->mapWallet.count(hash)) {
1808 if (!pwallet->AbandonTransaction(hash)) {
1821 "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n",
1837 pwallet->BlockUntilSyncedToCurrentChain();
1839 LOCK(pwallet->cs_wallet);
1841 std::string strDest = request.params[0].get_str();
1842 if (!pwallet->BackupWallet(strDest)) {
1855 "\nFills the keypool."+
1874 LOCK(pwallet->cs_wallet);
1877 unsigned int kpSize = 0;
1878 if (!request.params[0].isNull()) {
1879 if (request.params[0].get_int() < 0)
1881 kpSize = (
unsigned int)request.params[0].get_int();
1885 pwallet->TopUpKeyPool(kpSize);
1887 if (pwallet->GetKeyPoolSize() < kpSize) {
1900 "\nEntirely clears and refills the keypool."+
1913 LOCK(pwallet->cs_wallet);
1927 "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
1928 "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
1930 "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
1931 "time that overrides the old one.\n",
1938 "\nUnlock the wallet for 60 seconds\n"
1940 "\nLock the wallet again (before 60 seconds)\n"
1942 "\nAs a JSON-RPC call\n"
1952 int64_t relock_time;
1964 strWalletPass.reserve(100);
1967 strWalletPass = request.params[0].get_str().c_str();
1970 nSleepTime = request.params[1].get_int64();
1972 if (nSleepTime < 0) {
1976 constexpr int64_t MAX_SLEEP_TIME = 100000000;
1977 if (nSleepTime > MAX_SLEEP_TIME) {
1978 nSleepTime = MAX_SLEEP_TIME;
1981 if (strWalletPass.empty()) {
1985 if (!pwallet->
Unlock(strWalletPass)) {
1991 pwallet->nRelockTime =
GetTime() + nSleepTime;
1992 relock_time = pwallet->nRelockTime;
2003 std::weak_ptr<CWallet> weak_wallet =
wallet;
2005 if (auto shared_wallet = weak_wallet.lock()) {
2006 LOCK(shared_wallet->cs_wallet);
2008 if (shared_wallet->nRelockTime != relock_time) return;
2009 shared_wallet->Lock();
2010 shared_wallet->nRelockTime = 0;
2023 "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n",
2030 HelpExampleCli(
"walletpassphrasechange",
"\"old one\" \"new one\"")
2031 +
HelpExampleRpc(
"walletpassphrasechange",
"\"old one\", \"new one\"")
2038 LOCK(pwallet->cs_wallet);
2040 if (!pwallet->IsCrypted()) {
2047 strOldWalletPass.reserve(100);
2048 strOldWalletPass = request.params[0].get_str().c_str();
2051 strNewWalletPass.reserve(100);
2052 strNewWalletPass = request.params[1].get_str().c_str();
2054 if (strOldWalletPass.empty() || strNewWalletPass.empty()) {
2058 if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) {
2071 "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2072 "After calling this method, you will need to call walletpassphrase again\n"
2073 "before being able to call any methods which require the wallet to be unlocked.\n",
2077 "\nSet the passphrase for 2 minutes to perform a transaction\n"
2079 "\nPerform a send (requires passphrase set)\n"
2081 "\nClear the passphrase since we are done before 2 minutes is up\n"
2083 "\nAs a JSON-RPC call\n"
2091 LOCK(pwallet->cs_wallet);
2093 if (!pwallet->IsCrypted()) {
2098 pwallet->nRelockTime = 0;
2109 "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2110 "After this, any calls that interact with private keys such as sending or signing \n"
2111 "will require the passphrase to be set prior the making these calls.\n"
2112 "Use the walletpassphrase call for this, and then walletlock call.\n"
2113 "If the wallet is already encrypted, use the walletpassphrasechange call.\n",
2119 "\nEncrypt your wallet\n"
2121 "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
2123 "\nNow we can do something like sign\n"
2124 +
HelpExampleCli(
"signmessage",
"\"address\" \"test message\"") +
2125 "\nNow lock the wallet again by removing the passphrase\n"
2127 "\nAs a JSON-RPC call\n"
2135 LOCK(pwallet->cs_wallet);
2141 if (pwallet->IsCrypted()) {
2148 strWalletPass.reserve(100);
2149 strWalletPass = request.params[0].get_str().c_str();
2151 if (strWalletPass.empty()) {
2155 if (!pwallet->EncryptWallet(strWalletPass)) {
2159 return "wallet encrypted; The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup.";
2167 "\nUpdates list of temporarily unspendable outputs.\n"
2168 "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2169 "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2170 "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
2171 "Manually selected coins are automatically unlocked.\n"
2172 "Locks are stored in memory only, unless persistent=true, in which case they will be written to the\n"
2173 "wallet database and loaded on node start. Unwritten (persistent=false) locks are always cleared\n"
2174 "(by virtue of process exit) when a node stops or fails. Unlocking will clear both persistent and not.\n"
2175 "Also see the listunspent call\n",
2188 {
"persistent",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Whether to write/erase this lock in the wallet database, or keep the change in memory only. Ignored for unlocking."},
2194 "\nList the unspent transactions\n"
2196 "\nLock an unspent transaction\n"
2197 +
HelpExampleCli(
"lockunspent",
"false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2198 "\nList the locked transactions\n"
2200 "\nUnlock the transaction again\n"
2201 +
HelpExampleCli(
"lockunspent",
"true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2202 "\nLock the transaction persistently in the wallet database\n"
2203 +
HelpExampleCli(
"lockunspent",
"false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\" true") +
2204 "\nAs a JSON-RPC call\n"
2205 +
HelpExampleRpc(
"lockunspent",
"false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2214 pwallet->BlockUntilSyncedToCurrentChain();
2216 LOCK(pwallet->cs_wallet);
2220 bool fUnlock = request.params[0].get_bool();
2222 const bool persistent{request.params[2].isNull() ? false : request.params[2].get_bool()};
2224 if (request.params[1].isNull()) {
2226 if (!pwallet->UnlockAllCoins())
2234 const UniValue& output_params = request.params[1];
2238 std::vector<COutPoint> outputs;
2239 outputs.reserve(output_params.
size());
2241 for (
unsigned int idx = 0; idx < output_params.
size(); idx++) {
2258 const auto it = pwallet->mapWallet.find(outpt.
hash);
2259 if (it == pwallet->mapWallet.end()) {
2265 if (outpt.
n >= trans.
tx->vout.size()) {
2269 if (pwallet->IsSpent(outpt.
hash, outpt.
n)) {
2273 const bool is_locked = pwallet->IsLockedCoin(outpt.
hash, outpt.
n);
2275 if (fUnlock && !is_locked) {
2279 if (!fUnlock && is_locked && !persistent) {
2283 outputs.push_back(outpt);
2286 std::unique_ptr<WalletBatch> batch =
nullptr;
2288 if (fUnlock || persistent) batch = std::make_unique<WalletBatch>(pwallet->GetDatabase());
2291 for (
const COutPoint& outpt : outputs) {
2307 "\nReturns list of temporarily unspendable outputs.\n"
2308 "See the lockunspent call to lock and unlock transactions for spending.\n",
2321 "\nList the unspent transactions\n"
2323 "\nLock an unspent transaction\n"
2324 +
HelpExampleCli(
"lockunspent",
"false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2325 "\nList the locked transactions\n"
2327 "\nUnlock the transaction again\n"
2328 +
HelpExampleCli(
"lockunspent",
"true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2329 "\nAs a JSON-RPC call\n"
2337 LOCK(pwallet->cs_wallet);
2339 std::vector<COutPoint> vOutpts;
2340 pwallet->ListLockedCoins(vOutpts);
2344 for (
const COutPoint& outpt : vOutpts) {
2347 o.
pushKV(
"txid", outpt.hash.GetHex());
2348 o.
pushKV(
"vout", (
int)outpt.n);
2360 "\nSet the transaction fee rate in " +
CURRENCY_UNIT +
"/kvB for this wallet. Overrides the global -paytxfee command line parameter.\n"
2361 "Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.\n",
2377 LOCK(pwallet->cs_wallet);
2380 CFeeRate tx_fee_rate(nAmount, 1000);
2381 CFeeRate max_tx_fee_rate(pwallet->m_default_max_tx_fee, 1000);
2384 }
else if (tx_fee_rate < pwallet->chain().relayMinFee()) {
2386 }
else if (tx_fee_rate < pwallet->m_min_fee) {
2388 }
else if (tx_fee_rate > max_tx_fee_rate) {
2392 pwallet->m_pay_tx_fee = tx_fee_rate;
2402 "Returns an object with all balances in " +
CURRENCY_UNIT +
".\n",
2410 {
RPCResult::Type::STR_AMOUNT,
"untrusted_pending",
"untrusted pending balance (outputs created by others that are in the mempool)"},
2412 {
RPCResult::Type::STR_AMOUNT,
"used",
true,
"(only present if avoid_reuse is set) balance from coins sent to addresses that were previously spent from (potentially privacy violating)"},
2414 {
RPCResult::Type::OBJ,
"watchonly",
true,
"watchonly balances (not present if wallet does not watch anything)",
2417 {
RPCResult::Type::STR_AMOUNT,
"untrusted_pending",
"untrusted pending balance (outputs created by others that are in the mempool)"},
2433 wallet.BlockUntilSyncedToCurrentChain();
2442 balances_mine.pushKV(
"untrusted_pending",
ValueFromAmount(bal.m_mine_untrusted_pending));
2443 balances_mine.pushKV(
"immature",
ValueFromAmount(bal.m_mine_immature));
2448 balances_mine.pushKV(
"used",
ValueFromAmount(full_bal.m_mine_trusted + full_bal.m_mine_untrusted_pending - bal.m_mine_trusted - bal.m_mine_untrusted_pending));
2450 balances.pushKV(
"mine", balances_mine);
2452 auto spk_man =
wallet.GetLegacyScriptPubKeyMan();
2453 if (spk_man && spk_man->HaveWatchOnly()) {
2455 balances_watchonly.pushKV(
"trusted",
ValueFromAmount(bal.m_watchonly_trusted));
2456 balances_watchonly.pushKV(
"untrusted_pending",
ValueFromAmount(bal.m_watchonly_untrusted_pending));
2457 balances_watchonly.pushKV(
"immature",
ValueFromAmount(bal.m_watchonly_immature));
2458 balances.pushKV(
"watchonly", balances_watchonly);
2468 "Returns an object containing various wallet state info.\n",
2482 {
RPCResult::Type::NUM,
"keypoolsize",
"how many new keys are pre-generated (only counts external keys)"},
2483 {
RPCResult::Type::NUM,
"keypoolsize_hd_internal",
true,
"how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)"},
2484 {
RPCResult::Type::NUM_TIME,
"unlocked_until",
true,
"the " +
UNIX_EPOCH_TIME +
" until which the wallet is unlocked for transfers, or 0 if the wallet is locked (only present for passphrase-encrypted wallets)"},
2487 {
RPCResult::Type::BOOL,
"private_keys_enabled",
"false if privatekeys are disabled for this wallet (enforced watch-only wallet)"},
2488 {
RPCResult::Type::BOOL,
"avoid_reuse",
"whether this wallet tracks clean/dirty coins in terms of reuse"},
2489 {
RPCResult::Type::OBJ,
"scanning",
"current scanning details, or false if no scan is in progress",
2494 {
RPCResult::Type::BOOL,
"descriptors",
"whether this wallet uses descriptors for scriptPubKey management"},
2508 pwallet->BlockUntilSyncedToCurrentChain();
2510 LOCK(pwallet->cs_wallet);
2514 size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
2516 int64_t kp_oldest = pwallet->GetOldestKeyPoolTime();
2517 obj.
pushKV(
"walletname", pwallet->GetName());
2518 obj.
pushKV(
"walletversion", pwallet->GetVersion());
2519 obj.
pushKV(
"format", pwallet->GetDatabase().Format());
2523 obj.
pushKV(
"txcount", (
int)pwallet->mapWallet.size());
2524 if (kp_oldest > 0) {
2525 obj.
pushKV(
"keypoololdest", kp_oldest);
2527 obj.
pushKV(
"keypoolsize", (int64_t)kpExternalSize);
2538 obj.
pushKV(
"keypoolsize_hd_internal", (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize));
2540 if (pwallet->IsCrypted()) {
2541 obj.
pushKV(
"unlocked_until", pwallet->nRelockTime);
2546 if (pwallet->IsScanning()) {
2548 scanning.
pushKV(
"duration", pwallet->ScanningDuration() / 1000);
2549 scanning.
pushKV(
"progress", pwallet->ScanningProgress());
2550 obj.
pushKV(
"scanning", scanning);
2552 obj.
pushKV(
"scanning",
false);
2563 "Returns a list of wallets in the wallet directory.\n",
2586 wallet.pushKV(
"name", path.u8string());
2591 result.
pushKV(
"wallets", wallets);
2600 "Returns a list of currently loaded wallets.\n"
2601 "For full information on the wallet, use \"getwalletinfo\"\n",
2634 std::vector<bilingual_str> warnings;
2635 std::optional<bool> load_on_start = load_on_start_param.
isNull() ? std::nullopt : std::optional<bool>(load_on_start_param.
get_bool());
2636 std::shared_ptr<CWallet>
const wallet =
LoadWallet(context, wallet_name, load_on_start, options, status,
error, warnings);
2656 return {
wallet, warnings };
2662 "\nLoads a wallet from a wallet file or directory."
2663 "\nNote that all wallet command-line options used when starting bitcoind will be"
2664 "\napplied to the new wallet.\n",
2683 const std::string
name(request.params[0].get_str());
2698 std::string
flags =
"";
2701 flags += (
flags ==
"" ?
"" :
", ") + it.first;
2704 "\nChange the state of the given wallet flag for a wallet.\n",
2726 std::string flag_str = request.params[0].
get_str();
2727 bool value = request.params[1].isNull() || request.params[1].get_bool();
2741 if (pwallet->IsWalletFlagSet(flag) == value) {
2745 res.pushKV(
"flag_name", flag_str);
2746 res.pushKV(
"flag_state", value);
2749 pwallet->SetWalletFlag(flag);
2751 pwallet->UnsetWalletFlag(flag);
2767 "\nCreates and loads a new wallet.\n",
2773 {
"avoid_reuse",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind."},
2774 {
"descriptors",
RPCArg::Type::BOOL,
RPCArg::Default{
true},
"Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation"},
2776 {
"external_signer",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true."},
2781 {
RPCResult::Type::STR,
"name",
"The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path."},
2788 +
HelpExampleCliNamed(
"createwallet", {{
"wallet_name",
"descriptors"}, {
"avoid_reuse",
true}, {
"descriptors",
true}, {
"load_on_startup",
true}})
2789 +
HelpExampleRpcNamed(
"createwallet", {{
"wallet_name",
"descriptors"}, {
"avoid_reuse",
true}, {
"descriptors",
true}, {
"load_on_startup",
true}})
2795 if (!request.params[1].isNull() && request.params[1].get_bool()) {
2799 if (!request.params[2].isNull() && request.params[2].get_bool()) {
2803 passphrase.reserve(100);
2804 std::vector<bilingual_str> warnings;
2805 if (!request.params[3].isNull()) {
2806 passphrase = request.params[3].get_str().c_str();
2807 if (passphrase.empty()) {
2809 warnings.emplace_back(
Untranslated(
"Empty string given as passphrase, wallet will not be encrypted."));
2813 if (!request.params[4].isNull() && request.params[4].get_bool()) {
2816 if (request.params[5].isNull() || request.params[5].get_bool()) {
2822 if (!request.params[7].isNull() && request.params[7].get_bool()) {
2823#ifdef ENABLE_EXTERNAL_SIGNER
2842 std::optional<bool> load_on_start = request.params[6].isNull() ? std::nullopt : std::optional<bool>(request.params[6].get_bool());
2843 const std::shared_ptr<CWallet>
wallet =
CreateWallet(context, request.params[0].get_str(), load_on_start, options, status,
error, warnings);
2862 "\nRestore and loads a wallet from backup.\n",
2876 HelpExampleCli(
"restorewallet",
"\"testwallet\" \"home\\backups\\backup-file.bak\"")
2877 +
HelpExampleRpc(
"restorewallet",
"\"testwallet\" \"home\\backups\\backup-file.bak\"")
2878 +
HelpExampleCliNamed(
"restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak\""}, {
"load_on_startup",
true}})
2879 +
HelpExampleRpcNamed(
"restorewallet", {{
"wallet_name",
"testwallet"}, {
"backup_file",
"home\\backups\\backup-file.bak\""}, {
"load_on_startup",
true}})
2886 auto backup_file =
fs::u8path(request.params[1].get_str());
2892 std::string wallet_name = request.params[0].get_str();
2904 auto wallet_file = wallet_path /
"wallet.dat";
2906 fs::copy_file(backup_file, wallet_file, fs::copy_option::fail_if_exists);
2923 "Unloads the wallet referenced by the request endpoint otherwise unloads the wallet specified in the argument.\n"
2924 "Specifying the wallet name on a wallet endpoint is invalid.",
2926 {
"wallet_name",
RPCArg::Type::STR,
RPCArg::DefaultHint{
"the wallet name from the RPC endpoint"},
"The name of the wallet to unload. If provided both here and in the RPC endpoint, the two must be identical."},
2938 std::string wallet_name;
2940 if (!(request.params[0].isNull() || request.params[0].get_str() == wallet_name)) {
2944 wallet_name = request.params[0].get_str();
2956 std::vector<bilingual_str> warnings;
2957 std::optional<bool> load_on_start = request.params[1].isNull() ? std::nullopt : std::optional<bool>(request.params[1].get_bool());
2975 "\nReturns array of unspent transaction outputs\n"
2976 "with between minconf and maxconf (inclusive) confirmations.\n"
2977 "Optionally filter to only include txouts paid to specified addresses.\n",
2987 "See description of \"safe\" attribute below."},
3009 {
RPCResult::Type::NUM,
"ancestorcount",
true,
"The number of in-mempool ancestor transactions, including this one (if transaction is in the mempool)"},
3010 {
RPCResult::Type::NUM,
"ancestorsize",
true,
"The virtual transaction size of in-mempool ancestors, including this one (if transaction is in the mempool)"},
3011 {
RPCResult::Type::STR_AMOUNT,
"ancestorfees",
true,
"The total fees of in-mempool ancestors (including this one) with fee deltas used for mining priority in " +
CURRENCY_ATOM +
" (if transaction is in the mempool)"},
3013 {
RPCResult::Type::STR,
"witnessScript",
true,
"witnessScript if the scriptPubKey is P2WSH or P2SH-P2WSH"},
3015 {
RPCResult::Type::BOOL,
"solvable",
"Whether we know how to spend this output, ignoring the lack of keys"},
3016 {
RPCResult::Type::BOOL,
"reused",
true,
"(only present if avoid_reuse is set) Whether this output is reused/dirty (sent to an address that was previously spent from)"},
3017 {
RPCResult::Type::STR,
"desc",
true,
"(only when solvable) A descriptor for spending this output"},
3018 {
RPCResult::Type::BOOL,
"safe",
"Whether this output is considered safe to spend. Unconfirmed transactions\n"
3019 "from outside keys and unconfirmed replacement transactions are considered unsafe\n"
3020 "and are not eligible for spending by fundrawtransaction and sendtoaddress."},
3028 +
HelpExampleCli(
"listunspent",
"6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
3029 +
HelpExampleRpc(
"listunspent",
"6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
3037 if (!request.params[0].isNull()) {
3039 nMinDepth = request.params[0].get_int();
3042 int nMaxDepth = 9999999;
3043 if (!request.params[1].isNull()) {
3045 nMaxDepth = request.params[1].get_int();
3048 std::set<CTxDestination> destinations;
3049 if (!request.params[2].isNull()) {
3052 for (
unsigned int idx = 0; idx < inputs.
size(); idx++) {
3053 const UniValue& input = inputs[idx];
3058 if (!destinations.insert(dest).second) {
3064 bool include_unsafe =
true;
3065 if (!request.params[3].isNull()) {
3067 include_unsafe = request.params[3].get_bool();
3073 uint64_t nMaximumCount = 0;
3075 if (!request.params[4].isNull()) {
3087 if (options.
exists(
"minimumAmount"))
3090 if (options.
exists(
"maximumAmount"))
3093 if (options.
exists(
"minimumSumAmount"))
3096 if (options.
exists(
"maximumCount"))
3097 nMaximumCount = options[
"maximumCount"].get_int64();
3102 pwallet->BlockUntilSyncedToCurrentChain();
3105 std::vector<COutput> vecOutputs;
3112 LOCK(pwallet->cs_wallet);
3113 AvailableCoins(*pwallet, vecOutputs, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount);
3116 LOCK(pwallet->cs_wallet);
3120 for (
const COutput& out : vecOutputs) {
3122 const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
3124 bool reused = avoid_reuse && pwallet->IsSpentKey(out.tx->GetHash(), out.i);
3126 if (destinations.size() && (!fValidAddress || !destinations.count(address)))
3130 entry.
pushKV(
"txid", out.tx->GetHash().GetHex());
3131 entry.
pushKV(
"vout", out.i);
3133 if (fValidAddress) {
3136 const auto* address_book_entry = pwallet->FindAddressBookEntry(address);
3137 if (address_book_entry) {
3138 entry.
pushKV(
"label", address_book_entry->GetLabel());
3141 std::unique_ptr<SigningProvider> provider = pwallet->GetSolvingProvider(scriptPubKey);
3146 if (provider->GetCScript(hash, redeemScript)) {
3158 if (provider->GetCScript(
id, witnessScript)) {
3168 if (provider->GetCScript(
id, witnessScript)) {
3177 entry.
pushKV(
"confirmations", out.nDepth);
3179 size_t ancestor_count, descendant_count, ancestor_size;
3181 pwallet->chain().getTransactionAncestry(out.tx->GetHash(), ancestor_count, descendant_count, &ancestor_size, &ancestor_fees);
3182 if (ancestor_count) {
3183 entry.
pushKV(
"ancestorcount", uint64_t(ancestor_count));
3184 entry.
pushKV(
"ancestorsize", uint64_t(ancestor_size));
3185 entry.
pushKV(
"ancestorfees", uint64_t(ancestor_fees));
3188 entry.
pushKV(
"spendable", out.fSpendable);
3189 entry.
pushKV(
"solvable", out.fSolvable);
3190 if (out.fSolvable) {
3191 std::unique_ptr<SigningProvider> provider = pwallet->GetSolvingProvider(scriptPubKey);
3194 entry.
pushKV(
"desc", descriptor->ToString());
3197 if (avoid_reuse) entry.
pushKV(
"reused", reused);
3198 entry.
pushKV(
"safe", out.fSafe);
3213 " \"" +
FeeModes(
"\"\n\"") +
"\""},
3215 "Allows this transaction to be replaced by a transaction with higher fees"},
3217 "Used for fee estimation during coin selection.",
3239 wallet.BlockUntilSyncedToCurrentChain();
3241 change_position = -1;
3242 bool lockUnspents =
false;
3244 std::set<int> setSubtractFeeFromOutputs;
3281 if (options.
exists(
"add_inputs") ) {
3285 if (options.
exists(
"changeAddress") || options.
exists(
"change_address")) {
3286 const std::string change_address_str = (options.
exists(
"change_address") ? options[
"change_address"] : options[
"changeAddress"]).get_str();
3296 if (options.
exists(
"changePosition") || options.
exists(
"change_position")) {
3297 change_position = (options.
exists(
"change_position") ? options[
"change_position"] : options[
"changePosition"]).get_int();
3300 if (options.
exists(
"change_type")) {
3301 if (options.
exists(
"changeAddress") || options.
exists(
"change_address")) {
3304 if (std::optional<OutputType> parsed =
ParseOutputType(options[
"change_type"].get_str())) {
3311 const UniValue include_watching_option = options.
exists(
"include_watching") ? options[
"include_watching"] : options[
"includeWatching"];
3314 if (options.
exists(
"lockUnspents") || options.
exists(
"lock_unspents")) {
3315 lockUnspents = (options.
exists(
"lock_unspents") ? options[
"lock_unspents"] : options[
"lockUnspents"]).get_bool();
3318 if (options.
exists(
"include_unsafe")) {
3322 if (options.
exists(
"feeRate")) {
3323 if (options.
exists(
"fee_rate")) {
3326 if (options.
exists(
"conf_target")) {
3327 throw JSONRPCError(
RPC_INVALID_PARAMETER,
"Cannot specify both conf_target and feeRate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate.");
3329 if (options.
exists(
"estimate_mode")) {
3336 if (options.
exists(
"subtractFeeFromOutputs") || options.
exists(
"subtract_fee_from_outputs") )
3337 subtractFeeFromOutputs = (options.
exists(
"subtract_fee_from_outputs") ? options[
"subtract_fee_from_outputs"] : options[
"subtractFeeFromOutputs"]).get_array();
3339 if (options.
exists(
"replaceable")) {
3342 SetFeeEstimateMode(
wallet, coinControl, options[
"conf_target"], options[
"estimate_mode"], options[
"fee_rate"], override_min_fee);
3349 if (options.
exists(
"solving_data")) {
3351 if (solving_data.
exists(
"pubkeys")) {
3352 for (
const UniValue& pk_univ : solving_data[
"pubkeys"].get_array().getValues()) {
3353 const std::string& pk_str = pk_univ.
get_str();
3354 if (!
IsHex(pk_str)) {
3357 const std::vector<unsigned char> data(
ParseHex(pk_str));
3358 const CPubKey pubkey(data.begin(), data.end());
3369 if (solving_data.
exists(
"scripts")) {
3370 for (
const UniValue& script_univ : solving_data[
"scripts"].get_array().getValues()) {
3371 const std::string& script_str = script_univ.get_str();
3372 if (!
IsHex(script_str)) {
3375 std::vector<unsigned char> script_data(
ParseHex(script_str));
3376 const CScript script(script_data.begin(), script_data.end());
3381 if (solving_data.
exists(
"descriptors")) {
3382 for (
const UniValue& desc_univ : solving_data[
"descriptors"].get_array().getValues()) {
3383 const std::string& desc_str = desc_univ.get_str();
3386 std::vector<CScript> scripts_temp;
3387 std::unique_ptr<Descriptor> desc =
Parse(desc_str, desc_out,
error,
true);
3391 desc->Expand(0, desc_out, scripts_temp, desc_out);
3397 if (tx.
vout.size() == 0)
3400 if (change_position != -1 && (change_position < 0 || (
unsigned int)change_position > tx.
vout.size()))
3403 for (
unsigned int idx = 0; idx < subtractFeeFromOutputs.
size(); idx++) {
3404 int pos = subtractFeeFromOutputs[idx].
get_int();
3405 if (setSubtractFeeFromOutputs.count(pos))
3409 if (pos >=
int(tx.
vout.size()))
3411 setSubtractFeeFromOutputs.insert(pos);
3416 std::map<COutPoint, Coin> coins;
3420 wallet.chain().findCoins(coins);
3421 for (
const auto& coin : coins) {
3422 if (!coin.second.out.IsNull()) {
3437 "\nIf the transaction has no inputs, they will be automatically selected to meet its out value.\n"
3438 "It will add at most one change output to the outputs.\n"
3439 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
3440 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
3441 "The inputs added will not be signed, use signrawtransactionwithkey\n"
3442 "or signrawtransactionwithwallet for that.\n"
3443 "All existing inputs must either have their previous output transaction be in the wallet\n"
3444 "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n"
3445 "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
3446 "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
3447 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
3448 "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n",
3452 Cat<std::vector<RPCArg>>(
3455 {
"include_unsafe",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n"
3456 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
3457 "If that happens, you will need to fund the transaction with different inputs and republish it."},
3460 {
"change_type",
RPCArg::Type::STR,
RPCArg::DefaultHint{
"set by -changetype"},
"The output type to use. Only valid if changeAddress is not specified. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
3462 "Only solvable inputs can be used. Watch-only destinations are solvable if the public key and/or output script was imported,\n"
3463 "e.g. with 'importpubkey' or 'importmulti' with the 'pubkeys' or 'desc' field."},
3468 "The fee will be equally deducted from the amount of each specified output.\n"
3469 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
3470 "If no outputs are specified here, the sender pays the fee.",
3479 "If iswitness is not present, heuristic tests will be used in decoding.\n"
3480 "If true, only witness deserialization will be tried.\n"
3481 "If false, only non-witness deserialization will be tried.\n"
3482 "This boolean should reflect whether the transaction has inputs\n"
3483 "(e.g. fully valid, or on-chain transactions), if known by the caller."
3495 "\nCreate a transaction with no inputs\n"
3496 +
HelpExampleCli(
"createrawtransaction",
"\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
3497 "\nAdd sufficient unsigned inputs to meet the output value\n"
3498 +
HelpExampleCli(
"fundrawtransaction",
"\"rawtransactionhex\"") +
3499 "\nSign the transaction\n"
3500 +
HelpExampleCli(
"signrawtransactionwithwallet",
"\"fundedtransactionhex\"") +
3501 "\nSend the transaction\n"
3502 +
HelpExampleCli(
"sendrawtransaction",
"\"signedtransactionhex\"")
3509 RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType(), UniValue::VBOOL});
3513 bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool();
3514 bool try_no_witness = request.params[2].isNull() ? true : !request.params[2].get_bool();
3515 if (!
DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) {
3520 int change_position;
3524 FundTransaction(*pwallet, tx, fee, change_position, request.params[1], coin_control,
true);
3529 result.
pushKV(
"changepos", change_position);
3538 return RPCHelpMan{
"signrawtransactionwithwallet",
3539 "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
3540 "The second optional argument (may be null) is an array of previous transaction outputs that\n"
3541 "this transaction depends on but may not yet be in the block chain." +
3564 " \"ALL|ANYONECANPAY\"\n"
3565 " \"NONE|ANYONECANPAY\"\n"
3566 " \"SINGLE|ANYONECANPAY\""},
3599 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR},
true);
3602 if (!
DecodeHexTx(mtx, request.params[0].get_str())) {
3607 LOCK(pwallet->cs_wallet);
3611 std::map<COutPoint, Coin> coins;
3612 for (
const CTxIn& txin : mtx.
vin) {
3615 pwallet->chain().findCoins(coins);
3623 std::map<int, bilingual_str> input_errors;
3625 bool complete = pwallet->SignTransaction(mtx, coins, nHashType, input_errors);
3635 const bool want_psbt = method_name ==
"psbtbumpfee";
3639 "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
3640 + std::string(want_psbt ?
"Returns a PSBT instead of creating and signing a new transaction.\n" :
"") +
3641 "An opt-in RBF transaction with the given txid must be in the wallet.\n"
3642 "The command will pay the additional fee by reducing change outputs or adding inputs when necessary.\n"
3643 "It may add a new change output if one does not already exist.\n"
3644 "All inputs in the original transaction will be included in the replacement transaction.\n"
3645 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
3646 "By default, the new fee will be calculated automatically using the estimatesmartfee RPC.\n"
3647 "The user can specify a confirmation target for estimatesmartfee.\n"
3648 "Alternatively, the user can specify a fee rate in " +
CURRENCY_ATOM +
"/vB for the new transaction.\n"
3649 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
3650 "returned by getnetworkinfo) to enter the node's mempool.\n"
3651 "* WARNING: before version 0.21, fee_rate was in " +
CURRENCY_UNIT +
"/kvB. As of 0.21, fee_rate is in " +
CURRENCY_ATOM +
"/vB. *\n",
3658 "\nSpecify a fee rate in " +
CURRENCY_ATOM +
"/vB instead of relying on the built-in fee estimator.\n"
3659 "Must be at least " + incremental_fee +
" higher than the current transaction fee rate.\n"
3660 "WARNING: before version 0.21, fee_rate was in " +
CURRENCY_UNIT +
"/kvB. As of 0.21, fee_rate is in " +
CURRENCY_ATOM +
"/vB.\n"},
3662 "marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
3663 "be left unchanged from the original. If false, any input sequence numbers in the\n"
3664 "original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
3665 "so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
3666 "still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
3667 "are replaceable).\n"},
3676 std::vector<RPCResult>{{
RPCResult::Type::STR,
"psbt",
"The base64-encoded unsigned PSBT of the new transaction."}} :
3688 "\nBump the fee, get the new transaction\'s " + std::string(want_psbt ?
"psbt" :
"txid") +
"\n" +
3697 throw JSONRPCError(
RPC_WALLET_ERROR,
"bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
3700 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
3708 if (!request.params[1].isNull()) {
3709 UniValue options = request.params[1];
3720 if (options.
exists(
"confTarget") && options.
exists(
"conf_target")) {
3724 auto conf_target = options.
exists(
"confTarget") ? options[
"confTarget"] : options[
"conf_target"];
3726 if (options.
exists(
"replaceable")) {
3729 SetFeeEstimateMode(*pwallet, coin_control, conf_target, options[
"estimate_mode"], options[
"fee_rate"],
false);
3734 pwallet->BlockUntilSyncedToCurrentChain();
3736 LOCK(pwallet->cs_wallet);
3741 std::vector<bilingual_str> errors;
3785 bool complete =
false;
3800 result.
pushKV(
"errors", result_errors);
3813 "\nRescan the local blockchain for wallet related transactions.\n"
3814 "Note: Use \"getwalletinfo\" to query the scanning progress.\n",
3822 {
RPCResult::Type::NUM,
"start_height",
"The block height where the rescan started (the requested height or 0)"},
3823 {
RPCResult::Type::NUM,
"stop_height",
"The height of the last rescanned block. May be null in rare cases if there was a reorg and the call didn't scan any blocks because they were already scanned in the background."},
3840 int start_height = 0;
3841 std::optional<int> stop_height;
3844 LOCK(pwallet->cs_wallet);
3845 int tip_height = pwallet->GetLastBlockHeight();
3847 if (!request.params[0].isNull()) {
3848 start_height = request.params[0].get_int();
3849 if (start_height < 0 || start_height > tip_height) {
3854 if (!request.params[1].isNull()) {
3855 stop_height = request.params[1].get_int();
3856 if (*stop_height < 0 || *stop_height > tip_height) {
3858 }
else if (*stop_height < start_height) {
3864 if (!pwallet->chain().hasBlocks(pwallet->GetLastBlockHash(), start_height, stop_height)) {
3865 throw JSONRPCError(
RPC_MISC_ERROR,
"Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height.");
3868 CHECK_NONFATAL(pwallet->chain().findAncestorByHeight(pwallet->GetLastBlockHash(), start_height,
FoundBlock().hash(start_block)));
3872 pwallet->ScanForWalletTransactions(start_block, start_height, stop_height, reserver,
true );
3883 response.
pushKV(
"start_height", start_height);
3898 std::vector<std::vector<unsigned char>> solutions_data;
3909 UniValue wallet_detail = std::visit(*
this, embedded);
3910 subobj.
pushKVs(wallet_detail);
3914 if (subobj.
exists(
"pubkey")) obj.
pushKV(
"pubkey", subobj[
"pubkey"]);
3915 obj.
pushKV(
"embedded", std::move(subobj));
3918 obj.
pushKV(
"sigsrequired", solutions_data[0][0]);
3920 for (
size_t i = 1; i < solutions_data.size() - 1; ++i) {
3921 CPubKey key(solutions_data[i].begin(), solutions_data[i].end());
3924 obj.
pushKV(
"pubkeys", std::move(pubkeys));
3987 std::unique_ptr<SigningProvider> provider =
nullptr;
3988 provider =
wallet.GetSolvingProvider(script);
4008 "\nReturn information about the given bitcoin address.\n"
4009 "Some of the information will only be present if the address is in the active wallet.\n",
4020 {
RPCResult::Type::BOOL,
"solvable",
"If we know how to spend coins sent to this address, ignoring the possible lack of private keys."},
4021 {
RPCResult::Type::STR,
"desc",
true,
"A descriptor for spending coins sent to this address (only when solvable)."},
4022 {
RPCResult::Type::STR,
"parent_desc",
true,
"The descriptor used to derive this address if this is a descriptor wallet"},
4028 {
RPCResult::Type::STR,
"script",
true,
"The output script type. Only if isscript is true and the redeemscript is known. Possible\n"
4029 "types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash,\n"
4030 "witness_v0_scripthash, witness_unknown."},
4032 {
RPCResult::Type::ARR,
"pubkeys",
true,
"Array of pubkeys associated with the known redeemscript (only if script is multisig).",
4036 {
RPCResult::Type::NUM,
"sigsrequired",
true,
"The number of signatures required to spend multisig output (only if script is multisig)."},
4037 {
RPCResult::Type::STR_HEX,
"pubkey",
true,
"The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH)."},
4038 {
RPCResult::Type::OBJ,
"embedded",
true,
"Information about the address embedded in P2SH or P2WSH, if relevant and known.",
4040 {
RPCResult::Type::ELISION,
"",
"Includes all getaddressinfo output fields for the embedded address, excluding metadata (timestamp, hdkeypath, hdseedid)\n"
4041 "and relation to the wallet (ismine, iswatchonly)."},
4048 {
RPCResult::Type::ARR,
"labels",
"Array of labels associated with the address. Currently limited to one label but returned\n"
4049 "as an array to keep the API stable if multiple labels are enabled in the future.",
4064 LOCK(pwallet->cs_wallet);
4066 std::string error_msg;
4072 if (error_msg.empty()) error_msg =
"Invalid address";
4080 ret.
pushKV(
"address", currentAddress);
4085 std::unique_ptr<SigningProvider> provider = pwallet->GetSolvingProvider(scriptPubKey);
4092 bool solvable = inferred->IsSolvable() ||
IsSolvable(*provider, scriptPubKey);
4093 ret.
pushKV(
"solvable", solvable);
4095 ret.
pushKV(
"desc", inferred->ToString());
4098 ret.
pushKV(
"solvable",
false);
4104 std::string desc_str;
4106 ret.
pushKV(
"parent_desc", desc_str);
4119 if (
const std::unique_ptr<CKeyMetadata> meta = spk_man->
GetMetadata(dest)) {
4120 ret.
pushKV(
"timestamp", meta->nCreateTime);
4121 if (meta->has_key_origin) {
4123 ret.
pushKV(
"hdseedid", meta->hd_seed_id.GetHex());
4124 ret.
pushKV(
"hdmasterfingerprint",
HexStr(meta->key_origin.fingerprint));
4135 const auto* address_book_entry = pwallet->FindAddressBookEntry(dest);
4136 if (address_book_entry) {
4137 labels.
push_back(address_book_entry->GetLabel());
4139 ret.
pushKV(
"labels", std::move(labels));
4149 "\nReturns the list of addresses assigned the specified label.\n",
4158 {
RPCResult::Type::STR,
"purpose",
"Purpose of address (\"send\" for sending address, \"receive\" for receiving address)"},
4171 LOCK(pwallet->cs_wallet);
4177 std::set<std::string> addresses;
4178 for (
const std::pair<const CTxDestination, CAddressBookData>& item : pwallet->m_address_book) {
4179 if (item.second.IsChange())
continue;
4180 if (item.second.GetLabel() == label) {
4185 bool unique = addresses.emplace(address).second;
4207 "\nReturns the list of all labels, or labels that are assigned to addresses with a specific purpose.\n",
4218 "\nList all labels\n"
4220 "\nList labels that have receiving addresses\n"
4222 "\nList labels that have sending addresses\n"
4224 "\nAs a JSON-RPC call\n"
4232 LOCK(pwallet->cs_wallet);
4234 std::string purpose;
4235 if (!request.params[0].isNull()) {
4236 purpose = request.params[0].get_str();
4240 std::set<std::string> label_set;
4241 for (
const std::pair<const CTxDestination, CAddressBookData>& entry : pwallet->m_address_book) {
4242 if (entry.second.IsChange())
continue;
4243 if (purpose.empty() || entry.second.purpose == purpose) {
4244 label_set.insert(entry.second.GetLabel());
4249 for (
const std::string&
name : label_set) {
4261 "\nEXPERIMENTAL warning: this call may be changed in future releases.\n"
4262 "\nSend a transaction.\n",
4265 "That is, each address can only appear once and there can only be one 'data' object.\n"
4266 "For convenience, a dictionary, which holds the key-value pairs directly, is also accepted.",
4282 " \"" +
FeeModes(
"\"\n\"") +
"\""},
4285 Cat<std::vector<RPCArg>>(
4288 {
"include_unsafe",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n"
4289 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
4290 "If that happens, you will need to fund the transaction with different inputs and republish it."},
4291 {
"add_to_wallet",
RPCArg::Type::BOOL,
RPCArg::Default{
true},
"When false, returns a serialized transaction which will not be added to the wallet or broadcast"},
4294 {
"change_type",
RPCArg::Type::STR,
RPCArg::DefaultHint{
"set by -changetype"},
"The output type to use. Only valid if change_address is not specified. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
4297 "Only solvable inputs can be used. Watch-only destinations are solvable if the public key and/or output script was imported,\n"
4298 "e.g. with 'importpubkey' or 'importmulti' with the 'pubkeys' or 'desc' field."},
4310 "The fee will be equally deducted from the amount of each specified output.\n"
4311 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
4312 "If no outputs are specified here, the sender pays the fee.",
4325 {
RPCResult::Type::STR_HEX,
"txid",
true,
"The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."},
4326 {
RPCResult::Type::STR_HEX,
"hex",
true,
"If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"},
4327 {
RPCResult::Type::STR,
"psbt",
true,
"If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"}
4331 "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode\n"
4333 "Send 0.2 BTC with a fee rate of 1.1 " +
CURRENCY_ATOM +
"/vB using positional arguments\n"
4335 "Send 0.2 BTC with a fee rate of 1 " +
CURRENCY_ATOM +
"/vB using the options argument\n"
4337 "Send 0.3 BTC with a fee rate of 25 " +
CURRENCY_ATOM +
"/vB using named arguments\n"
4339 "Create a transaction that should confirm the next block, with a specific input, and return result without adding to wallet or broadcasting to the network\n"
4340 +
HelpExampleCli(
"send",
"'{\"" +
EXAMPLE_ADDRESS[0] +
"\": 0.1}' 1 economical '{\"add_to_wallet\": false, \"inputs\": [{\"txid\":\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\", \"vout\":1}]}'")
4357 if (options.exists(
"conf_target") || options.exists(
"estimate_mode")) {
4358 if (!request.params[1].isNull() || !request.params[2].isNull()) {
4362 options.pushKV(
"conf_target", request.params[1]);
4363 options.pushKV(
"estimate_mode", request.params[2]);
4365 if (options.exists(
"fee_rate")) {
4366 if (!request.params[3].isNull()) {
4370 options.pushKV(
"fee_rate", request.params[3]);
4372 if (!options[
"conf_target"].isNull() && (options[
"estimate_mode"].isNull() || (options[
"estimate_mode"].get_str() ==
"unset"))) {
4375 if (options.exists(
"feeRate")) {
4378 if (options.exists(
"changeAddress")) {
4381 if (options.exists(
"changePosition")) {
4384 if (options.exists(
"includeWatching")) {
4387 if (options.exists(
"lockUnspents")) {
4390 if (options.exists(
"subtractFeeFromOutputs")) {
4394 const bool psbt_opt_in = options.exists(
"psbt") && options[
"psbt"].get_bool();
4397 int change_position;
4398 bool rbf = pwallet->m_signal_rbf;
4399 if (options.exists(
"replaceable")) {
4400 rbf = options[
"replaceable"].get_bool();
4407 FundTransaction(*pwallet, rawTx, fee, change_position, options, coin_control,
false);
4409 bool add_to_wallet =
true;
4410 if (options.exists(
"add_to_wallet")) {
4411 add_to_wallet = options[
"add_to_wallet"].get_bool();
4431 if (psbt_opt_in || !complete || !add_to_wallet) {
4439 std::string err_string;
4442 result.
pushKV(
"txid", tx->GetHash().GetHex());
4443 if (add_to_wallet && !psbt_opt_in) {
4444 pwallet->CommitTransaction(tx, {}, {} );
4446 result.
pushKV(
"hex", hex);
4449 result.
pushKV(
"complete", complete);
4459 "\nSet or generate a new HD wallet seed. Non-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n"
4460 "HD will have a new HD seed set so that new keys added to the keypool will be derived from this new seed.\n"
4461 "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed." +
4464 {
"newkeypool",
RPCArg::Type::BOOL,
RPCArg::Default{
true},
"Whether to flush old unused addresses, including change addresses, from the keypool and regenerate it.\n"
4465 "If true, the next address from getnewaddress and change address from getrawchangeaddress will be from this new seed.\n"
4466 "If false, addresses (including change addresses if the wallet already had HD Chain Split enabled) from the existing\n"
4467 "keypool will be used until it has been depleted."},
4469 "The seed value can be retrieved using the dumpwallet command. It is the private key marked hdseed=1"},
4492 if (!pwallet->CanSupportFeature(
FEATURE_HD)) {
4493 throw JSONRPCError(
RPC_WALLET_ERROR,
"Cannot set an HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD");
4498 bool flush_key_pool =
true;
4499 if (!request.params[0].isNull()) {
4500 flush_key_pool = request.params[0].get_bool();
4504 if (request.params[1].isNull()) {
4530 "\nUpdate a PSBT with input information from our wallet and then sign inputs\n"
4531 "that we can sign for." +
4541 " \"ALL|ANYONECANPAY\"\n"
4542 " \"NONE|ANYONECANPAY\"\n"
4543 " \"SINGLE|ANYONECANPAY\""},
4564 wallet.BlockUntilSyncedToCurrentChain();
4566 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VBOOL, UniValue::VSTR});
4579 bool sign = request.params[1].isNull() ? true : request.params[1].get_bool();
4580 bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
4581 bool complete =
true;
4594 result.
pushKV(
"complete", complete);
4604 "\nCreates and funds a transaction in the Partially Signed Transaction format.\n"
4605 "Implements the Creator and Updater roles.\n"
4606 "All existing inputs must either have their previous output transaction be in the wallet\n"
4607 "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n",
4621 "That is, each address can only appear once and there can only be one 'data' object.\n"
4622 "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n"
4623 "accepted as second parameter.",
4639 Cat<std::vector<RPCArg>>(
4642 {
"include_unsafe",
RPCArg::Type::BOOL,
RPCArg::Default{
false},
"Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n"
4643 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
4644 "If that happens, you will need to fund the transaction with different inputs and republish it."},
4647 {
"change_type",
RPCArg::Type::STR,
RPCArg::DefaultHint{
"set by -changetype"},
"The output type to use. Only valid if changeAddress is not specified. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
4653 "The fee will be equally deducted from the amount of each specified output.\n"
4654 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
4655 "If no outputs are specified here, the sender pays the fee.",
4674 "\nCreate a transaction with no inputs\n"
4675 +
HelpExampleCli(
"walletcreatefundedpsbt",
"\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
4685 wallet.BlockUntilSyncedToCurrentChain();
4697 int change_position;
4698 bool rbf{
wallet.m_signal_rbf};
4699 const UniValue &replaceable_arg = request.params[3][
"replaceable"];
4700 if (!replaceable_arg.
isNull()) {
4702 rbf = replaceable_arg.
isTrue();
4715 bool bip32derivs = request.params[4].isNull() ? true : request.params[4].get_bool();
4716 bool complete =
true;
4729 result.
pushKV(
"changepos", change_position);
4738 "\nUpgrade the wallet. Upgrades to the latest version if no version number is specified.\n"
4739 "New keys may be generated and a new wallet backup will need to be made.",
4767 if (!request.params[0].isNull()) {
4768 version = request.params[0].get_int();
4771 const int previous_version{pwallet->GetVersion()};
4772 const bool wallet_upgraded{pwallet->UpgradeWallet(version,
error)};
4773 const int current_version{pwallet->GetVersion()};
4776 if (wallet_upgraded) {
4777 if (previous_version == current_version) {
4778 result =
"Already at latest version. Wallet version unchanged.";
4780 result =
strprintf(
"Wallet upgraded successfully from version %i to version %i.", previous_version, current_version);
4785 obj.
pushKV(
"wallet_name", pwallet->GetName());
4786 obj.
pushKV(
"previous_version", previous_version);
4787 obj.
pushKV(
"current_version", current_version);
4788 if (!result.empty()) {
4789 obj.
pushKV(
"result", result);
4799#ifdef ENABLE_EXTERNAL_SIGNER
4803 "walletdisplayaddress",
4804 "Display address on an external signer for verification.",
4835 result.
pushKV(
"address", request.params[0].get_str());
4908 {
"wallet", &
send, },
4920#ifdef ENABLE_EXTERNAL_SIGNER
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
int64_t CAmount
Amount in satoshis (Can be negative)
std::string WriteHDKeypath(const std::vector< uint32_t > &keypath)
Write HD keypaths as strings.
UrlDecodeFn *const URL_DECODE
static CAmount AmountFromValue(const UniValue &value)
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
const std::string & GetLabel() const
std::vector< CTransactionRef > vtx
std::optional< OutputType > m_change_type
Override the default change type if set, ignored if destChange is set.
std::optional< bool > m_signal_bip125_rbf
Override the wallet's m_signal_rbf if set.
std::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
void SelectExternal(const COutPoint &outpoint, const CTxOut &txout)
int m_max_depth
Maximum chain depth value for coin availability.
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
int m_min_depth
Minimum chain depth value for coin availability.
FlatSigningProvider m_external_provider
SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs.
std::optional< CFeeRate > m_feerate
Override the wallet's m_pay_tx_fee if set.
bool fOverrideFeeRate
Override automatic min/max checks on fee, m_feerate must be set if true.
bool m_add_inputs
If false, only selected inputs are used.
CTxDestination destChange
Custom change destination, if not set an address is generated.
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
bool m_include_unsafe_inputs
If false, only safe inputs will be used.
bool m_avoid_partial_spends
Avoid partial use of funds sent to a given address.
FeeEstimateMode m_fee_mode
Fee estimation mode to control arguments to estimateSmartFee.
Double ended buffer combining vector and stream-like interfaces.
Fee rate in satoshis per kilobyte: CAmount / kB.
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
CKeyID seed_id
seed hash160
An encapsulated private key.
const unsigned char * begin() const
bool IsValid() const
Check whether this private key is valid.
const unsigned char * end() const
bool IsCompressed() const
Check whether the public key corresponding to this private key is (to be) compressed.
CPubKey GetPubKey() const
Compute the public key from a private key.
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
A reference to a CKey: the Hash160 of its serialized public key.
An outpoint - a combination of a transaction hash and an index n into its vout.
An encapsulated public key.
bool IsCompressed() const
Check whether this is a compressed 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 hasher class for RIPEMD-160.
CRIPEMD160 & Write(const unsigned char *data, size_t len)
void Finalize(unsigned char hash[OUTPUT_SIZE])
Serialized script, used inside transaction inputs and outputs.
bool IsPayToScriptHash() const
bool IsPayToWitnessScriptHash() const
A reference to a CScript: the Hash160 of its serialization (see script.h)
The basic transaction that is broadcasted on the network and contained in blocks.
An input of a transaction.
An output of a transaction.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
RecursiveMutex cs_wallet
Main wallet lock.
bool Unlock(const CKeyingMaterial &vMasterKeyIn, bool accept_no_keys=false)
interfaces::Chain & chain() const
Interface for accessing chain state.
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
std::multimap< int64_t, CWalletTx * > TxItems
A transaction with a bunch of additional info that only the owner cares about.
mapValue_t mapValue
Key/value map with information about the transaction.
const uint256 & GetHash() const
int64_t GetTxTime() const
unsigned int nTimeReceived
time received by this node
const SigningProvider *const provider
UniValue operator()(const WitnessV0KeyHash &id) const
UniValue operator()(const PKHash &pkhash) const
UniValue operator()(const ScriptHash &scripthash) const
UniValue operator()(const WitnessUnknown &id) const
void ProcessSubScript(const CScript &subscript, UniValue &obj) const
DescribeWalletAddressVisitor(const SigningProvider *_provider)
UniValue operator()(const WitnessV1Taproot &id) const
UniValue operator()(const WitnessV0ScriptHash &id) const
UniValue operator()(const CNoDestination &dest) const
bool GetDescriptorString(std::string &out, const bool priv) const
RecursiveMutex cs_KeyStore
enum JSONRPCRequest::Mode mode
const CHDChain & GetHDChain() const
void SetHDSeed(const CPubKey &key)
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
CPubKey GenerateNewSeed()
CPubKey DeriveNewSeed(const CKey &key)
virtual std::unique_ptr< CKeyMetadata > GetMetadata(const CTxDestination &dest) const
An interface to be implemented by keystores that support signing.
virtual bool GetCScript(const CScriptID &scriptid, CScript &script) const
virtual bool GetPubKey(const CKeyID &address, CPubKey &pubkey) const
A Span is an object that can refer to a contiguous sequence of objects.
const std::string & get_str() const
const UniValue & get_obj() const
void __pushKV(const std::string &key, const UniValue &val)
const std::vector< UniValue > & getValues() const
const std::vector< std::string > & getKeys() const
bool pushKVs(const UniValue &obj)
bool push_back(const UniValue &val)
const UniValue & get_array() const
bool exists(const std::string &key) const
bool pushKV(const std::string &key, const UniValue &val)
RAII object to check and reserve a wallet rescan.
std::string GetHex() const
Path class wrapper to prepare application code for transition from boost::filesystem library to std::...
std::string u8string() const
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
virtual void rpcRunLater(const std::string &name, std::function< void()> fn, int64_t seconds)=0
Run function after given number of seconds. Cancel any previous calls with same name.
virtual RBFTransactionState isRBFOptIn(const CTransaction &tx)=0
Check if transaction is RBF opt in.
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
Helper for findBlock to selectively return pieces of block data.
void push_back(const T &value)
int ParseSighashString(const UniValue &sighash)
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
void TxToUniv(const CTransaction &tx, const uint256 &hashBlock, UniValue &entry, bool include_hex=true, int serialize_flags=0, const CTxUndo *txundo=nullptr, TxVerbosity verbosity=TxVerbosity::SHOW_DETAILS)
UniValue ValueFromAmount(const CAmount amount)
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
std::vector< fs::path > ListDatabases(const fs::path &wallet_dir)
Recursively list database paths in directory.
std::unique_ptr< Descriptor > InferDescriptor(const CScript &script, const SigningProvider &provider)
Find a descriptor for the specified script, using information from provider where possible.
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
const std::string CURRENCY_ATOM
const std::string CURRENCY_UNIT
@ SAT_VB
Use sat/vB fee rate unit.
bool DisplayAddress(const CTxDestination &dest) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Display address on an external signer.
bool TopUpKeyPool(unsigned int kpSize=0)
@ SIGHASH_DEFAULT
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
isminetype
IsMine() return codes, which depend on ScriptPubKeyMan implementation.
bool IsValidDestinationString(const std::string &str, const CChainParams ¶ms)
std::string EncodeDestination(const CTxDestination &dest)
CKey DecodeSecret(const std::string &str)
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg)
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Result CommitTransaction(CWallet &wallet, const uint256 &txid, CMutableTransaction &&mtx, std::vector< bilingual_str > &errors, uint256 &bumped_txid)
Commit the bumpfee transaction.
Result CreateRateBumpTransaction(CWallet &wallet, const uint256 &txid, const CCoinControl &coin_control, std::vector< bilingual_str > &errors, CAmount &old_fee, CAmount &new_fee, CMutableTransaction &mtx)
Create bumpfee transaction based on feerate estimates.
bool SignTransaction(CWallet &wallet, CMutableTransaction &mtx)
Sign the new transaction,.
static path u8path(const std::string &string)
static bool exists(const path &p)
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
std::optional< OutputType > ParseOutputType(const std::string &type)
RBFTransactionState
The rbf state of unconfirmed transactions.
@ UNKNOWN
Unconfirmed tx that does not signal rbf and is not in the mempool.
@ REPLACEABLE_BIP125
Either this tx or a mempool ancestor signals rbf.
static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP...
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
bool DecodeBase64PSBT(PartiallySignedTransaction &psbt, const std::string &base64_tx, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
bool FinalizeAndExtractPSBT(PartiallySignedTransaction &psbtx, CMutableTransaction &result)
Finalizes a PSBT if possible, and extracts it to a CMutableTransaction if it could be finalized.
void SignTransactionResultToJSON(CMutableTransaction &mtx, bool complete, const std::map< COutPoint, Coin > &coins, const std::map< int, bilingual_str > &input_errors, UniValue &result)
CMutableTransaction ConstructTransaction(const UniValue &inputs_in, const UniValue &outputs_in, const UniValue &locktime, bool rbf)
Create a transaction from univalue parameters.
void ParsePrevouts(const UniValue &prevTxsUnival, FillableSigningProvider *keystore, std::map< COutPoint, Coin > &coins)
Parse a prevtxs UniValue array and get the map of coins from it.
bool CachedTxIsFromMe(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
std::set< std::set< CTxDestination > > GetAddressGroupings(const CWallet &wallet)
std::map< CTxDestination, CAmount > GetAddressBalances(const CWallet &wallet)
bool ScriptIsChange(const CWallet &wallet, const CScript &script)
void CachedTxGetAmounts(const CWallet &wallet, const CWalletTx &wtx, std::list< COutputEntry > &listReceived, std::list< COutputEntry > &listSent, CAmount &nFee, const isminefilter &filter)
CAmount CachedTxGetDebit(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
filter decides which addresses will count towards the debit
CAmount CachedTxGetCredit(const CWallet &wallet, const CWalletTx &wtx, const isminefilter &filter)
Balance GetBalance(const CWallet &wallet, const int min_depth, bool avoid_reuse)
bool CachedTxIsTrusted(const CWallet &wallet, const CWalletTx &wtx, std::set< uint256 > &trusted_parents)
UniValue JSONRPCError(int code, const std::string &message)
RPCErrorCode
Bitcoin RPC error codes.
@ RPC_WALLET_NOT_SPECIFIED
No wallet specified (error when there are multiple wallets loaded)
@ RPC_WALLET_INVALID_LABEL_NAME
Invalid label name.
@ RPC_WALLET_UNLOCK_NEEDED
Enter the wallet passphrase with walletpassphrase first.
@ RPC_MISC_ERROR
General application defined errors.
@ RPC_WALLET_INSUFFICIENT_FUNDS
Not enough funds in wallet or account.
@ RPC_WALLET_WRONG_ENC_STATE
Command given in wrong wallet encryption state (encrypting an encrypted wallet etc....
@ RPC_WALLET_ENCRYPTION_FAILED
Failed to encrypt the wallet.
@ RPC_TYPE_ERROR
Unexpected type was passed as parameter.
@ RPC_METHOD_DEPRECATED
RPC method is deprecated.
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
@ RPC_WALLET_ERROR
Wallet errors.
@ RPC_WALLET_ALREADY_LOADED
This same wallet is already loaded.
@ RPC_WALLET_NOT_FOUND
Invalid wallet specified.
@ RPC_WALLET_KEYPOOL_RAN_OUT
Keypool ran out, call keypoolrefill first.
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
@ RPC_WALLET_PASSPHRASE_INCORRECT
The wallet passphrase entered was incorrect.
@ RPC_INVALID_REQUEST
Standard JSON-RPC 2.0 errors.
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
void RPCTypeCheck(const UniValue ¶ms, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
CTxDestination AddAndGetMultisigDestination(const int required, const std::vector< CPubKey > &pubkeys, OutputType type, FillableSigningProvider &keystore, CScript &script_out)
std::string HelpExampleRpcNamed(const std::string &methodname, const RPCArgList &args)
void RPCTypeCheckArgument(const UniValue &value, const UniValueType &typeExpected)
Type-check one argument; throws JSONRPCError if wrong type given.
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string)
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.
CPubKey HexToPubKey(const std::string &hex_in)
uint256 ParseHashO(const UniValue &o, std::string strKey)
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
const std::string EXAMPLE_ADDRESS[2]
Example bech32 addresses for the RPCExamples help documentation.
unsigned int ParseConfirmTarget(const UniValue &value, unsigned int max_target)
Parse a confirm target option and raise an RPC error if it is invalid.
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
std::string HelpExampleCliNamed(const std::string &methodname, const RPCArgList &args)
CPubKey AddrToPubKey(const FillableSigningProvider &keystore, const std::string &addr_in)
UniValue DescribeAddress(const CTxDestination &dest)
static RPCHelpMan createwallet()
static RPCHelpMan getnewaddress()
static RPCHelpMan sethdseed()
RPCHelpMan importprivkey()
static RPCHelpMan walletlock()
static RPCHelpMan bumpfee_helper(std::string method_name)
static RPCHelpMan psbtbumpfee()
static RPCHelpMan listreceivedbylabel()
static void SetFeeEstimateMode(const CWallet &wallet, CCoinControl &cc, const UniValue &conf_target, const UniValue &estimate_mode, const UniValue &fee_rate, bool override_min_fee)
Update coin control with fee estimation based on the given parameters.
static std::string LabelFromValue(const UniValue &value)
static RPCHelpMan sendtoaddress()
Span< const CRPCCommand > GetWalletRPCCommands()
static RPCHelpMan listunspent()
static RPCHelpMan getrawchangeaddress()
static const std::vector< RPCResult > TransactionDescriptionString()
static RPCHelpMan rescanblockchain()
static RPCHelpMan walletprocesspsbt()
RPCHelpMan importdescriptors()
static const std::string WALLET_ENDPOINT_BASE
static RPCHelpMan fundrawtransaction()
static RPCHelpMan gettransaction()
RPCHelpMan listdescriptors()
static RPCHelpMan restorewallet()
static UniValue AddressBookDataToJSON(const CAddressBookData &data, const bool verbose)
Convert CAddressBookData to JSON record.
RPCHelpMan importaddress()
void FundTransaction(CWallet &wallet, CMutableTransaction &tx, CAmount &fee_out, int &change_position, const UniValue &options, CCoinControl &coinControl, bool override_min_fee)
static RPCHelpMan listaddressgroupings()
RPCHelpMan importwallet()
static RPCHelpMan addmultisigaddress()
static RPCHelpMan walletdisplayaddress()
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
static RPCHelpMan walletpassphrasechange()
static RPCHelpMan getaddressesbylabel()
static RPCHelpMan listtransactions()
static std::tuple< std::shared_ptr< CWallet >, std::vector< bilingual_str > > LoadWalletHelper(WalletContext &context, UniValue load_on_start_param, const std::string wallet_name)
static RPCHelpMan listlockunspent()
UniValue SendMoney(CWallet &wallet, const CCoinControl &coin_control, std::vector< CRecipient > &recipients, mapValue_t map_value, bool verbose)
static RPCHelpMan getunconfirmedbalance()
static RPCHelpMan listwallets()
static RPCHelpMan upgradewallet()
static RPCHelpMan unloadwallet()
void EnsureWalletIsUnlocked(const CWallet &wallet)
RPCHelpMan importpubkey()
static RPCHelpMan walletcreatefundedpsbt()
LegacyScriptPubKeyMan & EnsureLegacyScriptPubKeyMan(CWallet &wallet, bool also_create)
static RPCHelpMan getbalances()
static RPCHelpMan listwalletdir()
static RPCHelpMan keypoolrefill()
bool HaveKey(const SigningProvider &wallet, const CKey &key)
Checks if a CKey is in the given CWallet compressed or otherwise.
static UniValue DescribeWalletAddress(const CWallet &wallet, const CTxDestination &dest)
static void ListTransactions(const CWallet &wallet, const CWalletTx &wtx, int nMinDepth, bool fLong, UniValue &ret, const isminefilter &filter_ismine, const std::string *filter_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
List transactions based on the given criteria.
static RPCHelpMan signmessage()
static bool ParseIncludeWatchonly(const UniValue &include_watchonly, const CWallet &wallet)
Used by RPC commands that have an include_watchonly parameter.
RPCHelpMan getaddressinfo()
static CAmount GetReceived(const CWallet &wallet, const UniValue ¶ms, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
static RPCHelpMan getwalletinfo()
static RPCHelpMan lockunspent()
static RPCHelpMan listlabels()
RPCHelpMan importprunedfunds()
static RPCHelpMan setwalletflag()
static std::vector< RPCArg > FundTxDoc()
RPCHelpMan signrawtransactionwithwallet()
static RPCHelpMan newkeypool()
static RPCHelpMan setlabel()
static UniValue ListReceived(const CWallet &wallet, const UniValue ¶ms, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
static RPCHelpMan getreceivedbyaddress()
static RPCHelpMan getreceivedbylabel()
static RPCHelpMan encryptwallet()
static RPCHelpMan backupwallet()
static void WalletTxToJSON(const CWallet &wallet, const CWalletTx &wtx, UniValue &entry)
static void MaybePushAddress(UniValue &entry, const CTxDestination &dest)
void ParseRecipients(const UniValue &address_amounts, const UniValue &subtract_fee_outputs, std::vector< CRecipient > &recipients)
static RPCHelpMan getbalance()
static RPCHelpMan loadwallet()
static bool GetAvoidReuseFlag(const CWallet &wallet, const UniValue ¶m)
static RPCHelpMan listsinceblock()
static RPCHelpMan settxfee()
RPCHelpMan removeprunedfunds()
static RPCHelpMan listreceivedbyaddress()
static RPCHelpMan sendmany()
WalletContext & EnsureWalletContext(const std::any &context)
static RPCHelpMan walletpassphrase()
static RPCHelpMan bumpfee()
static const std::string HELP_REQUIRING_PASSPHRASE
bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest &request, std::string &wallet_name)
static RPCHelpMan abandontransaction()
static const unsigned int DEFAULT_KEYPOOL_SIZE
Default for -keypool.
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
bool IsSolvable(const SigningProvider &provider, const CScript &script)
FlatSigningProvider Merge(const FlatSigningProvider &a, const FlatSigningProvider &b)
constexpr Span< A > MakeSpan(A(&a)[N])
MakeSpan for arrays:
void AvailableCoins(const CWallet &wallet, std::vector< COutput > &vCoins, const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t nMaximumCount)
populate vCoins with vector of available COutputs.
bool CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, CTransactionRef &tx, CAmount &nFeeRet, int &nChangePosInOut, bilingual_str &error, const CCoinControl &coin_control, FeeCalculation &fee_calc_out, bool sign)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
TxoutType Solver(const CScript &scriptPubKey, std::vector< std::vector< unsigned char > > &vSolutionsRet)
Parse a scriptPubKey and identify script type for standard scripts.
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
std::string GetTxnOutputType(TxoutType t)
Get the name of a TxoutType as a string.
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.
CKeyID ToKeyID(const PKHash &key_hash)
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::string EncodeBase64(Span< const unsigned char > input)
std::vector< unsigned char > ParseHex(const char *psz)
bool IsHex(const std::string &str)
auto Join(const std::vector< T > &list, const BaseType &separator, UnaryOp unary_op) -> decltype(unary_op(list.at(0)))
Join a list of items.
CAmount m_mine_untrusted_pending
Untrusted, but in mempool (pending)
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::optional< int > last_scanned_height
enum CWallet::ScanResult::@17 status
SecureString create_passphrase
std::map< CKeyID, CPubKey > pubkeys
std::map< CScriptID, CScript > scripts
A version of CTransaction with the PSBT format.
@ OBJ_USER_KEYS
Special type where the user must set the keys e.g. to define multiple addresses; as opposed to e....
@ STR_HEX
Special type that is a STR with only hex chars.
@ AMOUNT
Special type representing a floating point amount (can be either NUM or STR)
@ OMITTED_NAMED_ARG
Optional arg that is a named argument and has a default value of null.
@ OMITTED
Optional argument with default value omitted because they are implicitly clear.
@ ELISION
Special type to denote elision (...)
@ NUM_TIME
Special numeric to denote unix epoch time.
@ ARR_FIXED
Special array that has a fixed number of entries.
@ 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.
Wrapper for UniValue::VType, which includes typeAny: Used to denote don't care type.
WalletContext struct containing references to state shared between CWallet instances,...
CTxDestination subtype to encode any future Witness version.
std::vector< uint256 > txids
#define AssertLockNotHeld(cs)
bool error(const char *fmt, const Args &... args)
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int64_t GetTime()
DEPRECATED Use either GetTimeSeconds (not mockable) or GetTime<T> (mockable)
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
const UniValue NullUniValue
const UniValue & find_value(const UniValue &obj, const std::string &name)
std::string FeeModes(const std::string &delimiter)
bool FeeModeFromString(const std::string &mode_string, FeeEstimateMode &fee_estimate_mode)
const std::string InvalidEstimateModeErrorMessage()
std::string StringForFeeReason(FeeReason reason)
std::string SigningResultString(const SigningResult res)
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost's create_directories if the requested directory exists.
V Cat(V v1, V &&v2)
Concatenate two vectors, moving elements.
static const int PROTOCOL_VERSION
network protocol versioning
std::map< std::string, std::string > mapValue_t
const std::map< uint64_t, std::string > WALLET_FLAG_CAVEATS
bool RemoveWallet(WalletContext &context, const std::shared_ptr< CWallet > &wallet, std::optional< bool > load_on_start, std::vector< bilingual_str > &warnings)
void UnloadWallet(std::shared_ptr< CWallet > &&wallet)
Explicitly unload and delete the wallet.
std::vector< std::shared_ptr< CWallet > > GetWallets(WalletContext &context)
std::shared_ptr< CWallet > GetWallet(WalletContext &context, const std::string &name)
std::shared_ptr< CWallet > CreateWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
std::shared_ptr< CWallet > LoadWallet(WalletContext &context, const std::string &name, std::optional< bool > load_on_start, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector< bilingual_str > &warnings)
static constexpr uint64_t MUTABLE_WALLET_FLAGS
static const std::map< std::string, WalletFlags > WALLET_FLAG_MAP
fs::path GetWalletDir()
Get the path of the wallet directory.
@ WALLET_FLAG_EXTERNAL_SIGNER
Indicates that the wallet needs an external signer.
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_AVOID_REUSE
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.
@ WALLET_FLAG_BLANK_WALLET
Flag set when a wallet contains no HD seed and no private keys, scripts, addresses,...