Merge #11107: Fix races in AppInitMain and others with lock and atomic bools
[bitcoinplatinum.git] / src / wallet / rpcwallet.cpp
blob5d98498a4b0b4487b3d7245a75f4ea8306e9cf73
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"
30 #include <init.h> // For StartShutdown
32 #include <stdint.h>
34 #include <univalue.h>
36 static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
38 CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
40 if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
41 // wallet endpoint was used
42 std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
43 for (CWalletRef pwallet : ::vpwallets) {
44 if (pwallet->GetName() == requestedWallet) {
45 return pwallet;
48 throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
50 return ::vpwallets.size() == 1 || (request.fHelp && ::vpwallets.size() > 0) ? ::vpwallets[0] : nullptr;
53 std::string HelpRequiringPassphrase(CWallet * const pwallet)
55 return pwallet && pwallet->IsCrypted()
56 ? "\nRequires wallet passphrase to be set with walletpassphrase call."
57 : "";
60 bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
62 if (pwallet) return true;
63 if (avoidException) return false;
64 if (::vpwallets.empty()) {
65 // Note: It isn't currently possible to trigger this error because
66 // wallet RPC methods aren't registered unless a wallet is loaded. But
67 // this error is being kept as a precaution, because it's possible in
68 // the future that wallet RPC methods might get or remain registered
69 // when no wallets are loaded.
70 throw JSONRPCError(
71 RPC_METHOD_NOT_FOUND, "Method not found (wallet method is disabled because no wallet is loaded)");
73 throw JSONRPCError(RPC_WALLET_NOT_SPECIFIED,
74 "Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
77 void EnsureWalletIsUnlocked(CWallet * const pwallet)
79 if (pwallet->IsLocked()) {
80 throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
84 void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
86 int confirms = wtx.GetDepthInMainChain();
87 entry.push_back(Pair("confirmations", confirms));
88 if (wtx.IsCoinBase())
89 entry.push_back(Pair("generated", true));
90 if (confirms > 0)
92 entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
93 entry.push_back(Pair("blockindex", wtx.nIndex));
94 entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
95 } else {
96 entry.push_back(Pair("trusted", wtx.IsTrusted()));
98 uint256 hash = wtx.GetHash();
99 entry.push_back(Pair("txid", hash.GetHex()));
100 UniValue conflicts(UniValue::VARR);
101 for (const uint256& conflict : wtx.GetConflicts())
102 conflicts.push_back(conflict.GetHex());
103 entry.push_back(Pair("walletconflicts", conflicts));
104 entry.push_back(Pair("time", wtx.GetTxTime()));
105 entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
107 // Add opt-in RBF status
108 std::string rbfStatus = "no";
109 if (confirms <= 0) {
110 LOCK(mempool.cs);
111 RBFTransactionState rbfState = IsRBFOptIn(wtx, mempool);
112 if (rbfState == RBF_TRANSACTIONSTATE_UNKNOWN)
113 rbfStatus = "unknown";
114 else if (rbfState == RBF_TRANSACTIONSTATE_REPLACEABLE_BIP125)
115 rbfStatus = "yes";
117 entry.push_back(Pair("bip125-replaceable", rbfStatus));
119 for (const std::pair<std::string, std::string>& item : wtx.mapValue)
120 entry.push_back(Pair(item.first, item.second));
123 std::string AccountFromValue(const UniValue& value)
125 std::string strAccount = value.get_str();
126 if (strAccount == "*")
127 throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
128 return strAccount;
131 UniValue getnewaddress(const JSONRPCRequest& request)
133 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
134 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
135 return NullUniValue;
138 if (request.fHelp || request.params.size() > 1)
139 throw std::runtime_error(
140 "getnewaddress ( \"account\" )\n"
141 "\nReturns a new Bitcoin address for receiving payments.\n"
142 "If 'account' is specified (DEPRECATED), it is added to the address book \n"
143 "so payments received with the address will be credited to 'account'.\n"
144 "\nArguments:\n"
145 "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"
146 "\nResult:\n"
147 "\"address\" (string) The new bitcoin address\n"
148 "\nExamples:\n"
149 + HelpExampleCli("getnewaddress", "")
150 + HelpExampleRpc("getnewaddress", "")
153 LOCK2(cs_main, pwallet->cs_wallet);
155 // Parse the account first so we don't generate a key if there's an error
156 std::string strAccount;
157 if (!request.params[0].isNull())
158 strAccount = AccountFromValue(request.params[0]);
160 if (!pwallet->IsLocked()) {
161 pwallet->TopUpKeyPool();
164 // Generate a new key that is added to wallet
165 CPubKey newKey;
166 if (!pwallet->GetKeyFromPool(newKey)) {
167 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
169 CKeyID keyID = newKey.GetID();
171 pwallet->SetAddressBook(keyID, strAccount, "receive");
173 return EncodeDestination(keyID);
177 CTxDestination GetAccountAddress(CWallet* const pwallet, std::string strAccount, bool bForceNew=false)
179 CPubKey pubKey;
180 if (!pwallet->GetAccountPubkey(pubKey, strAccount, bForceNew)) {
181 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
184 return pubKey.GetID();
187 UniValue getaccountaddress(const JSONRPCRequest& request)
189 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
190 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
191 return NullUniValue;
194 if (request.fHelp || request.params.size() != 1)
195 throw std::runtime_error(
196 "getaccountaddress \"account\"\n"
197 "\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
198 "\nArguments:\n"
199 "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"
200 "\nResult:\n"
201 "\"address\" (string) The account bitcoin address\n"
202 "\nExamples:\n"
203 + HelpExampleCli("getaccountaddress", "")
204 + HelpExampleCli("getaccountaddress", "\"\"")
205 + HelpExampleCli("getaccountaddress", "\"myaccount\"")
206 + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
209 LOCK2(cs_main, pwallet->cs_wallet);
211 // Parse the account first so we don't generate a key if there's an error
212 std::string strAccount = AccountFromValue(request.params[0]);
214 UniValue ret(UniValue::VSTR);
216 ret = EncodeDestination(GetAccountAddress(pwallet, strAccount));
217 return ret;
221 UniValue getrawchangeaddress(const JSONRPCRequest& request)
223 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
224 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
225 return NullUniValue;
228 if (request.fHelp || request.params.size() > 0)
229 throw std::runtime_error(
230 "getrawchangeaddress\n"
231 "\nReturns a new Bitcoin address, for receiving change.\n"
232 "This is for use with raw transactions, NOT normal use.\n"
233 "\nResult:\n"
234 "\"address\" (string) The address\n"
235 "\nExamples:\n"
236 + HelpExampleCli("getrawchangeaddress", "")
237 + HelpExampleRpc("getrawchangeaddress", "")
240 LOCK2(cs_main, pwallet->cs_wallet);
242 if (!pwallet->IsLocked()) {
243 pwallet->TopUpKeyPool();
246 CReserveKey reservekey(pwallet);
247 CPubKey vchPubKey;
248 if (!reservekey.GetReservedKey(vchPubKey, true))
249 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
251 reservekey.KeepKey();
253 CKeyID keyID = vchPubKey.GetID();
255 return EncodeDestination(keyID);
259 UniValue setaccount(const JSONRPCRequest& request)
261 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
262 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
263 return NullUniValue;
266 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
267 throw std::runtime_error(
268 "setaccount \"address\" \"account\"\n"
269 "\nDEPRECATED. Sets the account associated with the given address.\n"
270 "\nArguments:\n"
271 "1. \"address\" (string, required) The bitcoin address to be associated with an account.\n"
272 "2. \"account\" (string, required) The account to assign the address to.\n"
273 "\nExamples:\n"
274 + HelpExampleCli("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"tabby\"")
275 + HelpExampleRpc("setaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"tabby\"")
278 LOCK2(cs_main, pwallet->cs_wallet);
280 CTxDestination dest = DecodeDestination(request.params[0].get_str());
281 if (!IsValidDestination(dest)) {
282 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
285 std::string strAccount;
286 if (!request.params[1].isNull())
287 strAccount = AccountFromValue(request.params[1]);
289 // Only add the account if the address is yours.
290 if (IsMine(*pwallet, dest)) {
291 // Detect when changing the account of an address that is the 'unused current key' of another account:
292 if (pwallet->mapAddressBook.count(dest)) {
293 std::string strOldAccount = pwallet->mapAddressBook[dest].name;
294 if (dest == GetAccountAddress(pwallet, strOldAccount)) {
295 GetAccountAddress(pwallet, strOldAccount, true);
298 pwallet->SetAddressBook(dest, strAccount, "receive");
300 else
301 throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
303 return NullUniValue;
307 UniValue getaccount(const JSONRPCRequest& request)
309 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
310 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
311 return NullUniValue;
314 if (request.fHelp || request.params.size() != 1)
315 throw std::runtime_error(
316 "getaccount \"address\"\n"
317 "\nDEPRECATED. Returns the account associated with the given address.\n"
318 "\nArguments:\n"
319 "1. \"address\" (string, required) The bitcoin address for account lookup.\n"
320 "\nResult:\n"
321 "\"accountname\" (string) the account address\n"
322 "\nExamples:\n"
323 + HelpExampleCli("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
324 + HelpExampleRpc("getaccount", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"")
327 LOCK2(cs_main, pwallet->cs_wallet);
329 CTxDestination dest = DecodeDestination(request.params[0].get_str());
330 if (!IsValidDestination(dest)) {
331 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
334 std::string strAccount;
335 std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(dest);
336 if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) {
337 strAccount = (*mi).second.name;
339 return strAccount;
343 UniValue getaddressesbyaccount(const JSONRPCRequest& request)
345 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
346 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
347 return NullUniValue;
350 if (request.fHelp || request.params.size() != 1)
351 throw std::runtime_error(
352 "getaddressesbyaccount \"account\"\n"
353 "\nDEPRECATED. Returns the list of addresses for the given account.\n"
354 "\nArguments:\n"
355 "1. \"account\" (string, required) The account name.\n"
356 "\nResult:\n"
357 "[ (json array of string)\n"
358 " \"address\" (string) a bitcoin address associated with the given account\n"
359 " ,...\n"
360 "]\n"
361 "\nExamples:\n"
362 + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
363 + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
366 LOCK2(cs_main, pwallet->cs_wallet);
368 std::string strAccount = AccountFromValue(request.params[0]);
370 // Find all addresses that have the given account
371 UniValue ret(UniValue::VARR);
372 for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
373 const CTxDestination& dest = item.first;
374 const std::string& strName = item.second.name;
375 if (strName == strAccount) {
376 ret.push_back(EncodeDestination(dest));
379 return ret;
382 static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)
384 CAmount curBalance = pwallet->GetBalance();
386 // Check amount
387 if (nValue <= 0)
388 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
390 if (nValue > curBalance)
391 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
393 if (pwallet->GetBroadcastTransactions() && !g_connman) {
394 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
397 // Parse Bitcoin address
398 CScript scriptPubKey = GetScriptForDestination(address);
400 // Create and send the transaction
401 CReserveKey reservekey(pwallet);
402 CAmount nFeeRequired;
403 std::string strError;
404 std::vector<CRecipient> vecSend;
405 int nChangePosRet = -1;
406 CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
407 vecSend.push_back(recipient);
408 if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet, strError, coin_control)) {
409 if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
410 strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
411 throw JSONRPCError(RPC_WALLET_ERROR, strError);
413 CValidationState state;
414 if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
415 strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
416 throw JSONRPCError(RPC_WALLET_ERROR, strError);
420 UniValue sendtoaddress(const JSONRPCRequest& request)
422 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
423 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
424 return NullUniValue;
427 if (request.fHelp || request.params.size() < 2 || request.params.size() > 8)
428 throw std::runtime_error(
429 "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount replaceable conf_target \"estimate_mode\")\n"
430 "\nSend an amount to a given address.\n"
431 + HelpRequiringPassphrase(pwallet) +
432 "\nArguments:\n"
433 "1. \"address\" (string, required) The bitcoin address to send to.\n"
434 "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
435 "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
436 " This is not part of the transaction, just kept in your wallet.\n"
437 "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
438 " to which you're sending the transaction. This is not part of the \n"
439 " transaction, just kept in your wallet.\n"
440 "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
441 " The recipient will receive less bitcoins than you enter in the amount field.\n"
442 "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
443 "7. conf_target (numeric, optional) Confirmation target (in blocks)\n"
444 "8. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
445 " \"UNSET\"\n"
446 " \"ECONOMICAL\"\n"
447 " \"CONSERVATIVE\"\n"
448 "\nResult:\n"
449 "\"txid\" (string) The transaction id.\n"
450 "\nExamples:\n"
451 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
452 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"donation\" \"seans outpost\"")
453 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1 \"\" \"\" true")
454 + HelpExampleRpc("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.1, \"donation\", \"seans outpost\"")
457 ObserveSafeMode();
458 LOCK2(cs_main, pwallet->cs_wallet);
460 CTxDestination dest = DecodeDestination(request.params[0].get_str());
461 if (!IsValidDestination(dest)) {
462 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
465 // Amount
466 CAmount nAmount = AmountFromValue(request.params[1]);
467 if (nAmount <= 0)
468 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
470 // Wallet comments
471 CWalletTx wtx;
472 if (!request.params[2].isNull() && !request.params[2].get_str().empty())
473 wtx.mapValue["comment"] = request.params[2].get_str();
474 if (!request.params[3].isNull() && !request.params[3].get_str().empty())
475 wtx.mapValue["to"] = request.params[3].get_str();
477 bool fSubtractFeeFromAmount = false;
478 if (!request.params[4].isNull()) {
479 fSubtractFeeFromAmount = request.params[4].get_bool();
482 CCoinControl coin_control;
483 if (!request.params[5].isNull()) {
484 coin_control.signalRbf = request.params[5].get_bool();
487 if (!request.params[6].isNull()) {
488 coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
491 if (!request.params[7].isNull()) {
492 if (!FeeModeFromString(request.params[7].get_str(), coin_control.m_fee_mode)) {
493 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
498 EnsureWalletIsUnlocked(pwallet);
500 SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx, coin_control);
502 return wtx.GetHash().GetHex();
505 UniValue listaddressgroupings(const JSONRPCRequest& request)
507 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
508 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
509 return NullUniValue;
512 if (request.fHelp || request.params.size() != 0)
513 throw std::runtime_error(
514 "listaddressgroupings\n"
515 "\nLists groups of addresses which have had their common ownership\n"
516 "made public by common use as inputs or as the resulting change\n"
517 "in past transactions\n"
518 "\nResult:\n"
519 "[\n"
520 " [\n"
521 " [\n"
522 " \"address\", (string) The bitcoin address\n"
523 " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
524 " \"account\" (string, optional) DEPRECATED. The account\n"
525 " ]\n"
526 " ,...\n"
527 " ]\n"
528 " ,...\n"
529 "]\n"
530 "\nExamples:\n"
531 + HelpExampleCli("listaddressgroupings", "")
532 + HelpExampleRpc("listaddressgroupings", "")
535 ObserveSafeMode();
536 LOCK2(cs_main, pwallet->cs_wallet);
538 UniValue jsonGroupings(UniValue::VARR);
539 std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
540 for (const std::set<CTxDestination>& grouping : pwallet->GetAddressGroupings()) {
541 UniValue jsonGrouping(UniValue::VARR);
542 for (const CTxDestination& address : grouping)
544 UniValue addressInfo(UniValue::VARR);
545 addressInfo.push_back(EncodeDestination(address));
546 addressInfo.push_back(ValueFromAmount(balances[address]));
548 if (pwallet->mapAddressBook.find(address) != pwallet->mapAddressBook.end()) {
549 addressInfo.push_back(pwallet->mapAddressBook.find(address)->second.name);
552 jsonGrouping.push_back(addressInfo);
554 jsonGroupings.push_back(jsonGrouping);
556 return jsonGroupings;
559 UniValue signmessage(const JSONRPCRequest& request)
561 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
562 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
563 return NullUniValue;
566 if (request.fHelp || request.params.size() != 2)
567 throw std::runtime_error(
568 "signmessage \"address\" \"message\"\n"
569 "\nSign a message with the private key of an address"
570 + HelpRequiringPassphrase(pwallet) + "\n"
571 "\nArguments:\n"
572 "1. \"address\" (string, required) The bitcoin address to use for the private key.\n"
573 "2. \"message\" (string, required) The message to create a signature of.\n"
574 "\nResult:\n"
575 "\"signature\" (string) The signature of the message encoded in base 64\n"
576 "\nExamples:\n"
577 "\nUnlock the wallet for 30 seconds\n"
578 + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
579 "\nCreate the signature\n"
580 + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
581 "\nVerify the signature\n"
582 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
583 "\nAs json rpc\n"
584 + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
587 LOCK2(cs_main, pwallet->cs_wallet);
589 EnsureWalletIsUnlocked(pwallet);
591 std::string strAddress = request.params[0].get_str();
592 std::string strMessage = request.params[1].get_str();
594 CTxDestination dest = DecodeDestination(strAddress);
595 if (!IsValidDestination(dest)) {
596 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
599 const CKeyID *keyID = boost::get<CKeyID>(&dest);
600 if (!keyID) {
601 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
604 CKey key;
605 if (!pwallet->GetKey(*keyID, key)) {
606 throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
609 CHashWriter ss(SER_GETHASH, 0);
610 ss << strMessageMagic;
611 ss << strMessage;
613 std::vector<unsigned char> vchSig;
614 if (!key.SignCompact(ss.GetHash(), vchSig))
615 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
617 return EncodeBase64(vchSig.data(), vchSig.size());
620 UniValue getreceivedbyaddress(const JSONRPCRequest& request)
622 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
623 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
624 return NullUniValue;
627 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
628 throw std::runtime_error(
629 "getreceivedbyaddress \"address\" ( minconf )\n"
630 "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
631 "\nArguments:\n"
632 "1. \"address\" (string, required) The bitcoin address for transactions.\n"
633 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
634 "\nResult:\n"
635 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
636 "\nExamples:\n"
637 "\nThe amount from transactions with at least 1 confirmation\n"
638 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\"") +
639 "\nThe amount including unconfirmed transactions, zero confirmations\n"
640 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 0") +
641 "\nThe amount with at least 6 confirmations\n"
642 + HelpExampleCli("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" 6") +
643 "\nAs a json rpc call\n"
644 + HelpExampleRpc("getreceivedbyaddress", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", 6")
647 ObserveSafeMode();
648 LOCK2(cs_main, pwallet->cs_wallet);
650 // Bitcoin address
651 CTxDestination dest = DecodeDestination(request.params[0].get_str());
652 if (!IsValidDestination(dest)) {
653 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
655 CScript scriptPubKey = GetScriptForDestination(dest);
656 if (!IsMine(*pwallet, scriptPubKey)) {
657 return ValueFromAmount(0);
660 // Minimum confirmations
661 int nMinDepth = 1;
662 if (!request.params[1].isNull())
663 nMinDepth = request.params[1].get_int();
665 // Tally
666 CAmount nAmount = 0;
667 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
668 const CWalletTx& wtx = pairWtx.second;
669 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
670 continue;
672 for (const CTxOut& txout : wtx.tx->vout)
673 if (txout.scriptPubKey == scriptPubKey)
674 if (wtx.GetDepthInMainChain() >= nMinDepth)
675 nAmount += txout.nValue;
678 return ValueFromAmount(nAmount);
682 UniValue getreceivedbyaccount(const JSONRPCRequest& request)
684 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
685 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
686 return NullUniValue;
689 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
690 throw std::runtime_error(
691 "getreceivedbyaccount \"account\" ( minconf )\n"
692 "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with at least [minconf] confirmations.\n"
693 "\nArguments:\n"
694 "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
695 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
696 "\nResult:\n"
697 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
698 "\nExamples:\n"
699 "\nAmount received by the default account with at least 1 confirmation\n"
700 + HelpExampleCli("getreceivedbyaccount", "\"\"") +
701 "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
702 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
703 "\nThe amount with at least 6 confirmations\n"
704 + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
705 "\nAs a json rpc call\n"
706 + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
709 ObserveSafeMode();
710 LOCK2(cs_main, pwallet->cs_wallet);
712 // Minimum confirmations
713 int nMinDepth = 1;
714 if (!request.params[1].isNull())
715 nMinDepth = request.params[1].get_int();
717 // Get the set of pub keys assigned to account
718 std::string strAccount = AccountFromValue(request.params[0]);
719 std::set<CTxDestination> setAddress = pwallet->GetAccountAddresses(strAccount);
721 // Tally
722 CAmount nAmount = 0;
723 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
724 const CWalletTx& wtx = pairWtx.second;
725 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
726 continue;
728 for (const CTxOut& txout : wtx.tx->vout)
730 CTxDestination address;
731 if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) {
732 if (wtx.GetDepthInMainChain() >= nMinDepth)
733 nAmount += txout.nValue;
738 return ValueFromAmount(nAmount);
742 UniValue getbalance(const JSONRPCRequest& request)
744 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
745 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
746 return NullUniValue;
749 if (request.fHelp || request.params.size() > 3)
750 throw std::runtime_error(
751 "getbalance ( \"account\" minconf include_watchonly )\n"
752 "\nIf account is not specified, returns the server's total available balance.\n"
753 "If account is specified (DEPRECATED), returns the balance in the account.\n"
754 "Note that the account \"\" is not the same as leaving the parameter out.\n"
755 "The server total may be different to the balance in the default \"\" account.\n"
756 "\nArguments:\n"
757 "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n"
758 " specific account name to find the balance associated with wallet keys in\n"
759 " a named account, or as the empty string (\"\") to find the balance\n"
760 " associated with wallet keys not in any named account, or as \"*\" to find\n"
761 " the balance associated with all wallet keys regardless of account.\n"
762 " When this option is specified, it calculates the balance in a different\n"
763 " way than when it is not specified, and which can count spends twice when\n"
764 " there are conflicting pending transactions (such as those created by\n"
765 " the bumpfee command), temporarily resulting in low or even negative\n"
766 " balances. In general, account balance calculation is not considered\n"
767 " reliable and has resulted in confusing outcomes, so it is recommended to\n"
768 " avoid passing this argument.\n"
769 "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
770 "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
771 "\nResult:\n"
772 "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
773 "\nExamples:\n"
774 "\nThe total amount in the wallet with 1 or more confirmations\n"
775 + HelpExampleCli("getbalance", "") +
776 "\nThe total amount in the wallet at least 6 blocks confirmed\n"
777 + HelpExampleCli("getbalance", "\"*\" 6") +
778 "\nAs a json rpc call\n"
779 + HelpExampleRpc("getbalance", "\"*\", 6")
782 ObserveSafeMode();
783 LOCK2(cs_main, pwallet->cs_wallet);
785 const UniValue& account_value = request.params[0];
786 const UniValue& minconf = request.params[1];
787 const UniValue& include_watchonly = request.params[2];
789 if (account_value.isNull()) {
790 if (!minconf.isNull()) {
791 throw JSONRPCError(RPC_INVALID_PARAMETER,
792 "getbalance minconf option is only currently supported if an account is specified");
794 if (!include_watchonly.isNull()) {
795 throw JSONRPCError(RPC_INVALID_PARAMETER,
796 "getbalance include_watchonly option is only currently supported if an account is specified");
798 return ValueFromAmount(pwallet->GetBalance());
801 const std::string& account_param = account_value.get_str();
802 const std::string* account = account_param != "*" ? &account_param : nullptr;
804 int nMinDepth = 1;
805 if (!minconf.isNull())
806 nMinDepth = minconf.get_int();
807 isminefilter filter = ISMINE_SPENDABLE;
808 if(!include_watchonly.isNull())
809 if(include_watchonly.get_bool())
810 filter = filter | ISMINE_WATCH_ONLY;
812 return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account));
815 UniValue getunconfirmedbalance(const JSONRPCRequest &request)
817 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
818 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
819 return NullUniValue;
822 if (request.fHelp || request.params.size() > 0)
823 throw std::runtime_error(
824 "getunconfirmedbalance\n"
825 "Returns the server's total unconfirmed balance\n");
827 ObserveSafeMode();
828 LOCK2(cs_main, pwallet->cs_wallet);
830 return ValueFromAmount(pwallet->GetUnconfirmedBalance());
834 UniValue movecmd(const JSONRPCRequest& request)
836 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
837 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
838 return NullUniValue;
841 if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
842 throw std::runtime_error(
843 "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
844 "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
845 "\nArguments:\n"
846 "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
847 "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
848 "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
849 "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n"
850 "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
851 "\nResult:\n"
852 "true|false (boolean) true if successful.\n"
853 "\nExamples:\n"
854 "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
855 + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
856 "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
857 + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
858 "\nAs a json rpc call\n"
859 + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
862 ObserveSafeMode();
863 LOCK2(cs_main, pwallet->cs_wallet);
865 std::string strFrom = AccountFromValue(request.params[0]);
866 std::string strTo = AccountFromValue(request.params[1]);
867 CAmount nAmount = AmountFromValue(request.params[2]);
868 if (nAmount <= 0)
869 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
870 if (!request.params[3].isNull())
871 // unused parameter, used to be nMinDepth, keep type-checking it though
872 (void)request.params[3].get_int();
873 std::string strComment;
874 if (!request.params[4].isNull())
875 strComment = request.params[4].get_str();
877 if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) {
878 throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
881 return true;
885 UniValue sendfrom(const JSONRPCRequest& request)
887 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
888 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
889 return NullUniValue;
892 if (request.fHelp || request.params.size() < 3 || request.params.size() > 6)
893 throw std::runtime_error(
894 "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf \"comment\" \"comment_to\" )\n"
895 "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a bitcoin address."
896 + HelpRequiringPassphrase(pwallet) + "\n"
897 "\nArguments:\n"
898 "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
899 " Specifying an account does not influence coin selection, but it does associate the newly created\n"
900 " transaction with the account, so the account's balance computation and transaction history can reflect\n"
901 " the spend.\n"
902 "2. \"toaddress\" (string, required) The bitcoin address to send funds to.\n"
903 "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
904 "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
905 "5. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
906 " This is not part of the transaction, just kept in your wallet.\n"
907 "6. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
908 " to which you're sending the transaction. This is not part of the transaction, \n"
909 " it is just kept in your wallet.\n"
910 "\nResult:\n"
911 "\"txid\" (string) The transaction id.\n"
912 "\nExamples:\n"
913 "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
914 + HelpExampleCli("sendfrom", "\"\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01") +
915 "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
916 + HelpExampleCli("sendfrom", "\"tabby\" \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.01 6 \"donation\" \"seans outpost\"") +
917 "\nAs a json rpc call\n"
918 + HelpExampleRpc("sendfrom", "\"tabby\", \"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\", 0.01, 6, \"donation\", \"seans outpost\"")
921 ObserveSafeMode();
922 LOCK2(cs_main, pwallet->cs_wallet);
924 std::string strAccount = AccountFromValue(request.params[0]);
925 CTxDestination dest = DecodeDestination(request.params[1].get_str());
926 if (!IsValidDestination(dest)) {
927 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
929 CAmount nAmount = AmountFromValue(request.params[2]);
930 if (nAmount <= 0)
931 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
932 int nMinDepth = 1;
933 if (!request.params[3].isNull())
934 nMinDepth = request.params[3].get_int();
936 CWalletTx wtx;
937 wtx.strFromAccount = strAccount;
938 if (!request.params[4].isNull() && !request.params[4].get_str().empty())
939 wtx.mapValue["comment"] = request.params[4].get_str();
940 if (!request.params[5].isNull() && !request.params[5].get_str().empty())
941 wtx.mapValue["to"] = request.params[5].get_str();
943 EnsureWalletIsUnlocked(pwallet);
945 // Check funds
946 CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
947 if (nAmount > nBalance)
948 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
950 CCoinControl no_coin_control; // This is a deprecated API
951 SendMoney(pwallet, dest, nAmount, false, wtx, no_coin_control);
953 return wtx.GetHash().GetHex();
957 UniValue sendmany(const JSONRPCRequest& request)
959 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
960 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
961 return NullUniValue;
964 if (request.fHelp || request.params.size() < 2 || request.params.size() > 8)
965 throw std::runtime_error(
966 "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] replaceable conf_target \"estimate_mode\")\n"
967 "\nSend multiple times. Amounts are double-precision floating point numbers."
968 + HelpRequiringPassphrase(pwallet) + "\n"
969 "\nArguments:\n"
970 "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
971 "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
972 " {\n"
973 " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n"
974 " ,...\n"
975 " }\n"
976 "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
977 "4. \"comment\" (string, optional) A comment\n"
978 "5. subtractfeefrom (array, optional) A json array with addresses.\n"
979 " The fee will be equally deducted from the amount of each selected address.\n"
980 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
981 " If no addresses are specified here, the sender pays the fee.\n"
982 " [\n"
983 " \"address\" (string) Subtract fee from this address\n"
984 " ,...\n"
985 " ]\n"
986 "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
987 "7. conf_target (numeric, optional) Confirmation target (in blocks)\n"
988 "8. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
989 " \"UNSET\"\n"
990 " \"ECONOMICAL\"\n"
991 " \"CONSERVATIVE\"\n"
992 "\nResult:\n"
993 "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
994 " the number of addresses.\n"
995 "\nExamples:\n"
996 "\nSend two amounts to two different addresses:\n"
997 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
998 "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
999 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
1000 "\nSend two amounts to two different addresses, subtract fee from amount:\n"
1001 + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
1002 "\nAs a json rpc call\n"
1003 + HelpExampleRpc("sendmany", "\"\", \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\", 6, \"testing\"")
1006 ObserveSafeMode();
1007 LOCK2(cs_main, pwallet->cs_wallet);
1009 if (pwallet->GetBroadcastTransactions() && !g_connman) {
1010 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
1013 std::string strAccount = AccountFromValue(request.params[0]);
1014 UniValue sendTo = request.params[1].get_obj();
1015 int nMinDepth = 1;
1016 if (!request.params[2].isNull())
1017 nMinDepth = request.params[2].get_int();
1019 CWalletTx wtx;
1020 wtx.strFromAccount = strAccount;
1021 if (!request.params[3].isNull() && !request.params[3].get_str().empty())
1022 wtx.mapValue["comment"] = request.params[3].get_str();
1024 UniValue subtractFeeFromAmount(UniValue::VARR);
1025 if (!request.params[4].isNull())
1026 subtractFeeFromAmount = request.params[4].get_array();
1028 CCoinControl coin_control;
1029 if (!request.params[5].isNull()) {
1030 coin_control.signalRbf = request.params[5].get_bool();
1033 if (!request.params[6].isNull()) {
1034 coin_control.m_confirm_target = ParseConfirmTarget(request.params[6]);
1037 if (!request.params[7].isNull()) {
1038 if (!FeeModeFromString(request.params[7].get_str(), coin_control.m_fee_mode)) {
1039 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
1043 std::set<CTxDestination> destinations;
1044 std::vector<CRecipient> vecSend;
1046 CAmount totalAmount = 0;
1047 std::vector<std::string> keys = sendTo.getKeys();
1048 for (const std::string& name_ : keys) {
1049 CTxDestination dest = DecodeDestination(name_);
1050 if (!IsValidDestination(dest)) {
1051 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + name_);
1054 if (destinations.count(dest)) {
1055 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
1057 destinations.insert(dest);
1059 CScript scriptPubKey = GetScriptForDestination(dest);
1060 CAmount nAmount = AmountFromValue(sendTo[name_]);
1061 if (nAmount <= 0)
1062 throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
1063 totalAmount += nAmount;
1065 bool fSubtractFeeFromAmount = false;
1066 for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) {
1067 const UniValue& addr = subtractFeeFromAmount[idx];
1068 if (addr.get_str() == name_)
1069 fSubtractFeeFromAmount = true;
1072 CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
1073 vecSend.push_back(recipient);
1076 EnsureWalletIsUnlocked(pwallet);
1078 // Check funds
1079 CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount);
1080 if (totalAmount > nBalance)
1081 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
1083 // Send
1084 CReserveKey keyChange(pwallet);
1085 CAmount nFeeRequired = 0;
1086 int nChangePosRet = -1;
1087 std::string strFailReason;
1088 bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason, coin_control);
1089 if (!fCreated)
1090 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
1091 CValidationState state;
1092 if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
1093 strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
1094 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
1097 return wtx.GetHash().GetHex();
1100 // Defined in rpc/misc.cpp
1101 extern CScript _createmultisig_redeemScript(CWallet * const pwallet, const UniValue& params);
1103 UniValue addmultisigaddress(const JSONRPCRequest& request)
1105 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1106 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1107 return NullUniValue;
1110 if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
1112 std::string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1113 "\nAdd a nrequired-to-sign multisignature address to the wallet.\n"
1114 "Each key is a Bitcoin address or hex-encoded public key.\n"
1115 "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1117 "\nArguments:\n"
1118 "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1119 "2. \"keys\" (string, required) A json array of bitcoin addresses or hex-encoded public keys\n"
1120 " [\n"
1121 " \"address\" (string) bitcoin address or hex-encoded public key\n"
1122 " ...,\n"
1123 " ]\n"
1124 "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
1126 "\nResult:\n"
1127 "\"address\" (string) A bitcoin address associated with the keys.\n"
1129 "\nExamples:\n"
1130 "\nAdd a multisig address from 2 addresses\n"
1131 + HelpExampleCli("addmultisigaddress", "2 \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"") +
1132 "\nAs json rpc call\n"
1133 + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"16sSauSf5pF2UkUwvKGq4qjNRzBZYqgEL5\\\",\\\"171sgjn4YtPu27adkKGrdDwzRTxnRkBfKV\\\"]\"")
1135 throw std::runtime_error(msg);
1138 LOCK2(cs_main, pwallet->cs_wallet);
1140 std::string strAccount;
1141 if (!request.params[2].isNull())
1142 strAccount = AccountFromValue(request.params[2]);
1144 // Construct using pay-to-script-hash:
1145 CScript inner = _createmultisig_redeemScript(pwallet, request.params);
1146 CScriptID innerID(inner);
1147 pwallet->AddCScript(inner);
1149 pwallet->SetAddressBook(innerID, strAccount, "send");
1150 return EncodeDestination(innerID);
1153 class Witnessifier : public boost::static_visitor<bool>
1155 public:
1156 CWallet * const pwallet;
1157 CTxDestination result;
1158 bool already_witness;
1160 explicit Witnessifier(CWallet *_pwallet) : pwallet(_pwallet), already_witness(false) {}
1162 bool operator()(const CKeyID &keyID) {
1163 if (pwallet) {
1164 CScript basescript = GetScriptForDestination(keyID);
1165 CScript witscript = GetScriptForWitness(basescript);
1166 SignatureData sigs;
1167 // This check is to make sure that the script we created can actually be solved for and signed by us
1168 // if we were to have the private keys. This is just to make sure that the script is valid and that,
1169 // if found in a transaction, we would still accept and relay that transaction.
1170 if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) ||
1171 !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
1172 return false;
1174 return ExtractDestination(witscript, result);
1176 return false;
1179 bool operator()(const CScriptID &scriptID) {
1180 CScript subscript;
1181 if (pwallet && pwallet->GetCScript(scriptID, subscript)) {
1182 int witnessversion;
1183 std::vector<unsigned char> witprog;
1184 if (subscript.IsWitnessProgram(witnessversion, witprog)) {
1185 ExtractDestination(subscript, result);
1186 already_witness = true;
1187 return true;
1189 CScript witscript = GetScriptForWitness(subscript);
1190 SignatureData sigs;
1191 // This check is to make sure that the script we created can actually be solved for and signed by us
1192 // if we were to have the private keys. This is just to make sure that the script is valid and that,
1193 // if found in a transaction, we would still accept and relay that transaction.
1194 if (!ProduceSignature(DummySignatureCreator(pwallet), witscript, sigs) ||
1195 !VerifyScript(sigs.scriptSig, witscript, &sigs.scriptWitness, MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_WITNESS_PUBKEYTYPE, DummySignatureCreator(pwallet).Checker())) {
1196 return false;
1198 return ExtractDestination(witscript, result);
1200 return false;
1203 bool operator()(const WitnessV0KeyHash& id)
1205 already_witness = true;
1206 result = id;
1207 return true;
1210 bool operator()(const WitnessV0ScriptHash& id)
1212 already_witness = true;
1213 result = id;
1214 return true;
1217 template<typename T>
1218 bool operator()(const T& dest) { return false; }
1221 UniValue addwitnessaddress(const JSONRPCRequest& request)
1223 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1224 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1225 return NullUniValue;
1228 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1230 std::string msg = "addwitnessaddress \"address\" ( p2sh )\n"
1231 "\nAdd a witness address for a script (with pubkey or redeemscript known).\n"
1232 "It returns the witness script.\n"
1234 "\nArguments:\n"
1235 "1. \"address\" (string, required) An address known to the wallet\n"
1236 "2. p2sh (bool, optional, default=true) Embed inside P2SH\n"
1238 "\nResult:\n"
1239 "\"witnessaddress\", (string) The value of the new address (P2SH or BIP173).\n"
1240 "}\n"
1242 throw std::runtime_error(msg);
1246 LOCK(cs_main);
1247 if (!IsWitnessEnabled(chainActive.Tip(), Params().GetConsensus()) && !gArgs.GetBoolArg("-walletprematurewitness", false)) {
1248 throw JSONRPCError(RPC_WALLET_ERROR, "Segregated witness not enabled on network");
1252 CTxDestination dest = DecodeDestination(request.params[0].get_str());
1253 if (!IsValidDestination(dest)) {
1254 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
1257 bool p2sh = true;
1258 if (!request.params[1].isNull()) {
1259 p2sh = request.params[1].get_bool();
1262 Witnessifier w(pwallet);
1263 bool ret = boost::apply_visitor(w, dest);
1264 if (!ret) {
1265 throw JSONRPCError(RPC_WALLET_ERROR, "Public key or redeemscript not known to wallet, or the key is uncompressed");
1268 CScript witprogram = GetScriptForDestination(w.result);
1270 if (p2sh) {
1271 w.result = CScriptID(witprogram);
1274 if (w.already_witness) {
1275 if (!(dest == w.result)) {
1276 throw JSONRPCError(RPC_WALLET_ERROR, "Cannot convert between witness address types");
1278 } else {
1279 pwallet->AddCScript(witprogram);
1280 pwallet->SetAddressBook(w.result, "", "receive");
1283 return EncodeDestination(w.result);
1286 struct tallyitem
1288 CAmount nAmount;
1289 int nConf;
1290 std::vector<uint256> txids;
1291 bool fIsWatchonly;
1292 tallyitem()
1294 nAmount = 0;
1295 nConf = std::numeric_limits<int>::max();
1296 fIsWatchonly = false;
1300 UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts)
1302 // Minimum confirmations
1303 int nMinDepth = 1;
1304 if (!params[0].isNull())
1305 nMinDepth = params[0].get_int();
1307 // Whether to include empty accounts
1308 bool fIncludeEmpty = false;
1309 if (!params[1].isNull())
1310 fIncludeEmpty = params[1].get_bool();
1312 isminefilter filter = ISMINE_SPENDABLE;
1313 if(!params[2].isNull())
1314 if(params[2].get_bool())
1315 filter = filter | ISMINE_WATCH_ONLY;
1317 // Tally
1318 std::map<CTxDestination, tallyitem> mapTally;
1319 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1320 const CWalletTx& wtx = pairWtx.second;
1322 if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
1323 continue;
1325 int nDepth = wtx.GetDepthInMainChain();
1326 if (nDepth < nMinDepth)
1327 continue;
1329 for (const CTxOut& txout : wtx.tx->vout)
1331 CTxDestination address;
1332 if (!ExtractDestination(txout.scriptPubKey, address))
1333 continue;
1335 isminefilter mine = IsMine(*pwallet, address);
1336 if(!(mine & filter))
1337 continue;
1339 tallyitem& item = mapTally[address];
1340 item.nAmount += txout.nValue;
1341 item.nConf = std::min(item.nConf, nDepth);
1342 item.txids.push_back(wtx.GetHash());
1343 if (mine & ISMINE_WATCH_ONLY)
1344 item.fIsWatchonly = true;
1348 // Reply
1349 UniValue ret(UniValue::VARR);
1350 std::map<std::string, tallyitem> mapAccountTally;
1351 for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
1352 const CTxDestination& dest = item.first;
1353 const std::string& strAccount = item.second.name;
1354 std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest);
1355 if (it == mapTally.end() && !fIncludeEmpty)
1356 continue;
1358 CAmount nAmount = 0;
1359 int nConf = std::numeric_limits<int>::max();
1360 bool fIsWatchonly = false;
1361 if (it != mapTally.end())
1363 nAmount = (*it).second.nAmount;
1364 nConf = (*it).second.nConf;
1365 fIsWatchonly = (*it).second.fIsWatchonly;
1368 if (fByAccounts)
1370 tallyitem& _item = mapAccountTally[strAccount];
1371 _item.nAmount += nAmount;
1372 _item.nConf = std::min(_item.nConf, nConf);
1373 _item.fIsWatchonly = fIsWatchonly;
1375 else
1377 UniValue obj(UniValue::VOBJ);
1378 if(fIsWatchonly)
1379 obj.push_back(Pair("involvesWatchonly", true));
1380 obj.push_back(Pair("address", EncodeDestination(dest)));
1381 obj.push_back(Pair("account", strAccount));
1382 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1383 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1384 if (!fByAccounts)
1385 obj.push_back(Pair("label", strAccount));
1386 UniValue transactions(UniValue::VARR);
1387 if (it != mapTally.end())
1389 for (const uint256& _item : (*it).second.txids)
1391 transactions.push_back(_item.GetHex());
1394 obj.push_back(Pair("txids", transactions));
1395 ret.push_back(obj);
1399 if (fByAccounts)
1401 for (std::map<std::string, tallyitem>::iterator it = mapAccountTally.begin(); it != mapAccountTally.end(); ++it)
1403 CAmount nAmount = (*it).second.nAmount;
1404 int nConf = (*it).second.nConf;
1405 UniValue obj(UniValue::VOBJ);
1406 if((*it).second.fIsWatchonly)
1407 obj.push_back(Pair("involvesWatchonly", true));
1408 obj.push_back(Pair("account", (*it).first));
1409 obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1410 obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1411 ret.push_back(obj);
1415 return ret;
1418 UniValue listreceivedbyaddress(const JSONRPCRequest& request)
1420 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1421 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1422 return NullUniValue;
1425 if (request.fHelp || request.params.size() > 3)
1426 throw std::runtime_error(
1427 "listreceivedbyaddress ( minconf include_empty include_watchonly)\n"
1428 "\nList balances by receiving address.\n"
1429 "\nArguments:\n"
1430 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1431 "2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1432 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1434 "\nResult:\n"
1435 "[\n"
1436 " {\n"
1437 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1438 " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1439 " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1440 " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
1441 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1442 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1443 " \"txids\": [\n"
1444 " n, (numeric) The ids of transactions received with the address \n"
1445 " ...\n"
1446 " ]\n"
1447 " }\n"
1448 " ,...\n"
1449 "]\n"
1451 "\nExamples:\n"
1452 + HelpExampleCli("listreceivedbyaddress", "")
1453 + HelpExampleCli("listreceivedbyaddress", "6 true")
1454 + HelpExampleRpc("listreceivedbyaddress", "6, true, true")
1457 ObserveSafeMode();
1458 LOCK2(cs_main, pwallet->cs_wallet);
1460 return ListReceived(pwallet, request.params, false);
1463 UniValue listreceivedbyaccount(const JSONRPCRequest& request)
1465 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1466 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1467 return NullUniValue;
1470 if (request.fHelp || request.params.size() > 3)
1471 throw std::runtime_error(
1472 "listreceivedbyaccount ( minconf include_empty include_watchonly)\n"
1473 "\nDEPRECATED. List balances by account.\n"
1474 "\nArguments:\n"
1475 "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1476 "2. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1477 "3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1479 "\nResult:\n"
1480 "[\n"
1481 " {\n"
1482 " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1483 " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1484 " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1485 " \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n"
1486 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1487 " }\n"
1488 " ,...\n"
1489 "]\n"
1491 "\nExamples:\n"
1492 + HelpExampleCli("listreceivedbyaccount", "")
1493 + HelpExampleCli("listreceivedbyaccount", "6 true")
1494 + HelpExampleRpc("listreceivedbyaccount", "6, true, true")
1497 ObserveSafeMode();
1498 LOCK2(cs_main, pwallet->cs_wallet);
1500 return ListReceived(pwallet, request.params, true);
1503 static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
1505 if (IsValidDestination(dest)) {
1506 entry.push_back(Pair("address", EncodeDestination(dest)));
1511 * List transactions based on the given criteria.
1513 * @param pwallet The wallet.
1514 * @param wtx The wallet transaction.
1515 * @param strAccount The account, if any, or "*" for all.
1516 * @param nMinDepth The minimum confirmation depth.
1517 * @param fLong Whether to include the JSON version of the transaction.
1518 * @param ret The UniValue into which the result is stored.
1519 * @param filter The "is mine" filter bool.
1521 void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
1523 CAmount nFee;
1524 std::string strSentAccount;
1525 std::list<COutputEntry> listReceived;
1526 std::list<COutputEntry> listSent;
1528 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
1530 bool fAllAccounts = (strAccount == std::string("*"));
1531 bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
1533 // Sent
1534 if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1536 for (const COutputEntry& s : listSent)
1538 UniValue entry(UniValue::VOBJ);
1539 if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) {
1540 entry.push_back(Pair("involvesWatchonly", true));
1542 entry.push_back(Pair("account", strSentAccount));
1543 MaybePushAddress(entry, s.destination);
1544 entry.push_back(Pair("category", "send"));
1545 entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
1546 if (pwallet->mapAddressBook.count(s.destination)) {
1547 entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name));
1549 entry.push_back(Pair("vout", s.vout));
1550 entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1551 if (fLong)
1552 WalletTxToJSON(wtx, entry);
1553 entry.push_back(Pair("abandoned", wtx.isAbandoned()));
1554 ret.push_back(entry);
1558 // Received
1559 if (listReceived.size() > 0 && wtx.GetDepthInMainChain() >= nMinDepth)
1561 for (const COutputEntry& r : listReceived)
1563 std::string account;
1564 if (pwallet->mapAddressBook.count(r.destination)) {
1565 account = pwallet->mapAddressBook[r.destination].name;
1567 if (fAllAccounts || (account == strAccount))
1569 UniValue entry(UniValue::VOBJ);
1570 if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) {
1571 entry.push_back(Pair("involvesWatchonly", true));
1573 entry.push_back(Pair("account", account));
1574 MaybePushAddress(entry, r.destination);
1575 if (wtx.IsCoinBase())
1577 if (wtx.GetDepthInMainChain() < 1)
1578 entry.push_back(Pair("category", "orphan"));
1579 else if (wtx.GetBlocksToMaturity() > 0)
1580 entry.push_back(Pair("category", "immature"));
1581 else
1582 entry.push_back(Pair("category", "generate"));
1584 else
1586 entry.push_back(Pair("category", "receive"));
1588 entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
1589 if (pwallet->mapAddressBook.count(r.destination)) {
1590 entry.push_back(Pair("label", account));
1592 entry.push_back(Pair("vout", r.vout));
1593 if (fLong)
1594 WalletTxToJSON(wtx, entry);
1595 ret.push_back(entry);
1601 void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccount, UniValue& ret)
1603 bool fAllAccounts = (strAccount == std::string("*"));
1605 if (fAllAccounts || acentry.strAccount == strAccount)
1607 UniValue entry(UniValue::VOBJ);
1608 entry.push_back(Pair("account", acentry.strAccount));
1609 entry.push_back(Pair("category", "move"));
1610 entry.push_back(Pair("time", acentry.nTime));
1611 entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1612 entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1613 entry.push_back(Pair("comment", acentry.strComment));
1614 ret.push_back(entry);
1618 UniValue listtransactions(const JSONRPCRequest& request)
1620 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1621 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1622 return NullUniValue;
1625 if (request.fHelp || request.params.size() > 4)
1626 throw std::runtime_error(
1627 "listtransactions ( \"account\" count skip include_watchonly)\n"
1628 "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1629 "\nArguments:\n"
1630 "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1631 "2. count (numeric, optional, default=10) The number of transactions to return\n"
1632 "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
1633 "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1634 "\nResult:\n"
1635 "[\n"
1636 " {\n"
1637 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
1638 " It will be \"\" for the default account.\n"
1639 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for \n"
1640 " move transactions (category = move).\n"
1641 " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1642 " transaction between accounts, and not associated with an address,\n"
1643 " transaction id or block. 'send' and 'receive' transactions are \n"
1644 " associated with an address, transaction id and block details\n"
1645 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
1646 " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1647 " and for the 'move' category for inbound funds.\n"
1648 " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
1649 " \"vout\": n, (numeric) the vout value\n"
1650 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1651 " 'send' category of transactions.\n"
1652 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and \n"
1653 " 'receive' category of transactions. Negative confirmations indicate the\n"
1654 " transaction conflicts with the block chain\n"
1655 " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
1656 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1657 " category of transactions.\n"
1658 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
1659 " category of transactions.\n"
1660 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1661 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1662 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1663 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1664 " for 'send' and 'receive' category of transactions.\n"
1665 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1666 " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
1667 " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1668 " negative amounts).\n"
1669 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1670 " may be unknown for unconfirmed transactions not in the mempool\n"
1671 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1672 " 'send' category of transactions.\n"
1673 " }\n"
1674 "]\n"
1676 "\nExamples:\n"
1677 "\nList the most recent 10 transactions in the systems\n"
1678 + HelpExampleCli("listtransactions", "") +
1679 "\nList transactions 100 to 120\n"
1680 + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1681 "\nAs a json rpc call\n"
1682 + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1685 ObserveSafeMode();
1686 LOCK2(cs_main, pwallet->cs_wallet);
1688 std::string strAccount = "*";
1689 if (!request.params[0].isNull())
1690 strAccount = request.params[0].get_str();
1691 int nCount = 10;
1692 if (!request.params[1].isNull())
1693 nCount = request.params[1].get_int();
1694 int nFrom = 0;
1695 if (!request.params[2].isNull())
1696 nFrom = request.params[2].get_int();
1697 isminefilter filter = ISMINE_SPENDABLE;
1698 if(!request.params[3].isNull())
1699 if(request.params[3].get_bool())
1700 filter = filter | ISMINE_WATCH_ONLY;
1702 if (nCount < 0)
1703 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1704 if (nFrom < 0)
1705 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1707 UniValue ret(UniValue::VARR);
1709 const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;
1711 // iterate backwards until we have nCount items to return:
1712 for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1714 CWalletTx *const pwtx = (*it).second.first;
1715 if (pwtx != nullptr)
1716 ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter);
1717 CAccountingEntry *const pacentry = (*it).second.second;
1718 if (pacentry != nullptr)
1719 AcentryToJSON(*pacentry, strAccount, ret);
1721 if ((int)ret.size() >= (nCount+nFrom)) break;
1723 // ret is newest to oldest
1725 if (nFrom > (int)ret.size())
1726 nFrom = ret.size();
1727 if ((nFrom + nCount) > (int)ret.size())
1728 nCount = ret.size() - nFrom;
1730 std::vector<UniValue> arrTmp = ret.getValues();
1732 std::vector<UniValue>::iterator first = arrTmp.begin();
1733 std::advance(first, nFrom);
1734 std::vector<UniValue>::iterator last = arrTmp.begin();
1735 std::advance(last, nFrom+nCount);
1737 if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end());
1738 if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first);
1740 std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest
1742 ret.clear();
1743 ret.setArray();
1744 ret.push_backV(arrTmp);
1746 return ret;
1749 UniValue listaccounts(const JSONRPCRequest& request)
1751 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1752 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1753 return NullUniValue;
1756 if (request.fHelp || request.params.size() > 2)
1757 throw std::runtime_error(
1758 "listaccounts ( minconf include_watchonly)\n"
1759 "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1760 "\nArguments:\n"
1761 "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1762 "2. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n"
1763 "\nResult:\n"
1764 "{ (json object where keys are account names, and values are numeric balances\n"
1765 " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1766 " ...\n"
1767 "}\n"
1768 "\nExamples:\n"
1769 "\nList account balances where there at least 1 confirmation\n"
1770 + HelpExampleCli("listaccounts", "") +
1771 "\nList account balances including zero confirmation transactions\n"
1772 + HelpExampleCli("listaccounts", "0") +
1773 "\nList account balances for 6 or more confirmations\n"
1774 + HelpExampleCli("listaccounts", "6") +
1775 "\nAs json rpc call\n"
1776 + HelpExampleRpc("listaccounts", "6")
1779 ObserveSafeMode();
1780 LOCK2(cs_main, pwallet->cs_wallet);
1782 int nMinDepth = 1;
1783 if (!request.params[0].isNull())
1784 nMinDepth = request.params[0].get_int();
1785 isminefilter includeWatchonly = ISMINE_SPENDABLE;
1786 if(!request.params[1].isNull())
1787 if(request.params[1].get_bool())
1788 includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
1790 std::map<std::string, CAmount> mapAccountBalances;
1791 for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) {
1792 if (IsMine(*pwallet, entry.first) & includeWatchonly) { // This address belongs to me
1793 mapAccountBalances[entry.second.name] = 0;
1797 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1798 const CWalletTx& wtx = pairWtx.second;
1799 CAmount nFee;
1800 std::string strSentAccount;
1801 std::list<COutputEntry> listReceived;
1802 std::list<COutputEntry> listSent;
1803 int nDepth = wtx.GetDepthInMainChain();
1804 if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1805 continue;
1806 wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
1807 mapAccountBalances[strSentAccount] -= nFee;
1808 for (const COutputEntry& s : listSent)
1809 mapAccountBalances[strSentAccount] -= s.amount;
1810 if (nDepth >= nMinDepth)
1812 for (const COutputEntry& r : listReceived)
1813 if (pwallet->mapAddressBook.count(r.destination)) {
1814 mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount;
1816 else
1817 mapAccountBalances[""] += r.amount;
1821 const std::list<CAccountingEntry>& acentries = pwallet->laccentries;
1822 for (const CAccountingEntry& entry : acentries)
1823 mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1825 UniValue ret(UniValue::VOBJ);
1826 for (const std::pair<std::string, CAmount>& accountBalance : mapAccountBalances) {
1827 ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1829 return ret;
1832 UniValue listsinceblock(const JSONRPCRequest& request)
1834 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1835 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1836 return NullUniValue;
1839 if (request.fHelp || request.params.size() > 4)
1840 throw std::runtime_error(
1841 "listsinceblock ( \"blockhash\" target_confirmations include_watchonly include_removed )\n"
1842 "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
1843 "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
1844 "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
1845 "\nArguments:\n"
1846 "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1847 "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"
1848 "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1849 "4. include_removed: (bool, optional, default=true) Show transactions that were removed due to a reorg in the \"removed\" array\n"
1850 " (not guaranteed to work on pruned nodes)\n"
1851 "\nResult:\n"
1852 "{\n"
1853 " \"transactions\": [\n"
1854 " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1855 " \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
1856 " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1857 " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1858 " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1859 " \"vout\" : n, (numeric) the vout value\n"
1860 " \"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"
1861 " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1862 " When it's < 0, it means the transaction conflicted that many blocks ago.\n"
1863 " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1864 " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
1865 " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1866 " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1867 " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1868 " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1869 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1870 " may be unknown for unconfirmed transactions not in the mempool\n"
1871 " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n"
1872 " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1873 " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1874 " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1875 " ],\n"
1876 " \"removed\": [\n"
1877 " <structure is the same as \"transactions\" above, only present if include_removed=true>\n"
1878 " 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"
1879 " ],\n"
1880 " \"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"
1881 "}\n"
1882 "\nExamples:\n"
1883 + HelpExampleCli("listsinceblock", "")
1884 + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1885 + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1888 ObserveSafeMode();
1889 LOCK2(cs_main, pwallet->cs_wallet);
1891 const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain.
1892 const CBlockIndex* paltindex = nullptr; // Block index of the specified block, even if it's in a deactivated chain.
1893 int target_confirms = 1;
1894 isminefilter filter = ISMINE_SPENDABLE;
1896 if (!request.params[0].isNull()) {
1897 uint256 blockId;
1899 blockId.SetHex(request.params[0].get_str());
1900 BlockMap::iterator it = mapBlockIndex.find(blockId);
1901 if (it != mapBlockIndex.end()) {
1902 paltindex = pindex = it->second;
1903 if (chainActive[pindex->nHeight] != pindex) {
1904 // the block being asked for is a part of a deactivated chain;
1905 // we don't want to depend on its perceived height in the block
1906 // chain, we want to instead use the last common ancestor
1907 pindex = chainActive.FindFork(pindex);
1912 if (!request.params[1].isNull()) {
1913 target_confirms = request.params[1].get_int();
1915 if (target_confirms < 1) {
1916 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1920 if (!request.params[2].isNull() && request.params[2].get_bool()) {
1921 filter = filter | ISMINE_WATCH_ONLY;
1924 bool include_removed = (request.params[3].isNull() || request.params[3].get_bool());
1926 int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1928 UniValue transactions(UniValue::VARR);
1930 for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1931 CWalletTx tx = pairWtx.second;
1933 if (depth == -1 || tx.GetDepthInMainChain() < depth) {
1934 ListTransactions(pwallet, tx, "*", 0, true, transactions, filter);
1938 // when a reorg'd block is requested, we also list any relevant transactions
1939 // in the blocks of the chain that was detached
1940 UniValue removed(UniValue::VARR);
1941 while (include_removed && paltindex && paltindex != pindex) {
1942 CBlock block;
1943 if (!ReadBlockFromDisk(block, paltindex, Params().GetConsensus())) {
1944 throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
1946 for (const CTransactionRef& tx : block.vtx) {
1947 auto it = pwallet->mapWallet.find(tx->GetHash());
1948 if (it != pwallet->mapWallet.end()) {
1949 // We want all transactions regardless of confirmation count to appear here,
1950 // even negative confirmation ones, hence the big negative.
1951 ListTransactions(pwallet, it->second, "*", -100000000, true, removed, filter);
1954 paltindex = paltindex->pprev;
1957 CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
1958 uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
1960 UniValue ret(UniValue::VOBJ);
1961 ret.push_back(Pair("transactions", transactions));
1962 if (include_removed) ret.push_back(Pair("removed", removed));
1963 ret.push_back(Pair("lastblock", lastblock.GetHex()));
1965 return ret;
1968 UniValue gettransaction(const JSONRPCRequest& request)
1970 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1971 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1972 return NullUniValue;
1975 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
1976 throw std::runtime_error(
1977 "gettransaction \"txid\" ( include_watchonly )\n"
1978 "\nGet detailed information about in-wallet transaction <txid>\n"
1979 "\nArguments:\n"
1980 "1. \"txid\" (string, required) The transaction id\n"
1981 "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n"
1982 "\nResult:\n"
1983 "{\n"
1984 " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
1985 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1986 " 'send' category of transactions.\n"
1987 " \"confirmations\" : n, (numeric) The number of confirmations\n"
1988 " \"blockhash\" : \"hash\", (string) The block hash\n"
1989 " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
1990 " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
1991 " \"txid\" : \"transactionid\", (string) The transaction id.\n"
1992 " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
1993 " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
1994 " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
1995 " may be unknown for unconfirmed transactions not in the mempool\n"
1996 " \"details\" : [\n"
1997 " {\n"
1998 " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
1999 " \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n"
2000 " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
2001 " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
2002 " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
2003 " \"vout\" : n, (numeric) the vout value\n"
2004 " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
2005 " 'send' category of transactions.\n"
2006 " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
2007 " 'send' category of transactions.\n"
2008 " }\n"
2009 " ,...\n"
2010 " ],\n"
2011 " \"hex\" : \"data\" (string) Raw data for transaction\n"
2012 "}\n"
2014 "\nExamples:\n"
2015 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2016 + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
2017 + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2020 ObserveSafeMode();
2021 LOCK2(cs_main, pwallet->cs_wallet);
2023 uint256 hash;
2024 hash.SetHex(request.params[0].get_str());
2026 isminefilter filter = ISMINE_SPENDABLE;
2027 if(!request.params[1].isNull())
2028 if(request.params[1].get_bool())
2029 filter = filter | ISMINE_WATCH_ONLY;
2031 UniValue entry(UniValue::VOBJ);
2032 auto it = pwallet->mapWallet.find(hash);
2033 if (it == pwallet->mapWallet.end()) {
2034 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2036 const CWalletTx& wtx = it->second;
2038 CAmount nCredit = wtx.GetCredit(filter);
2039 CAmount nDebit = wtx.GetDebit(filter);
2040 CAmount nNet = nCredit - nDebit;
2041 CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
2043 entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
2044 if (wtx.IsFromMe(filter))
2045 entry.push_back(Pair("fee", ValueFromAmount(nFee)));
2047 WalletTxToJSON(wtx, entry);
2049 UniValue details(UniValue::VARR);
2050 ListTransactions(pwallet, wtx, "*", 0, false, details, filter);
2051 entry.push_back(Pair("details", details));
2053 std::string strHex = EncodeHexTx(static_cast<CTransaction>(wtx), RPCSerializationFlags());
2054 entry.push_back(Pair("hex", strHex));
2056 return entry;
2059 UniValue abandontransaction(const JSONRPCRequest& request)
2061 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2062 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2063 return NullUniValue;
2066 if (request.fHelp || request.params.size() != 1)
2067 throw std::runtime_error(
2068 "abandontransaction \"txid\"\n"
2069 "\nMark in-wallet transaction <txid> as abandoned\n"
2070 "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
2071 "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
2072 "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
2073 "It has no effect on transactions which are already conflicted or abandoned.\n"
2074 "\nArguments:\n"
2075 "1. \"txid\" (string, required) The transaction id\n"
2076 "\nResult:\n"
2077 "\nExamples:\n"
2078 + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2079 + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2082 ObserveSafeMode();
2083 LOCK2(cs_main, pwallet->cs_wallet);
2085 uint256 hash;
2086 hash.SetHex(request.params[0].get_str());
2088 if (!pwallet->mapWallet.count(hash)) {
2089 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2091 if (!pwallet->AbandonTransaction(hash)) {
2092 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment");
2095 return NullUniValue;
2099 UniValue backupwallet(const JSONRPCRequest& request)
2101 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2102 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2103 return NullUniValue;
2106 if (request.fHelp || request.params.size() != 1)
2107 throw std::runtime_error(
2108 "backupwallet \"destination\"\n"
2109 "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
2110 "\nArguments:\n"
2111 "1. \"destination\" (string) The destination directory or file\n"
2112 "\nExamples:\n"
2113 + HelpExampleCli("backupwallet", "\"backup.dat\"")
2114 + HelpExampleRpc("backupwallet", "\"backup.dat\"")
2117 LOCK2(cs_main, pwallet->cs_wallet);
2119 std::string strDest = request.params[0].get_str();
2120 if (!pwallet->BackupWallet(strDest)) {
2121 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
2124 return NullUniValue;
2128 UniValue keypoolrefill(const JSONRPCRequest& request)
2130 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2131 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2132 return NullUniValue;
2135 if (request.fHelp || request.params.size() > 1)
2136 throw std::runtime_error(
2137 "keypoolrefill ( newsize )\n"
2138 "\nFills the keypool."
2139 + HelpRequiringPassphrase(pwallet) + "\n"
2140 "\nArguments\n"
2141 "1. newsize (numeric, optional, default=100) The new keypool size\n"
2142 "\nExamples:\n"
2143 + HelpExampleCli("keypoolrefill", "")
2144 + HelpExampleRpc("keypoolrefill", "")
2147 LOCK2(cs_main, pwallet->cs_wallet);
2149 // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
2150 unsigned int kpSize = 0;
2151 if (!request.params[0].isNull()) {
2152 if (request.params[0].get_int() < 0)
2153 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
2154 kpSize = (unsigned int)request.params[0].get_int();
2157 EnsureWalletIsUnlocked(pwallet);
2158 pwallet->TopUpKeyPool(kpSize);
2160 if (pwallet->GetKeyPoolSize() < kpSize) {
2161 throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
2164 return NullUniValue;
2168 static void LockWallet(CWallet* pWallet)
2170 LOCK(pWallet->cs_wallet);
2171 pWallet->nRelockTime = 0;
2172 pWallet->Lock();
2175 UniValue walletpassphrase(const JSONRPCRequest& request)
2177 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2178 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2179 return NullUniValue;
2182 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2183 throw std::runtime_error(
2184 "walletpassphrase \"passphrase\" timeout\n"
2185 "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
2186 "This is needed prior to performing transactions related to private keys such as sending bitcoins\n"
2187 "\nArguments:\n"
2188 "1. \"passphrase\" (string, required) The wallet passphrase\n"
2189 "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n"
2190 "\nNote:\n"
2191 "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
2192 "time that overrides the old one.\n"
2193 "\nExamples:\n"
2194 "\nUnlock the wallet for 60 seconds\n"
2195 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
2196 "\nLock the wallet again (before 60 seconds)\n"
2197 + HelpExampleCli("walletlock", "") +
2198 "\nAs json rpc call\n"
2199 + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
2203 LOCK2(cs_main, pwallet->cs_wallet);
2205 if (request.fHelp)
2206 return true;
2207 if (!pwallet->IsCrypted()) {
2208 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2211 // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed
2212 SecureString strWalletPass;
2213 strWalletPass.reserve(100);
2214 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2215 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2216 strWalletPass = request.params[0].get_str().c_str();
2218 if (strWalletPass.length() > 0)
2220 if (!pwallet->Unlock(strWalletPass)) {
2221 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2224 else
2225 throw std::runtime_error(
2226 "walletpassphrase <passphrase> <timeout>\n"
2227 "Stores the wallet decryption key in memory for <timeout> seconds.");
2229 pwallet->TopUpKeyPool();
2231 int64_t nSleepTime = request.params[1].get_int64();
2232 pwallet->nRelockTime = GetTime() + nSleepTime;
2233 RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);
2235 return NullUniValue;
2239 UniValue walletpassphrasechange(const JSONRPCRequest& request)
2241 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2242 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2243 return NullUniValue;
2246 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 2)) {
2247 throw std::runtime_error(
2248 "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
2249 "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
2250 "\nArguments:\n"
2251 "1. \"oldpassphrase\" (string) The current passphrase\n"
2252 "2. \"newpassphrase\" (string) The new passphrase\n"
2253 "\nExamples:\n"
2254 + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
2255 + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
2259 LOCK2(cs_main, pwallet->cs_wallet);
2261 if (request.fHelp)
2262 return true;
2263 if (!pwallet->IsCrypted()) {
2264 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2267 // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2268 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2269 SecureString strOldWalletPass;
2270 strOldWalletPass.reserve(100);
2271 strOldWalletPass = request.params[0].get_str().c_str();
2273 SecureString strNewWalletPass;
2274 strNewWalletPass.reserve(100);
2275 strNewWalletPass = request.params[1].get_str().c_str();
2277 if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
2278 throw std::runtime_error(
2279 "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2280 "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2282 if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) {
2283 throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2286 return NullUniValue;
2290 UniValue walletlock(const JSONRPCRequest& request)
2292 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2293 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2294 return NullUniValue;
2297 if (pwallet->IsCrypted() && (request.fHelp || request.params.size() != 0)) {
2298 throw std::runtime_error(
2299 "walletlock\n"
2300 "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2301 "After calling this method, you will need to call walletpassphrase again\n"
2302 "before being able to call any methods which require the wallet to be unlocked.\n"
2303 "\nExamples:\n"
2304 "\nSet the passphrase for 2 minutes to perform a transaction\n"
2305 + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2306 "\nPerform a send (requires passphrase set)\n"
2307 + HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 1.0") +
2308 "\nClear the passphrase since we are done before 2 minutes is up\n"
2309 + HelpExampleCli("walletlock", "") +
2310 "\nAs json rpc call\n"
2311 + HelpExampleRpc("walletlock", "")
2315 LOCK2(cs_main, pwallet->cs_wallet);
2317 if (request.fHelp)
2318 return true;
2319 if (!pwallet->IsCrypted()) {
2320 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
2323 pwallet->Lock();
2324 pwallet->nRelockTime = 0;
2326 return NullUniValue;
2330 UniValue encryptwallet(const JSONRPCRequest& request)
2332 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2333 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2334 return NullUniValue;
2337 if (!pwallet->IsCrypted() && (request.fHelp || request.params.size() != 1)) {
2338 throw std::runtime_error(
2339 "encryptwallet \"passphrase\"\n"
2340 "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2341 "After this, any calls that interact with private keys such as sending or signing \n"
2342 "will require the passphrase to be set prior the making these calls.\n"
2343 "Use the walletpassphrase call for this, and then walletlock call.\n"
2344 "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2345 "Note that this will shutdown the server.\n"
2346 "\nArguments:\n"
2347 "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2348 "\nExamples:\n"
2349 "\nEncrypt your wallet\n"
2350 + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2351 "\nNow set the passphrase to use the wallet, such as for signing or sending bitcoin\n"
2352 + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2353 "\nNow we can do something like sign\n"
2354 + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
2355 "\nNow lock the wallet again by removing the passphrase\n"
2356 + HelpExampleCli("walletlock", "") +
2357 "\nAs a json rpc call\n"
2358 + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2362 LOCK2(cs_main, pwallet->cs_wallet);
2364 if (request.fHelp)
2365 return true;
2366 if (pwallet->IsCrypted()) {
2367 throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
2370 // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2371 // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2372 SecureString strWalletPass;
2373 strWalletPass.reserve(100);
2374 strWalletPass = request.params[0].get_str().c_str();
2376 if (strWalletPass.length() < 1)
2377 throw std::runtime_error(
2378 "encryptwallet <passphrase>\n"
2379 "Encrypts the wallet with <passphrase>.");
2381 if (!pwallet->EncryptWallet(strWalletPass)) {
2382 throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
2385 // BDB seems to have a bad habit of writing old data into
2386 // slack space in .dat files; that is bad if the old data is
2387 // unencrypted private keys. So:
2388 StartShutdown();
2389 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.";
2392 UniValue lockunspent(const JSONRPCRequest& request)
2394 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2395 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2396 return NullUniValue;
2399 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2400 throw std::runtime_error(
2401 "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
2402 "\nUpdates list of temporarily unspendable outputs.\n"
2403 "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2404 "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2405 "A locked transaction output will not be chosen by automatic coin selection, when spending bitcoins.\n"
2406 "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2407 "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2408 "Also see the listunspent call\n"
2409 "\nArguments:\n"
2410 "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2411 "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n"
2412 " [ (json array of json objects)\n"
2413 " {\n"
2414 " \"txid\":\"id\", (string) The transaction id\n"
2415 " \"vout\": n (numeric) The output number\n"
2416 " }\n"
2417 " ,...\n"
2418 " ]\n"
2420 "\nResult:\n"
2421 "true|false (boolean) Whether the command was successful or not\n"
2423 "\nExamples:\n"
2424 "\nList the unspent transactions\n"
2425 + HelpExampleCli("listunspent", "") +
2426 "\nLock an unspent transaction\n"
2427 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2428 "\nList the locked transactions\n"
2429 + HelpExampleCli("listlockunspent", "") +
2430 "\nUnlock the transaction again\n"
2431 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2432 "\nAs a json rpc call\n"
2433 + HelpExampleRpc("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2436 LOCK2(cs_main, pwallet->cs_wallet);
2438 RPCTypeCheckArgument(request.params[0], UniValue::VBOOL);
2440 bool fUnlock = request.params[0].get_bool();
2442 if (request.params[1].isNull()) {
2443 if (fUnlock)
2444 pwallet->UnlockAllCoins();
2445 return true;
2448 RPCTypeCheckArgument(request.params[1], UniValue::VARR);
2450 UniValue outputs = request.params[1].get_array();
2451 for (unsigned int idx = 0; idx < outputs.size(); idx++) {
2452 const UniValue& output = outputs[idx];
2453 if (!output.isObject())
2454 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object");
2455 const UniValue& o = output.get_obj();
2457 RPCTypeCheckObj(o,
2459 {"txid", UniValueType(UniValue::VSTR)},
2460 {"vout", UniValueType(UniValue::VNUM)},
2463 std::string txid = find_value(o, "txid").get_str();
2464 if (!IsHex(txid))
2465 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
2467 int nOutput = find_value(o, "vout").get_int();
2468 if (nOutput < 0)
2469 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
2471 COutPoint outpt(uint256S(txid), nOutput);
2473 if (fUnlock)
2474 pwallet->UnlockCoin(outpt);
2475 else
2476 pwallet->LockCoin(outpt);
2479 return true;
2482 UniValue listlockunspent(const JSONRPCRequest& request)
2484 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2485 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2486 return NullUniValue;
2489 if (request.fHelp || request.params.size() > 0)
2490 throw std::runtime_error(
2491 "listlockunspent\n"
2492 "\nReturns list of temporarily unspendable outputs.\n"
2493 "See the lockunspent call to lock and unlock transactions for spending.\n"
2494 "\nResult:\n"
2495 "[\n"
2496 " {\n"
2497 " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
2498 " \"vout\" : n (numeric) The vout value\n"
2499 " }\n"
2500 " ,...\n"
2501 "]\n"
2502 "\nExamples:\n"
2503 "\nList the unspent transactions\n"
2504 + HelpExampleCli("listunspent", "") +
2505 "\nLock an unspent transaction\n"
2506 + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2507 "\nList the locked transactions\n"
2508 + HelpExampleCli("listlockunspent", "") +
2509 "\nUnlock the transaction again\n"
2510 + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2511 "\nAs a json rpc call\n"
2512 + HelpExampleRpc("listlockunspent", "")
2515 ObserveSafeMode();
2516 LOCK2(cs_main, pwallet->cs_wallet);
2518 std::vector<COutPoint> vOutpts;
2519 pwallet->ListLockedCoins(vOutpts);
2521 UniValue ret(UniValue::VARR);
2523 for (COutPoint &outpt : vOutpts) {
2524 UniValue o(UniValue::VOBJ);
2526 o.push_back(Pair("txid", outpt.hash.GetHex()));
2527 o.push_back(Pair("vout", (int)outpt.n));
2528 ret.push_back(o);
2531 return ret;
2534 UniValue settxfee(const JSONRPCRequest& request)
2536 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2537 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2538 return NullUniValue;
2541 if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
2542 throw std::runtime_error(
2543 "settxfee amount\n"
2544 "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
2545 "\nArguments:\n"
2546 "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n"
2547 "\nResult\n"
2548 "true|false (boolean) Returns true if successful\n"
2549 "\nExamples:\n"
2550 + HelpExampleCli("settxfee", "0.00001")
2551 + HelpExampleRpc("settxfee", "0.00001")
2554 LOCK2(cs_main, pwallet->cs_wallet);
2556 // Amount
2557 CAmount nAmount = AmountFromValue(request.params[0]);
2559 payTxFee = CFeeRate(nAmount, 1000);
2560 return true;
2563 UniValue getwalletinfo(const JSONRPCRequest& request)
2565 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2566 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2567 return NullUniValue;
2570 if (request.fHelp || request.params.size() != 0)
2571 throw std::runtime_error(
2572 "getwalletinfo\n"
2573 "Returns an object containing various wallet state info.\n"
2574 "\nResult:\n"
2575 "{\n"
2576 " \"walletname\": xxxxx, (string) the wallet name\n"
2577 " \"walletversion\": xxxxx, (numeric) the wallet version\n"
2578 " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2579 " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2580 " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
2581 " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
2582 " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n"
2583 " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated (only counts external keys)\n"
2584 " \"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"
2585 " \"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"
2586 " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
2587 " \"hdmasterkeyid\": \"<hash160>\" (string) the Hash160 of the HD master pubkey\n"
2588 "}\n"
2589 "\nExamples:\n"
2590 + HelpExampleCli("getwalletinfo", "")
2591 + HelpExampleRpc("getwalletinfo", "")
2594 ObserveSafeMode();
2595 LOCK2(cs_main, pwallet->cs_wallet);
2597 UniValue obj(UniValue::VOBJ);
2599 size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
2600 obj.push_back(Pair("walletname", pwallet->GetName()));
2601 obj.push_back(Pair("walletversion", pwallet->GetVersion()));
2602 obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance())));
2603 obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance())));
2604 obj.push_back(Pair("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance())));
2605 obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size()));
2606 obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime()));
2607 obj.push_back(Pair("keypoolsize", (int64_t)kpExternalSize));
2608 CKeyID masterKeyID = pwallet->GetHDChain().masterKeyID;
2609 if (!masterKeyID.IsNull() && pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) {
2610 obj.push_back(Pair("keypoolsize_hd_internal", (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize)));
2612 if (pwallet->IsCrypted()) {
2613 obj.push_back(Pair("unlocked_until", pwallet->nRelockTime));
2615 obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
2616 if (!masterKeyID.IsNull())
2617 obj.push_back(Pair("hdmasterkeyid", masterKeyID.GetHex()));
2618 return obj;
2621 UniValue listwallets(const JSONRPCRequest& request)
2623 if (request.fHelp || request.params.size() != 0)
2624 throw std::runtime_error(
2625 "listwallets\n"
2626 "Returns a list of currently loaded wallets.\n"
2627 "For full information on the wallet, use \"getwalletinfo\"\n"
2628 "\nResult:\n"
2629 "[ (json array of strings)\n"
2630 " \"walletname\" (string) the wallet name\n"
2631 " ...\n"
2632 "]\n"
2633 "\nExamples:\n"
2634 + HelpExampleCli("listwallets", "")
2635 + HelpExampleRpc("listwallets", "")
2638 UniValue obj(UniValue::VARR);
2640 for (CWalletRef pwallet : vpwallets) {
2642 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2643 return NullUniValue;
2646 LOCK(pwallet->cs_wallet);
2648 obj.push_back(pwallet->GetName());
2651 return obj;
2654 UniValue resendwallettransactions(const JSONRPCRequest& request)
2656 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2657 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2658 return NullUniValue;
2661 if (request.fHelp || request.params.size() != 0)
2662 throw std::runtime_error(
2663 "resendwallettransactions\n"
2664 "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2665 "Intended only for testing; the wallet code periodically re-broadcasts\n"
2666 "automatically.\n"
2667 "Returns an RPC error if -walletbroadcast is set to false.\n"
2668 "Returns array of transaction ids that were re-broadcast.\n"
2671 if (!g_connman)
2672 throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
2674 LOCK2(cs_main, pwallet->cs_wallet);
2676 if (!pwallet->GetBroadcastTransactions()) {
2677 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast");
2680 std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get());
2681 UniValue result(UniValue::VARR);
2682 for (const uint256& txid : txids)
2684 result.push_back(txid.ToString());
2686 return result;
2689 UniValue listunspent(const JSONRPCRequest& request)
2691 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2692 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2693 return NullUniValue;
2696 if (request.fHelp || request.params.size() > 5)
2697 throw std::runtime_error(
2698 "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
2699 "\nReturns array of unspent transaction outputs\n"
2700 "with between minconf and maxconf (inclusive) confirmations.\n"
2701 "Optionally filter to only include txouts paid to specified addresses.\n"
2702 "\nArguments:\n"
2703 "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
2704 "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
2705 "3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
2706 " [\n"
2707 " \"address\" (string) bitcoin address\n"
2708 " ,...\n"
2709 " ]\n"
2710 "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
2711 " See description of \"safe\" attribute below.\n"
2712 "5. query_options (json, optional) JSON with query options\n"
2713 " {\n"
2714 " \"minimumAmount\" (numeric or string, default=0) Minimum value of each UTXO in " + CURRENCY_UNIT + "\n"
2715 " \"maximumAmount\" (numeric or string, default=unlimited) Maximum value of each UTXO in " + CURRENCY_UNIT + "\n"
2716 " \"maximumCount\" (numeric or string, default=unlimited) Maximum number of UTXOs\n"
2717 " \"minimumSumAmount\" (numeric or string, default=unlimited) Minimum sum value of all UTXOs in " + CURRENCY_UNIT + "\n"
2718 " }\n"
2719 "\nResult\n"
2720 "[ (array of json object)\n"
2721 " {\n"
2722 " \"txid\" : \"txid\", (string) the transaction id \n"
2723 " \"vout\" : n, (numeric) the vout value\n"
2724 " \"address\" : \"address\", (string) the bitcoin address\n"
2725 " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
2726 " \"scriptPubKey\" : \"key\", (string) the script key\n"
2727 " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
2728 " \"confirmations\" : n, (numeric) The number of confirmations\n"
2729 " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
2730 " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
2731 " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
2732 " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n"
2733 " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
2734 " and are not eligible for spending by fundrawtransaction and sendtoaddress.\n"
2735 " }\n"
2736 " ,...\n"
2737 "]\n"
2739 "\nExamples\n"
2740 + HelpExampleCli("listunspent", "")
2741 + HelpExampleCli("listunspent", "6 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2742 + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"")
2743 + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
2744 + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
2747 ObserveSafeMode();
2749 int nMinDepth = 1;
2750 if (!request.params[0].isNull()) {
2751 RPCTypeCheckArgument(request.params[0], UniValue::VNUM);
2752 nMinDepth = request.params[0].get_int();
2755 int nMaxDepth = 9999999;
2756 if (!request.params[1].isNull()) {
2757 RPCTypeCheckArgument(request.params[1], UniValue::VNUM);
2758 nMaxDepth = request.params[1].get_int();
2761 std::set<CTxDestination> destinations;
2762 if (!request.params[2].isNull()) {
2763 RPCTypeCheckArgument(request.params[2], UniValue::VARR);
2764 UniValue inputs = request.params[2].get_array();
2765 for (unsigned int idx = 0; idx < inputs.size(); idx++) {
2766 const UniValue& input = inputs[idx];
2767 CTxDestination dest = DecodeDestination(input.get_str());
2768 if (!IsValidDestination(dest)) {
2769 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + input.get_str());
2771 if (!destinations.insert(dest).second) {
2772 throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
2777 bool include_unsafe = true;
2778 if (!request.params[3].isNull()) {
2779 RPCTypeCheckArgument(request.params[3], UniValue::VBOOL);
2780 include_unsafe = request.params[3].get_bool();
2783 CAmount nMinimumAmount = 0;
2784 CAmount nMaximumAmount = MAX_MONEY;
2785 CAmount nMinimumSumAmount = MAX_MONEY;
2786 uint64_t nMaximumCount = 0;
2788 if (!request.params[4].isNull()) {
2789 const UniValue& options = request.params[4].get_obj();
2791 if (options.exists("minimumAmount"))
2792 nMinimumAmount = AmountFromValue(options["minimumAmount"]);
2794 if (options.exists("maximumAmount"))
2795 nMaximumAmount = AmountFromValue(options["maximumAmount"]);
2797 if (options.exists("minimumSumAmount"))
2798 nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
2800 if (options.exists("maximumCount"))
2801 nMaximumCount = options["maximumCount"].get_int64();
2804 UniValue results(UniValue::VARR);
2805 std::vector<COutput> vecOutputs;
2806 assert(pwallet != nullptr);
2807 LOCK2(cs_main, pwallet->cs_wallet);
2809 pwallet->AvailableCoins(vecOutputs, !include_unsafe, nullptr, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2810 for (const COutput& out : vecOutputs) {
2811 CTxDestination address;
2812 const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
2813 bool fValidAddress = ExtractDestination(scriptPubKey, address);
2815 if (destinations.size() && (!fValidAddress || !destinations.count(address)))
2816 continue;
2818 UniValue entry(UniValue::VOBJ);
2819 entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
2820 entry.push_back(Pair("vout", out.i));
2822 if (fValidAddress) {
2823 entry.push_back(Pair("address", EncodeDestination(address)));
2825 if (pwallet->mapAddressBook.count(address)) {
2826 entry.push_back(Pair("account", pwallet->mapAddressBook[address].name));
2829 if (scriptPubKey.IsPayToScriptHash()) {
2830 const CScriptID& hash = boost::get<CScriptID>(address);
2831 CScript redeemScript;
2832 if (pwallet->GetCScript(hash, redeemScript)) {
2833 entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
2838 entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
2839 entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue)));
2840 entry.push_back(Pair("confirmations", out.nDepth));
2841 entry.push_back(Pair("spendable", out.fSpendable));
2842 entry.push_back(Pair("solvable", out.fSolvable));
2843 entry.push_back(Pair("safe", out.fSafe));
2844 results.push_back(entry);
2847 return results;
2850 UniValue fundrawtransaction(const JSONRPCRequest& request)
2852 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2853 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2854 return NullUniValue;
2857 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2858 throw std::runtime_error(
2859 "fundrawtransaction \"hexstring\" ( options )\n"
2860 "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
2861 "This will not modify existing inputs, and will add at most one change output to the outputs.\n"
2862 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
2863 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
2864 "The inputs added will not be signed, use signrawtransaction for that.\n"
2865 "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
2866 "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
2867 "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
2868 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
2869 "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
2870 "\nArguments:\n"
2871 "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
2872 "2. options (object, optional)\n"
2873 " {\n"
2874 " \"changeAddress\" (string, optional, default pool address) The bitcoin address to receive the change\n"
2875 " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
2876 " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
2877 " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
2878 " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific fee rate in " + CURRENCY_UNIT + "/kB\n"
2879 " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
2880 " The fee will be equally deducted from the amount of each specified output.\n"
2881 " The outputs are specified by their zero-based index, before any change output is added.\n"
2882 " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
2883 " If no outputs are specified here, the sender pays the fee.\n"
2884 " [vout_index,...]\n"
2885 " \"replaceable\" (boolean, optional) Marks this transaction as BIP125 replaceable.\n"
2886 " Allows this transaction to be replaced by a transaction with higher fees\n"
2887 " \"conf_target\" (numeric, optional) Confirmation target (in blocks)\n"
2888 " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
2889 " \"UNSET\"\n"
2890 " \"ECONOMICAL\"\n"
2891 " \"CONSERVATIVE\"\n"
2892 " }\n"
2893 " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
2894 "\nResult:\n"
2895 "{\n"
2896 " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
2897 " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
2898 " \"changepos\": n (numeric) The position of the added change output, or -1\n"
2899 "}\n"
2900 "\nExamples:\n"
2901 "\nCreate a transaction with no inputs\n"
2902 + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
2903 "\nAdd sufficient unsigned inputs to meet the output value\n"
2904 + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
2905 "\nSign the transaction\n"
2906 + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
2907 "\nSend the transaction\n"
2908 + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
2911 ObserveSafeMode();
2912 RPCTypeCheck(request.params, {UniValue::VSTR});
2914 CCoinControl coinControl;
2915 int changePosition = -1;
2916 bool lockUnspents = false;
2917 UniValue subtractFeeFromOutputs;
2918 std::set<int> setSubtractFeeFromOutputs;
2920 if (!request.params[1].isNull()) {
2921 if (request.params[1].type() == UniValue::VBOOL) {
2922 // backward compatibility bool only fallback
2923 coinControl.fAllowWatchOnly = request.params[1].get_bool();
2925 else {
2926 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
2928 UniValue options = request.params[1];
2930 RPCTypeCheckObj(options,
2932 {"changeAddress", UniValueType(UniValue::VSTR)},
2933 {"changePosition", UniValueType(UniValue::VNUM)},
2934 {"includeWatching", UniValueType(UniValue::VBOOL)},
2935 {"lockUnspents", UniValueType(UniValue::VBOOL)},
2936 {"reserveChangeKey", UniValueType(UniValue::VBOOL)}, // DEPRECATED (and ignored), should be removed in 0.16 or so.
2937 {"feeRate", UniValueType()}, // will be checked below
2938 {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
2939 {"replaceable", UniValueType(UniValue::VBOOL)},
2940 {"conf_target", UniValueType(UniValue::VNUM)},
2941 {"estimate_mode", UniValueType(UniValue::VSTR)},
2943 true, true);
2945 if (options.exists("changeAddress")) {
2946 CTxDestination dest = DecodeDestination(options["changeAddress"].get_str());
2948 if (!IsValidDestination(dest)) {
2949 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "changeAddress must be a valid bitcoin address");
2952 coinControl.destChange = dest;
2955 if (options.exists("changePosition"))
2956 changePosition = options["changePosition"].get_int();
2958 if (options.exists("includeWatching"))
2959 coinControl.fAllowWatchOnly = options["includeWatching"].get_bool();
2961 if (options.exists("lockUnspents"))
2962 lockUnspents = options["lockUnspents"].get_bool();
2964 if (options.exists("feeRate"))
2966 coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"]));
2967 coinControl.fOverrideFeeRate = true;
2970 if (options.exists("subtractFeeFromOutputs"))
2971 subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
2973 if (options.exists("replaceable")) {
2974 coinControl.signalRbf = options["replaceable"].get_bool();
2976 if (options.exists("conf_target")) {
2977 if (options.exists("feeRate")) {
2978 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate");
2980 coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"]);
2982 if (options.exists("estimate_mode")) {
2983 if (options.exists("feeRate")) {
2984 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate");
2986 if (!FeeModeFromString(options["estimate_mode"].get_str(), coinControl.m_fee_mode)) {
2987 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
2993 // parse hex string from parameter
2994 CMutableTransaction tx;
2995 if (!DecodeHexTx(tx, request.params[0].get_str(), true))
2996 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
2998 if (tx.vout.size() == 0)
2999 throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
3001 if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size()))
3002 throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
3004 for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
3005 int pos = subtractFeeFromOutputs[idx].get_int();
3006 if (setSubtractFeeFromOutputs.count(pos))
3007 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
3008 if (pos < 0)
3009 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
3010 if (pos >= int(tx.vout.size()))
3011 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
3012 setSubtractFeeFromOutputs.insert(pos);
3015 CAmount nFeeOut;
3016 std::string strFailReason;
3018 if (!pwallet->FundTransaction(tx, nFeeOut, changePosition, strFailReason, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
3019 throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
3022 UniValue result(UniValue::VOBJ);
3023 result.push_back(Pair("hex", EncodeHexTx(tx)));
3024 result.push_back(Pair("changepos", changePosition));
3025 result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
3027 return result;
3030 UniValue bumpfee(const JSONRPCRequest& request)
3032 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3034 if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
3035 return NullUniValue;
3037 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
3038 throw std::runtime_error(
3039 "bumpfee \"txid\" ( options ) \n"
3040 "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
3041 "An opt-in RBF transaction with the given txid must be in the wallet.\n"
3042 "The command will pay the additional fee by decreasing (or perhaps removing) its change output.\n"
3043 "If the change output is not big enough to cover the increased fee, the command will currently fail\n"
3044 "instead of adding new inputs to compensate. (A future implementation could improve this.)\n"
3045 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
3046 "By default, the new fee will be calculated automatically using estimatefee.\n"
3047 "The user can specify a confirmation target for estimatefee.\n"
3048 "Alternatively, the user can specify totalFee, or use RPC settxfee to set a higher fee rate.\n"
3049 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
3050 "returned by getnetworkinfo) to enter the node's mempool.\n"
3051 "\nArguments:\n"
3052 "1. txid (string, required) The txid to be bumped\n"
3053 "2. options (object, optional)\n"
3054 " {\n"
3055 " \"confTarget\" (numeric, optional) Confirmation target (in blocks)\n"
3056 " \"totalFee\" (numeric, optional) Total fee (NOT feerate) to pay, in satoshis.\n"
3057 " In rare cases, the actual fee paid might be slightly higher than the specified\n"
3058 " totalFee if the tx change output has to be removed because it is too close to\n"
3059 " the dust threshold.\n"
3060 " \"replaceable\" (boolean, optional, default true) Whether the new transaction should still be\n"
3061 " marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
3062 " be left unchanged from the original. If false, any input sequence numbers in the\n"
3063 " original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
3064 " so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
3065 " still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
3066 " are replaceable).\n"
3067 " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
3068 " \"UNSET\"\n"
3069 " \"ECONOMICAL\"\n"
3070 " \"CONSERVATIVE\"\n"
3071 " }\n"
3072 "\nResult:\n"
3073 "{\n"
3074 " \"txid\": \"value\", (string) The id of the new transaction\n"
3075 " \"origfee\": n, (numeric) Fee of the replaced transaction\n"
3076 " \"fee\": n, (numeric) Fee of the new transaction\n"
3077 " \"errors\": [ str... ] (json array of strings) Errors encountered during processing (may be empty)\n"
3078 "}\n"
3079 "\nExamples:\n"
3080 "\nBump the fee, get the new transaction\'s txid\n" +
3081 HelpExampleCli("bumpfee", "<txid>"));
3084 RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
3085 uint256 hash;
3086 hash.SetHex(request.params[0].get_str());
3088 // optional parameters
3089 CAmount totalFee = 0;
3090 CCoinControl coin_control;
3091 coin_control.signalRbf = true;
3092 if (!request.params[1].isNull()) {
3093 UniValue options = request.params[1];
3094 RPCTypeCheckObj(options,
3096 {"confTarget", UniValueType(UniValue::VNUM)},
3097 {"totalFee", UniValueType(UniValue::VNUM)},
3098 {"replaceable", UniValueType(UniValue::VBOOL)},
3099 {"estimate_mode", UniValueType(UniValue::VSTR)},
3101 true, true);
3103 if (options.exists("confTarget") && options.exists("totalFee")) {
3104 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.");
3105 } else if (options.exists("confTarget")) { // TODO: alias this to conf_target
3106 coin_control.m_confirm_target = ParseConfirmTarget(options["confTarget"]);
3107 } else if (options.exists("totalFee")) {
3108 totalFee = options["totalFee"].get_int64();
3109 if (totalFee <= 0) {
3110 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid totalFee %s (must be greater than 0)", FormatMoney(totalFee)));
3114 if (options.exists("replaceable")) {
3115 coin_control.signalRbf = options["replaceable"].get_bool();
3117 if (options.exists("estimate_mode")) {
3118 if (!FeeModeFromString(options["estimate_mode"].get_str(), coin_control.m_fee_mode)) {
3119 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
3124 LOCK2(cs_main, pwallet->cs_wallet);
3125 EnsureWalletIsUnlocked(pwallet);
3127 CFeeBumper feeBump(pwallet, hash, coin_control, totalFee);
3128 BumpFeeResult res = feeBump.getResult();
3129 if (res != BumpFeeResult::OK)
3131 switch(res) {
3132 case BumpFeeResult::INVALID_ADDRESS_OR_KEY:
3133 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, feeBump.getErrors()[0]);
3134 break;
3135 case BumpFeeResult::INVALID_REQUEST:
3136 throw JSONRPCError(RPC_INVALID_REQUEST, feeBump.getErrors()[0]);
3137 break;
3138 case BumpFeeResult::INVALID_PARAMETER:
3139 throw JSONRPCError(RPC_INVALID_PARAMETER, feeBump.getErrors()[0]);
3140 break;
3141 case BumpFeeResult::WALLET_ERROR:
3142 throw JSONRPCError(RPC_WALLET_ERROR, feeBump.getErrors()[0]);
3143 break;
3144 default:
3145 throw JSONRPCError(RPC_MISC_ERROR, feeBump.getErrors()[0]);
3146 break;
3150 // sign bumped transaction
3151 if (!feeBump.signTransaction(pwallet)) {
3152 throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
3154 // commit the bumped transaction
3155 if(!feeBump.commit(pwallet)) {
3156 throw JSONRPCError(RPC_WALLET_ERROR, feeBump.getErrors()[0]);
3158 UniValue result(UniValue::VOBJ);
3159 result.push_back(Pair("txid", feeBump.getBumpedTxId().GetHex()));
3160 result.push_back(Pair("origfee", ValueFromAmount(feeBump.getOldFee())));
3161 result.push_back(Pair("fee", ValueFromAmount(feeBump.getNewFee())));
3162 UniValue errors(UniValue::VARR);
3163 for (const std::string& err: feeBump.getErrors())
3164 errors.push_back(err);
3165 result.push_back(Pair("errors", errors));
3167 return result;
3170 UniValue generate(const JSONRPCRequest& request)
3172 CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3174 if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3175 return NullUniValue;
3178 if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
3179 throw std::runtime_error(
3180 "generate nblocks ( maxtries )\n"
3181 "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n"
3182 "\nArguments:\n"
3183 "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
3184 "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
3185 "\nResult:\n"
3186 "[ blockhashes ] (array) hashes of blocks generated\n"
3187 "\nExamples:\n"
3188 "\nGenerate 11 blocks\n"
3189 + HelpExampleCli("generate", "11")
3193 int num_generate = request.params[0].get_int();
3194 uint64_t max_tries = 1000000;
3195 if (!request.params[1].isNull()) {
3196 max_tries = request.params[1].get_int();
3199 std::shared_ptr<CReserveScript> coinbase_script;
3200 pwallet->GetScriptForMining(coinbase_script);
3202 // If the keypool is exhausted, no script is returned at all. Catch this.
3203 if (!coinbase_script) {
3204 throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
3207 //throw an error if no script was provided
3208 if (coinbase_script->reserveScript.empty()) {
3209 throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available");
3212 return generateBlocks(coinbase_script, num_generate, max_tries, true);
3215 extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
3216 extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
3217 extern UniValue importprivkey(const JSONRPCRequest& request);
3218 extern UniValue importaddress(const JSONRPCRequest& request);
3219 extern UniValue importpubkey(const JSONRPCRequest& request);
3220 extern UniValue dumpwallet(const JSONRPCRequest& request);
3221 extern UniValue importwallet(const JSONRPCRequest& request);
3222 extern UniValue importprunedfunds(const JSONRPCRequest& request);
3223 extern UniValue removeprunedfunds(const JSONRPCRequest& request);
3224 extern UniValue importmulti(const JSONRPCRequest& request);
3226 static const CRPCCommand commands[] =
3227 { // category name actor (function) argNames
3228 // --------------------- ------------------------ ----------------------- ----------
3229 { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options"} },
3230 { "hidden", "resendwallettransactions", &resendwallettransactions, {} },
3231 { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
3232 { "wallet", "abortrescan", &abortrescan, {} },
3233 { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account"} },
3234 { "wallet", "addwitnessaddress", &addwitnessaddress, {"address","p2sh"} },
3235 { "wallet", "backupwallet", &backupwallet, {"destination"} },
3236 { "wallet", "bumpfee", &bumpfee, {"txid", "options"} },
3237 { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
3238 { "wallet", "dumpwallet", &dumpwallet, {"filename"} },
3239 { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
3240 { "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
3241 { "wallet", "getaccount", &getaccount, {"address"} },
3242 { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
3243 { "wallet", "getbalance", &getbalance, {"account","minconf","include_watchonly"} },
3244 { "wallet", "getnewaddress", &getnewaddress, {"account"} },
3245 { "wallet", "getrawchangeaddress", &getrawchangeaddress, {} },
3246 { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf"} },
3247 { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf"} },
3248 { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
3249 { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
3250 { "wallet", "getwalletinfo", &getwalletinfo, {} },
3251 { "wallet", "importmulti", &importmulti, {"requests","options"} },
3252 { "wallet", "importprivkey", &importprivkey, {"privkey","label","rescan"} },
3253 { "wallet", "importwallet", &importwallet, {"filename"} },
3254 { "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
3255 { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
3256 { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
3257 { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
3258 { "wallet", "listaccounts", &listaccounts, {"minconf","include_watchonly"} },
3259 { "wallet", "listaddressgroupings", &listaddressgroupings, {} },
3260 { "wallet", "listlockunspent", &listlockunspent, {} },
3261 { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, {"minconf","include_empty","include_watchonly"} },
3262 { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly"} },
3263 { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
3264 { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
3265 { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
3266 { "wallet", "listwallets", &listwallets, {} },
3267 { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
3268 { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
3269 { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
3270 { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
3271 { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
3272 { "wallet", "setaccount", &setaccount, {"address","account"} },
3273 { "wallet", "settxfee", &settxfee, {"amount"} },
3274 { "wallet", "signmessage", &signmessage, {"address","message"} },
3275 { "wallet", "walletlock", &walletlock, {} },
3276 { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
3277 { "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout"} },
3278 { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
3280 { "generating", "generate", &generate, {"nblocks","maxtries"} },
3283 void RegisterWalletRPCCommands(CRPCTable &t)
3285 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
3286 t.appendCommand(commands[vcidx].name, &commands[vcidx]);