Merge #11583: Do not make it trivial for inbound peers to generate log entries
[bitcoinplatinum.git] / src / wallet / rpcwallet.cpp
blob473acd8367d4a68df95d52dca13a5db9e745c788
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include <amount.h>
7 #include <base58.h>
8 #include <chain.h>
9 #include <consensus/validation.h>
10 #include <core_io.h>
11 #include <httpserver.h>
12 #include <validation.h>
13 #include <net.h>
14 #include <policy/feerate.h>
15 #include <policy/fees.h>
16 #include <policy/policy.h>
17 #include <policy/rbf.h>
18 #include <rpc/mining.h>
19 #include <rpc/safemode.h>
20 #include <rpc/server.h>
21 #include <script/sign.h>
22 #include <timedata.h>
23 #include <util.h>
24 #include <utilmoneystr.h>
25 #include <wallet/coincontrol.h>
26 #include <wallet/feebumper.h>
27 #include <wallet/wallet.h>
28 #include <wallet/walletdb.h>
29 #include <wallet/walletutil.h>
31 #include <init.h> // For StartShutdown
33 #include <stdint.h>
35 #include <univalue.h>
37 static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
39 CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
41 if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
42 // wallet endpoint was used
43 std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
44 for (CWalletRef pwallet : ::vpwallets) {
45 if (pwallet->GetName() == requestedWallet) {
46 return pwallet;
49 throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
51 return ::vpwallets.size() == 1 || (request.fHelp && ::vpwallets.size() > 0) ? ::vpwallets[0] : nullptr;
54 std::string HelpRequiringPassphrase(CWallet * const pwallet)
56 return pwallet && pwallet->IsCrypted()
57 ? "\nRequires wallet passphrase to be set with walletpassphrase call."
58 : "";
61 bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
63 if (pwallet) return true;
64 if (avoidException) return false;
65 if (::vpwallets.empty()) {
66 // Note: It isn't currently possible to trigger this error because
67 // wallet RPC methods aren't registered unless a wallet is loaded. But
68 // this error is being kept as a precaution, because it's possible in
69 // the future that wallet RPC methods might get or remain registered
70 // when no wallets are loaded.
71 throw JSONRPCError(
72 RPC_METHOD_NOT_FOUND, "Method not found (wallet method is disabled because no wallet is loaded)");
74 throw JSONRPCError(RPC_WALLET_NOT_SPECIFIED,
75 "Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
78 void EnsureWalletIsUnlocked(CWallet * const pwallet)
80 if (pwallet->IsLocked()) {
81 throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
85 void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
87 int confirms = wtx.GetDepthInMainChain();
88 entry.push_back(Pair("confirmations", confirms));
89 if (wtx.IsCoinBase())
90 entry.push_back(Pair("generated", true));
91 if (confirms > 0)
93 entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
94 entry.push_back(Pair("blockindex", wtx.nIndex));
95 entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
96 } else {
97 entry.push_back(Pair("trusted", wtx.IsTrusted()));
99 uint256 hash = wtx.GetHash();
100 entry.push_back(Pair("txid", hash.GetHex()));
101 UniValue conflicts(UniValue::VARR);
102 for (const uint256& conflict : wtx.GetConflicts())
103 conflicts.push_back(conflict.GetHex());
104 entry.push_back(Pair("walletconflicts", conflicts));
105 entry.push_back(Pair("time", wtx.GetTxTime()));
106 entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
108 // Add opt-in RBF status
109 std::string rbfStatus = "no";
110 if (confirms <= 0) {
111 LOCK(mempool.cs);
112 RBFTransactionState rbfState = IsRBFOptIn(*wtx.tx, mempool);
113 if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN)
114 rbfStatus = "unknown";
115 else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125)
116 rbfStatus = "yes";
118 entry.push_back(Pair("bip125-replaceable", rbfStatus));
120 for (const std::pair<std::string, std::string>& item : wtx.mapValue)
121 entry.push_back(Pair(item.first, item.second));
124 std::string AccountFromValue(const UniValue& value)
126 std::string strAccount = value.get_str();
127 if (strAccount == "*")
128 throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
129 return strAccount;
132 UniValue getnewaddress(const JSONRPCRequest& request)
134 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
135 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
136 return NullUniValue;
139 if (request.fHelp || request.params.size() > 1)
140 throw std::runtime_error(
141 "getnewaddress ( \"account\" )\n"
142 "\nReturns a new Bitcoin address for receiving payments.\n"
143 "If 'account' is specified (DEPRECATED), it is added to the address book \n"
144 "so payments received with the address will be credited to 'account'.\n"
145 "\nArguments:\n"
146 "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created if there is no account by the given name.\n"
147 "\nResult:\n"
148 "\"address\" (string) The new bitcoin address\n"
149 "\nExamples:\n"
150 + HelpExampleCli("getnewaddress", "")
151 + HelpExampleRpc("getnewaddress", "")
154 LOCK2(cs_main, pwallet->cs_wallet);
156 // Parse the account first so we don't generate a key if there's an error
157 std::string strAccount;
158 if (!request.params[0].isNull())
159 strAccount = AccountFromValue(request.params[0]);
161 if (!pwallet->IsLocked()) {
162 pwallet->TopUpKeyPool();
165 // Generate a new key that is added to wallet
166 CPubKey newKey;
167 if (!pwallet->GetKeyFromPool(newKey)) {
168 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
170 CKeyID keyID = newKey.GetID();
172 pwallet->SetAddressBook(keyID, strAccount, "receive");
174 return EncodeDestination(keyID);
178 CTxDestination GetAccountAddress(CWallet* const pwallet, std::string strAccount, bool bForceNew=false)
180 CPubKey pubKey;
181 if (!pwallet->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
182 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
185 return pubKey.GetID();
188 UniValue getaccountaddress(const JSONRPCRequest& request)
190 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
191 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
192 return NullUniValue;
195 if (request.fHelp || request.params.size() != 1)
196 throw std::runtime_error(
197 "getaccountaddress \"account\"\n"
198 "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
199 "\nArguments:\n"
200 "1. \"account\" (string, required) The account name for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
201 "\nResult:\n"
202 "\"address\" (string) The account bitcoin address\n"
203 "\nExamples:\n"
204 + HelpExampleCli("getaccountaddress", "")
205 + HelpExampleCli("getaccountaddress", "\"\"")
206 + HelpExampleCli("getaccountaddress", "\"myaccount\"")
207 + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
210 LOCK2(cs_main, pwallet->cs_wallet);
212 // Parse the account first so we don't generate a key if there's an error
213 std::string strAccount = AccountFromValue(request.params[0]);
215 UniValue ret(UniValue::VSTR);
217 ret = EncodeDestination(GetAccountAddress(pwallet, strAccount));
218 return ret;
222 UniValue getrawchangeaddress(const JSONRPCRequest& request)
224 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
225 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
226 return NullUniValue;
229 if (request.fHelp || request.params.size() > 0)
230 throw std::runtime_error(
231 "getrawchangeaddress\n"
232 "\nReturns a new Bitcoin address, for receiving change.\n"
233 "This is for use with raw transactions, NOT normal use.\n"
234 "\nResult:\n"
235 "\"address\" (string) The address\n"
236 "\nExamples:\n"
237 + HelpExampleCli("getrawchangeaddress", "")
238 + HelpExampleRpc("getrawchangeaddress", "")
241 LOCK2(cs_main, pwallet->cs_wallet);
243 if (!pwallet->IsLocked()) {
244 pwallet->TopUpKeyPool();
247 CReserveKey reservekey(pwallet);
248 CPubKey vchPubKey;
249 if (!reservekey.GetReservedKey(vchPubKey, true))
250 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
252 reservekey.KeepKey();
254 CKeyID keyID = vchPubKey.GetID();
256 return EncodeDestination(keyID);
260 UniValue setaccount(const JSONRPCRequest& request)
262 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
263 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
264 return NullUniValue;
267 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
268 throw std::runtime_error(
269 "setaccount \"address\" \"account\"\n"
270 "\nDEPRECATED. Sets the account associated with the given address.\n"
271 "\nArguments:\n"
272 "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n"
273 "2. \"account\" (string, required) The account to assign the address to.\n"
274 "\nExamples:\n"
275 + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"")
276 + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"")
279 LOCK2(cs_main, pwallet->cs_wallet);
281 CTxDestination dest = DecodeDestination(request.params[0].get_str());
282 if (!IsValidDestination(dest)) {
283 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
286 std::string strAccount;
287 if (!request.params[1].isNull())
288 strAccount = AccountFromValue(request.params[1]);
290 // Only add the account if the address is yours.
291 if (IsMine(*pwallet, dest)) {
292 // Detect when changing the account of an address that is the 'unused current key' of another account:
293 if (pwallet->mapAddressBook.count(dest)) {
294 std::string strOldAccount = pwallet->mapAddressBook[dest].name;
295 if (dest == GetAccountAddress(pwallet, strOldAccount)) {
296 GetAccountAddress(pwallet, strOldAccount, true);
299 pwallet->SetAddressBook(dest, strAccount, "receive");
301 else
302 throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
304 return NullUniValue;
308 UniValue getaccount(const JSONRPCRequest& request)
310 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
311 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
312 return NullUniValue;
315 if (request.fHelp || request.params.size() != 1)
316 throw std::runtime_error(
317 "getaccount \"address\"\n"
318 "\nDEPRECATED. Returns the account associated with the given address.\n"
319 "\nArguments:\n"
320 "1. \"address\" (string, required) The bitcoin address for account lookup.\n"
321 "\nResult:\n"
322 "\"accountname\" (string) the account address\n"
323 "\nExamples:\n"
324 + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
325 + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
328 LOCK2(cs_main, pwallet->cs_wallet);
330 CTxDestination dest = DecodeDestination(request.params[0].get_str());
331 if (!IsValidDestination(dest)) {
332 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
335 std::string strAccount;
336 std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(dest);
337 if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) {
338 strAccount = (*mi).second.name;
340 return strAccount;
344 UniValue getaddressesbyaccount(const JSONRPCRequest& request)
346 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
347 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
348 return NullUniValue;
351 if (request.fHelp || request.params.size() != 1)
352 throw std::runtime_error(
353 "getaddressesbyaccount \"account\"\n"
354 "\nDEPRECATED. Returns the list of addresses for the given account.\n"
355 "\nArguments:\n"
356 "1. \"account\" (string, required) The account name.\n"
357 "\nResult:\n"
358 "[ (json array of string)\n"
359 " \"address\" (string) a bitcoin address associated with the given account\n"
360 " ,...\n"
361 "]\n"
362 "\nExamples:\n"
363 + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
364 + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
367 LOCK2(cs_main, pwallet->cs_wallet);
369 std::string strAccount = AccountFromValue(request.params[0]);
371 // Find all addresses that have the given account
372 UniValue ret(UniValue::VARR);
373 for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
374 const CTxDestination& dest = item.first;
375 const std::string& strName = item.second.name;
376 if (strName == strAccount) {
377 ret.push_back(EncodeDestination(dest));
380 return ret;
383 static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)
385 CAmount curBalance = pwallet->GetBalance();
387 // Check amount
388 if (nValue <= 0)
389 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
391 if (nValue > curBalance)
392 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
394 if (pwallet->GetBroadcastTransactions() && !g_connman) {
395 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
398 // Parse Bitcoin address
399 CScript scriptPubKey = GetScriptForDestination(address);
401 // Create and send the transaction
402 CReserveKey reservekey(pwallet);
403 CAmount nFeeRequired;
404 std::string strError;
405 std::vector<CRecipient> vecSend;
406 int nChangePosRet = -1;
407 CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
408 vecSend.push_back(recipient);
409 if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError, coin_control)) {
410 if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
411 strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
412 throw JSONRPCError(RPC_WALLET_ERROR, strError);
414 CValidationState state;
415 if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
416 strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
417 throw JSONRPCError(RPC_WALLET_ERROR, strError);
421 UniValue sendtoaddress(const JSONRPCRequest& request)
423 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
424 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
425 return NullUniValue;
428 if (request.fHelp || request.params.size() < 2 || request.params.size() > 8)
429 throw std::runtime_error(
430 "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount replaceable conf_target \"estimate_mode\")\n"
431 "\nSend an amount to a given address.\n"
432 + HelpRequiringPassphrase(pwallet) +
433 "\nArguments:\n"
434 "1. \"address\" (string, required) The bitcoin address to send to.\n"
435 "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
436 "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
437 " This is not part of the transaction, just kept in your wallet.\n"
438 "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
439 " to which you're sending the transaction. This is not part of the \n"
440 " transaction, just kept in your wallet.\n"
441 "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
442 " The recipient will receive less bitcoins than you enter in the amount field.\n"
443 "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
444 "7. conf_target (numeric, optional) Confirmation target (in blocks)\n"
445 "8. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
446 " \"UNSET\"\n"
447 " \"ECONOMICAL\"\n"
448 " \"CONSERVATIVE\"\n"
449 "\nResult:\n"
450 "\"txid\" (string) The transaction id.\n"
451 "\nExamples:\n"
452 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
453 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
454 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
455 + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
458 ObserveSafeMode();
460 // Make sure the results are valid at least up to the most recent block
461 // the user could have gotten from another RPC command prior to now
462 pwallet->BlockUntilSyncedToCurrentChain();
464 LOCK2(cs_main, pwallet->cs_wallet);
466 CTxDestination dest = DecodeDestination(request.params[0].get_str());
467 if (!IsValidDestination(dest)) {
468 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
471 // Amount
472 CAmount nAmount = AmountFromValue(request.params[1]);
473 if (nAmount <= 0)
474 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
476 // Wallet comments
477 CWalletTx wtx;
478 if (!request.params[2].isNull() && !request.params[2].get_str().empty())
479 wtx.mapValue["comment"] = request.params[2].get_str();
480 if (!request.params[3].isNull() && !request.params[3].get_str().empty())
481 wtx.mapValue["to"] = request.params[3].get_str();
483 bool fSubtractFeeFromAmount = false;
484 if (!request.params[4].isNull()) {
485 fSubtractFeeFromAmount = request.params[4].get_bool();
488 CCoinControl coin_control;
489 if (!request.params[5].isNull()) {
490 coin_control.signalRbf = request.params[5].get_bool();
493 if (!request.params[6].isNull()) {
494 coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
497 if (!request.params[7].isNull()) {
498 if (!FeeModeFromString(request.params[7].get_str(), coin_control.m_fee_mode)) {
499 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
504 EnsureWalletIsUnlocked(pwallet);
506 SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx, coin_control);
508 return wtx.GetHash().GetHex();
511 UniValue listaddressgroupings(const JSONRPCRequest& request)
513 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
514 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
515 return NullUniValue;
518 if (request.fHelp || request.params.size() != 0)
519 throw std::runtime_error(
520 "listaddressgroupings\n"
521 "\nLists groups of addresses which have had their common ownership\n"
522 "made public by common use as inputs or as the resulting change\n"
523 "in past transactions\n"
524 "\nResult:\n"
525 "[\n"
526 " [\n"
527 " [\n"
528 " \"address\", (string) The bitcoin address\n"
529 " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
530 " \"account\" (string, optional) DEPRECATED. The account\n"
531 " ]\n"
532 " ,...\n"
533 " ]\n"
534 " ,...\n"
535 "]\n"
536 "\nExamples:\n"
537 + HelpExampleCli("listaddressgroupings", "")
538 + HelpExampleRpc("listaddressgroupings", "")
541 ObserveSafeMode();
543 // Make sure the results are valid at least up to the most recent block
544 // the user could have gotten from another RPC command prior to now
545 pwallet->BlockUntilSyncedToCurrentChain();
547 LOCK2(cs_main, pwallet->cs_wallet);
549 UniValue jsonGroupings(UniValue::VARR);
550 std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
551 for (const std::set<CTxDestination>& grouping : pwallet->GetAddressGroupings()) {
552 UniValue jsonGrouping(UniValue::VARR);
553 for (const CTxDestination& address : grouping)
555 UniValue addressInfo(UniValue::VARR);
556 addressInfo.push_back(EncodeDestination(address));
557 addressInfo.push_back(ValueFromAmount(balances[address]));
559 if (pwallet->mapAddressBook.find(address) != pwallet->mapAddressBook.end()) {
560 addressInfo.push_back(pwallet->mapAddressBook.find(address)->second.name);
563 jsonGrouping.push_back(addressInfo);
565 jsonGroupings.push_back(jsonGrouping);
567 return jsonGroupings;
570 UniValue signmessage(const JSONRPCRequest& request)
572 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
573 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
574 return NullUniValue;
577 if (request.fHelp || request.params.size() != 2)
578 throw std::runtime_error(
579 "signmessage \"address\" \"message\"\n"
580 "\nSign a message with the private key of an address"
581 + HelpRequiringPassphrase(pwallet) + "\n"
582 "\nArguments:\n"
583 "1. \"address\" (string, required) The bitcoin address to use for the private key.\n"
584 "2. \"message\" (string, required) The message to create a signature of.\n"
585 "\nResult:\n"
586 "\"signature\" (string) The signature of the message encoded in base 64\n"
587 "\nExamples:\n"
588 "\nUnlock the wallet for 30 seconds\n"
589 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
590 "\nCreate the signature\n"
591 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
592 "\nVerify the signature\n"
593 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
594 "\nAs json rpc\n"
595 + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
598 LOCK2(cs_main, pwallet->cs_wallet);
600 EnsureWalletIsUnlocked(pwallet);
602 std::string strAddress = request.params[0].get_str();
603 std::string strMessage = request.params[1].get_str();
605 CTxDestination dest = DecodeDestination(strAddress);
606 if (!IsValidDestination(dest)) {
607 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
610 const CKeyID *keyID = boost::get<CKeyID>(&dest);
611 if (!keyID) {
612 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
615 CKey key;
616 if (!pwallet->GetKey(*keyID, key)) {
617 throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
620 CHashWriter ss(SER_GETHASH, 0);
621 ss << strMessageMagic;
622 ss << strMessage;
624 std::vector<unsigned char> vchSig;
625 if (!key.SignCompact(ss.GetHash(), vchSig))
626 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
628 return EncodeBase64(vchSig.data(), vchSig.size());
631 UniValue getreceivedbyaddress(const JSONRPCRequest& request)
633 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
634 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
635 return NullUniValue;
638 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
639 throw std::runtime_error(
640 "getreceivedbyaddress \"address\" ( minconf )\n"
641 "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
642 "\nArguments:\n"
643 "1. \"address\" (string, required) The bitcoin address for transactions.\n"
644 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
645 "\nResult:\n"
646 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
647 "\nExamples:\n"
648 "\nThe amount from transactions with at least 1 confirmation\n"
649 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
650 "\nThe amount including unconfirmed transactions, zero confirmations\n"
651 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") +
652 "\nThe amount with at least 6 confirmations\n"
653 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") +
654 "\nAs a json rpc call\n"
655 + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")
658 ObserveSafeMode();
660 // Make sure the results are valid at least up to the most recent block
661 // the user could have gotten from another RPC command prior to now
662 pwallet->BlockUntilSyncedToCurrentChain();
664 LOCK2(cs_main, pwallet->cs_wallet);
666 // Bitcoin address
667 CTxDestination dest = DecodeDestination(request.params[0].get_str());
668 if (!IsValidDestination(dest)) {
669 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
671 CScript scriptPubKey = GetScriptForDestination(dest);
672 if (!IsMine(*pwallet, scriptPubKey)) {
673 throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");
676 // Minimum confirmations
677 int nMinDepth = 1;
678 if (!request.params[1].isNull())
679 nMinDepth = request.params[1].get_int();
681 // Tally
682 CAmount nAmount = 0;
683 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
684 const CWalletTx& wtx = pairWtx.second;
685 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
686 continue;
688 for (const CTxOut& txout : wtx.tx->vout)
689 if (txout.scriptPubKey == scriptPubKey)
690 if (wtx.GetDepthInMainChain() >= nMinDepth)
691 nAmount += txout.nValue;
694 return ValueFromAmount(nAmount);
698 UniValue getreceivedbyaccount(const JSONRPCRequest& request)
700 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
701 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
702 return NullUniValue;
705 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
706 throw std::runtime_error(
707 "getreceivedbyaccount \"account\" ( minconf )\n"
708 "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
709 "\nArguments:\n"
710 "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
711 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
712 "\nResult:\n"
713 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
714 "\nExamples:\n"
715 "\nAmount received by the default account with at least 1 confirmation\n"
716 + HelpExampleCli("getreceivedbyaccount", "\"\"") +
717 "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
718 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
719 "\nThe amount with at least 6 confirmations\n"
720 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
721 "\nAs a json rpc call\n"
722 + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
725 ObserveSafeMode();
727 // Make sure the results are valid at least up to the most recent block
728 // the user could have gotten from another RPC command prior to now
729 pwallet->BlockUntilSyncedToCurrentChain();
731 LOCK2(cs_main, pwallet->cs_wallet);
733 // Minimum confirmations
734 int nMinDepth = 1;
735 if (!request.params[1].isNull())
736 nMinDepth = request.params[1].get_int();
738 // Get the set of pub keys assigned to account
739 std::string strAccount = AccountFromValue(request.params[0]);
740 std::set<CTxDestination> setAddress = pwallet->GetAccountAddresses(strAccount);
742 // Tally
743 CAmount nAmount = 0;
744 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
745 const CWalletTx& wtx = pairWtx.second;
746 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
747 continue;
749 for (const CTxOut& txout : wtx.tx->vout)
751 CTxDestination address;
752 if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) {
753 if (wtx.GetDepthInMainChain() >= nMinDepth)
754 nAmount += txout.nValue;
759 return ValueFromAmount(nAmount);
763 UniValue getbalance(const JSONRPCRequest& request)
765 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
766 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
767 return NullUniValue;
770 if (request.fHelp || request.params.size() > 3)
771 throw std::runtime_error(
772 "getbalance ( \"account\" minconf include_watchonly )\n"
773 "\nIf account is not specified, returns the server's total available balance.\n"
774 "If account is specified (DEPRECATED), returns the balance in the account.\n"
775 "Note that the account \"\" is not the same as leaving the parameter out.\n"
776 "The server total may be different to the balance in the default \"\" account.\n"
777 "\nArguments:\n"
778 "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n"
779 " specific account name to find the balance associated with wallet keys in\n"
780 " a named account, or as the empty string (\"\") to find the balance\n"
781 " associated with wallet keys not in any named account, or as \"*\" to find\n"
782 " the balance associated with all wallet keys regardless of account.\n"
783 " When this option is specified, it calculates the balance in a different\n"
784 " way than when it is not specified, and which can count spends twice when\n"
785 " there are conflicting pending transactions (such as those created by\n"
786 " the bumpfee command), temporarily resulting in low or even negative\n"
787 " balances. In general, account balance calculation is not considered\n"
788 " reliable and has resulted in confusing outcomes, so it is recommended to\n"
789 " avoid passing this argument.\n"
790 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
791 "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
792 "\nResult:\n"
793 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
794 "\nExamples:\n"
795 "\nThe total amount in the wallet with 1 or more confirmations\n"
796 + HelpExampleCli("getbalance", "") +
797 "\nThe total amount in the wallet at least 6 blocks confirmed\n"
798 + HelpExampleCli("getbalance", "\"*\" 6") +
799 "\nAs a json rpc call\n"
800 + HelpExampleRpc("getbalance", "\"*\", 6")
803 ObserveSafeMode();
805 // Make sure the results are valid at least up to the most recent block
806 // the user could have gotten from another RPC command prior to now
807 pwallet->BlockUntilSyncedToCurrentChain();
809 LOCK2(cs_main, pwallet->cs_wallet);
811 const UniValue& account_value = request.params[0];
812 const UniValue& minconf = request.params[1];
813 const UniValue& include_watchonly = request.params[2];
815 if (account_value.isNull()) {
816 if (!minconf.isNull()) {
817 throw JSONRPCError(RPC_INVALID_PARAMETER,
818 "getbalance minconf option is only currently supported if an account is specified");
820 if (!include_watchonly.isNull()) {
821 throw JSONRPCError(RPC_INVALID_PARAMETER,
822 "getbalance include_watchonly option is only currently supported if an account is specified");
824 return ValueFromAmount(pwallet->GetBalance());
827 const std::string& account_param = account_value.get_str();
828 const std::string* account = account_param != "*" ? &account_param : nullptr;
830 int nMinDepth = 1;
831 if (!minconf.isNull())
832 nMinDepth = minconf.get_int();
833 isminefilter filter = ISMINE_SPENDABLE;
834 if(!include_watchonly.isNull())
835 if(include_watchonly.get_bool())
836 filter = filter | ISMINE_WATCH_ONLY;
838 return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account));
841 UniValue getunconfirmedbalance(const JSONRPCRequest &request)
843 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
844 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
845 return NullUniValue;
848 if (request.fHelp || request.params.size() > 0)
849 throw std::runtime_error(
850 "getunconfirmedbalance\n"
851 "Returns the server's total unconfirmed balance\n");
853 ObserveSafeMode();
855 // Make sure the results are valid at least up to the most recent block
856 // the user could have gotten from another RPC command prior to now
857 pwallet->BlockUntilSyncedToCurrentChain();
859 LOCK2(cs_main, pwallet->cs_wallet);
861 return ValueFromAmount(pwallet->GetUnconfirmedBalance());
865 UniValue movecmd(const JSONRPCRequest& request)
867 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
868 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
869 return NullUniValue;
872 if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
873 throw std::runtime_error(
874 "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
875 "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
876 "\nArguments:\n"
877 "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
878 "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
879 "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
880 "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n"
881 "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
882 "\nResult:\n"
883 "true|false (boolean) true if successful.\n"
884 "\nExamples:\n"
885 "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
886 + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
887 "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
888 + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
889 "\nAs a json rpc call\n"
890 + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
893 ObserveSafeMode();
894 LOCK2(cs_main, pwallet->cs_wallet);
896 std::string strFrom = AccountFromValue(request.params[0]);
897 std::string strTo = AccountFromValue(request.params[1]);
898 CAmount nAmount = AmountFromValue(request.params[2]);
899 if (nAmount <= 0)
900 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
901 if (!request.params[3].isNull())
902 // unused parameter, used to be nMinDepth, keep type-checking it though
903 (void)request.params[3].get_int();
904 std::string strComment;
905 if (!request.params[4].isNull())
906 strComment = request.params[4].get_str();
908 if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) {
909 throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
912 return true;
916 UniValue sendfrom(const JSONRPCRequest& request)
918 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
919 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
920 return NullUniValue;
923 if (request.fHelp || request.params.size() < 3 || request.params.size() > 6)
924 throw std::runtime_error(
925 "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
926 "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address."
927 + HelpRequiringPassphrase(pwallet) + "\n"
928 "\nArguments:\n"
929 "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
930 " Specifying an account does not influence coin selection, but it does associate the newly created\n"
931 " transaction with the account, so the account's balance computation and transaction history can reflect\n"
932 " the spend.\n"
933 "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\n"
934 "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
935 "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
936 "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
937 " This is not part of the transaction, just kept in your wallet.\n"
938 "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
939 " to which you're sending the transaction. This is not part of the transaction, \n"
940 " it is just kept in your wallet.\n"
941 "\nResult:\n"
942 "\"txid\" (string) The transaction id.\n"
943 "\nExamples:\n"
944 "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
945 + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
946 "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
947 + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
948 "\nAs a json rpc call\n"
949 + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
952 ObserveSafeMode();
954 // Make sure the results are valid at least up to the most recent block
955 // the user could have gotten from another RPC command prior to now
956 pwallet->BlockUntilSyncedToCurrentChain();
958 LOCK2(cs_main, pwallet->cs_wallet);
960 std::string strAccount = AccountFromValue(request.params[0]);
961 CTxDestination dest = DecodeDestination(request.params[1].get_str());
962 if (!IsValidDestination(dest)) {
963 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
965 CAmount nAmount = AmountFromValue(request.params[2]);
966 if (nAmount <= 0)
967 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
968 int nMinDepth = 1;
969 if (!request.params[3].isNull())
970 nMinDepth = request.params[3].get_int();
972 CWalletTx wtx;
973 wtx.strFromAccount = strAccount;
974 if (!request.params[4].isNull() && !request.params[4].get_str().empty())
975 wtx.mapValue["comment"] = request.params[4].get_str();
976 if (!request.params[5].isNull() && !request.params[5].get_str().empty())
977 wtx.mapValue["to"] = request.params[5].get_str();
979 EnsureWalletIsUnlocked(pwallet);
981 // Check funds
982 CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
983 if (nAmount > nBalance)
984 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
986 CCoinControl no_coin_control; // This is a deprecated API
987 SendMoney(pwallet, dest, nAmount, false, wtx, no_coin_control);
989 return wtx.GetHash().GetHex();
993 UniValue sendmany(const JSONRPCRequest& request)
995 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
996 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
997 return NullUniValue;
1000 if (request.fHelp || request.params.size() < 2 || request.params.size() > 8)
1001 throw std::runtime_error(
1002 "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] replaceable conf_target \"estimate_mode\")\n"
1003 "\nSend multiple times. Amounts are double-precision floating point numbers."
1004 + HelpRequiringPassphrase(pwallet) + "\n"
1005 "\nArguments:\n"
1006 "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
1007 "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
1008 " {\n"
1009 " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n"
1010 " ,...\n"
1011 " }\n"
1012 "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
1013 "4. \"comment\" (string, optional) A comment\n"
1014 "5. subtractfeefrom (array, optional) A json array with addresses.\n"
1015 " The fee will be equally deducted from the amount of each selected address.\n"
1016 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
1017 " If no addresses are specified here, the sender pays the fee.\n"
1018 " [\n"
1019 " \"address\" (string) Subtract fee from this address\n"
1020 " ,...\n"
1021 " ]\n"
1022 "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
1023 "7. conf_target (numeric, optional) Confirmation target (in blocks)\n"
1024 "8. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
1025 " \"UNSET\"\n"
1026 " \"ECONOMICAL\"\n"
1027 " \"CONSERVATIVE\"\n"
1028 "\nResult:\n"
1029 "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
1030 " the number of addresses.\n"
1031 "\nExamples:\n"
1032 "\nSend two amounts to two different addresses:\n"
1033 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
1034 "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
1035 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
1036 "\nSend two amounts to two different addresses, subtract fee from amount:\n"
1037 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
1038 "\nAs a json rpc call\n"
1039 + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
1042 ObserveSafeMode();
1044 // Make sure the results are valid at least up to the most recent block
1045 // the user could have gotten from another RPC command prior to now
1046 pwallet->BlockUntilSyncedToCurrentChain();
1048 LOCK2(cs_main, pwallet->cs_wallet);
1050 if (pwallet->GetBroadcastTransactions() && !g_connman) {
1051 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
1054 std::string strAccount = AccountFromValue(request.params[0]);
1055 UniValue sendTo = request.params[1].get_obj();
1056 int nMinDepth = 1;
1057 if (!request.params[2].isNull())
1058 nMinDepth = request.params[2].get_int();
1060 CWalletTx wtx;
1061 wtx.strFromAccount = strAccount;
1062 if (!request.params[3].isNull() && !request.params[3].get_str().empty())
1063 wtx.mapValue["comment"] = request.params[3].get_str();
1065 UniValue subtractFeeFromAmount(UniValue::VARR);
1066 if (!request.params[4].isNull())
1067 subtractFeeFromAmount = request.params[4].get_array();
1069 CCoinControl coin_control;
1070 if (!request.params[5].isNull()) {
1071 coin_control.signalRbf = request.params[5].get_bool();
1074 if (!request.params[6].isNull()) {
1075 coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
1078 if (!request.params[7].isNull()) {
1079 if (!FeeModeFromString(request.params[7].get_str(), coin_control.m_fee_mode)) {
1080 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
1084 std::set<CTxDestination> destinations;
1085 std::vector<CRecipient> vecSend;
1087 CAmount totalAmount = 0;
1088 std::vector<std::string> keys = sendTo.getKeys();
1089 for (const std::string& name_ : keys) {
1090 CTxDestination dest = DecodeDestination(name_);
1091 if (!IsValidDestination(dest)) {
1092 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_);
1095 if (destinations.count(dest)) {
1096 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
1098 destinations.insert(dest);
1100 CScript scriptPubKey = GetScriptForDestination(dest);
1101 CAmount nAmount = AmountFromValue(sendTo[name_]);
1102 if (nAmount <= 0)
1103 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
1104 totalAmount += nAmount;
1106 bool fSubtractFeeFromAmount = false;
1107 for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) {
1108 const UniValue& addr = subtractFeeFromAmount[idx];
1109 if (addr.get_str() == name_)
1110 fSubtractFeeFromAmount = true;
1113 CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
1114 vecSend.push_back(recipient);
1117 EnsureWalletIsUnlocked(pwallet);
1119 // Check funds
1120 CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
1121 if (totalAmount > nBalance)
1122 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
1124 // Send
1125 CReserveKey keyChange(pwallet);
1126 CAmount nFeeRequired = 0;
1127 int nChangePosRet = -1;
1128 std::string strFailReason;
1129 bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason, coin_control);
1130 if (!fCreated)
1131 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
1132 CValidationState state;
1133 if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
1134 strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
1135 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
1138 return wtx.GetHash().GetHex();
1141 // Defined in rpc/misc.cpp
1142 extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params);
1144 UniValue addmultisigaddress(const JSONRPCRequest& request)
1146 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1147 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1148 return NullUniValue;
1151 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
1153 std::string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1154 "\nAdd a nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup.\n"
1155 "Each key is a Bitcoin address or hex-encoded public key.\n"
1156 "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1158 "\nArguments:\n"
1159 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1160 "2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
1161 " [\n"
1162 " \"address\" (string) bitcoin address or hex-encoded public key\n"
1163 " ...,\n"
1164 " ]\n"
1165 "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
1167 "\nResult:\n"
1168 "\"address\" (string) A bitcoin address associated with the keys.\n"
1170 "\nExamples:\n"
1171 "\nAdd a multisig address from 2 addresses\n"
1172 + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
1173 "\nAs json rpc call\n"
1174 + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
1176 throw std::runtime_error(msg);
1179 LOCK2(cs_main, pwallet->cs_wallet);
1181 std::string strAccount;
1182 if (!request.params[2].isNull())
1183 strAccount = AccountFromValue(request.params[2]);
1185 // Construct using pay-to-script-hash:
1186 CScript inner = _createmultisig_redeemScript(pwallet, request.params);
1187 CScriptID innerID(inner);
1188 pwallet->AddCScript(inner);
1190 pwallet->SetAddressBook(innerID, strAccount, "send");
1191 return EncodeDestination(innerID);
1194 class Witnessifier : public boost::static_visitor<bool>
1196 public:
1197 CWallet * const pwallet;
1198 CTxDestination result;
1199 bool already_witness;
1201 explicit Witnessifier(CWallet *_pwallet) : pwallet(_pwallet), already_witness(false) {}
1203 bool operator()(const CKeyID &keyID) {
1204 if (pwallet) {
1205 CScript basescript = GetScriptForDestination(keyID);
1206 CScript witscript = GetScriptForWitness(basescript);
1207 SignatureData sigs;
1208 // This check is to make sure that the script we created can actually be solved for and signed by us
1209 // if we were to have the private keys. This is just to make sure that the script is valid and that,
1210 // if found in a transaction, we would still accept and relay that transaction.
1211 if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) ||
1212 !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
1213 return false;
1215 return ExtractDestination(witscript, result);
1217 return false;
1220 bool operator()(const CScriptID &scriptID) {
1221 CScript subscript;
1222 if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
1223 int witnessversion;
1224 std::vector<unsigned char> witprog;
1225 if (subscript.IsWitnessProgram(witnessversion, witprog)) {
1226 ExtractDestination(subscript, result);
1227 already_witness = true;
1228 return true;
1230 CScript witscript = GetScriptForWitness(subscript);
1231 SignatureData sigs;
1232 // This check is to make sure that the script we created can actually be solved for and signed by us
1233 // if we were to have the private keys. This is just to make sure that the script is valid and that,
1234 // if found in a transaction, we would still accept and relay that transaction.
1235 if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) ||
1236 !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
1237 return false;
1239 return ExtractDestination(witscript, result);
1241 return false;
1244 bool operator()(const WitnessV0KeyHash& id)
1246 already_witness = true;
1247 result = id;
1248 return true;
1251 bool operator()(const WitnessV0ScriptHash& id)
1253 already_witness = true;
1254 result = id;
1255 return true;
1258 template<typename T>
1259 bool operator()(const T& dest) { return false; }
1262 UniValue addwitnessaddress(const JSONRPCRequest& request)
1264 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1265 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1266 return NullUniValue;
1269 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1271 std::string msg = "addwitnessaddress \"address\" ( p2sh )\n"
1272 "\nAdd a witness address for a script (with pubkey or redeemscript known). Requires a new wallet backup.\n"
1273 "It returns the witness script.\n"
1275 "\nArguments:\n"
1276 "1. \"address\" (string, required) An address known to the wallet\n"
1277 "2. p2sh (bool, optional, default=true) Embed inside P2SH\n"
1279 "\nResult:\n"
1280 "\"witnessaddress\", (string) The value of the new address (P2SH or BIP173).\n"
1281 "}\n"
1283 throw std::runtime_error(msg);
1287 LOCK(cs_main);
1288 if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !gArgs.GetBoolArg("-walletprematurewitness", false)) {
1289 throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network");
1293 CTxDestination dest = DecodeDestination(request.params[0].get_str());
1294 if (!IsValidDestination(dest)) {
1295 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
1298 bool p2sh = true;
1299 if (!request.params[1].isNull()) {
1300 p2sh = request.params[1].get_bool();
1303 Witnessifier w(pwallet);
1304 bool ret = boost::apply_visitor(w, dest);
1305 if (!ret) {
1306 throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed");
1309 CScript witprogram = GetScriptForDestination(w.result);
1311 if (p2sh) {
1312 w.result = CScriptID(witprogram);
1315 if (w.already_witness) {
1316 if (!(dest == w.result)) {
1317 throw JSONRPCError(RPC_WALLET_ERROR, "Cannot convert between witness address types");
1319 } else {
1320 pwallet->AddCScript(witprogram);
1321 pwallet->SetAddressBook(w.result, "", "receive");
1324 return EncodeDestination(w.result);
1327 struct tallyitem
1329 CAmount nAmount;
1330 int nConf;
1331 std::vector<uint256> txids;
1332 bool fIsWatchonly;
1333 tallyitem()
1335 nAmount = 0;
1336 nConf = std::numeric_limits<int>::max();
1337 fIsWatchonly = false;
1341 UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts)
1343 // Minimum confirmations
1344 int nMinDepth = 1;
1345 if (!params[0].isNull())
1346 nMinDepth = params[0].get_int();
1348 // Whether to include empty accounts
1349 bool fIncludeEmpty = false;
1350 if (!params[1].isNull())
1351 fIncludeEmpty = params[1].get_bool();
1353 isminefilter filter = ISMINE_SPENDABLE;
1354 if(!params[2].isNull())
1355 if(params[2].get_bool())
1356 filter = filter | ISMINE_WATCH_ONLY;
1358 // Tally
1359 std::map<CTxDestination, tallyitem> mapTally;
1360 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1361 const CWalletTx& wtx = pairWtx.second;
1363 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
1364 continue;
1366 int nDepth = wtx.GetDepthInMainChain();
1367 if (nDepth < nMinDepth)
1368 continue;
1370 for (const CTxOut& txout : wtx.tx->vout)
1372 CTxDestination address;
1373 if (!ExtractDestination(txout.scriptPubKey, address))
1374 continue;
1376 isminefilter mine = IsMine(*pwallet, address);
1377 if(!(mine & filter))
1378 continue;
1380 tallyitem& item = mapTally[address];
1381 item.nAmount += txout.nValue;
1382 item.nConf = std::min(item.nConf, nDepth);
1383 item.txids.push_back(wtx.GetHash());
1384 if (mine & ISMINE_WATCH_ONLY)
1385 item.fIsWatchonly = true;
1389 // Reply
1390 UniValue ret(UniValue::VARR);
1391 std::map<std::string, tallyitem> mapAccountTally;
1392 for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
1393 const CTxDestination& dest = item.first;
1394 const std::string& strAccount = item.second.name;
1395 std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest);
1396 if (it == mapTally.end() && !fIncludeEmpty)
1397 continue;
1399 CAmount nAmount = 0;
1400 int nConf = std::numeric_limits<int>::max();
1401 bool fIsWatchonly = false;
1402 if (it != mapTally.end())
1404 nAmount = (*it).second.nAmount;
1405 nConf = (*it).second.nConf;
1406 fIsWatchonly = (*it).second.fIsWatchonly;
1409 if (fByAccounts)
1411 tallyitem& _item = mapAccountTally[strAccount];
1412 _item.nAmount += nAmount;
1413 _item.nConf = std::min(_item.nConf, nConf);
1414 _item.fIsWatchonly = fIsWatchonly;
1416 else
1418 UniValue obj(UniValue::VOBJ);
1419 if(fIsWatchonly)
1420 obj.push_back(Pair("involvesWatchonly", true));
1421 obj.push_back(Pair("address", EncodeDestination(dest)));
1422 obj.push_back(Pair("account", strAccount));
1423 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1424 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1425 if (!fByAccounts)
1426 obj.push_back(Pair("label", strAccount));
1427 UniValue transactions(UniValue::VARR);
1428 if (it != mapTally.end())
1430 for (const uint256& _item : (*it).second.txids)
1432 transactions.push_back(_item.GetHex());
1435 obj.push_back(Pair("txids", transactions));
1436 ret.push_back(obj);
1440 if (fByAccounts)
1442 for (const auto& entry : mapAccountTally)
1444 CAmount nAmount = entry.second.nAmount;
1445 int nConf = entry.second.nConf;
1446 UniValue obj(UniValue::VOBJ);
1447 if (entry.second.fIsWatchonly)
1448 obj.push_back(Pair("involvesWatchonly", true));
1449 obj.push_back(Pair("account", entry.first));
1450 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1451 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1452 ret.push_back(obj);
1456 return ret;
1459 UniValue listreceivedbyaddress(const JSONRPCRequest& request)
1461 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1462 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1463 return NullUniValue;
1466 if (request.fHelp || request.params.size() > 3)
1467 throw std::runtime_error(
1468 "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
1469 "\nList balances by receiving address.\n"
1470 "\nArguments:\n"
1471 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1472 "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1473 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1475 "\nResult:\n"
1476 "[\n"
1477 " {\n"
1478 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1479 " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1480 " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1481 " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
1482 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1483 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1484 " \"txids\": [\n"
1485 " n, (numeric) The ids of transactions received with the address \n"
1486 " ...\n"
1487 " ]\n"
1488 " }\n"
1489 " ,...\n"
1490 "]\n"
1492 "\nExamples:\n"
1493 + HelpExampleCli("listreceivedbyaddress", "")
1494 + HelpExampleCli("listreceivedbyaddress", "6 true")
1495 + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
1498 ObserveSafeMode();
1500 // Make sure the results are valid at least up to the most recent block
1501 // the user could have gotten from another RPC command prior to now
1502 pwallet->BlockUntilSyncedToCurrentChain();
1504 LOCK2(cs_main, pwallet->cs_wallet);
1506 return ListReceived(pwallet, request.params, false);
1509 UniValue listreceivedbyaccount(const JSONRPCRequest& request)
1511 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1512 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1513 return NullUniValue;
1516 if (request.fHelp || request.params.size() > 3)
1517 throw std::runtime_error(
1518 "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
1519 "\nDEPRECATED. List balances by account.\n"
1520 "\nArguments:\n"
1521 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1522 "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1523 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1525 "\nResult:\n"
1526 "[\n"
1527 " {\n"
1528 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1529 " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1530 " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1531 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1532 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1533 " }\n"
1534 " ,...\n"
1535 "]\n"
1537 "\nExamples:\n"
1538 + HelpExampleCli("listreceivedbyaccount", "")
1539 + HelpExampleCli("listreceivedbyaccount", "6 true")
1540 + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
1543 ObserveSafeMode();
1545 // Make sure the results are valid at least up to the most recent block
1546 // the user could have gotten from another RPC command prior to now
1547 pwallet->BlockUntilSyncedToCurrentChain();
1549 LOCK2(cs_main, pwallet->cs_wallet);
1551 return ListReceived(pwallet, request.params, true);
1554 static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
1556 if (IsValidDestination(dest)) {
1557 entry.push_back(Pair("address", EncodeDestination(dest)));
1562 * List transactions based on the given criteria.
1564 * @param pwallet The wallet.
1565 * @param wtx The wallet transaction.
1566 * @param strAccount The account, if any, or "*" for all.
1567 * @param nMinDepth The minimum confirmation depth.
1568 * @param fLong Whether to include the JSON version of the transaction.
1569 * @param ret The UniValue into which the result is stored.
1570 * @param filter The "is mine" filter bool.
1572 void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
1574 CAmount nFee;
1575 std::string strSentAccount;
1576 std::list<COutputEntry> listReceived;
1577 std::list<COutputEntry> listSent;
1579 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
1581 bool fAllAccounts = (strAccount == std::string("*"));
1582 bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
1584 // Sent
1585 if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1587 for (const COutputEntry& s : listSent)
1589 UniValue entry(UniValue::VOBJ);
1590 if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) {
1591 entry.push_back(Pair("involvesWatchonly", true));
1593 entry.push_back(Pair("account", strSentAccount));
1594 MaybePushAddress(entry, s.destination);
1595 entry.push_back(Pair("category", "send"));
1596 entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
1597 if (pwallet->mapAddressBook.count(s.destination)) {
1598 entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name));
1600 entry.push_back(Pair("vout", s.vout));
1601 entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1602 if (fLong)
1603 WalletTxToJSON(wtx, entry);
1604 entry.push_back(Pair("abandoned", wtx.isAbandoned()));
1605 ret.push_back(entry);
1609 // Received
1610 if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1612 for (const COutputEntry& r : listReceived)
1614 std::string account;
1615 if (pwallet->mapAddressBook.count(r.destination)) {
1616 account = pwallet->mapAddressBook[r.destination].name;
1618 if (fAllAccounts || (account == strAccount))
1620 UniValue entry(UniValue::VOBJ);
1621 if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) {
1622 entry.push_back(Pair("involvesWatchonly", true));
1624 entry.push_back(Pair("account", account));
1625 MaybePushAddress(entry, r.destination);
1626 if (wtx.IsCoinBase())
1628 if (wtx.GetDepthInMainChain() < 1)
1629 entry.push_back(Pair("category", "orphan"));
1630 else if (wtx.GetBlocksToMaturity() > 0)
1631 entry.push_back(Pair("category", "immature"));
1632 else
1633 entry.push_back(Pair("category", "generate"));
1635 else
1637 entry.push_back(Pair("category", "receive"));
1639 entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
1640 if (pwallet->mapAddressBook.count(r.destination)) {
1641 entry.push_back(Pair("label", account));
1643 entry.push_back(Pair("vout", r.vout));
1644 if (fLong)
1645 WalletTxToJSON(wtx, entry);
1646 ret.push_back(entry);
1652 void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccount, UniValue& ret)
1654 bool fAllAccounts = (strAccount == std::string("*"));
1656 if (fAllAccounts || acentry.strAccount == strAccount)
1658 UniValue entry(UniValue::VOBJ);
1659 entry.push_back(Pair("account", acentry.strAccount));
1660 entry.push_back(Pair("category", "move"));
1661 entry.push_back(Pair("time", acentry.nTime));
1662 entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1663 entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1664 entry.push_back(Pair("comment", acentry.strComment));
1665 ret.push_back(entry);
1669 UniValue listtransactions(const JSONRPCRequest& request)
1671 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1672 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1673 return NullUniValue;
1676 if (request.fHelp || request.params.size() > 4)
1677 throw std::runtime_error(
1678 "listtransactions ( \"account\" count skip include_watchonly)\n"
1679 "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1680 "\nArguments:\n"
1681 "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1682 "2. count (numeric, optional, default=10) The number of transactions to return\n"
1683 "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
1684 "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1685 "\nResult:\n"
1686 "[\n"
1687 " {\n"
1688 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
1689 " It will be \"\" for the default account.\n"
1690 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for \n"
1691 " move transactions (category = move).\n"
1692 " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1693 " transaction between accounts, and not associated with an address,\n"
1694 " transaction id or block. 'send' and 'receive' transactions are \n"
1695 " associated with an address, transaction id and block details\n"
1696 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
1697 " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1698 " and for the 'move' category for inbound funds.\n"
1699 " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
1700 " \"vout\": n, (numeric) the vout value\n"
1701 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1702 " 'send' category of transactions.\n"
1703 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1704 " 'receive' category of transactions. Negative confirmations indicate the\n"
1705 " transaction conflicts with the block chain\n"
1706 " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
1707 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1708 " category of transactions.\n"
1709 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
1710 " category of transactions.\n"
1711 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1712 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1713 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1714 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1715 " for 'send' and 'receive' category of transactions.\n"
1716 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1717 " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
1718 " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1719 " negative amounts).\n"
1720 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1721 " may be unknown for unconfirmed transactions not in the mempool\n"
1722 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1723 " 'send' category of transactions.\n"
1724 " }\n"
1725 "]\n"
1727 "\nExamples:\n"
1728 "\nList the most recent 10 transactions in the systems\n"
1729 + HelpExampleCli("listtransactions", "") +
1730 "\nList transactions 100 to 120\n"
1731 + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1732 "\nAs a json rpc call\n"
1733 + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1736 ObserveSafeMode();
1738 // Make sure the results are valid at least up to the most recent block
1739 // the user could have gotten from another RPC command prior to now
1740 pwallet->BlockUntilSyncedToCurrentChain();
1742 LOCK2(cs_main, pwallet->cs_wallet);
1744 std::string strAccount = "*";
1745 if (!request.params[0].isNull())
1746 strAccount = request.params[0].get_str();
1747 int nCount = 10;
1748 if (!request.params[1].isNull())
1749 nCount = request.params[1].get_int();
1750 int nFrom = 0;
1751 if (!request.params[2].isNull())
1752 nFrom = request.params[2].get_int();
1753 isminefilter filter = ISMINE_SPENDABLE;
1754 if(!request.params[3].isNull())
1755 if(request.params[3].get_bool())
1756 filter = filter | ISMINE_WATCH_ONLY;
1758 if (nCount < 0)
1759 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1760 if (nFrom < 0)
1761 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1763 UniValue ret(UniValue::VARR);
1765 const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;
1767 // iterate backwards until we have nCount items to return:
1768 for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1770 CWalletTx *const pwtx = (*it).second.first;
1771 if (pwtx != nullptr)
1772 ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter);
1773 CAccountingEntry *const pacentry = (*it).second.second;
1774 if (pacentry != nullptr)
1775 AcentryToJSON(*pacentry, strAccount, ret);
1777 if ((int)ret.size() >= (nCount+nFrom)) break;
1779 // ret is newest to oldest
1781 if (nFrom > (int)ret.size())
1782 nFrom = ret.size();
1783 if ((nFrom + nCount) > (int)ret.size())
1784 nCount = ret.size() - nFrom;
1786 std::vector<UniValue> arrTmp = ret.getValues();
1788 std::vector<UniValue>::iterator first = arrTmp.begin();
1789 std::advance(first, nFrom);
1790 std::vector<UniValue>::iterator last = arrTmp.begin();
1791 std::advance(last, nFrom+nCount);
1793 if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end());
1794 if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first);
1796 std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest
1798 ret.clear();
1799 ret.setArray();
1800 ret.push_backV(arrTmp);
1802 return ret;
1805 UniValue listaccounts(const JSONRPCRequest& request)
1807 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1808 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1809 return NullUniValue;
1812 if (request.fHelp || request.params.size() > 2)
1813 throw std::runtime_error(
1814 "listaccounts ( minconf include_watchonly)\n"
1815 "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1816 "\nArguments:\n"
1817 "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1818 "2. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n"
1819 "\nResult:\n"
1820 "{ (json object where keys are account names, and values are numeric balances\n"
1821 " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1822 " ...\n"
1823 "}\n"
1824 "\nExamples:\n"
1825 "\nList account balances where there at least 1 confirmation\n"
1826 + HelpExampleCli("listaccounts", "") +
1827 "\nList account balances including zero confirmation transactions\n"
1828 + HelpExampleCli("listaccounts", "0") +
1829 "\nList account balances for 6 or more confirmations\n"
1830 + HelpExampleCli("listaccounts", "6") +
1831 "\nAs json rpc call\n"
1832 + HelpExampleRpc("listaccounts", "6")
1835 ObserveSafeMode();
1837 // Make sure the results are valid at least up to the most recent block
1838 // the user could have gotten from another RPC command prior to now
1839 pwallet->BlockUntilSyncedToCurrentChain();
1841 LOCK2(cs_main, pwallet->cs_wallet);
1843 int nMinDepth = 1;
1844 if (!request.params[0].isNull())
1845 nMinDepth = request.params[0].get_int();
1846 isminefilter includeWatchonly = ISMINE_SPENDABLE;
1847 if(!request.params[1].isNull())
1848 if(request.params[1].get_bool())
1849 includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
1851 std::map<std::string, CAmount> mapAccountBalances;
1852 for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) {
1853 if (IsMine(*pwallet, entry.first) & includeWatchonly) { // This address belongs to me
1854 mapAccountBalances[entry.second.name] = 0;
1858 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1859 const CWalletTx& wtx = pairWtx.second;
1860 CAmount nFee;
1861 std::string strSentAccount;
1862 std::list<COutputEntry> listReceived;
1863 std::list<COutputEntry> listSent;
1864 int nDepth = wtx.GetDepthInMainChain();
1865 if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1866 continue;
1867 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
1868 mapAccountBalances[strSentAccount] -= nFee;
1869 for (const COutputEntry& s : listSent)
1870 mapAccountBalances[strSentAccount] -= s.amount;
1871 if (nDepth >= nMinDepth)
1873 for (const COutputEntry& r : listReceived)
1874 if (pwallet->mapAddressBook.count(r.destination)) {
1875 mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount;
1877 else
1878 mapAccountBalances[""] += r.amount;
1882 const std::list<CAccountingEntry>& acentries = pwallet->laccentries;
1883 for (const CAccountingEntry& entry : acentries)
1884 mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1886 UniValue ret(UniValue::VOBJ);
1887 for (const std::pair<std::string, CAmount>& accountBalance : mapAccountBalances) {
1888 ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1890 return ret;
1893 UniValue listsinceblock(const JSONRPCRequest& request)
1895 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1896 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1897 return NullUniValue;
1900 if (request.fHelp || request.params.size() > 4)
1901 throw std::runtime_error(
1902 "listsinceblock ( \"blockhash\" target_confirmations include_watchonly include_removed )\n"
1903 "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
1904 "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
1905 "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
1906 "\nArguments:\n"
1907 "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1908 "2. target_confirmations: (numeric, optional, 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\n"
1909 "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1910 "4. include_removed: (bool, optional, default=true) Show transactions that were removed due to a reorg in the \"removed\" array\n"
1911 " (not guaranteed to work on pruned nodes)\n"
1912 "\nResult:\n"
1913 "{\n"
1914 " \"transactions\": [\n"
1915 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1916 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
1917 " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1918 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1919 " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1920 " \"vout\" : n, (numeric) the vout value\n"
1921 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the 'send' category of transactions.\n"
1922 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1923 " When it's < 0, it means the transaction conflicted that many blocks ago.\n"
1924 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1925 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
1926 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1927 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1928 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1929 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1930 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1931 " may be unknown for unconfirmed transactions not in the mempool\n"
1932 " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n"
1933 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1934 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1935 " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1936 " ],\n"
1937 " \"removed\": [\n"
1938 " <structure is the same as \"transactions\" above, only present if include_removed=true>\n"
1939 " Note: transactions that were readded in the active chain will appear as-is in this array, and may thus have a positive confirmation count.\n"
1940 " ],\n"
1941 " \"lastblock\": \"lastblockhash\" (string) The hash of the block (target_confirmations-1) from the best block on the main chain. 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\n"
1942 "}\n"
1943 "\nExamples:\n"
1944 + HelpExampleCli("listsinceblock", "")
1945 + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1946 + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1949 ObserveSafeMode();
1951 // Make sure the results are valid at least up to the most recent block
1952 // the user could have gotten from another RPC command prior to now
1953 pwallet->BlockUntilSyncedToCurrentChain();
1955 LOCK2(cs_main, pwallet->cs_wallet);
1957 const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain.
1958 const CBlockIndex* paltindex = nullptr; // Block index of the specified block, even if it's in a deactivated chain.
1959 int target_confirms = 1;
1960 isminefilter filter = ISMINE_SPENDABLE;
1962 if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
1963 uint256 blockId;
1965 blockId.SetHex(request.params[0].get_str());
1966 BlockMap::iterator it = mapBlockIndex.find(blockId);
1967 if (it == mapBlockIndex.end()) {
1968 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1970 paltindex = pindex = it->second;
1971 if (chainActive[pindex->nHeight] != pindex) {
1972 // the block being asked for is a part of a deactivated chain;
1973 // we don't want to depend on its perceived height in the block
1974 // chain, we want to instead use the last common ancestor
1975 pindex = chainActive.FindFork(pindex);
1979 if (!request.params[1].isNull()) {
1980 target_confirms = request.params[1].get_int();
1982 if (target_confirms < 1) {
1983 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1987 if (!request.params[2].isNull() && request.params[2].get_bool()) {
1988 filter = filter | ISMINE_WATCH_ONLY;
1991 bool include_removed = (request.params[3].isNull() || request.params[3].get_bool());
1993 int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1995 UniValue transactions(UniValue::VARR);
1997 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1998 CWalletTx tx = pairWtx.second;
2000 if (depth == -1 || tx.GetDepthInMainChain() < depth) {
2001 ListTransactions(pwallet, tx, "*", 0, true, transactions, filter);
2005 // when a reorg'd block is requested, we also list any relevant transactions
2006 // in the blocks of the chain that was detached
2007 UniValue removed(UniValue::VARR);
2008 while (include_removed && paltindex && paltindex != pindex) {
2009 CBlock block;
2010 if (!ReadBlockFromDisk(block, paltindex, Params().GetConsensus())) {
2011 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
2013 for (const CTransactionRef& tx : block.vtx) {
2014 auto it = pwallet->mapWallet.find(tx->GetHash());
2015 if (it != pwallet->mapWallet.end()) {
2016 // We want all transactions regardless of confirmation count to appear here,
2017 // even negative confirmation ones, hence the big negative.
2018 ListTransactions(pwallet, it->second, "*", -100000000, true, removed, filter);
2021 paltindex = paltindex->pprev;
2024 CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
2025 uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
2027 UniValue ret(UniValue::VOBJ);
2028 ret.push_back(Pair("transactions", transactions));
2029 if (include_removed) ret.push_back(Pair("removed", removed));
2030 ret.push_back(Pair("lastblock", lastblock.GetHex()));
2032 return ret;
2035 UniValue gettransaction(const JSONRPCRequest& request)
2037 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2038 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2039 return NullUniValue;
2042 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2043 throw std::runtime_error(
2044 "gettransaction \"txid\" ( include_watchonly )\n"
2045 "\nGet detailed information about in-wallet transaction <txid>\n"
2046 "\nArguments:\n"
2047 "1. \"txid\" (string, required) The transaction id\n"
2048 "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n"
2049 "\nResult:\n"
2050 "{\n"
2051 " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
2052 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
2053 " 'send' category of transactions.\n"
2054 " \"confirmations\" : n, (numeric) The number of confirmations\n"
2055 " \"blockhash\" : \"hash\", (string) The block hash\n"
2056 " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
2057 " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
2058 " \"txid\" : \"transactionid\", (string) The transaction id.\n"
2059 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
2060 " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
2061 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
2062 " may be unknown for unconfirmed transactions not in the mempool\n"
2063 " \"details\" : [\n"
2064 " {\n"
2065 " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
2066 " \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n"
2067 " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
2068 " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
2069 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
2070 " \"vout\" : n, (numeric) the vout value\n"
2071 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
2072 " 'send' category of transactions.\n"
2073 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
2074 " 'send' category of transactions.\n"
2075 " }\n"
2076 " ,...\n"
2077 " ],\n"
2078 " \"hex\" : \"data\" (string) Raw data for transaction\n"
2079 "}\n"
2081 "\nExamples:\n"
2082 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2083 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
2084 + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2087 ObserveSafeMode();
2089 // Make sure the results are valid at least up to the most recent block
2090 // the user could have gotten from another RPC command prior to now
2091 pwallet->BlockUntilSyncedToCurrentChain();
2093 LOCK2(cs_main, pwallet->cs_wallet);
2095 uint256 hash;
2096 hash.SetHex(request.params[0].get_str());
2098 isminefilter filter = ISMINE_SPENDABLE;
2099 if(!request.params[1].isNull())
2100 if(request.params[1].get_bool())
2101 filter = filter | ISMINE_WATCH_ONLY;
2103 UniValue entry(UniValue::VOBJ);
2104 auto it = pwallet->mapWallet.find(hash);
2105 if (it == pwallet->mapWallet.end()) {
2106 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2108 const CWalletTx& wtx = it->second;
2110 CAmount nCredit = wtx.GetCredit(filter);
2111 CAmount nDebit = wtx.GetDebit(filter);
2112 CAmount nNet = nCredit - nDebit;
2113 CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
2115 entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
2116 if (wtx.IsFromMe(filter))
2117 entry.push_back(Pair("fee", ValueFromAmount(nFee)));
2119 WalletTxToJSON(wtx, entry);
2121 UniValue details(UniValue::VARR);
2122 ListTransactions(pwallet, wtx, "*", 0, false, details, filter);
2123 entry.push_back(Pair("details", details));
2125 std::string strHex = EncodeHexTx(*wtx.tx, RPCSerializationFlags());
2126 entry.push_back(Pair("hex", strHex));
2128 return entry;
2131 UniValue abandontransaction(const JSONRPCRequest& request)
2133 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2134 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2135 return NullUniValue;
2138 if (request.fHelp || request.params.size() != 1)
2139 throw std::runtime_error(
2140 "abandontransaction \"txid\"\n"
2141 "\nMark in-wallet transaction <txid> as abandoned\n"
2142 "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
2143 "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
2144 "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
2145 "It has no effect on transactions which are already conflicted or abandoned.\n"
2146 "\nArguments:\n"
2147 "1. \"txid\" (string, required) The transaction id\n"
2148 "\nResult:\n"
2149 "\nExamples:\n"
2150 + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2151 + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2154 ObserveSafeMode();
2156 // Make sure the results are valid at least up to the most recent block
2157 // the user could have gotten from another RPC command prior to now
2158 pwallet->BlockUntilSyncedToCurrentChain();
2160 LOCK2(cs_main, pwallet->cs_wallet);
2162 uint256 hash;
2163 hash.SetHex(request.params[0].get_str());
2165 if (!pwallet->mapWallet.count(hash)) {
2166 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2168 if (!pwallet->AbandonTransaction(hash)) {
2169 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment");
2172 return NullUniValue;
2176 UniValue backupwallet(const JSONRPCRequest& request)
2178 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2179 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2180 return NullUniValue;
2183 if (request.fHelp || request.params.size() != 1)
2184 throw std::runtime_error(
2185 "backupwallet \"destination\"\n"
2186 "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
2187 "\nArguments:\n"
2188 "1. \"destination\" (string) The destination directory or file\n"
2189 "\nExamples:\n"
2190 + HelpExampleCli("backupwallet", "\"backup.dat\"")
2191 + HelpExampleRpc("backupwallet", "\"backup.dat\"")
2194 // Make sure the results are valid at least up to the most recent block
2195 // the user could have gotten from another RPC command prior to now
2196 pwallet->BlockUntilSyncedToCurrentChain();
2198 LOCK2(cs_main, pwallet->cs_wallet);
2200 std::string strDest = request.params[0].get_str();
2201 if (!pwallet->BackupWallet(strDest)) {
2202 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
2205 return NullUniValue;
2209 UniValue keypoolrefill(const JSONRPCRequest& request)
2211 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2212 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2213 return NullUniValue;
2216 if (request.fHelp || request.params.size() > 1)
2217 throw std::runtime_error(
2218 "keypoolrefill ( newsize )\n"
2219 "\nFills the keypool."
2220 + HelpRequiringPassphrase(pwallet) + "\n"
2221 "\nArguments\n"
2222 "1. newsize (numeric, optional, default=100) The new keypool size\n"
2223 "\nExamples:\n"
2224 + HelpExampleCli("keypoolrefill", "")
2225 + HelpExampleRpc("keypoolrefill", "")
2228 LOCK2(cs_main, pwallet->cs_wallet);
2230 // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
2231 unsigned int kpSize = 0;
2232 if (!request.params[0].isNull()) {
2233 if (request.params[0].get_int() < 0)
2234 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
2235 kpSize = (unsigned int)request.params[0].get_int();
2238 EnsureWalletIsUnlocked(pwallet);
2239 pwallet->TopUpKeyPool(kpSize);
2241 if (pwallet->GetKeyPoolSize() < kpSize) {
2242 throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
2245 return NullUniValue;
2249 static void LockWallet(CWallet* pWallet)
2251 LOCK(pWallet->cs_wallet);
2252 pWallet->nRelockTime = 0;
2253 pWallet->Lock();
2256 UniValue walletpassphrase(const JSONRPCRequest& request)
2258 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2259 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2260 return NullUniValue;
2263 if (request.fHelp || request.params.size() != 2) {
2264 throw std::runtime_error(
2265 "walletpassphrase \"passphrase\" timeout\n"
2266 "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
2267 "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
2268 "\nArguments:\n"
2269 "1. \"passphrase\" (string, required) The wallet passphrase\n"
2270 "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
2271 "\nNote:\n"
2272 "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
2273 "time that overrides the old one.\n"
2274 "\nExamples:\n"
2275 "\nUnlock the wallet for 60 seconds\n"
2276 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
2277 "\nLock the wallet again (before 60 seconds)\n"
2278 + HelpExampleCli("walletlock", "") +
2279 "\nAs json rpc call\n"
2280 + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
2284 LOCK2(cs_main, pwallet->cs_wallet);
2286 if (request.fHelp)
2287 return true;
2288 if (!pwallet->IsCrypted()) {
2289 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2292 // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed
2293 SecureString strWalletPass;
2294 strWalletPass.reserve(100);
2295 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2296 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2297 strWalletPass = request.params[0].get_str().c_str();
2299 if (strWalletPass.length() > 0)
2301 if (!pwallet->Unlock(strWalletPass)) {
2302 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2305 else
2306 throw std::runtime_error(
2307 "walletpassphrase <passphrase> <timeout>\n"
2308 "Stores the wallet decryption key in memory for <timeout> seconds.");
2310 pwallet->TopUpKeyPool();
2312 int64_t nSleepTime = request.params[1].get_int64();
2313 pwallet->nRelockTime = GetTime() + nSleepTime;
2314 RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);
2316 return NullUniValue;
2320 UniValue walletpassphrasechange(const JSONRPCRequest& request)
2322 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2323 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2324 return NullUniValue;
2327 if (request.fHelp || request.params.size() != 2) {
2328 throw std::runtime_error(
2329 "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
2330 "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
2331 "\nArguments:\n"
2332 "1. \"oldpassphrase\" (string) The current passphrase\n"
2333 "2. \"newpassphrase\" (string) The new passphrase\n"
2334 "\nExamples:\n"
2335 + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
2336 + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
2340 LOCK2(cs_main, pwallet->cs_wallet);
2342 if (request.fHelp)
2343 return true;
2344 if (!pwallet->IsCrypted()) {
2345 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2348 // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2349 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2350 SecureString strOldWalletPass;
2351 strOldWalletPass.reserve(100);
2352 strOldWalletPass = request.params[0].get_str().c_str();
2354 SecureString strNewWalletPass;
2355 strNewWalletPass.reserve(100);
2356 strNewWalletPass = request.params[1].get_str().c_str();
2358 if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
2359 throw std::runtime_error(
2360 "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2361 "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2363 if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) {
2364 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2367 return NullUniValue;
2371 UniValue walletlock(const JSONRPCRequest& request)
2373 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2374 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2375 return NullUniValue;
2378 if (request.fHelp || request.params.size() != 0) {
2379 throw std::runtime_error(
2380 "walletlock\n"
2381 "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2382 "After calling this method, you will need to call walletpassphrase again\n"
2383 "before being able to call any methods which require the wallet to be unlocked.\n"
2384 "\nExamples:\n"
2385 "\nSet the passphrase for 2 minutes to perform a transaction\n"
2386 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2387 "\nPerform a send (requires passphrase set)\n"
2388 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
2389 "\nClear the passphrase since we are done before 2 minutes is up\n"
2390 + HelpExampleCli("walletlock", "") +
2391 "\nAs json rpc call\n"
2392 + HelpExampleRpc("walletlock", "")
2396 LOCK2(cs_main, pwallet->cs_wallet);
2398 if (request.fHelp)
2399 return true;
2400 if (!pwallet->IsCrypted()) {
2401 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
2404 pwallet->Lock();
2405 pwallet->nRelockTime = 0;
2407 return NullUniValue;
2411 UniValue encryptwallet(const JSONRPCRequest& request)
2413 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2414 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2415 return NullUniValue;
2418 if (request.fHelp || request.params.size() != 1) {
2419 throw std::runtime_error(
2420 "encryptwallet \"passphrase\"\n"
2421 "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2422 "After this, any calls that interact with private keys such as sending or signing \n"
2423 "will require the passphrase to be set prior the making these calls.\n"
2424 "Use the walletpassphrase call for this, and then walletlock call.\n"
2425 "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2426 "Note that this will shutdown the server.\n"
2427 "\nArguments:\n"
2428 "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2429 "\nExamples:\n"
2430 "\nEncrypt your wallet\n"
2431 + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2432 "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
2433 + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2434 "\nNow we can do something like sign\n"
2435 + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
2436 "\nNow lock the wallet again by removing the passphrase\n"
2437 + HelpExampleCli("walletlock", "") +
2438 "\nAs a json rpc call\n"
2439 + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2443 LOCK2(cs_main, pwallet->cs_wallet);
2445 if (request.fHelp)
2446 return true;
2447 if (pwallet->IsCrypted()) {
2448 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
2451 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2452 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2453 SecureString strWalletPass;
2454 strWalletPass.reserve(100);
2455 strWalletPass = request.params[0].get_str().c_str();
2457 if (strWalletPass.length() < 1)
2458 throw std::runtime_error(
2459 "encryptwallet <passphrase>\n"
2460 "Encrypts the wallet with <passphrase>.");
2462 if (!pwallet->EncryptWallet(strWalletPass)) {
2463 throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
2466 // BDB seems to have a bad habit of writing old data into
2467 // slack space in .dat files; that is bad if the old data is
2468 // unencrypted private keys. So:
2469 StartShutdown();
2470 return "wallet encrypted; Bitcoin server stopping, restart to run with encrypted wallet. The keypool has been flushed and a new HD seed was generated (if you are using HD). You need to make a new backup.";
2473 UniValue lockunspent(const JSONRPCRequest& request)
2475 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2476 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2477 return NullUniValue;
2480 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2481 throw std::runtime_error(
2482 "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
2483 "\nUpdates list of temporarily unspendable outputs.\n"
2484 "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2485 "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2486 "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
2487 "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2488 "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2489 "Also see the listunspent call\n"
2490 "\nArguments:\n"
2491 "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2492 "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n"
2493 " [ (json array of json objects)\n"
2494 " {\n"
2495 " \"txid\":\"id\", (string) The transaction id\n"
2496 " \"vout\": n (numeric) The output number\n"
2497 " }\n"
2498 " ,...\n"
2499 " ]\n"
2501 "\nResult:\n"
2502 "true|false (boolean) Whether the command was successful or not\n"
2504 "\nExamples:\n"
2505 "\nList the unspent transactions\n"
2506 + HelpExampleCli("listunspent", "") +
2507 "\nLock an unspent transaction\n"
2508 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2509 "\nList the locked transactions\n"
2510 + HelpExampleCli("listlockunspent", "") +
2511 "\nUnlock the transaction again\n"
2512 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2513 "\nAs a json rpc call\n"
2514 + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2517 // Make sure the results are valid at least up to the most recent block
2518 // the user could have gotten from another RPC command prior to now
2519 pwallet->BlockUntilSyncedToCurrentChain();
2521 LOCK2(cs_main, pwallet->cs_wallet);
2523 RPCTypeCheckArgument(request.params[0], UniValue::VBOOL);
2525 bool fUnlock = request.params[0].get_bool();
2527 if (request.params[1].isNull()) {
2528 if (fUnlock)
2529 pwallet->UnlockAllCoins();
2530 return true;
2533 RPCTypeCheckArgument(request.params[1], UniValue::VARR);
2535 const UniValue& output_params = request.params[1];
2537 // Create and validate the COutPoints first.
2539 std::vector<COutPoint> outputs;
2540 outputs.reserve(output_params.size());
2542 for (unsigned int idx = 0; idx < output_params.size(); idx++) {
2543 const UniValue& o = output_params[idx].get_obj();
2545 RPCTypeCheckObj(o,
2547 {"txid", UniValueType(UniValue::VSTR)},
2548 {"vout", UniValueType(UniValue::VNUM)},
2551 const std::string& txid = find_value(o, "txid").get_str();
2552 if (!IsHex(txid)) {
2553 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
2556 const int nOutput = find_value(o, "vout").get_int();
2557 if (nOutput < 0) {
2558 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
2561 const COutPoint outpt(uint256S(txid), nOutput);
2563 const auto it = pwallet->mapWallet.find(outpt.hash);
2564 if (it == pwallet->mapWallet.end()) {
2565 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, unknown transaction");
2568 const CWalletTx& trans = it->second;
2570 if (outpt.n >= trans.tx->vout.size()) {
2571 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds");
2574 if (pwallet->IsSpent(outpt.hash, outpt.n)) {
2575 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output");
2578 const bool is_locked = pwallet->IsLockedCoin(outpt.hash, outpt.n);
2580 if (fUnlock && !is_locked) {
2581 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output");
2584 if (!fUnlock && is_locked) {
2585 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output already locked");
2588 outputs.push_back(outpt);
2591 // Atomically set (un)locked status for the outputs.
2592 for (const COutPoint& outpt : outputs) {
2593 if (fUnlock) pwallet->UnlockCoin(outpt);
2594 else pwallet->LockCoin(outpt);
2597 return true;
2600 UniValue listlockunspent(const JSONRPCRequest& request)
2602 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2603 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2604 return NullUniValue;
2607 if (request.fHelp || request.params.size() > 0)
2608 throw std::runtime_error(
2609 "listlockunspent\n"
2610 "\nReturns list of temporarily unspendable outputs.\n"
2611 "See the lockunspent call to lock and unlock transactions for spending.\n"
2612 "\nResult:\n"
2613 "[\n"
2614 " {\n"
2615 " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
2616 " \"vout\" : n (numeric) The vout value\n"
2617 " }\n"
2618 " ,...\n"
2619 "]\n"
2620 "\nExamples:\n"
2621 "\nList the unspent transactions\n"
2622 + HelpExampleCli("listunspent", "") +
2623 "\nLock an unspent transaction\n"
2624 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2625 "\nList the locked transactions\n"
2626 + HelpExampleCli("listlockunspent", "") +
2627 "\nUnlock the transaction again\n"
2628 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2629 "\nAs a json rpc call\n"
2630 + HelpExampleRpc("listlockunspent", "")
2633 ObserveSafeMode();
2634 LOCK2(cs_main, pwallet->cs_wallet);
2636 std::vector<COutPoint> vOutpts;
2637 pwallet->ListLockedCoins(vOutpts);
2639 UniValue ret(UniValue::VARR);
2641 for (COutPoint &outpt : vOutpts) {
2642 UniValue o(UniValue::VOBJ);
2644 o.push_back(Pair("txid", outpt.hash.GetHex()));
2645 o.push_back(Pair("vout", (int)outpt.n));
2646 ret.push_back(o);
2649 return ret;
2652 UniValue settxfee(const JSONRPCRequest& request)
2654 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2655 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2656 return NullUniValue;
2659 if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
2660 throw std::runtime_error(
2661 "settxfee amount\n"
2662 "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
2663 "\nArguments:\n"
2664 "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n"
2665 "\nResult\n"
2666 "true|false (boolean) Returns true if successful\n"
2667 "\nExamples:\n"
2668 + HelpExampleCli("settxfee", "0.00001")
2669 + HelpExampleRpc("settxfee", "0.00001")
2672 LOCK2(cs_main, pwallet->cs_wallet);
2674 // Amount
2675 CAmount nAmount = AmountFromValue(request.params[0]);
2677 payTxFee = CFeeRate(nAmount, 1000);
2678 return true;
2681 UniValue getwalletinfo(const JSONRPCRequest& request)
2683 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2684 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2685 return NullUniValue;
2688 if (request.fHelp || request.params.size() != 0)
2689 throw std::runtime_error(
2690 "getwalletinfo\n"
2691 "Returns an object containing various wallet state info.\n"
2692 "\nResult:\n"
2693 "{\n"
2694 " \"walletname\": xxxxx, (string) the wallet name\n"
2695 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
2696 " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2697 " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2698 " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
2699 " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
2700 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n"
2701 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated (only counts external keys)\n"
2702 " \"keypoolsize_hd_internal\": xxxx, (numeric) 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)\n"
2703 " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n"
2704 " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
2705 " \"hdmasterkeyid\": \"<hash160>\" (string) the Hash160 of the HD master pubkey\n"
2706 "}\n"
2707 "\nExamples:\n"
2708 + HelpExampleCli("getwalletinfo", "")
2709 + HelpExampleRpc("getwalletinfo", "")
2712 ObserveSafeMode();
2714 // Make sure the results are valid at least up to the most recent block
2715 // the user could have gotten from another RPC command prior to now
2716 pwallet->BlockUntilSyncedToCurrentChain();
2718 LOCK2(cs_main, pwallet->cs_wallet);
2720 UniValue obj(UniValue::VOBJ);
2722 size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
2723 obj.push_back(Pair("walletname", pwallet->GetName()));
2724 obj.push_back(Pair("walletversion", pwallet->GetVersion()));
2725 obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance())));
2726 obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance())));
2727 obj.push_back(Pair("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance())));
2728 obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size()));
2729 obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime()));
2730 obj.push_back(Pair("keypoolsize", (int64_t)kpExternalSize));
2731 CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID;
2732 if (!masterKeyID.IsNull() && pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) {
2733 obj.push_back(Pair("keypoolsize_hd_internal", (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize)));
2735 if (pwallet->IsCrypted()) {
2736 obj.push_back(Pair("unlocked_until", pwallet->nRelockTime));
2738 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
2739 if (!masterKeyID.IsNull())
2740 obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex()));
2741 return obj;
2744 UniValue listwallets(const JSONRPCRequest& request)
2746 if (request.fHelp || request.params.size() != 0)
2747 throw std::runtime_error(
2748 "listwallets\n"
2749 "Returns a list of currently loaded wallets.\n"
2750 "For full information on the wallet, use \"getwalletinfo\"\n"
2751 "\nResult:\n"
2752 "[ (json array of strings)\n"
2753 " \"walletname\" (string) the wallet name\n"
2754 " ...\n"
2755 "]\n"
2756 "\nExamples:\n"
2757 + HelpExampleCli("listwallets", "")
2758 + HelpExampleRpc("listwallets", "")
2761 UniValue obj(UniValue::VARR);
2763 for (CWalletRef pwallet : vpwallets) {
2765 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2766 return NullUniValue;
2769 LOCK(pwallet->cs_wallet);
2771 obj.push_back(pwallet->GetName());
2774 return obj;
2777 UniValue resendwallettransactions(const JSONRPCRequest& request)
2779 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2780 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2781 return NullUniValue;
2784 if (request.fHelp || request.params.size() != 0)
2785 throw std::runtime_error(
2786 "resendwallettransactions\n"
2787 "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2788 "Intended only for testing; the wallet code periodically re-broadcasts\n"
2789 "automatically.\n"
2790 "Returns an RPC error if -walletbroadcast is set to false.\n"
2791 "Returns array of transaction ids that were re-broadcast.\n"
2794 if (!g_connman)
2795 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
2797 LOCK2(cs_main, pwallet->cs_wallet);
2799 if (!pwallet->GetBroadcastTransactions()) {
2800 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast");
2803 std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get());
2804 UniValue result(UniValue::VARR);
2805 for (const uint256& txid : txids)
2807 result.push_back(txid.ToString());
2809 return result;
2812 UniValue listunspent(const JSONRPCRequest& request)
2814 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2815 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2816 return NullUniValue;
2819 if (request.fHelp || request.params.size() > 5)
2820 throw std::runtime_error(
2821 "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
2822 "\nReturns array of unspent transaction outputs\n"
2823 "with between minconf and maxconf (inclusive) confirmations.\n"
2824 "Optionally filter to only include txouts paid to specified addresses.\n"
2825 "\nArguments:\n"
2826 "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
2827 "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2828 "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
2829 " [\n"
2830 " \"address\" (string) bitcoin address\n"
2831 " ,...\n"
2832 " ]\n"
2833 "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
2834 " See description of \"safe\" attribute below.\n"
2835 "5. query_options (json, optional) JSON with query options\n"
2836 " {\n"
2837 " \"minimumAmount\" (numeric or string, default=0) Minimum value of each UTXO in " + CURRENCY_UNIT + "\n"
2838 " \"maximumAmount\" (numeric or string, default=unlimited) Maximum value of each UTXO in " + CURRENCY_UNIT + "\n"
2839 " \"maximumCount\" (numeric or string, default=unlimited) Maximum number of UTXOs\n"
2840 " \"minimumSumAmount\" (numeric or string, default=unlimited) Minimum sum value of all UTXOs in " + CURRENCY_UNIT + "\n"
2841 " }\n"
2842 "\nResult\n"
2843 "[ (array of json object)\n"
2844 " {\n"
2845 " \"txid\" : \"txid\", (string) the transaction id \n"
2846 " \"vout\" : n, (numeric) the vout value\n"
2847 " \"address\" : \"address\", (string) the bitcoin address\n"
2848 " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
2849 " \"scriptPubKey\" : \"key\", (string) the script key\n"
2850 " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
2851 " \"confirmations\" : n, (numeric) The number of confirmations\n"
2852 " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
2853 " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
2854 " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
2855 " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n"
2856 " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
2857 " and are not eligible for spending by fundrawtransaction and sendtoaddress.\n"
2858 " }\n"
2859 " ,...\n"
2860 "]\n"
2862 "\nExamples\n"
2863 + HelpExampleCli("listunspent", "")
2864 + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2865 + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2866 + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
2867 + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
2870 ObserveSafeMode();
2872 int nMinDepth = 1;
2873 if (!request.params[0].isNull()) {
2874 RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
2875 nMinDepth = request.params[0].get_int();
2878 int nMaxDepth = 9999999;
2879 if (!request.params[1].isNull()) {
2880 RPCTypeCheckArgument(request.params[1], UniValue::VNUM);
2881 nMaxDepth = request.params[1].get_int();
2884 std::set<CTxDestination> destinations;
2885 if (!request.params[2].isNull()) {
2886 RPCTypeCheckArgument(request.params[2], UniValue::VARR);
2887 UniValue inputs = request.params[2].get_array();
2888 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
2889 const UniValue& input = inputs[idx];
2890 CTxDestination dest = DecodeDestination(input.get_str());
2891 if (!IsValidDestination(dest)) {
2892 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + input.get_str());
2894 if (!destinations.insert(dest).second) {
2895 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
2900 bool include_unsafe = true;
2901 if (!request.params[3].isNull()) {
2902 RPCTypeCheckArgument(request.params[3], UniValue::VBOOL);
2903 include_unsafe = request.params[3].get_bool();
2906 CAmount nMinimumAmount = 0;
2907 CAmount nMaximumAmount = MAX_MONEY;
2908 CAmount nMinimumSumAmount = MAX_MONEY;
2909 uint64_t nMaximumCount = 0;
2911 if (!request.params[4].isNull()) {
2912 const UniValue& options = request.params[4].get_obj();
2914 if (options.exists("minimumAmount"))
2915 nMinimumAmount = AmountFromValue(options["minimumAmount"]);
2917 if (options.exists("maximumAmount"))
2918 nMaximumAmount = AmountFromValue(options["maximumAmount"]);
2920 if (options.exists("minimumSumAmount"))
2921 nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
2923 if (options.exists("maximumCount"))
2924 nMaximumCount = options["maximumCount"].get_int64();
2927 // Make sure the results are valid at least up to the most recent block
2928 // the user could have gotten from another RPC command prior to now
2929 pwallet->BlockUntilSyncedToCurrentChain();
2931 UniValue results(UniValue::VARR);
2932 std::vector<COutput> vecOutputs;
2933 LOCK2(cs_main, pwallet->cs_wallet);
2935 pwallet->AvailableCoins(vecOutputs, !include_unsafe, nullptr, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2936 for (const COutput& out : vecOutputs) {
2937 CTxDestination address;
2938 const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
2939 bool fValidAddress = ExtractDestination(scriptPubKey, address);
2941 if (destinations.size() && (!fValidAddress || !destinations.count(address)))
2942 continue;
2944 UniValue entry(UniValue::VOBJ);
2945 entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
2946 entry.push_back(Pair("vout", out.i));
2948 if (fValidAddress) {
2949 entry.push_back(Pair("address", EncodeDestination(address)));
2951 if (pwallet->mapAddressBook.count(address)) {
2952 entry.push_back(Pair("account", pwallet->mapAddressBook[address].name));
2955 if (scriptPubKey.IsPayToScriptHash()) {
2956 const CScriptID& hash = boost::get<CScriptID>(address);
2957 CScript redeemScript;
2958 if (pwallet->GetCScript(hash, redeemScript)) {
2959 entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
2964 entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
2965 entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue)));
2966 entry.push_back(Pair("confirmations", out.nDepth));
2967 entry.push_back(Pair("spendable", out.fSpendable));
2968 entry.push_back(Pair("solvable", out.fSolvable));
2969 entry.push_back(Pair("safe", out.fSafe));
2970 results.push_back(entry);
2973 return results;
2976 UniValue fundrawtransaction(const JSONRPCRequest& request)
2978 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2979 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2980 return NullUniValue;
2983 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2984 throw std::runtime_error(
2985 "fundrawtransaction \"hexstring\" ( options )\n"
2986 "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
2987 "This will not modify existing inputs, and will add at most one change output to the outputs.\n"
2988 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
2989 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
2990 "The inputs added will not be signed, use signrawtransaction for that.\n"
2991 "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
2992 "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
2993 "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
2994 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
2995 "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
2996 "\nArguments:\n"
2997 "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
2998 "2. options (object, optional)\n"
2999 " {\n"
3000 " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
3001 " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
3002 " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
3003 " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
3004 " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific fee rate in " + CURRENCY_UNIT + "/kB\n"
3005 " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
3006 " The fee will be equally deducted from the amount of each specified output.\n"
3007 " The outputs are specified by their zero-based index, before any change output is added.\n"
3008 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
3009 " If no outputs are specified here, the sender pays the fee.\n"
3010 " [vout_index,...]\n"
3011 " \"replaceable\" (boolean, optional) Marks this transaction as BIP125 replaceable.\n"
3012 " Allows this transaction to be replaced by a transaction with higher fees\n"
3013 " \"conf_target\" (numeric, optional) Confirmation target (in blocks)\n"
3014 " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
3015 " \"UNSET\"\n"
3016 " \"ECONOMICAL\"\n"
3017 " \"CONSERVATIVE\"\n"
3018 " }\n"
3019 " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
3020 "\nResult:\n"
3021 "{\n"
3022 " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
3023 " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
3024 " \"changepos\": n (numeric) The position of the added change output, or -1\n"
3025 "}\n"
3026 "\nExamples:\n"
3027 "\nCreate a transaction with no inputs\n"
3028 + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
3029 "\nAdd sufficient unsigned inputs to meet the output value\n"
3030 + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
3031 "\nSign the transaction\n"
3032 + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
3033 "\nSend the transaction\n"
3034 + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
3037 ObserveSafeMode();
3038 RPCTypeCheck(request.params, {UniValue::VSTR});
3040 // Make sure the results are valid at least up to the most recent block
3041 // the user could have gotten from another RPC command prior to now
3042 pwallet->BlockUntilSyncedToCurrentChain();
3044 CCoinControl coinControl;
3045 int changePosition = -1;
3046 bool lockUnspents = false;
3047 UniValue subtractFeeFromOutputs;
3048 std::set<int> setSubtractFeeFromOutputs;
3050 if (!request.params[1].isNull()) {
3051 if (request.params[1].type() == UniValue::VBOOL) {
3052 // backward compatibility bool only fallback
3053 coinControl.fAllowWatchOnly = request.params[1].get_bool();
3055 else {
3056 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
3058 UniValue options = request.params[1];
3060 RPCTypeCheckObj(options,
3062 {"changeAddress", UniValueType(UniValue::VSTR)},
3063 {"changePosition", UniValueType(UniValue::VNUM)},
3064 {"includeWatching", UniValueType(UniValue::VBOOL)},
3065 {"lockUnspents", UniValueType(UniValue::VBOOL)},
3066 {"reserveChangeKey", UniValueType(UniValue::VBOOL)}, // DEPRECATED (and ignored), should be removed in 0.16 or so.
3067 {"feeRate", UniValueType()}, // will be checked below
3068 {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
3069 {"replaceable", UniValueType(UniValue::VBOOL)},
3070 {"conf_target", UniValueType(UniValue::VNUM)},
3071 {"estimate_mode", UniValueType(UniValue::VSTR)},
3073 true, true);
3075 if (options.exists("changeAddress")) {
3076 CTxDestination dest = DecodeDestination(options["changeAddress"].get_str());
3078 if (!IsValidDestination(dest)) {
3079 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "changeAddress must be a valid bitcoin address");
3082 coinControl.destChange = dest;
3085 if (options.exists("changePosition"))
3086 changePosition = options["changePosition"].get_int();
3088 if (options.exists("includeWatching"))
3089 coinControl.fAllowWatchOnly = options["includeWatching"].get_bool();
3091 if (options.exists("lockUnspents"))
3092 lockUnspents = options["lockUnspents"].get_bool();
3094 if (options.exists("feeRate"))
3096 coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"]));
3097 coinControl.fOverrideFeeRate = true;
3100 if (options.exists("subtractFeeFromOutputs"))
3101 subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
3103 if (options.exists("replaceable")) {
3104 coinControl.signalRbf = options["replaceable"].get_bool();
3106 if (options.exists("conf_target")) {
3107 if (options.exists("feeRate")) {
3108 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate");
3110 coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"]);
3112 if (options.exists("estimate_mode")) {
3113 if (options.exists("feeRate")) {
3114 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate");
3116 if (!FeeModeFromString(options["estimate_mode"].get_str(), coinControl.m_fee_mode)) {
3117 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
3123 // parse hex string from parameter
3124 CMutableTransaction tx;
3125 if (!DecodeHexTx(tx, request.params[0].get_str(), true))
3126 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
3128 if (tx.vout.size() == 0)
3129 throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
3131 if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size()))
3132 throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
3134 for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
3135 int pos = subtractFeeFromOutputs[idx].get_int();
3136 if (setSubtractFeeFromOutputs.count(pos))
3137 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
3138 if (pos < 0)
3139 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
3140 if (pos >= int(tx.vout.size()))
3141 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
3142 setSubtractFeeFromOutputs.insert(pos);
3145 CAmount nFeeOut;
3146 std::string strFailReason;
3148 if (!pwallet->FundTransaction(tx, nFeeOut, changePosition, strFailReason, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
3149 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
3152 UniValue result(UniValue::VOBJ);
3153 result.push_back(Pair("hex", EncodeHexTx(tx)));
3154 result.push_back(Pair("changepos", changePosition));
3155 result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
3157 return result;
3160 UniValue bumpfee(const JSONRPCRequest& request)
3162 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3164 if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
3165 return NullUniValue;
3167 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
3168 throw std::runtime_error(
3169 "bumpfee \"txid\" ( options ) \n"
3170 "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
3171 "An opt-in RBF transaction with the given txid must be in the wallet.\n"
3172 "The command will pay the additional fee by decreasing (or perhaps removing) its change output.\n"
3173 "If the change output is not big enough to cover the increased fee, the command will currently fail\n"
3174 "instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
3175 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
3176 "By default, the new fee will be calculated automatically using estimatefee.\n"
3177 "The user can specify a confirmation target for estimatefee.\n"
3178 "Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
3179 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
3180 "returned by getnetworkinfo) to enter the node's mempool.\n"
3181 "\nArguments:\n"
3182 "1. txid (string, required) The txid to be bumped\n"
3183 "2. options (object, optional)\n"
3184 " {\n"
3185 " \"confTarget\" (numeric, optional) Confirmation target (in blocks)\n"
3186 " \"totalFee\" (numeric, optional) Total fee (NOT feerate) to pay, in satoshis.\n"
3187 " In rare cases, the actual fee paid might be slightly higher than the specified\n"
3188 " totalFee if the tx change output has to be removed because it is too close to\n"
3189 " the dust threshold.\n"
3190 " \"replaceable\" (boolean, optional, default true) Whether the new transaction should still be\n"
3191 " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
3192 " be left unchanged from the original. If false, any input sequence numbers in the\n"
3193 " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
3194 " so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
3195 " still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
3196 " are replaceable).\n"
3197 " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
3198 " \"UNSET\"\n"
3199 " \"ECONOMICAL\"\n"
3200 " \"CONSERVATIVE\"\n"
3201 " }\n"
3202 "\nResult:\n"
3203 "{\n"
3204 " \"txid\": \"value\", (string) The id of the new transaction\n"
3205 " \"origfee\": n, (numeric) Fee of the replaced transaction\n"
3206 " \"fee\": n, (numeric) Fee of the new transaction\n"
3207 " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n"
3208 "}\n"
3209 "\nExamples:\n"
3210 "\nBump the fee, get the new transaction\'s txid\n" +
3211 HelpExampleCli("bumpfee", "<txid>"));
3214 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
3215 uint256 hash;
3216 hash.SetHex(request.params[0].get_str());
3218 // optional parameters
3219 CAmount totalFee = 0;
3220 CCoinControl coin_control;
3221 coin_control.signalRbf = true;
3222 if (!request.params[1].isNull()) {
3223 UniValue options = request.params[1];
3224 RPCTypeCheckObj(options,
3226 {"confTarget", UniValueType(UniValue::VNUM)},
3227 {"totalFee", UniValueType(UniValue::VNUM)},
3228 {"replaceable", UniValueType(UniValue::VBOOL)},
3229 {"estimate_mode", UniValueType(UniValue::VSTR)},
3231 true, true);
3233 if (options.exists("confTarget") && options.exists("totalFee")) {
3234 throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and totalFee options should not both be set. Please provide either a confirmation target for fee estimation or an explicit total fee for the transaction.");
3235 } else if (options.exists("confTarget")) { // TODO: alias this to conf_target
3236 coin_control.m_confirm_target = ParseConfirmTarget(options["confTarget"]);
3237 } else if (options.exists("totalFee")) {
3238 totalFee = options["totalFee"].get_int64();
3239 if (totalFee <= 0) {
3240 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee %s (must be greater than 0)", FormatMoney(totalFee)));
3244 if (options.exists("replaceable")) {
3245 coin_control.signalRbf = options["replaceable"].get_bool();
3247 if (options.exists("estimate_mode")) {
3248 if (!FeeModeFromString(options["estimate_mode"].get_str(), coin_control.m_fee_mode)) {
3249 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
3254 // Make sure the results are valid at least up to the most recent block
3255 // the user could have gotten from another RPC command prior to now
3256 pwallet->BlockUntilSyncedToCurrentChain();
3258 LOCK2(cs_main, pwallet->cs_wallet);
3259 EnsureWalletIsUnlocked(pwallet);
3262 std::vector<std::string> errors;
3263 CAmount old_fee;
3264 CAmount new_fee;
3265 CMutableTransaction mtx;
3266 feebumper::Result res = feebumper::CreateTransaction(pwallet, hash, coin_control, totalFee, errors, old_fee, new_fee, mtx);
3267 if (res != feebumper::Result::OK) {
3268 switch(res) {
3269 case feebumper::Result::INVALID_ADDRESS_OR_KEY:
3270 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errors[0]);
3271 break;
3272 case feebumper::Result::INVALID_REQUEST:
3273 throw JSONRPCError(RPC_INVALID_REQUEST, errors[0]);
3274 break;
3275 case feebumper::Result::INVALID_PARAMETER:
3276 throw JSONRPCError(RPC_INVALID_PARAMETER, errors[0]);
3277 break;
3278 case feebumper::Result::WALLET_ERROR:
3279 throw JSONRPCError(RPC_WALLET_ERROR, errors[0]);
3280 break;
3281 default:
3282 throw JSONRPCError(RPC_MISC_ERROR, errors[0]);
3283 break;
3287 // sign bumped transaction
3288 if (!feebumper::SignTransaction(pwallet, mtx)) {
3289 throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
3291 // commit the bumped transaction
3292 uint256 txid;
3293 if (feebumper::CommitTransaction(pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) {
3294 throw JSONRPCError(RPC_WALLET_ERROR, errors[0]);
3296 UniValue result(UniValue::VOBJ);
3297 result.push_back(Pair("txid", txid.GetHex()));
3298 result.push_back(Pair("origfee", ValueFromAmount(old_fee)));
3299 result.push_back(Pair("fee", ValueFromAmount(new_fee)));
3300 UniValue result_errors(UniValue::VARR);
3301 for (const std::string& error : errors) {
3302 result_errors.push_back(error);
3304 result.push_back(Pair("errors", result_errors));
3306 return result;
3309 UniValue generate(const JSONRPCRequest& request)
3311 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3313 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3314 return NullUniValue;
3317 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
3318 throw std::runtime_error(
3319 "generate nblocks ( maxtries )\n"
3320 "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n"
3321 "\nArguments:\n"
3322 "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
3323 "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
3324 "\nResult:\n"
3325 "[ blockhashes ] (array) hashes of blocks generated\n"
3326 "\nExamples:\n"
3327 "\nGenerate 11 blocks\n"
3328 + HelpExampleCli("generate", "11")
3332 int num_generate = request.params[0].get_int();
3333 uint64_t max_tries = 1000000;
3334 if (!request.params[1].isNull()) {
3335 max_tries = request.params[1].get_int();
3338 std::shared_ptr<CReserveScript> coinbase_script;
3339 pwallet->GetScriptForMining(coinbase_script);
3341 // If the keypool is exhausted, no script is returned at all. Catch this.
3342 if (!coinbase_script) {
3343 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
3346 //throw an error if no script was provided
3347 if (coinbase_script->reserveScript.empty()) {
3348 throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available");
3351 return generateBlocks(coinbase_script, num_generate, max_tries, true);
3354 UniValue rescanblockchain(const JSONRPCRequest& request)
3356 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3357 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3358 return NullUniValue;
3361 if (request.fHelp || request.params.size() > 2) {
3362 throw std::runtime_error(
3363 "rescanblockchain (\"start_height\") (\"stop_height\")\n"
3364 "\nRescan the local blockchain for wallet related transactions.\n"
3365 "\nArguments:\n"
3366 "1. \"start_height\" (numeric, optional) block height where the rescan should start\n"
3367 "2. \"stop_height\" (numeric, optional) the last block height that should be scanned\n"
3368 "\nResult:\n"
3369 "{\n"
3370 " \"start_height\" (numeric) The block height where the rescan has started. If omitted, rescan started from the genesis block.\n"
3371 " \"stop_height\" (numeric) The height of the last rescanned block. If omitted, rescan stopped at the chain tip.\n"
3372 "}\n"
3373 "\nExamples:\n"
3374 + HelpExampleCli("rescanblockchain", "100000 120000")
3375 + HelpExampleRpc("rescanblockchain", "100000, 120000")
3379 LOCK2(cs_main, pwallet->cs_wallet);
3381 CBlockIndex *pindexStart = chainActive.Genesis();
3382 CBlockIndex *pindexStop = nullptr;
3383 if (!request.params[0].isNull()) {
3384 pindexStart = chainActive[request.params[0].get_int()];
3385 if (!pindexStart) {
3386 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start_height");
3390 if (!request.params[1].isNull()) {
3391 pindexStop = chainActive[request.params[1].get_int()];
3392 if (!pindexStop) {
3393 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid stop_height");
3395 else if (pindexStop->nHeight < pindexStart->nHeight) {
3396 throw JSONRPCError(RPC_INVALID_PARAMETER, "stop_height must be greater then start_height");
3400 // We can't rescan beyond non-pruned blocks, stop and throw an error
3401 if (fPruneMode) {
3402 CBlockIndex *block = pindexStop ? pindexStop : chainActive.Tip();
3403 while (block && block->nHeight >= pindexStart->nHeight) {
3404 if (!(block->nStatus & BLOCK_HAVE_DATA)) {
3405 throw JSONRPCError(RPC_MISC_ERROR, "Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height.");
3407 block = block->pprev;
3411 CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions(pindexStart, pindexStop, true);
3412 if (!stopBlock) {
3413 if (pwallet->IsAbortingRescan()) {
3414 throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted.");
3416 // if we got a nullptr returned, ScanForWalletTransactions did rescan up to the requested stopindex
3417 stopBlock = pindexStop ? pindexStop : chainActive.Tip();
3419 else {
3420 throw JSONRPCError(RPC_MISC_ERROR, "Rescan failed. Potentially corrupted data files.");
3423 UniValue response(UniValue::VOBJ);
3424 response.pushKV("start_height", pindexStart->nHeight);
3425 response.pushKV("stop_height", stopBlock->nHeight);
3426 return response;
3429 extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
3430 extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
3431 extern UniValue importprivkey(const JSONRPCRequest& request);
3432 extern UniValue importaddress(const JSONRPCRequest& request);
3433 extern UniValue importpubkey(const JSONRPCRequest& request);
3434 extern UniValue dumpwallet(const JSONRPCRequest& request);
3435 extern UniValue importwallet(const JSONRPCRequest& request);
3436 extern UniValue importprunedfunds(const JSONRPCRequest& request);
3437 extern UniValue removeprunedfunds(const JSONRPCRequest& request);
3438 extern UniValue importmulti(const JSONRPCRequest& request);
3439 extern UniValue rescanblockchain(const JSONRPCRequest& request);
3441 static const CRPCCommand commands[] =
3442 { // category name actor (function) argNames
3443 // --------------------- ------------------------ ----------------------- ----------
3444 { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options"} },
3445 { "hidden", "resendwallettransactions", &resendwallettransactions, {} },
3446 { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
3447 { "wallet", "abortrescan", &abortrescan, {} },
3448 { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account"} },
3449 { "wallet", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
3450 { "wallet", "backupwallet", &backupwallet, {"destination"} },
3451 { "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
3452 { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
3453 { "wallet", "dumpwallet", &dumpwallet, {"filename"} },
3454 { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
3455 { "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
3456 { "wallet", "getaccount", &getaccount, {"address"} },
3457 { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
3458 { "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
3459 { "wallet", "getnewaddress", &getnewaddress, {"account"} },
3460 { "wallet", "getrawchangeaddress", &getrawchangeaddress, {} },
3461 { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf"} },
3462 { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
3463 { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
3464 { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
3465 { "wallet", "getwalletinfo", &getwalletinfo, {} },
3466 { "wallet", "importmulti", &importmulti, {"requests","options"} },
3467 { "wallet", "importprivkey", &importprivkey, {"privkey","label","rescan"} },
3468 { "wallet", "importwallet", &importwallet, {"filename"} },
3469 { "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
3470 { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
3471 { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
3472 { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
3473 { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
3474 { "wallet", "listaddressgroupings", &listaddressgroupings, {} },
3475 { "wallet", "listlockunspent", &listlockunspent, {} },
3476 { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} },
3477 { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly"} },
3478 { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
3479 { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
3480 { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
3481 { "wallet", "listwallets", &listwallets, {} },
3482 { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
3483 { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
3484 { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
3485 { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
3486 { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
3487 { "wallet", "setaccount", &setaccount, {"address","account"} },
3488 { "wallet", "settxfee", &settxfee, {"amount"} },
3489 { "wallet", "signmessage", &signmessage, {"address","message"} },
3490 { "wallet", "walletlock", &walletlock, {} },
3491 { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
3492 { "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout"} },
3493 { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
3494 { "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} },
3496 { "generating", "generate", &generate, {"nblocks","maxtries"} },
3499 void RegisterWalletRPCCommands(CRPCTable &t)
3501 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
3502 t.appendCommand(commands[vcidx].name, &commands[vcidx]);