Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

rpcwallet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Copyright (c) 2014-2020 The Dash Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include <amount.h>
8 #include <base58.h>
9 #include <chain.h>
10 #include <consensus/validation.h>
11 #include <core_io.h>
12 #include <httpserver.h>
13 #include <keepass.h>
14 #include <net.h>
15 #include <policy/feerate.h>
16 #include <policy/fees.h>
18 #include <rpc/mining.h>
19 #include <rpc/safemode.h>
20 #include <rpc/server.h>
21 #include <rpc/util.h>
22 #include <timedata.h>
23 #include <txmempool.h>
24 #include <util.h>
25 #include <utilmoneystr.h>
26 #include <validation.h>
27 #include <wallet/coincontrol.h>
28 #include <wallet/wallet.h>
29 #include <wallet/walletdb.h>
30 #include <wallet/walletutil.h>
31 
32 #include <init.h> // For StartShutdown
33 
36 
37 #include <stdint.h>
38 
39 #include <univalue.h>
40 
41 #include <functional>
42 
43 static const std::string WALLET_ENDPOINT_BASE = "/wallet/";
44 
46 {
47  if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
48  // wallet endpoint was used
49  std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
50  CWallet* pwallet = GetWallet(requestedWallet);
51  if (!pwallet) throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
52  return pwallet;
53  }
54 
55  std::vector<CWallet*> wallets = GetWallets();
56  return wallets.size() == 1 || (request.fHelp && wallets.size() > 0) ? wallets[0] : nullptr;
57 }
58 
59 std::string HelpRequiringPassphrase(CWallet * const pwallet)
60 {
61  return pwallet && pwallet->IsCrypted()
62  ? "\nRequires wallet passphrase to be set with walletpassphrase call."
63  : "";
64 }
65 
66 bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
67 {
68  if (pwallet) return true;
69  if (avoidException) return false;
70  if (!HasWallets()) {
71  // Note: It isn't currently possible to trigger this error because
72  // wallet RPC methods aren't registered unless a wallet is loaded. But
73  // this error is being kept as a precaution, because it's possible in
74  // the future that wallet RPC methods might get or remain registered
75  // when no wallets are loaded.
76  throw JSONRPCError(
77  RPC_METHOD_NOT_FOUND, "Method not found (wallet method is disabled because no wallet is loaded)");
78  }
80  "Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
81 }
82 
83 void EnsureWalletIsUnlocked(CWallet * const pwallet)
84 {
85  if (pwallet->IsLocked()) {
86  throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
87  }
88 }
89 
90 void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry)
91 {
92  AssertLockHeld(cs_main); // for mapBlockIndex
93  int confirms = wtx.GetDepthInMainChain();
94  bool fLocked = llmq::quorumInstantSendManager->IsLocked(wtx.GetHash());
95  bool chainlock = false;
96  if (confirms > 0) {
97  chainlock = llmq::chainLocksHandler->HasChainLock(mapBlockIndex[wtx.hashBlock]->nHeight, wtx.hashBlock);
98  }
99  entry.push_back(Pair("confirmations", confirms));
100  entry.push_back(Pair("instantlock", fLocked || chainlock));
101  entry.push_back(Pair("instantlock_internal", fLocked));
102  entry.push_back(Pair("chainlock", chainlock));
103  if (wtx.IsCoinBase())
104  entry.push_back(Pair("generated", true));
105  if (confirms > 0)
106  {
107  entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex()));
108  entry.push_back(Pair("blockindex", wtx.nIndex));
109  entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()));
110  } else {
111  entry.push_back(Pair("trusted", wtx.IsTrusted()));
112  }
113  uint256 hash = wtx.GetHash();
114  entry.push_back(Pair("txid", hash.GetHex()));
115  UniValue conflicts(UniValue::VARR);
116  for (const uint256& conflict : wtx.GetConflicts())
117  conflicts.push_back(conflict.GetHex());
118  entry.push_back(Pair("walletconflicts", conflicts));
119  entry.push_back(Pair("time", wtx.GetTxTime()));
120  entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived));
121 
122  for (const std::pair<std::string, std::string>& item : wtx.mapValue)
123  entry.push_back(Pair(item.first, item.second));
124 }
125 
126 std::string AccountFromValue(const UniValue& value)
127 {
128  std::string strAccount = value.get_str();
129  if (strAccount == "*")
130  throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
131  return strAccount;
132 }
133 
135 {
136  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
137  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
138  return NullUniValue;
139  }
140 
141  if (request.fHelp || request.params.size() > 1)
142  throw std::runtime_error(
143  "getnewaddress ( \"account\" )\n"
144  "\nReturns a new Dash address for receiving payments.\n"
145  "If 'account' is specified (DEPRECATED), it is added to the address book \n"
146  "so payments received with the address will be credited to 'account'.\n"
147  "\nArguments:\n"
148  "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"
149  "\nResult:\n"
150  "\"address\" (string) The new dash address\n"
151  "\nExamples:\n"
152  + HelpExampleCli("getnewaddress", "")
153  + HelpExampleRpc("getnewaddress", "")
154  );
155 
156  LOCK2(cs_main, pwallet->cs_wallet);
157 
158  // Parse the account first so we don't generate a key if there's an error
159  std::string strAccount;
160  if (!request.params[0].isNull())
161  strAccount = AccountFromValue(request.params[0]);
162 
163  if (!pwallet->IsLocked(true)) {
164  pwallet->TopUpKeyPool();
165  }
166 
167  // Generate a new key that is added to wallet
168  CPubKey newKey;
169  if (!pwallet->GetKeyFromPool(newKey, false)) {
170  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
171  }
172  CKeyID keyID = newKey.GetID();
173 
174  pwallet->SetAddressBook(keyID, strAccount, "receive");
175 
176  return EncodeDestination(keyID);
177 }
178 
179 
180 CTxDestination GetAccountDestination(CWallet* const pwallet, std::string strAccount, bool bForceNew=false)
181 {
182  CTxDestination dest;
183  if (!pwallet->GetAccountDestination(dest, strAccount, bForceNew)) {
184  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
185  }
186 
187  return dest;
188 }
189 
191 {
192  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
193  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
194  return NullUniValue;
195  }
196 
197  if (request.fHelp || request.params.size() != 1)
198  throw std::runtime_error(
199  "getaccountaddress \"account\"\n"
200  "\nDEPRECATED. Returns the current Dash address for receiving payments to this account.\n"
201  "\nArguments:\n"
202  "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"
203  "\nResult:\n"
204  "\"address\" (string) The account dash address\n"
205  "\nExamples:\n"
206  + HelpExampleCli("getaccountaddress", "")
207  + HelpExampleCli("getaccountaddress", "\"\"")
208  + HelpExampleCli("getaccountaddress", "\"myaccount\"")
209  + HelpExampleRpc("getaccountaddress", "\"myaccount\"")
210  );
211 
212  LOCK2(cs_main, pwallet->cs_wallet);
213 
214  // Parse the account first so we don't generate a key if there's an error
215  std::string strAccount = AccountFromValue(request.params[0]);
216 
218 
219  ret = EncodeDestination(GetAccountDestination(pwallet, strAccount));
220  return ret;
221 }
222 
223 
225 {
226  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
227  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
228  return NullUniValue;
229  }
230 
231  if (request.fHelp || request.params.size() > 0)
232  throw std::runtime_error(
233  "getrawchangeaddress\n"
234  "\nReturns a new Dash address, for receiving change.\n"
235  "This is for use with raw transactions, NOT normal use.\n"
236  "\nResult:\n"
237  "\"address\" (string) The address\n"
238  "\nExamples:\n"
239  + HelpExampleCli("getrawchangeaddress", "")
240  + HelpExampleRpc("getrawchangeaddress", "")
241  );
242 
243  LOCK2(cs_main, pwallet->cs_wallet);
244 
245  if (!pwallet->IsLocked(true)) {
246  pwallet->TopUpKeyPool();
247  }
248 
249  CReserveKey reservekey(pwallet);
250  CPubKey vchPubKey;
251  if (!reservekey.GetReservedKey(vchPubKey, true))
252  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
253 
254  reservekey.KeepKey();
255 
256  CKeyID keyID = vchPubKey.GetID();
257 
258  return EncodeDestination(keyID);
259 }
260 
261 
263 {
264  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
265  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
266  return NullUniValue;
267  }
268 
269  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
270  throw std::runtime_error(
271  "setaccount \"address\" \"account\"\n"
272  "\nDEPRECATED. Sets the account associated with the given address.\n"
273  "\nArguments:\n"
274  "1. \"address\" (string, required) The dash address to be associated with an account.\n"
275  "2. \"account\" (string, required) The account to assign the address to.\n"
276  "\nExamples:\n"
277  + HelpExampleCli("setaccount", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"tabby\"")
278  + HelpExampleRpc("setaccount", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", \"tabby\"")
279  );
280 
281  LOCK2(cs_main, pwallet->cs_wallet);
282 
283  CTxDestination dest = DecodeDestination(request.params[0].get_str());
284  if (!IsValidDestination(dest)) {
285  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Dash address");
286  }
287 
288  std::string strAccount;
289  if (!request.params[1].isNull())
290  strAccount = AccountFromValue(request.params[1]);
291 
292  // Only add the account if the address is yours.
293  if (IsMine(*pwallet, dest)) {
294  // Detect when changing the account of an address that is the 'unused current key' of another account:
295  if (pwallet->mapAddressBook.count(dest)) {
296  std::string strOldAccount = pwallet->mapAddressBook[dest].name;
297  if (dest == GetAccountDestination(pwallet, strOldAccount)) {
298  GetAccountDestination(pwallet, strOldAccount, true);
299  }
300  }
301  pwallet->SetAddressBook(dest, strAccount, "receive");
302  }
303  else
304  throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address");
305 
306  return NullUniValue;
307 }
308 
309 
311 {
312  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
313  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
314  return NullUniValue;
315  }
316 
317  if (request.fHelp || request.params.size() != 1)
318  throw std::runtime_error(
319  "getaccount \"address\"\n"
320  "\nDEPRECATED. Returns the account associated with the given address.\n"
321  "\nArguments:\n"
322  "1. \"address\" (string, required) The dash address for account lookup.\n"
323  "\nResult:\n"
324  "\"accountname\" (string) the account address\n"
325  "\nExamples:\n"
326  + HelpExampleCli("getaccount", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\"")
327  + HelpExampleRpc("getaccount", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\"")
328  );
329 
330  LOCK2(cs_main, pwallet->cs_wallet);
331 
332  CTxDestination dest = DecodeDestination(request.params[0].get_str());
333  if (!IsValidDestination(dest)) {
334  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Dash address");
335  }
336 
337  std::string strAccount;
338  std::map<CTxDestination, CAddressBookData>::iterator mi = pwallet->mapAddressBook.find(dest);
339  if (mi != pwallet->mapAddressBook.end() && !(*mi).second.name.empty()) {
340  strAccount = (*mi).second.name;
341  }
342  return strAccount;
343 }
344 
345 
347 {
348  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
349  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
350  return NullUniValue;
351  }
352 
353  if (request.fHelp || request.params.size() != 1)
354  throw std::runtime_error(
355  "getaddressesbyaccount \"account\"\n"
356  "\nDEPRECATED. Returns the list of addresses for the given account.\n"
357  "\nArguments:\n"
358  "1. \"account\" (string, required) The account name.\n"
359  "\nResult:\n"
360  "[ (json array of string)\n"
361  " \"address\" (string) a dash address associated with the given account\n"
362  " ,...\n"
363  "]\n"
364  "\nExamples:\n"
365  + HelpExampleCli("getaddressesbyaccount", "\"tabby\"")
366  + HelpExampleRpc("getaddressesbyaccount", "\"tabby\"")
367  );
368 
369  LOCK2(cs_main, pwallet->cs_wallet);
370 
371  std::string strAccount = AccountFromValue(request.params[0]);
372 
373  // Find all addresses that have the given account
375  for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
376  const CTxDestination& dest = item.first;
377  const std::string& strName = item.second.name;
378  if (strName == strAccount) {
379  ret.push_back(EncodeDestination(dest));
380  }
381  }
382  return ret;
383 }
384 
385 static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx& wtxNew, const CCoinControl& coin_control)
386 {
387  CAmount curBalance = pwallet->GetBalance();
388 
389  // Check amount
390  if (nValue <= 0)
391  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
392 
393  if (nValue > curBalance)
394  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
395 
396  if (pwallet->GetBroadcastTransactions() && !g_connman) {
397  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
398  }
399 
400  // Parse Dash address
401  CScript scriptPubKey = GetScriptForDestination(address);
402 
403  // Create and send the transaction
404  CReserveKey reservekey(pwallet);
405  CAmount nFeeRequired;
406  std::string strError;
407  std::vector<CRecipient> vecSend;
408  int nChangePosRet = -1;
409  CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount};
410  vecSend.push_back(recipient);
411  if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, nChangePosRet,
412  strError, coin_control)) {
413  if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance)
414  strError = strprintf("Error: This transaction requires a transaction fee of at least %s", FormatMoney(nFeeRequired));
415  throw JSONRPCError(RPC_WALLET_ERROR, strError);
416  }
417  CValidationState state;
418  if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), state)) {
419  strError = strprintf("Error: The transaction was rejected! Reason given: %s", state.GetRejectReason());
420  throw JSONRPCError(RPC_WALLET_ERROR, strError);
421  }
422 }
423 
425 {
426  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
427  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
428  return NullUniValue;
429  }
430 
431  if (request.fHelp || request.params.size() < 2 || request.params.size() > 9)
432  throw std::runtime_error(
433  "sendtoaddress \"address\" amount ( \"comment\" \"comment_to\" subtractfeefromamount use_is use_ps conf_target \"estimate_mode\")\n"
434  "\nSend an amount to a given address.\n"
435  + HelpRequiringPassphrase(pwallet) +
436  "\nArguments:\n"
437  "1. \"address\" (string, required) The dash address to send to.\n"
438  "2. \"amount\" (numeric or string, required) The amount in " + CURRENCY_UNIT + " to send. eg 0.1\n"
439  "3. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
440  " This is not part of the transaction, just kept in your wallet.\n"
441  "4. \"comment_to\" (string, optional) A comment to store the name of the person or organization \n"
442  " to which you're sending the transaction. This is not part of the \n"
443  " transaction, just kept in your wallet.\n"
444  "5. subtractfeefromamount (boolean, optional, default=false) The fee will be deducted from the amount being sent.\n"
445  " The recipient will receive less amount of Dash than you enter in the amount field.\n"
446  "6. \"use_is\" (bool, optional, default=false) Deprecated and ignored\n"
447  "7. \"use_ps\" (bool, optional, default=false) Use PrivateSend funds only\n"
448  "8. conf_target (numeric, optional) Confirmation target (in blocks)\n"
449  "9. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
450  " \"UNSET\"\n"
451  " \"ECONOMICAL\"\n"
452  " \"CONSERVATIVE\"\n"
453  "\nResult:\n"
454  "\"txid\" (string) The transaction id.\n"
455  "\nExamples:\n"
456  + HelpExampleCli("sendtoaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 0.1")
457  + HelpExampleCli("sendtoaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 0.1 \"donation\" \"seans outpost\"")
458  + HelpExampleCli("sendtoaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 0.1 \"\" \"\" true")
459  + HelpExampleRpc("sendtoaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", 0.1, \"donation\", \"seans outpost\"")
460  );
461 
462  ObserveSafeMode();
463 
464  // Make sure the results are valid at least up to the most recent block
465  // the user could have gotten from another RPC command prior to now
467 
469  LOCK(pwallet->cs_wallet);
470 
471  CTxDestination dest = DecodeDestination(request.params[0].get_str());
472  if (!IsValidDestination(dest)) {
473  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
474  }
475 
476  // Amount
477  CAmount nAmount = AmountFromValue(request.params[1]);
478  if (nAmount <= 0)
479  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
480 
481  // Wallet comments
482  CWalletTx wtx;
483  if (!request.params[2].isNull() && !request.params[2].get_str().empty())
484  wtx.mapValue["comment"] = request.params[2].get_str();
485  if (!request.params[3].isNull() && !request.params[3].get_str().empty())
486  wtx.mapValue["to"] = request.params[3].get_str();
487 
488  bool fSubtractFeeFromAmount = false;
489  if (!request.params[4].isNull()) {
490  fSubtractFeeFromAmount = request.params[4].get_bool();
491  }
492 
493  CCoinControl coin_control;
494 
495  if (!request.params[6].isNull()) {
496  coin_control.UsePrivateSend(request.params[6].get_bool());
497  }
498 
499  if (!request.params[7].isNull()) {
500  coin_control.m_confirm_target = ParseConfirmTarget(request.params[7]);
501  }
502 
503  if (!request.params[8].isNull()) {
504  if (!FeeModeFromString(request.params[8].get_str(), coin_control.m_fee_mode)) {
505  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
506  }
507  }
508 
509  EnsureWalletIsUnlocked(pwallet);
510 
511  SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx, coin_control);
512 
513  return wtx.GetHash().GetHex();
514 }
515 
516 // DEPRECATED
518 {
519  if (request.fHelp) {
520  throw std::runtime_error("instantsendtoaddress is deprecated and sendtoaddress should be used instead");
521  }
522  LogPrintf("WARNING: Used deprecated RPC method 'instantsendtoaddress'! Please use 'sendtoaddress' instead\n");
523  return sendtoaddress(request);
524 }
525 
527 {
528  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
529  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
530  return NullUniValue;
531  }
532 
533  if (request.fHelp || request.params.size() != 0)
534  throw std::runtime_error(
535  "listaddressgroupings\n"
536  "\nLists groups of addresses which have had their common ownership\n"
537  "made public by common use as inputs or as the resulting change\n"
538  "in past transactions\n"
539  "\nResult:\n"
540  "[\n"
541  " [\n"
542  " [\n"
543  " \"address\", (string) The dash address\n"
544  " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n"
545  " \"account\" (string, optional) DEPRECATED. The account\n"
546  " ]\n"
547  " ,...\n"
548  " ]\n"
549  " ,...\n"
550  "]\n"
551  "\nExamples:\n"
552  + HelpExampleCli("listaddressgroupings", "")
553  + HelpExampleRpc("listaddressgroupings", "")
554  );
555 
556  ObserveSafeMode();
557 
558  // Make sure the results are valid at least up to the most recent block
559  // the user could have gotten from another RPC command prior to now
561 
562  LOCK2(cs_main, pwallet->cs_wallet);
563 
564  UniValue jsonGroupings(UniValue::VARR);
565  std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
566  for (const std::set<CTxDestination>& grouping : pwallet->GetAddressGroupings()) {
567  UniValue jsonGrouping(UniValue::VARR);
568  for (const CTxDestination& address : grouping)
569  {
570  UniValue addressInfo(UniValue::VARR);
571  addressInfo.push_back(EncodeDestination(address));
572  addressInfo.push_back(ValueFromAmount(balances[address]));
573  {
574  if (pwallet->mapAddressBook.find(address) != pwallet->mapAddressBook.end()) {
575  addressInfo.push_back(pwallet->mapAddressBook.find(address)->second.name);
576  }
577  }
578  jsonGrouping.push_back(addressInfo);
579  }
580  jsonGroupings.push_back(jsonGrouping);
581  }
582  return jsonGroupings;
583 }
584 
586 {
587  CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
588  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
589  return NullUniValue;
590 
591  if (request.fHelp || request.params.size() > 1)
592  throw std::runtime_error(
593  "listaddressbalances ( minamount )\n"
594  "\nLists addresses of this wallet and their balances\n"
595  "\nArguments:\n"
596  "1. minamount (numeric, optional, default=0) Minimum balance in " + CURRENCY_UNIT + " an address should have to be shown in the list\n"
597  "\nResult:\n"
598  "{\n"
599  " \"address\": amount, (string) The dash address and the amount in " + CURRENCY_UNIT + "\n"
600  " ,...\n"
601  "}\n"
602  "\nExamples:\n"
603  + HelpExampleCli("listaddressbalances", "")
604  + HelpExampleCli("listaddressbalances", "10")
605  + HelpExampleRpc("listaddressbalances", "")
606  + HelpExampleRpc("listaddressbalances", "10")
607  );
608 
609  LOCK2(cs_main, pwallet->cs_wallet);
610 
611  CAmount nMinAmount = 0;
612  if (!request.params[0].isNull())
613  nMinAmount = AmountFromValue(request.params[0]);
614 
615  if (nMinAmount < 0)
616  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
617 
618  UniValue jsonBalances(UniValue::VOBJ);
619  std::map<CTxDestination, CAmount> balances = pwallet->GetAddressBalances();
620  for (auto& balance : balances)
621  if (balance.second >= nMinAmount)
622  jsonBalances.push_back(Pair(EncodeDestination(balance.first), ValueFromAmount(balance.second)));
623 
624  return jsonBalances;
625 }
626 
628 {
629  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
630  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
631  return NullUniValue;
632  }
633 
634  if (request.fHelp || request.params.size() != 2)
635  throw std::runtime_error(
636  "signmessage \"address\" \"message\"\n"
637  "\nSign a message with the private key of an address"
638  + HelpRequiringPassphrase(pwallet) + "\n"
639  "\nArguments:\n"
640  "1. \"address\" (string, required) The dash address to use for the private key.\n"
641  "2. \"message\" (string, required) The message to create a signature of.\n"
642  "\nResult:\n"
643  "\"signature\" (string) The signature of the message encoded in base 64\n"
644  "\nExamples:\n"
645  "\nUnlock the wallet for 30 seconds\n"
646  + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
647  "\nCreate the signature\n"
648  + HelpExampleCli("signmessage", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"my message\"") +
649  "\nVerify the signature\n"
650  + HelpExampleCli("verifymessage", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"signature\" \"my message\"") +
651  "\nAs json rpc\n"
652  + HelpExampleRpc("signmessage", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", \"my message\"")
653  );
654 
655  LOCK2(cs_main, pwallet->cs_wallet);
656 
657  EnsureWalletIsUnlocked(pwallet);
658 
659  std::string strAddress = request.params[0].get_str();
660  std::string strMessage = request.params[1].get_str();
661 
662  CTxDestination dest = DecodeDestination(strAddress);
663  if (!IsValidDestination(dest)) {
664  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
665  }
666 
667  const CKeyID *keyID = boost::get<CKeyID>(&dest);
668  if (!keyID) {
669  throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
670  }
671 
672  CKey key;
673  if (!pwallet->GetKey(*keyID, key)) {
674  throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
675  }
676 
677  CHashWriter ss(SER_GETHASH, 0);
678  ss << strMessageMagic;
679  ss << strMessage;
680 
681  std::vector<unsigned char> vchSig;
682  if (!key.SignCompact(ss.GetHash(), vchSig))
683  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
684 
685  return EncodeBase64(vchSig.data(), vchSig.size());
686 }
687 
689 {
690  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
691  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
692  return NullUniValue;
693  }
694 
695  if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
696  throw std::runtime_error(
697  "getreceivedbyaddress \"address\" ( minconf addlocked )\n"
698  "\nReturns the total amount received by the given address in transactions with at least minconf confirmations.\n"
699  "\nArguments:\n"
700  "1. \"address\" (string, required) The dash address for transactions.\n"
701  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
702  "3. addlocked (bool, optional, default=false) Whether to include transactions locked via InstantSend.\n"
703  "\nResult:\n"
704  "amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n"
705  "\nExamples:\n"
706  "\nThe amount from transactions with at least 1 confirmation\n"
707  + HelpExampleCli("getreceivedbyaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\"") +
708  "\nThe amount including unconfirmed transactions, zero confirmations\n"
709  + HelpExampleCli("getreceivedbyaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 0") +
710  "\nThe amount with at least 6 confirmations\n"
711  + HelpExampleCli("getreceivedbyaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 6") +
712  "\nAs a json rpc call\n"
713  + HelpExampleRpc("getreceivedbyaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", 6")
714  );
715 
716  ObserveSafeMode();
717 
718  // Make sure the results are valid at least up to the most recent block
719  // the user could have gotten from another RPC command prior to now
721 
722  LOCK2(cs_main, pwallet->cs_wallet);
723 
724  // Dash address
725  CTxDestination dest = DecodeDestination(request.params[0].get_str());
726  if (!IsValidDestination(dest)) {
727  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Dash address");
728  }
729  CScript scriptPubKey = GetScriptForDestination(dest);
730  if (!IsMine(*pwallet, scriptPubKey)) {
731  throw JSONRPCError(RPC_WALLET_ERROR, "Address not found in wallet");
732  }
733 
734  // Minimum confirmations
735  int nMinDepth = 1;
736  if (!request.params[1].isNull())
737  nMinDepth = request.params[1].get_int();
738  bool fAddLocked = (!request.params[2].isNull() && request.params[2].get_bool());
739 
740  // Tally
741  CAmount nAmount = 0;
742  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
743  const CWalletTx& wtx = pairWtx.second;
744  if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
745  continue;
746 
747  for (const CTxOut& txout : wtx.tx->vout)
748  if (txout.scriptPubKey == scriptPubKey)
749  if ((wtx.GetDepthInMainChain() >= nMinDepth) || (fAddLocked && wtx.IsLockedByInstantSend()))
750  nAmount += txout.nValue;
751  }
752 
753  return ValueFromAmount(nAmount);
754 }
755 
756 
758 {
759  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
760  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
761  return NullUniValue;
762  }
763 
764  if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
765  throw std::runtime_error(
766  "getreceivedbyaccount \"account\" ( minconf addlocked )\n"
767  "\nDEPRECATED. Returns the total amount received by addresses with <account> in transactions with specified minimum number of confirmations.\n"
768  "\nArguments:\n"
769  "1. \"account\" (string, required) The selected account, may be the default account using \"\".\n"
770  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
771  "3. addlocked (bool, optional, default=false) Whether to include transactions locked via InstantSend.\n"
772  "\nResult:\n"
773  "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
774  "\nExamples:\n"
775  "\nAmount received by the default account with at least 1 confirmation\n"
776  + HelpExampleCli("getreceivedbyaccount", "\"\"") +
777  "\nAmount received at the tabby account including unconfirmed amounts with zero confirmations\n"
778  + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 0") +
779  "\nThe amount with at least 6 confirmations\n"
780  + HelpExampleCli("getreceivedbyaccount", "\"tabby\" 6") +
781  "\nAs a json rpc call\n"
782  + HelpExampleRpc("getreceivedbyaccount", "\"tabby\", 6")
783  );
784 
785  ObserveSafeMode();
786 
787  // Make sure the results are valid at least up to the most recent block
788  // the user could have gotten from another RPC command prior to now
790 
791  LOCK2(cs_main, pwallet->cs_wallet);
792 
793  // Minimum confirmations
794  int nMinDepth = 1;
795  if (!request.params[1].isNull())
796  nMinDepth = request.params[1].get_int();
797  bool fAddLocked = (!request.params[2].isNull() && request.params[2].get_bool());
798 
799  // Get the set of pub keys assigned to account
800  std::string strAccount = AccountFromValue(request.params[0]);
801  std::set<CTxDestination> setAddress = pwallet->GetAccountAddresses(strAccount);
802 
803  // Tally
804  CAmount nAmount = 0;
805  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
806  const CWalletTx& wtx = pairWtx.second;
807  if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
808  continue;
809 
810  for (const CTxOut& txout : wtx.tx->vout)
811  {
812  CTxDestination address;
813  if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*pwallet, address) && setAddress.count(address)) {
814  if ((wtx.GetDepthInMainChain() >= nMinDepth) || (fAddLocked && wtx.IsLockedByInstantSend()))
815  nAmount += txout.nValue;
816  }
817  }
818  }
819 
820  return ValueFromAmount(nAmount);
821 }
822 
823 
825 {
826  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
827  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
828  return NullUniValue;
829  }
830 
831  if (request.fHelp || request.params.size() > 4)
832  throw std::runtime_error(
833  "getbalance ( \"account\" minconf addlocked include_watchonly )\n"
834  "\nIf account is not specified, returns the server's total available balance.\n"
835  "The available balance is what the wallet considers currently spendable, and is\n"
836  "thus affected by options which limit spendability such as -spendzeroconfchange.\n"
837  "If account is specified (DEPRECATED), returns the balance in the account.\n"
838  "Note that the account \"\" is not the same as leaving the parameter out.\n"
839  "The server total may be different to the balance in the default \"\" account.\n"
840  "\nArguments:\n"
841  "1. \"account\" (string, optional) DEPRECATED. The selected account, or \"*\" for entire wallet. It may be the default account using \"\".\n"
842  "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
843  "3. addlocked (bool, optional, default=false) Whether to include the value of transactions locked via InstantSend in the wallet's balance.\n"
844  "4. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
845  "\nResult:\n"
846  "amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
847  "\nExamples:\n"
848  "\nThe total amount in the wallet with 1 or more confirmations\n"
849  + HelpExampleCli("getbalance", "") +
850  "\nThe total amount in the wallet at least 6 blocks confirmed\n"
851  + HelpExampleCli("getbalance", "\"*\" 6") +
852  "\nAs a json rpc call\n"
853  + HelpExampleRpc("getbalance", "\"*\", 6")
854  );
855 
856  ObserveSafeMode();
857 
858  // Make sure the results are valid at least up to the most recent block
859  // the user could have gotten from another RPC command prior to now
861 
862  LOCK2(cs_main, pwallet->cs_wallet);
863 
864  const UniValue& account_value = request.params[0];
865  const UniValue& minconf = request.params[1];
866  const UniValue& addlocked = request.params[2];
867  const UniValue& include_watchonly = request.params[3];
868 
869  if (account_value.isNull()) {
870  if (!minconf.isNull()) {
872  "getbalance minconf option is only currently supported if an account is specified");
873  }
874  if (!include_watchonly.isNull()) {
876  "getbalance include_watchonly option is only currently supported if an account is specified");
877  }
878  return ValueFromAmount(pwallet->GetBalance());
879  }
880 
881  const std::string& account_param = account_value.get_str();
882  const std::string* account = account_param != "*" ? &account_param : nullptr;
883 
884  int nMinDepth = 1;
885  if (!minconf.isNull())
886  nMinDepth = minconf.get_int();
887  bool fAddLocked = false;
888  if (!addlocked.isNull())
889  fAddLocked = addlocked.get_bool();
891  if(!include_watchonly.isNull())
892  if(include_watchonly.get_bool())
893  filter = filter | ISMINE_WATCH_ONLY;
894 
895  return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account, fAddLocked));
896 }
897 
899 {
900  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
901  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
902  return NullUniValue;
903  }
904 
905  if (request.fHelp || request.params.size() > 0)
906  throw std::runtime_error(
907  "getunconfirmedbalance\n"
908  "Returns the server's total unconfirmed balance\n");
909 
910  ObserveSafeMode();
911 
912  // Make sure the results are valid at least up to the most recent block
913  // the user could have gotten from another RPC command prior to now
915 
916  LOCK2(cs_main, pwallet->cs_wallet);
917 
918  return ValueFromAmount(pwallet->GetUnconfirmedBalance());
919 }
920 
921 
923 {
924  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
925  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
926  return NullUniValue;
927  }
928 
929  if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
930  throw std::runtime_error(
931  "move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
932  "\nDEPRECATED. Move a specified amount from one account in your wallet to another.\n"
933  "\nArguments:\n"
934  "1. \"fromaccount\" (string, required) The name of the account to move funds from. May be the default account using \"\".\n"
935  "2. \"toaccount\" (string, required) The name of the account to move funds to. May be the default account using \"\".\n"
936  "3. amount (numeric) Quantity of " + CURRENCY_UNIT + " to move between accounts.\n"
937  "4. (dummy) (numeric, optional) Ignored. Remains for backward compatibility.\n"
938  "5. \"comment\" (string, optional) An optional comment, stored in the wallet only.\n"
939  "\nResult:\n"
940  "true|false (boolean) true if successful.\n"
941  "\nExamples:\n"
942  "\nMove 0.01 " + CURRENCY_UNIT + " from the default account to the account named tabby\n"
943  + HelpExampleCli("move", "\"\" \"tabby\" 0.01") +
944  "\nMove 0.01 " + CURRENCY_UNIT + " timotei to akiko with a comment and funds have 6 confirmations\n"
945  + HelpExampleCli("move", "\"timotei\" \"akiko\" 0.01 6 \"happy birthday!\"") +
946  "\nAs a json rpc call\n"
947  + HelpExampleRpc("move", "\"timotei\", \"akiko\", 0.01, 6, \"happy birthday!\"")
948  );
949 
950  ObserveSafeMode();
951  LOCK2(cs_main, pwallet->cs_wallet);
952 
953  std::string strFrom = AccountFromValue(request.params[0]);
954  std::string strTo = AccountFromValue(request.params[1]);
955  CAmount nAmount = AmountFromValue(request.params[2]);
956  if (nAmount <= 0)
957  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
958  if (!request.params[3].isNull())
959  // unused parameter, used to be nMinDepth, keep type-checking it though
960  (void)request.params[3].get_int();
961  std::string strComment;
962  if (!request.params[4].isNull())
963  strComment = request.params[4].get_str();
964 
965  if (!pwallet->AccountMove(strFrom, strTo, nAmount, strComment)) {
966  throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
967  }
968 
969  return true;
970 }
971 
972 
974 {
975  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
976  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
977  return NullUniValue;
978  }
979 
980  if (request.fHelp || request.params.size() < 3 || request.params.size() > 7)
981  throw std::runtime_error(
982  "sendfrom \"fromaccount\" \"toaddress\" amount ( minconf addlocked \"comment\" \"comment_to\" )\n"
983  "\nDEPRECATED (use sendtoaddress). Sent an amount from an account to a dash address."
984  + HelpRequiringPassphrase(pwallet) + "\n"
985  "\nArguments:\n"
986  "1. \"fromaccount\" (string, required) The name of the account to send funds from. May be the default account using \"\".\n"
987  " Specifying an account does not influence coin selection, but it does associate the newly created\n"
988  " transaction with the account, so the account's balance computation and transaction history can reflect\n"
989  " the spend.\n"
990  "2. \"toaddress\" (string, required) The dash address to send funds to.\n"
991  "3. amount (numeric or string, required) The amount in " + CURRENCY_UNIT + " (transaction fee is added on top).\n"
992  "4. minconf (numeric, optional, default=1) Only use funds with at least this many confirmations.\n"
993  "5. addlocked (bool, optional, default=false) Whether to include transactions locked via InstantSend.\n"
994  "6. \"comment\" (string, optional) A comment used to store what the transaction is for. \n"
995  " This is not part of the transaction, just kept in your wallet.\n"
996  "7. \"comment_to\" (string, optional) An optional comment to store the name of the person or organization \n"
997  " to which you're sending the transaction. This is not part of the transaction, \n"
998  " it is just kept in your wallet.\n"
999  "\nResult:\n"
1000  "\"txid\" (string) The transaction id.\n"
1001  "\nExamples:\n"
1002  "\nSend 0.01 " + CURRENCY_UNIT + " from the default account to the address, must have at least 1 confirmation\n"
1003  + HelpExampleCli("sendfrom", "\"\" \"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 0.01") +
1004  "\nSend 0.01 from the tabby account to the given address, funds must have at least 6 confirmations\n"
1005  + HelpExampleCli("sendfrom", "\"tabby\" \"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 0.01 6 false \"donation\" \"seans outpost\"") +
1006  "\nAs a json rpc call\n"
1007  + HelpExampleRpc("sendfrom", "\"tabby\", \"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", 0.01, 6, false, \"donation\", \"seans outpost\"")
1008  );
1009 
1010  ObserveSafeMode();
1011 
1012  // Make sure the results are valid at least up to the most recent block
1013  // the user could have gotten from another RPC command prior to now
1014  pwallet->BlockUntilSyncedToCurrentChain();
1015 
1016  LOCK2(cs_main, mempool.cs);
1017  LOCK(pwallet->cs_wallet);
1018 
1019  std::string strAccount = AccountFromValue(request.params[0]);
1020  CTxDestination dest = DecodeDestination(request.params[1].get_str());
1021  if (!IsValidDestination(dest)) {
1022  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Dash address");
1023  }
1024  CAmount nAmount = AmountFromValue(request.params[2]);
1025  if (nAmount <= 0)
1026  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
1027  int nMinDepth = 1;
1028  if (!request.params[3].isNull())
1029  nMinDepth = request.params[3].get_int();
1030  bool fAddLocked = (!request.params[4].isNull() && request.params[4].get_bool());
1031 
1032  CWalletTx wtx;
1033  wtx.strFromAccount = strAccount;
1034  if (!request.params[5].isNull() && !request.params[5].get_str().empty())
1035  wtx.mapValue["comment"] = request.params[5].get_str();
1036  if (!request.params[6].isNull() && !request.params[6].get_str().empty())
1037  wtx.mapValue["to"] = request.params[6].get_str();
1038 
1039  EnsureWalletIsUnlocked(pwallet);
1040 
1041  // Check funds
1042  CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount, fAddLocked);
1043  if (nAmount > nBalance)
1044  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
1045 
1046  CCoinControl no_coin_control; // This is a deprecated API
1047  SendMoney(pwallet, dest, nAmount, false, wtx, no_coin_control);
1048 
1049  return wtx.GetHash().GetHex();
1050 }
1051 
1052 
1054 {
1055  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1056  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1057  return NullUniValue;
1058  }
1059 
1060  if (request.fHelp || request.params.size() < 2 || request.params.size() > 10)
1061  throw std::runtime_error(
1062  "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf addlocked \"comment\" [\"address\",...] subtractfeefrom use_is use_ps conf_target \"estimate_mode\")\n"
1063  "\nSend multiple times. Amounts are double-precision floating point numbers."
1064  + HelpRequiringPassphrase(pwallet) + "\n"
1065  "\nArguments:\n"
1066  "1. \"fromaccount\" (string, required) DEPRECATED. The account to send the funds from. Should be \"\" for the default account\n"
1067  "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
1068  " {\n"
1069  " \"address\":amount (numeric or string) The dash address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n"
1070  " ,...\n"
1071  " }\n"
1072  "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
1073  "4. addlocked (bool, optional, default=false) Whether to include transactions locked via InstantSend.\n"
1074  "5. \"comment\" (string, optional) A comment\n"
1075  "6. subtractfeefrom (array, optional) A json array with addresses.\n"
1076  " The fee will be equally deducted from the amount of each selected address.\n"
1077  " Those recipients will receive less dashs than you enter in their corresponding amount field.\n"
1078  " If no addresses are specified here, the sender pays the fee.\n"
1079  " [\n"
1080  " \"address\" (string) Subtract fee from this address\n"
1081  " ,...\n"
1082  " ]\n"
1083  "7. \"use_is\" (bool, optional, default=false) Deprecated and ignored\n"
1084  "8. \"use_ps\" (bool, optional, default=false) Use PrivateSend funds only\n"
1085  "9. conf_target (numeric, optional) Confirmation target (in blocks)\n"
1086  "10. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
1087  " \"UNSET\"\n"
1088  " \"ECONOMICAL\"\n"
1089  " \"CONSERVATIVE\"\n"
1090  "\nResult:\n"
1091  "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
1092  " the number of addresses.\n"
1093  "\nExamples:\n"
1094  "\nSend two amounts to two different addresses:\n"
1095  + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\\\":0.01,\\\"XuQQkwA4FYkq2XERzMY2CiAZhJTEDAbtcG\\\":0.02}\"") +
1096  "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
1097  + HelpExampleCli("sendmany", "\"tabby\" \"{\\\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\\\":0.01,\\\"XuQQkwA4FYkq2XERzMY2CiAZhJTEDAbtcG\\\":0.02}\" 6 false \"testing\"") +
1098  "\nAs a json rpc call\n"
1099  + HelpExampleRpc("sendmany", "\"tabby\", \"{\\\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\\\":0.01,\\\"XuQQkwA4FYkq2XERzMY2CiAZhJTEDAbtcG\\\":0.02}\", 6, false, \"testing\"")
1100  );
1101 
1102  ObserveSafeMode();
1103 
1104  // Make sure the results are valid at least up to the most recent block
1105  // the user could have gotten from another RPC command prior to now
1106  pwallet->BlockUntilSyncedToCurrentChain();
1107 
1108  LOCK2(cs_main, mempool.cs);
1109  LOCK(pwallet->cs_wallet);
1110 
1111  if (pwallet->GetBroadcastTransactions() && !g_connman) {
1112  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
1113  }
1114 
1115  std::string strAccount = AccountFromValue(request.params[0]);
1116  UniValue sendTo = request.params[1].get_obj();
1117  int nMinDepth = 1;
1118  if (!request.params[2].isNull())
1119  nMinDepth = request.params[2].get_int();
1120  bool fAddLocked = (!request.params[3].isNull() && request.params[3].get_bool());
1121 
1122  CWalletTx wtx;
1123  wtx.strFromAccount = strAccount;
1124  if (!request.params[4].isNull() && !request.params[4].get_str().empty())
1125  wtx.mapValue["comment"] = request.params[4].get_str();
1126 
1127  UniValue subtractFeeFrom(UniValue::VARR);
1128  if (!request.params[5].isNull())
1129  subtractFeeFrom = request.params[5].get_array();
1130 
1131  // request.params[6] ("use_is") is deprecated and not used here
1132 
1133  CCoinControl coin_control;
1134 
1135  if (!request.params[7].isNull()) {
1136  coin_control.UsePrivateSend(request.params[7].get_bool());
1137  }
1138 
1139  if (!request.params[8].isNull()) {
1140  coin_control.m_confirm_target = ParseConfirmTarget(request.params[8]);
1141  }
1142 
1143  if (!request.params[9].isNull()) {
1144  if (!FeeModeFromString(request.params[9].get_str(), coin_control.m_fee_mode)) {
1145  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
1146  }
1147  }
1148 
1149  std::set<CTxDestination> destinations;
1150  std::vector<CRecipient> vecSend;
1151 
1152  CAmount totalAmount = 0;
1153  std::vector<std::string> keys = sendTo.getKeys();
1154  for (const std::string& name_ : keys) {
1155  CTxDestination dest = DecodeDestination(name_);
1156  if (!IsValidDestination(dest)) {
1157  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Dash address: ") + name_);
1158  }
1159 
1160  if (destinations.count(dest)) {
1161  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
1162  }
1163  destinations.insert(dest);
1164 
1165  CScript scriptPubKey = GetScriptForDestination(dest);
1166  CAmount nAmount = AmountFromValue(sendTo[name_]);
1167  if (nAmount <= 0)
1168  throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
1169  totalAmount += nAmount;
1170 
1171  bool fSubtractFeeFromAmount = false;
1172  for (unsigned int idx = 0; idx < subtractFeeFrom.size(); idx++) {
1173  const UniValue& addr = subtractFeeFrom[idx];
1174  if (addr.get_str() == name_)
1175  fSubtractFeeFromAmount = true;
1176  }
1177 
1178  CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount};
1179  vecSend.push_back(recipient);
1180  }
1181 
1182  EnsureWalletIsUnlocked(pwallet);
1183 
1184  // Check funds
1185  CAmount nBalance = pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount, fAddLocked);
1186  if (totalAmount > nBalance)
1187  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
1188 
1189  // Send
1190  CReserveKey keyChange(pwallet);
1191  CAmount nFeeRequired = 0;
1192  int nChangePosRet = -1;
1193  std::string strFailReason;
1194 
1195  bool fCreated = pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, nChangePosRet, strFailReason,
1196  coin_control);
1197  if (!fCreated)
1198  throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason);
1199  CValidationState state;
1200  if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) {
1201  strFailReason = strprintf("Transaction commit failed:: %s", state.GetRejectReason());
1202  throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
1203  }
1204 
1205  return wtx.GetHash().GetHex();
1206 }
1207 
1209 {
1210  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1211  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1212  return NullUniValue;
1213  }
1214 
1215  if (request.fHelp || request.params.size() < 2 || request.params.size() > 3)
1216  {
1217  std::string msg = "addmultisigaddress nrequired [\"key\",...] ( \"account\" )\n"
1218  "\nAdd a nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup.\n"
1219  "Each key is a Dash address or hex-encoded public key.\n"
1220  "This functionality is only intended for use with non-watchonly addresses.\n"
1221  "See `importaddress` for watchonly p2sh address support.\n"
1222  "If 'account' is specified (DEPRECATED), assign address to that account.\n"
1223 
1224  "\nArguments:\n"
1225  "1. nrequired (numeric, required) The number of required signatures out of the n keys or addresses.\n"
1226  "2. \"keys\" (string, required) A json array of dash addresses or hex-encoded public keys\n"
1227  " [\n"
1228  " \"address\" (string) dash address or hex-encoded public key\n"
1229  " ...,\n"
1230  " ]\n"
1231  "3. \"account\" (string, optional) DEPRECATED. An account to assign the addresses to.\n"
1232 
1233  "\nResult:\n"
1234  "{\n"
1235  " \"address\":\"multisigaddress\", (string) The value of the new multisig address.\n"
1236  " \"redeemScript\":\"script\" (string) The string value of the hex-encoded redemption script.\n"
1237  "}\n"
1238  "\nResult (DEPRECATED. To see this result in v0.16 instead, please start dashd with -deprecatedrpc=addmultisigaddress).\n"
1239  " clients should transition to the new output api before upgrading to v0.17.\n"
1240  "\"address\" (string) A dash address associated with the keys.\n"
1241 
1242  "\nExamples:\n"
1243  "\nAdd a multisig address from 2 addresses\n"
1244  + HelpExampleCli("addmultisigaddress", "2 \"[\\\"Xt4qk9uKvQYAonVGSZNXqxeDmtjaEWgfrS\\\",\\\"XoSoWQkpgLpppPoyyzbUFh1fq2RBvW6UK2\\\"]\"") +
1245  "\nAs json rpc call\n"
1246  + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"Xt4qk9uKvQYAonVGSZNXqxeDmtjaEWgfrS\\\",\\\"XoSoWQkpgLpppPoyyzbUFh1fq2RBvW6UK2\\\"]\"")
1247  ;
1248  throw std::runtime_error(msg);
1249  }
1250 
1251  LOCK2(cs_main, pwallet->cs_wallet);
1252 
1253  std::string strAccount;
1254  if (!request.params[2].isNull())
1255  strAccount = AccountFromValue(request.params[2]);
1256 
1257  int required = request.params[0].get_int();
1258 
1259  // Get the public keys
1260  const UniValue& keys_or_addrs = request.params[1].get_array();
1261  std::vector<CPubKey> pubkeys;
1262  for (unsigned int i = 0; i < keys_or_addrs.size(); ++i) {
1263  if (IsHex(keys_or_addrs[i].get_str()) && (keys_or_addrs[i].get_str().length() == 66 || keys_or_addrs[i].get_str().length() == 130)) {
1264  pubkeys.push_back(HexToPubKey(keys_or_addrs[i].get_str()));
1265  } else {
1266  pubkeys.push_back(AddrToPubKey(pwallet, keys_or_addrs[i].get_str()));
1267  }
1268  }
1269 
1270  // Construct using pay-to-script-hash:
1271  CScript inner = CreateMultisigRedeemscript(required, pubkeys);
1272  CScriptID innerID(inner);
1273  pwallet->AddCScript(inner);
1274 
1275  pwallet->SetAddressBook(innerID, strAccount, "send");
1276 
1277  // Return old style interface
1278  if (IsDeprecatedRPCEnabled("addmultisigaddress")) {
1279  return EncodeDestination(innerID);
1280  }
1281 
1282  UniValue result(UniValue::VOBJ);
1283  result.pushKV("address", EncodeDestination(innerID));
1284  result.pushKV("redeemScript", HexStr(inner.begin(), inner.end()));
1285  return result;
1286 }
1287 
1288 
1290 {
1292  int nConf;
1293  std::vector<uint256> txids;
1296  {
1297  nAmount = 0;
1298  nConf = std::numeric_limits<int>::max();
1299  fIsWatchonly = false;
1300  }
1301 };
1302 
1303 UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByAccounts)
1304 {
1305  // Minimum confirmations
1306  int nMinDepth = 1;
1307  if (!params[0].isNull())
1308  nMinDepth = params[0].get_int();
1309  bool fAddLocked = false;
1310  if (!params[1].isNull())
1311  fAddLocked = params[1].get_bool();
1312 
1313  // Whether to include empty accounts
1314  bool fIncludeEmpty = false;
1315  if (!params[2].isNull())
1316  fIncludeEmpty = params[2].get_bool();
1317 
1318  isminefilter filter = ISMINE_SPENDABLE;
1319  if(!params[3].isNull())
1320  if(params[3].get_bool())
1321  filter = filter | ISMINE_WATCH_ONLY;
1322 
1323  // Tally
1324  std::map<CTxDestination, tallyitem> mapTally;
1325  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1326  const CWalletTx& wtx = pairWtx.second;
1327 
1328  if (wtx.IsCoinBase() || !CheckFinalTx(*wtx.tx))
1329  continue;
1330 
1331  int nDepth = wtx.GetDepthInMainChain();
1332  if ((nDepth < nMinDepth) && !(fAddLocked && wtx.IsLockedByInstantSend()))
1333  continue;
1334 
1335  for (const CTxOut& txout : wtx.tx->vout)
1336  {
1337  CTxDestination address;
1338  if (!ExtractDestination(txout.scriptPubKey, address))
1339  continue;
1340 
1341  isminefilter mine = IsMine(*pwallet, address);
1342  if(!(mine & filter))
1343  continue;
1344 
1345  tallyitem& item = mapTally[address];
1346  item.nAmount += txout.nValue;
1347  item.nConf = std::min(item.nConf, nDepth);
1348  item.txids.push_back(wtx.GetHash());
1349  if (mine & ISMINE_WATCH_ONLY)
1350  item.fIsWatchonly = true;
1351  }
1352  }
1353 
1354  // Reply
1355  UniValue ret(UniValue::VARR);
1356  std::map<std::string, tallyitem> mapAccountTally;
1357  for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
1358  const CTxDestination& dest = item.first;
1359  const std::string& strAccount = item.second.name;
1360  std::map<CTxDestination, tallyitem>::iterator it = mapTally.find(dest);
1361  if (it == mapTally.end() && !fIncludeEmpty)
1362  continue;
1363 
1364  isminefilter mine = IsMine(*pwallet, dest);
1365  if(!(mine & filter))
1366  continue;
1367 
1368  CAmount nAmount = 0;
1369  int nConf = std::numeric_limits<int>::max();
1370  bool fIsWatchonly = false;
1371  if (it != mapTally.end())
1372  {
1373  nAmount = (*it).second.nAmount;
1374  nConf = (*it).second.nConf;
1375  fIsWatchonly = (*it).second.fIsWatchonly;
1376  }
1377 
1378  if (fByAccounts)
1379  {
1380  tallyitem& _item = mapAccountTally[strAccount];
1381  _item.nAmount += nAmount;
1382  _item.nConf = std::min(_item.nConf, nConf);
1383  _item.fIsWatchonly = fIsWatchonly;
1384  }
1385  else
1386  {
1387  UniValue obj(UniValue::VOBJ);
1388  if(fIsWatchonly)
1389  obj.push_back(Pair("involvesWatchonly", true));
1390  obj.push_back(Pair("address", EncodeDestination(dest)));
1391  obj.push_back(Pair("account", strAccount));
1392  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1393  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1394  if (!fByAccounts)
1395  obj.push_back(Pair("label", strAccount));
1396  UniValue transactions(UniValue::VARR);
1397  if (it != mapTally.end())
1398  {
1399  for (const uint256& _item : (*it).second.txids)
1400  {
1401  transactions.push_back(_item.GetHex());
1402  }
1403  }
1404  obj.push_back(Pair("txids", transactions));
1405  ret.push_back(obj);
1406  }
1407  }
1408 
1409  if (fByAccounts)
1410  {
1411  for (const auto& entry : mapAccountTally)
1412  {
1413  CAmount nAmount = entry.second.nAmount;
1414  int nConf = entry.second.nConf;
1415  UniValue obj(UniValue::VOBJ);
1416  if (entry.second.fIsWatchonly)
1417  obj.push_back(Pair("involvesWatchonly", true));
1418  obj.push_back(Pair("account", entry.first));
1419  obj.push_back(Pair("amount", ValueFromAmount(nAmount)));
1420  obj.push_back(Pair("confirmations", (nConf == std::numeric_limits<int>::max() ? 0 : nConf)));
1421  ret.push_back(obj);
1422  }
1423  }
1424 
1425  return ret;
1426 }
1427 
1429 {
1430  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1431  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1432  return NullUniValue;
1433  }
1434 
1435  if (request.fHelp || request.params.size() > 4)
1436  throw std::runtime_error(
1437  "listreceivedbyaddress ( minconf addlocked include_empty include_watchonly)\n"
1438  "\nList incoming payments grouped by receiving address.\n"
1439  "\nArguments:\n"
1440  "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1441  "2. addlocked (bool, optional, default=false) Whether to include transactions locked via InstantSend.\n"
1442  "3. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n"
1443  "4. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1444 
1445  "\nResult:\n"
1446  "[\n"
1447  " {\n"
1448  " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1449  " \"address\" : \"receivingaddress\", (string) The receiving address\n"
1450  " \"account\" : \"accountname\", (string) DEPRECATED. The account of the receiving address. The default account is \"\".\n"
1451  " \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n"
1452  " \"confirmations\" : n (numeric) The number of confirmations of the most recent transaction included.\n"
1453  " If 'addlocked' is true, the number of confirmations can be less than\n"
1454  " configured for transactions locked via InstantSend\n"
1455  " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
1456  " \"txids\": [\n"
1457  " \"txid\", (string) The ids of transactions received with the address \n"
1458  " ...\n"
1459  " ]\n"
1460  " }\n"
1461  " ,...\n"
1462  "]\n"
1463 
1464  "\nExamples:\n"
1465  + HelpExampleCli("listreceivedbyaddress", "")
1466  + HelpExampleCli("listreceivedbyaddress", "6 false true")
1467  + HelpExampleRpc("listreceivedbyaddress", "6, false, true, true")
1468  );
1469 
1470  ObserveSafeMode();
1471 
1472  // Make sure the results are valid at least up to the most recent block
1473  // the user could have gotten from another RPC command prior to now
1474  pwallet->BlockUntilSyncedToCurrentChain();
1475 
1476  LOCK2(cs_main, pwallet->cs_wallet);
1477 
1478  return ListReceived(pwallet, request.params, false);
1479 }
1480 
1482 {
1483  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1484  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1485  return NullUniValue;
1486  }
1487 
1488  if (request.fHelp || request.params.size() > 4)
1489  throw std::runtime_error(
1490  "listreceivedbyaccount ( minconf addlocked include_empty include_watchonly)\n"
1491  "\nDEPRECATED. List incoming payments grouped by account.\n"
1492  "\nArguments:\n"
1493  "1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n"
1494  "2. addlocked (bool, optional, default=false) Whether to include transactions locked via InstantSend.\n"
1495  "3. include_empty (bool, optional, default=false) Whether to include accounts that haven't received any payments.\n"
1496  "4. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n"
1497 
1498  "\nResult:\n"
1499  "[\n"
1500  " {\n"
1501  " \"involvesWatchonly\" : true, (bool) Only returned if imported addresses were involved in transaction\n"
1502  " \"account\" : \"accountname\", (string) The account name of the receiving account\n"
1503  " \"amount\" : x.xxx, (numeric) The total amount received by addresses with this account\n"
1504  " \"confirmations\" : n (numeric) The number of blockchain confirmations of the most recent transaction included\n"
1505  " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1506  " }\n"
1507  " ,...\n"
1508  "]\n"
1509 
1510  "\nExamples:\n"
1511  + HelpExampleCli("listreceivedbyaccount", "")
1512  + HelpExampleCli("listreceivedbyaccount", "6 false true")
1513  + HelpExampleRpc("listreceivedbyaccount", "6, false, true, true")
1514  );
1515 
1516  ObserveSafeMode();
1517 
1518  // Make sure the results are valid at least up to the most recent block
1519  // the user could have gotten from another RPC command prior to now
1520  pwallet->BlockUntilSyncedToCurrentChain();
1521 
1522  LOCK2(cs_main, pwallet->cs_wallet);
1523 
1524  return ListReceived(pwallet, request.params, true);
1525 }
1526 
1527 static void MaybePushAddress(UniValue & entry, const CTxDestination &dest)
1528 {
1529  if (IsValidDestination(dest)) {
1530  entry.push_back(Pair("address", EncodeDestination(dest)));
1531  }
1532 }
1533 
1545 void ListTransactions(CWallet * const pwallet, const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter)
1546 {
1547  CAmount nFee;
1548  std::string strSentAccount;
1549  std::list<COutputEntry> listReceived;
1550  std::list<COutputEntry> listSent;
1551 
1552  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, filter);
1553 
1554  bool fAllAccounts = (strAccount == std::string("*"));
1555  bool involvesWatchonly = wtx.IsFromMe(ISMINE_WATCH_ONLY);
1556 
1557  // Sent
1558  if ((!listSent.empty() || nFee != 0) && (fAllAccounts || strAccount == strSentAccount))
1559  {
1560  for (const COutputEntry& s : listSent)
1561  {
1562  UniValue entry(UniValue::VOBJ);
1563  if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) {
1564  entry.push_back(Pair("involvesWatchonly", true));
1565  }
1566  entry.push_back(Pair("account", strSentAccount));
1567  MaybePushAddress(entry, s.destination);
1568  std::map<std::string, std::string>::const_iterator it = wtx.mapValue.find("DS");
1569  entry.push_back(Pair("category", (it != wtx.mapValue.end() && it->second == "1") ? "privatesend" : "send"));
1570  entry.push_back(Pair("amount", ValueFromAmount(-s.amount)));
1571  if (pwallet->mapAddressBook.count(s.destination)) {
1572  entry.push_back(Pair("label", pwallet->mapAddressBook[s.destination].name));
1573  }
1574  entry.push_back(Pair("vout", s.vout));
1575  entry.push_back(Pair("fee", ValueFromAmount(-nFee)));
1576  if (fLong)
1577  WalletTxToJSON(wtx, entry);
1578  entry.push_back(Pair("abandoned", wtx.isAbandoned()));
1579  ret.push_back(entry);
1580  }
1581  }
1582 
1583  // Received
1584  if (listReceived.size() > 0 && ((wtx.GetDepthInMainChain() >= nMinDepth) || wtx.IsLockedByInstantSend()))
1585  {
1586  for (const COutputEntry& r : listReceived)
1587  {
1588  std::string account;
1589  if (pwallet->mapAddressBook.count(r.destination)) {
1590  account = pwallet->mapAddressBook[r.destination].name;
1591  }
1592  if (fAllAccounts || (account == strAccount))
1593  {
1594  UniValue entry(UniValue::VOBJ);
1595  if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) {
1596  entry.push_back(Pair("involvesWatchonly", true));
1597  }
1598  entry.push_back(Pair("account", account));
1599  MaybePushAddress(entry, r.destination);
1600  if (wtx.IsCoinBase())
1601  {
1602  if (wtx.GetDepthInMainChain() < 1)
1603  entry.push_back(Pair("category", "orphan"));
1604  else if (wtx.GetBlocksToMaturity() > 0)
1605  entry.push_back(Pair("category", "immature"));
1606  else
1607  entry.push_back(Pair("category", "generate"));
1608  }
1609  else
1610  {
1611  entry.push_back(Pair("category", "receive"));
1612  }
1613  entry.push_back(Pair("amount", ValueFromAmount(r.amount)));
1614  if (pwallet->mapAddressBook.count(r.destination)) {
1615  entry.push_back(Pair("label", account));
1616  }
1617  entry.push_back(Pair("vout", r.vout));
1618  if (fLong)
1619  WalletTxToJSON(wtx, entry);
1620  ret.push_back(entry);
1621  }
1622  }
1623  }
1624 }
1625 
1626 void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccount, UniValue& ret)
1627 {
1628  bool fAllAccounts = (strAccount == std::string("*"));
1629 
1630  if (fAllAccounts || acentry.strAccount == strAccount)
1631  {
1632  UniValue entry(UniValue::VOBJ);
1633  entry.push_back(Pair("account", acentry.strAccount));
1634  entry.push_back(Pair("category", "move"));
1635  entry.push_back(Pair("time", acentry.nTime));
1636  entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit)));
1637  entry.push_back(Pair("otheraccount", acentry.strOtherAccount));
1638  entry.push_back(Pair("comment", acentry.strComment));
1639  ret.push_back(entry);
1640  }
1641 }
1642 
1644 {
1645  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1646  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1647  return NullUniValue;
1648  }
1649 
1650  if (request.fHelp || request.params.size() > 4)
1651  throw std::runtime_error(
1652  "listtransactions ( \"account\" count skip include_watchonly)\n"
1653  "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
1654  "\nArguments:\n"
1655  "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
1656  "2. count (numeric, optional, default=10) The number of transactions to return\n"
1657  "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
1658  "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1659  "\nResult:\n"
1660  "[\n"
1661  " {\n"
1662  " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
1663  " It will be \"\" for the default account.\n"
1664  " \"address\":\"address\", (string) The dash address of the transaction. Not present for \n"
1665  " move transactions (category = move).\n"
1666  " \"category\":\"send|receive|move\", (string) The transaction category. 'move' is a local (off blockchain)\n"
1667  " transaction between accounts, and not associated with an address,\n"
1668  " transaction id or block. 'send' and 'receive' transactions are \n"
1669  " associated with an address, transaction id and block details\n"
1670  " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the\n"
1671  " 'move' category for moves outbound. It is positive for the 'receive' category,\n"
1672  " and for the 'move' category for inbound funds.\n"
1673  " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
1674  " \"vout\": n, (numeric) the vout value\n"
1675  " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
1676  " 'send' category of transactions.\n"
1677  " \"confirmations\": n, (numeric) The number of blockchain confirmations for the transaction. Available for 'send' and \n"
1678  " 'receive' category of transactions. Negative confirmations indicate the\n"
1679  " transation conflicts with the block chain\n"
1680  " \"instantlock\" : true|false, (bool) Current transaction lock state. Available for 'send' and 'receive' category of transactions\n"
1681  " \"instantlock_internal\" : true|false, (bool) Current internal transaction lock state. Available for 'send' and 'receive' category of transactions\n"
1682  " \"chainlock\" : true|false, (bool) The state of the corresponding block chainlock\n"
1683  " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
1684  " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive'\n"
1685  " category of transactions.\n"
1686  " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive'\n"
1687  " category of transactions.\n"
1688  " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1689  " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1690  " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
1691  " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
1692  " for 'send' and 'receive' category of transactions.\n"
1693  " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1694  " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
1695  " from (for receiving funds, positive amounts), or went to (for sending funds,\n"
1696  " negative amounts).\n"
1697  " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
1698  " 'send' category of transactions.\n"
1699  " }\n"
1700  "]\n"
1701 
1702  "\nExamples:\n"
1703  "\nList the most recent 10 transactions in the systems\n"
1704  + HelpExampleCli("listtransactions", "") +
1705  "\nList transactions 100 to 120\n"
1706  + HelpExampleCli("listtransactions", "\"*\" 20 100") +
1707  "\nAs a json rpc call\n"
1708  + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
1709  );
1710 
1711  ObserveSafeMode();
1712 
1713  // Make sure the results are valid at least up to the most recent block
1714  // the user could have gotten from another RPC command prior to now
1715  pwallet->BlockUntilSyncedToCurrentChain();
1716 
1717  LOCK2(cs_main, pwallet->cs_wallet);
1718 
1719  std::string strAccount = "*";
1720  if (!request.params[0].isNull())
1721  strAccount = request.params[0].get_str();
1722  int nCount = 10;
1723  if (!request.params[1].isNull())
1724  nCount = request.params[1].get_int();
1725  int nFrom = 0;
1726  if (!request.params[2].isNull())
1727  nFrom = request.params[2].get_int();
1728  isminefilter filter = ISMINE_SPENDABLE;
1729  if(!request.params[3].isNull())
1730  if(request.params[3].get_bool())
1731  filter = filter | ISMINE_WATCH_ONLY;
1732 
1733  if (nCount < 0)
1734  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
1735  if (nFrom < 0)
1736  throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
1737 
1738  UniValue ret(UniValue::VARR);
1739 
1740  const CWallet::TxItems & txOrdered = pwallet->wtxOrdered;
1741 
1742  // iterate backwards until we have nCount items to return:
1743  for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
1744  {
1745  CWalletTx *const pwtx = (*it).second.first;
1746  if (pwtx != nullptr)
1747  ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter);
1748  CAccountingEntry *const pacentry = (*it).second.second;
1749  if (pacentry != nullptr)
1750  AcentryToJSON(*pacentry, strAccount, ret);
1751 
1752  if ((int)ret.size() >= (nCount+nFrom)) break;
1753  }
1754  // ret is newest to oldest
1755 
1756  if (nFrom > (int)ret.size())
1757  nFrom = ret.size();
1758  if ((nFrom + nCount) > (int)ret.size())
1759  nCount = ret.size() - nFrom;
1760 
1761  std::vector<UniValue> arrTmp = ret.getValues();
1762 
1763  std::vector<UniValue>::iterator first = arrTmp.begin();
1764  std::advance(first, nFrom);
1765  std::vector<UniValue>::iterator last = arrTmp.begin();
1766  std::advance(last, nFrom+nCount);
1767 
1768  if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end());
1769  if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first);
1770 
1771  std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest
1772 
1773  ret.clear();
1774  ret.setArray();
1775  ret.push_backV(arrTmp);
1776 
1777  return ret;
1778 }
1779 
1781 {
1782  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1783  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1784  return NullUniValue;
1785  }
1786 
1787  if (request.fHelp || request.params.size() > 3)
1788  throw std::runtime_error(
1789  "listaccounts ( minconf addlocked include_watchonly)\n"
1790  "\nDEPRECATED. Returns Object that has account names as keys, account balances as values.\n"
1791  "\nArguments:\n"
1792  "1. minconf (numeric, optional, default=1) Only include transactions with at least this many confirmations\n"
1793  "2. addlocked (bool, optional, default=false) Whether to include transactions locked via InstantSend.\n"
1794  "3. include_watchonly (bool, optional, default=false) Include balances in watch-only addresses (see 'importaddress')\n"
1795  "\nResult:\n"
1796  "{ (json object where keys are account names, and values are numeric balances\n"
1797  " \"account\": x.xxx, (numeric) The property name is the account name, and the value is the total balance for the account.\n"
1798  " ...\n"
1799  "}\n"
1800  "\nExamples:\n"
1801  "\nList account balances where there at least 1 confirmation\n"
1802  + HelpExampleCli("listaccounts", "") +
1803  "\nList account balances including zero confirmation transactions\n"
1804  + HelpExampleCli("listaccounts", "0") +
1805  "\nList account balances for 6 or more confirmations\n"
1806  + HelpExampleCli("listaccounts", "6") +
1807  "\nAs json rpc call\n"
1808  + HelpExampleRpc("listaccounts", "6")
1809  );
1810 
1811  ObserveSafeMode();
1812 
1813  // Make sure the results are valid at least up to the most recent block
1814  // the user could have gotten from another RPC command prior to now
1815  pwallet->BlockUntilSyncedToCurrentChain();
1816 
1817  LOCK2(cs_main, pwallet->cs_wallet);
1818 
1819  int nMinDepth = 1;
1820  if (!request.params[0].isNull())
1821  nMinDepth = request.params[0].get_int();
1822  bool fAddLocked = false;
1823  if (!request.params[1].isNull())
1824  fAddLocked = request.params[1].get_bool();
1825  isminefilter includeWatchonly = ISMINE_SPENDABLE;
1826  if(!request.params[2].isNull())
1827  if(request.params[2].get_bool())
1828  includeWatchonly = includeWatchonly | ISMINE_WATCH_ONLY;
1829 
1830  std::map<std::string, CAmount> mapAccountBalances;
1831  for (const std::pair<CTxDestination, CAddressBookData>& entry : pwallet->mapAddressBook) {
1832  if (IsMine(*pwallet, entry.first) & includeWatchonly) { // This address belongs to me
1833  mapAccountBalances[entry.second.name] = 0;
1834  }
1835  }
1836 
1837  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1838  const CWalletTx& wtx = pairWtx.second;
1839  CAmount nFee;
1840  std::string strSentAccount;
1841  std::list<COutputEntry> listReceived;
1842  std::list<COutputEntry> listSent;
1843  int nDepth = wtx.GetDepthInMainChain();
1844  if (wtx.GetBlocksToMaturity() > 0 || nDepth < 0)
1845  continue;
1846  wtx.GetAmounts(listReceived, listSent, nFee, strSentAccount, includeWatchonly);
1847  mapAccountBalances[strSentAccount] -= nFee;
1848  for (const COutputEntry& s : listSent)
1849  mapAccountBalances[strSentAccount] -= s.amount;
1850  if ((nDepth >= nMinDepth) || (fAddLocked && wtx.IsLockedByInstantSend()))
1851  {
1852  for (const COutputEntry& r : listReceived)
1853  if (pwallet->mapAddressBook.count(r.destination)) {
1854  mapAccountBalances[pwallet->mapAddressBook[r.destination].name] += r.amount;
1855  }
1856  else
1857  mapAccountBalances[""] += r.amount;
1858  }
1859  }
1860 
1861  const std::list<CAccountingEntry> & acentries = pwallet->laccentries;
1862  for (const CAccountingEntry& entry : acentries)
1863  mapAccountBalances[entry.strAccount] += entry.nCreditDebit;
1864 
1865  UniValue ret(UniValue::VOBJ);
1866  for (const std::pair<std::string, CAmount>& accountBalance : mapAccountBalances) {
1867  ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second)));
1868  }
1869  return ret;
1870 }
1871 
1873 {
1874  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
1875  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
1876  return NullUniValue;
1877  }
1878 
1879  if (request.fHelp || request.params.size() > 4)
1880  throw std::runtime_error(
1881  "listsinceblock ( \"blockhash\" target_confirmations include_watchonly include_removed )\n"
1882  "\nGet all transactions in blocks since block [blockhash], or all transactions if omitted.\n"
1883  "If \"blockhash\" is no longer a part of the main chain, transactions from the fork point onward are included.\n"
1884  "Additionally, if include_removed is set, transactions affecting the wallet which were removed are returned in the \"removed\" array.\n"
1885  "\nArguments:\n"
1886  "1. \"blockhash\" (string, optional) The block hash to list transactions since\n"
1887  "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"
1888  "3. include_watchonly: (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
1889  "4. include_removed: (bool, optional, default=true) Show transactions that were removed due to a reorg in the \"removed\" array\n"
1890  " (not guaranteed to work on pruned nodes)\n"
1891  "\nResult:\n"
1892  "{\n"
1893  " \"transactions\": [\n"
1894  " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
1895  " \"address\":\"address\", (string) The dash address of the transaction. Not present for move transactions (category = move).\n"
1896  " \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
1897  " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
1898  " outbound. It is positive for the 'receive' category, and for the 'move' category for inbound funds.\n"
1899  " \"vout\" : n, (numeric) the vout value\n"
1900  " \"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"
1901  " \"confirmations\" : n, (numeric) The number of blockchain confirmations for the transaction. Available for 'send' and 'receive' category of transactions.\n"
1902  " When it's < 0, it means the transaction conflicted that many blocks ago.\n"
1903  " \"instantlock\" : true|false, (bool) Current transaction lock state. Available for 'send' and 'receive' category of transactions\n"
1904  " \"instantlock_internal\" : true|false, (bool) Current internal transaction lock state. Available for 'send' and 'receive' category of transactions\n"
1905  " \"chainlock\" : true|false, (bool) The state of the corresponding block chainlock\n"
1906  " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction. Available for 'send' and 'receive' category of transactions.\n"
1907  " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it. Available for 'send' and 'receive' category of transactions.\n"
1908  " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
1909  " \"txid\": \"transactionid\", (string) The transaction id. Available for 'send' and 'receive' category of transactions.\n"
1910  " \"time\": xxx, (numeric) The transaction time in seconds since epoch (Jan 1 1970 GMT).\n"
1911  " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (Jan 1 1970 GMT). Available for 'send' and 'receive' category of transactions.\n"
1912  " \"abandoned\": xxx, (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n"
1913  " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
1914  " \"label\" : \"label\" (string) A comment for the address/transaction, if any\n"
1915  " \"to\": \"...\", (string) If a comment to is associated with the transaction.\n"
1916  " ],\n"
1917  " \"removed\": [\n"
1918  " <structure is the same as \"transactions\" above, only present if include_removed=true>\n"
1919  " 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"
1920  " ],\n"
1921  " \"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"
1922  "}\n"
1923  "\nExamples:\n"
1924  + HelpExampleCli("listsinceblock", "")
1925  + HelpExampleCli("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\" 6")
1926  + HelpExampleRpc("listsinceblock", "\"000000000000000bacf66f7497b7dc45ef753ee9a7d38571037cdb1a57f663ad\", 6")
1927  );
1928 
1929  ObserveSafeMode();
1930 
1931  // Make sure the results are valid at least up to the most recent block
1932  // the user could have gotten from another RPC command prior to now
1933  pwallet->BlockUntilSyncedToCurrentChain();
1934 
1935  LOCK2(cs_main, pwallet->cs_wallet);
1936 
1937  const CBlockIndex* pindex = nullptr; // Block index of the specified block or the common ancestor, if the block provided was in a deactivated chain.
1938  const CBlockIndex* paltindex = nullptr; // Block index of the specified block, even if it's in a deactivated chain.
1939  int target_confirms = 1;
1940  isminefilter filter = ISMINE_SPENDABLE;
1941 
1942  if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
1943  uint256 blockId;
1944 
1945  blockId.SetHex(request.params[0].get_str());
1946  BlockMap::iterator it = mapBlockIndex.find(blockId);
1947  if (it == mapBlockIndex.end()) {
1948  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
1949  }
1950  paltindex = pindex = it->second;
1951  if (chainActive[pindex->nHeight] != pindex) {
1952  // the block being asked for is a part of a deactivated chain;
1953  // we don't want to depend on its perceived height in the block
1954  // chain, we want to instead use the last common ancestor
1955  pindex = chainActive.FindFork(pindex);
1956  }
1957  }
1958 
1959  if (!request.params[1].isNull()) {
1960  target_confirms = request.params[1].get_int();
1961 
1962  if (target_confirms < 1) {
1963  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
1964  }
1965  }
1966 
1967  if (!request.params[2].isNull() && request.params[2].get_bool()) {
1968  filter = filter | ISMINE_WATCH_ONLY;
1969  }
1970 
1971  bool include_removed = (request.params[3].isNull() || request.params[3].get_bool());
1972 
1973  int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1;
1974 
1975  UniValue transactions(UniValue::VARR);
1976 
1977  for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet) {
1978  CWalletTx tx = pairWtx.second;
1979 
1980  if (depth == -1 || tx.GetDepthInMainChain() < depth) {
1981  ListTransactions(pwallet, tx, "*", 0, true, transactions, filter);
1982  }
1983  }
1984 
1985  // when a reorg'd block is requested, we also list any relevant transactions
1986  // in the blocks of the chain that was detached
1987  UniValue removed(UniValue::VARR);
1988  while (include_removed && paltindex && paltindex != pindex) {
1989  CBlock block;
1990  if (!ReadBlockFromDisk(block, paltindex, Params().GetConsensus())) {
1991  throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
1992  }
1993  for (const CTransactionRef& tx : block.vtx) {
1994  auto it = pwallet->mapWallet.find(tx->GetHash());
1995  if (it != pwallet->mapWallet.end()) {
1996  // We want all transactions regardless of confirmation count to appear here,
1997  // even negative confirmation ones, hence the big negative.
1998  ListTransactions(pwallet, it->second, "*", -100000000, true, removed, filter);
1999  }
2000  }
2001  paltindex = paltindex->pprev;
2002  }
2003 
2004  CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms];
2005  uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256();
2006 
2007  UniValue ret(UniValue::VOBJ);
2008  ret.push_back(Pair("transactions", transactions));
2009  if (include_removed) ret.push_back(Pair("removed", removed));
2010  ret.push_back(Pair("lastblock", lastblock.GetHex()));
2011 
2012  return ret;
2013 }
2014 
2016 {
2017  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2018  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2019  return NullUniValue;
2020  }
2021 
2022  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2023  throw std::runtime_error(
2024  "gettransaction \"txid\" ( include_watchonly )\n"
2025  "\nGet detailed information about in-wallet transaction <txid>\n"
2026  "\nArguments:\n"
2027  "1. \"txid\" (string, required) The transaction id\n"
2028  "2. \"include_watchonly\" (bool, optional, default=false) Whether to include watch-only addresses in balance calculation and details[]\n"
2029  "\nResult:\n"
2030  "{\n"
2031  " \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n"
2032  " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
2033  " 'send' category of transactions.\n"
2034  " \"instantlock\" : true|false, (bool) Current transaction lock state\n"
2035  " \"instantlock_internal\" : true|false, (bool) Current internal transaction lock state\n"
2036  " \"chainlock\" : true|false, (bool) The state of the corresponding block chainlock\n"
2037  " \"confirmations\" : n, (numeric) The number of blockchain confirmations\n"
2038  " \"blockhash\" : \"hash\", (string) The block hash\n"
2039  " \"blockindex\" : xx, (numeric) The index of the transaction in the block that includes it\n"
2040  " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n"
2041  " \"txid\" : \"transactionid\", (string) The transaction id.\n"
2042  " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n"
2043  " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n"
2044  " \"details\" : [\n"
2045  " {\n"
2046  " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
2047  " \"address\" : \"address\", (string) The dash address involved in the transaction\n"
2048  " \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
2049  " \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
2050  " \"label\" : \"label\", (string) A comment for the address/transaction, if any\n"
2051  " \"vout\" : n, (numeric) the vout value\n"
2052  " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
2053  " 'send' category of transactions.\n"
2054  " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
2055  " 'send' category of transactions.\n"
2056  " }\n"
2057  " ,...\n"
2058  " ],\n"
2059  " \"hex\" : \"data\" (string) Raw data for transaction\n"
2060  "}\n"
2061 
2062  "\nExamples:\n"
2063  + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2064  + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\" true")
2065  + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2066  );
2067 
2068  ObserveSafeMode();
2069 
2070  // Make sure the results are valid at least up to the most recent block
2071  // the user could have gotten from another RPC command prior to now
2072  pwallet->BlockUntilSyncedToCurrentChain();
2073 
2074  LOCK2(cs_main, pwallet->cs_wallet);
2075 
2076  uint256 hash;
2077  hash.SetHex(request.params[0].get_str());
2078 
2079  isminefilter filter = ISMINE_SPENDABLE;
2080  if(!request.params[1].isNull())
2081  if(request.params[1].get_bool())
2082  filter = filter | ISMINE_WATCH_ONLY;
2083 
2084  UniValue entry(UniValue::VOBJ);
2085  auto it = pwallet->mapWallet.find(hash);
2086  if (it == pwallet->mapWallet.end()) {
2087  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2088  }
2089  const CWalletTx& wtx = it->second;
2090 
2091  CAmount nCredit = wtx.GetCredit(filter);
2092  CAmount nDebit = wtx.GetDebit(filter);
2093  CAmount nNet = nCredit - nDebit;
2094  CAmount nFee = (wtx.IsFromMe(filter) ? wtx.tx->GetValueOut() - nDebit : 0);
2095 
2096  entry.push_back(Pair("amount", ValueFromAmount(nNet - nFee)));
2097  if (wtx.IsFromMe(filter))
2098  entry.push_back(Pair("fee", ValueFromAmount(nFee)));
2099 
2100  WalletTxToJSON(wtx, entry);
2101 
2102  UniValue details(UniValue::VARR);
2103  ListTransactions(pwallet, wtx, "*", 0, false, details, filter);
2104  entry.push_back(Pair("details", details));
2105 
2106  std::string strHex = EncodeHexTx(*wtx.tx);
2107  entry.push_back(Pair("hex", strHex));
2108 
2109  return entry;
2110 }
2111 
2113 {
2114  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2115  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2116  return NullUniValue;
2117  }
2118 
2119  if (request.fHelp || request.params.size() != 1)
2120  throw std::runtime_error(
2121  "abandontransaction \"txid\"\n"
2122  "\nMark in-wallet transaction <txid> as abandoned\n"
2123  "This will mark this transaction and all its in-wallet descendants as abandoned which will allow\n"
2124  "for their inputs to be respent. It can be used to replace \"stuck\" or evicted transactions.\n"
2125  "It only works on transactions which are not included in a block and are not currently in the mempool.\n"
2126  "It has no effect on transactions which are already conflicted or abandoned.\n"
2127  "\nArguments:\n"
2128  "1. \"txid\" (string, required) The transaction id\n"
2129  "\nResult:\n"
2130  "\nExamples:\n"
2131  + HelpExampleCli("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2132  + HelpExampleRpc("abandontransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
2133  );
2134 
2135  ObserveSafeMode();
2136 
2137  // Make sure the results are valid at least up to the most recent block
2138  // the user could have gotten from another RPC command prior to now
2139  pwallet->BlockUntilSyncedToCurrentChain();
2140 
2141  LOCK2(cs_main, pwallet->cs_wallet);
2142 
2143  uint256 hash;
2144  hash.SetHex(request.params[0].get_str());
2145 
2146  if (!pwallet->mapWallet.count(hash)) {
2147  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
2148  }
2149  if (!pwallet->AbandonTransaction(hash)) {
2150  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not eligible for abandonment");
2151  }
2152 
2153  return NullUniValue;
2154 }
2155 
2156 
2158 {
2159  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2160  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2161  return NullUniValue;
2162  }
2163 
2164  if (request.fHelp || request.params.size() != 1)
2165  throw std::runtime_error(
2166  "backupwallet \"destination\"\n"
2167  "\nSafely copies current wallet file to destination, which can be a directory or a path with filename.\n"
2168  "\nArguments:\n"
2169  "1. \"destination\" (string) The destination directory or file\n"
2170  "\nExamples:\n"
2171  + HelpExampleCli("backupwallet", "\"backup.dat\"")
2172  + HelpExampleRpc("backupwallet", "\"backup.dat\"")
2173  );
2174 
2175  // Make sure the results are valid at least up to the most recent block
2176  // the user could have gotten from another RPC command prior to now
2177  pwallet->BlockUntilSyncedToCurrentChain();
2178 
2179  LOCK2(cs_main, pwallet->cs_wallet);
2180 
2181  std::string strDest = request.params[0].get_str();
2182  if (!pwallet->BackupWallet(strDest)) {
2183  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
2184  }
2185 
2186  return NullUniValue;
2187 }
2188 
2189 
2191 {
2192  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2193  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2194  return NullUniValue;
2195  }
2196 
2197  if (request.fHelp || request.params.size() > 1)
2198  throw std::runtime_error(
2199  "keypoolrefill ( newsize )\n"
2200  "\nFills the keypool."
2201  + HelpRequiringPassphrase(pwallet) + "\n"
2202  "\nArguments:\n"
2203  "1. newsize (numeric, optional, default=" + itostr(DEFAULT_KEYPOOL_SIZE) + ") The new keypool size\n"
2204  "\nExamples:\n"
2205  + HelpExampleCli("keypoolrefill", "")
2206  + HelpExampleRpc("keypoolrefill", "")
2207  );
2208 
2209  LOCK2(cs_main, pwallet->cs_wallet);
2210 
2211  // 0 is interpreted by TopUpKeyPool() as the default keypool size given by -keypool
2212  unsigned int kpSize = 0;
2213  if (!request.params[0].isNull()) {
2214  if (request.params[0].get_int() < 0)
2215  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected valid size.");
2216  kpSize = (unsigned int)request.params[0].get_int();
2217  }
2218 
2219  EnsureWalletIsUnlocked(pwallet);
2220  pwallet->TopUpKeyPool(kpSize);
2221 
2222  if (pwallet->GetKeyPoolSize() < (pwallet->IsHDEnabled() ? kpSize * 2 : kpSize)) {
2223  throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
2224  }
2225 
2226  return NullUniValue;
2227 }
2228 
2229 
2230 static void LockWallet(CWallet* pWallet)
2231 {
2232  LOCK(pWallet->cs_wallet);
2233  pWallet->nRelockTime = 0;
2234  pWallet->Lock();
2235 }
2236 
2238 {
2239  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2240  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2241  return NullUniValue;
2242  }
2243 
2244  if (request.fHelp || request.params.size() < 2 || request.params.size() > 3) {
2245  throw std::runtime_error(
2246  "walletpassphrase \"passphrase\" timeout ( mixingonly )\n"
2247  "\nStores the wallet decryption key in memory for 'timeout' seconds.\n"
2248  "This is needed prior to performing transactions related to private keys such as sending dashs\n"
2249  "\nArguments:\n"
2250  "1. \"passphrase\" (string, required) The wallet passphrase\n"
2251  "2. timeout (numeric, required) The time to keep the decryption key in seconds; capped at 100000000 (~3 years).\n"
2252  "3. mixingonly (boolean, optional, default=false) If is true sending functions are disabled.\n"
2253  "\nNote:\n"
2254  "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n"
2255  "time that overrides the old one.\n"
2256  "\nExamples:\n"
2257  "\nUnlock the wallet for 60 seconds\n"
2258  + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") +
2259  "\nUnlock the wallet for 60 seconds but allow PrivateSend mixing only\n"
2260  + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60 true") +
2261  "\nLock the wallet again (before 60 seconds)\n"
2262  + HelpExampleCli("walletlock", "") +
2263  "\nAs json rpc call\n"
2264  + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60")
2265  );
2266  }
2267 
2268  LOCK2(cs_main, pwallet->cs_wallet);
2269 
2270  if (request.fHelp)
2271  return true;
2272  if (!pwallet->IsCrypted()) {
2273  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
2274  }
2275 
2276  // Note that the walletpassphrase is stored in request.params[0] which is not mlock()ed
2277  SecureString strWalletPass;
2278  strWalletPass.reserve(100);
2279  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2280  // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2281  strWalletPass = request.params[0].get_str().c_str();
2282 
2283  // Get the timeout
2284  int64_t nSleepTime = request.params[1].get_int64();
2285  // Timeout cannot be negative, otherwise it will relock immediately
2286  if (nSleepTime < 0) {
2287  throw JSONRPCError(RPC_INVALID_PARAMETER, "Timeout cannot be negative.");
2288  }
2289  // Clamp timeout
2290  constexpr int64_t MAX_SLEEP_TIME = 100000000; // larger values trigger a macos/libevent bug?
2291  if (nSleepTime > MAX_SLEEP_TIME) {
2292  nSleepTime = MAX_SLEEP_TIME;
2293  }
2294 
2295  bool fForMixingOnly = false;
2296  if (!request.params[2].isNull())
2297  fForMixingOnly = request.params[2].get_bool();
2298 
2299  if (fForMixingOnly && !pwallet->IsLocked()) {
2300  // Downgrading from "fuly unlocked" mode to "mixing only" one is not supported.
2301  // Updating unlock time when current unlock mode is not changed or when it is upgraded
2302  // from "mixing only" to "fuly unlocked" is ok.
2303  throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already fully unlocked.");
2304  }
2305 
2306  if (!pwallet->Unlock(strWalletPass, fForMixingOnly))
2307  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2308 
2309  pwallet->TopUpKeyPool();
2310 
2311  pwallet->nRelockTime = GetTime() + nSleepTime;
2312  RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), std::bind(LockWallet, pwallet), nSleepTime);
2313 
2314  return NullUniValue;
2315 }
2316 
2317 
2319 {
2320  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2321  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2322  return NullUniValue;
2323  }
2324 
2325  if (request.fHelp || request.params.size() != 2) {
2326  throw std::runtime_error(
2327  "walletpassphrasechange \"oldpassphrase\" \"newpassphrase\"\n"
2328  "\nChanges the wallet passphrase from 'oldpassphrase' to 'newpassphrase'.\n"
2329  "\nArguments:\n"
2330  "1. \"oldpassphrase\" (string) The current passphrase\n"
2331  "2. \"newpassphrase\" (string) The new passphrase\n"
2332  "\nExamples:\n"
2333  + HelpExampleCli("walletpassphrasechange", "\"old one\" \"new one\"")
2334  + HelpExampleRpc("walletpassphrasechange", "\"old one\", \"new one\"")
2335  );
2336  }
2337 
2338  LOCK2(cs_main, pwallet->cs_wallet);
2339 
2340  if (request.fHelp)
2341  return true;
2342  if (!pwallet->IsCrypted()) {
2343  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
2344  }
2345 
2346  // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
2347  // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2348  SecureString strOldWalletPass;
2349  strOldWalletPass.reserve(100);
2350  strOldWalletPass = request.params[0].get_str().c_str();
2351 
2352  SecureString strNewWalletPass;
2353  strNewWalletPass.reserve(100);
2354  strNewWalletPass = request.params[1].get_str().c_str();
2355 
2356  if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1)
2357  throw std::runtime_error(
2358  "walletpassphrasechange <oldpassphrase> <newpassphrase>\n"
2359  "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
2360 
2361  if (!pwallet->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) {
2362  throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
2363  }
2364 
2365  return NullUniValue;
2366 }
2367 
2368 
2370 {
2371  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2372  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2373  return NullUniValue;
2374  }
2375 
2376  if (request.fHelp || request.params.size() != 0) {
2377  throw std::runtime_error(
2378  "walletlock\n"
2379  "\nRemoves the wallet encryption key from memory, locking the wallet.\n"
2380  "After calling this method, you will need to call walletpassphrase again\n"
2381  "before being able to call any methods which require the wallet to be unlocked.\n"
2382  "\nExamples:\n"
2383  "\nSet the passphrase for 2 minutes to perform a transaction\n"
2384  + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 120") +
2385  "\nPerform a send (requires passphrase set)\n"
2386  + HelpExampleCli("sendtoaddress", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" 1.0") +
2387  "\nClear the passphrase since we are done before 2 minutes is up\n"
2388  + HelpExampleCli("walletlock", "") +
2389  "\nAs json rpc call\n"
2390  + HelpExampleRpc("walletlock", "")
2391  );
2392  }
2393 
2394  LOCK2(cs_main, pwallet->cs_wallet);
2395 
2396  if (request.fHelp)
2397  return true;
2398  if (!pwallet->IsCrypted()) {
2399  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
2400  }
2401 
2402  pwallet->Lock();
2403  pwallet->nRelockTime = 0;
2404 
2405  return NullUniValue;
2406 }
2407 
2408 
2410 {
2411  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2412  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2413  return NullUniValue;
2414  }
2415 
2416  if (request.fHelp || request.params.size() != 1) {
2417  throw std::runtime_error(
2418  "encryptwallet \"passphrase\"\n"
2419  "\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
2420  "After this, any calls that interact with private keys such as sending or signing \n"
2421  "will require the passphrase to be set prior the making these calls.\n"
2422  "Use the walletpassphrase call for this, and then walletlock call.\n"
2423  "If the wallet is already encrypted, use the walletpassphrasechange call.\n"
2424  "Note that this will shutdown the server.\n"
2425  "\nArguments:\n"
2426  "1. \"passphrase\" (string) The pass phrase to encrypt the wallet with. It must be at least 1 character, but should be long.\n"
2427  "\nExamples:\n"
2428  "\nEncrypt your wallet\n"
2429  + HelpExampleCli("encryptwallet", "\"my pass phrase\"") +
2430  "\nNow set the passphrase to use the wallet, such as for signing or sending dash\n"
2431  + HelpExampleCli("walletpassphrase", "\"my pass phrase\"") +
2432  "\nNow we can do something like sign\n"
2433  + HelpExampleCli("signmessage", "\"address\" \"test message\"") +
2434  "\nNow lock the wallet again by removing the passphrase\n"
2435  + HelpExampleCli("walletlock", "") +
2436  "\nAs a json rpc call\n"
2437  + HelpExampleRpc("encryptwallet", "\"my pass phrase\"")
2438  );
2439  }
2440 
2441  LOCK2(cs_main, pwallet->cs_wallet);
2442 
2443  if (request.fHelp)
2444  return true;
2445  if (pwallet->IsCrypted()) {
2446  throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
2447  }
2448 
2449  // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
2450  // Alternately, find a way to make request.params[0] mlock()'d to begin with.
2451  SecureString strWalletPass;
2452  strWalletPass.reserve(100);
2453  strWalletPass = request.params[0].get_str().c_str();
2454 
2455  if (strWalletPass.length() < 1)
2456  throw std::runtime_error(
2457  "encryptwallet <passphrase>\n"
2458  "Encrypts the wallet with <passphrase>.");
2459 
2460  if (!pwallet->EncryptWallet(strWalletPass)) {
2461  throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
2462  }
2463 
2464  // BDB seems to have a bad habit of writing old data into
2465  // slack space in .dat files; that is bad if the old data is
2466  // unencrypted private keys. So:
2467  StartShutdown();
2468  return "Wallet encrypted; Dash Core 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.";
2469 }
2470 
2472 {
2473  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2474  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2475  return NullUniValue;
2476  }
2477 
2478  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
2479  throw std::runtime_error(
2480  "lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
2481  "\nUpdates list of temporarily unspendable outputs.\n"
2482  "Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
2483  "If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
2484  "A locked transaction output will not be chosen by automatic coin selection, when spending dashs.\n"
2485  "Locks are stored in memory only. Nodes start with zero locked outputs, and the locked output list\n"
2486  "is always cleared (by virtue of process exit) when a node stops or fails.\n"
2487  "Also see the listunspent call\n"
2488  "\nArguments:\n"
2489  "1. unlock (boolean, required) Whether to unlock (true) or lock (false) the specified transactions\n"
2490  "2. \"transactions\" (string, optional) A json array of objects. Each object the txid (string) vout (numeric)\n"
2491  " [ (json array of json objects)\n"
2492  " {\n"
2493  " \"txid\":\"id\", (string) The transaction id\n"
2494  " \"vout\": n (numeric) The output number\n"
2495  " }\n"
2496  " ,...\n"
2497  " ]\n"
2498 
2499  "\nResult:\n"
2500  "true|false (boolean) Whether the command was successful or not\n"
2501 
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("lockunspent", "false, \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"")
2513  );
2514 
2515  // Make sure the results are valid at least up to the most recent block
2516  // the user could have gotten from another RPC command prior to now
2517  pwallet->BlockUntilSyncedToCurrentChain();
2518 
2519  LOCK2(cs_main, pwallet->cs_wallet);
2520 
2522 
2523  bool fUnlock = request.params[0].get_bool();
2524 
2525  if (request.params[1].isNull()) {
2526  if (fUnlock)
2527  pwallet->UnlockAllCoins();
2528  return true;
2529  }
2530 
2532 
2533  const UniValue& output_params = request.params[1];
2534 
2535  // Create and validate the COutPoints first.
2536 
2537  std::vector<COutPoint> outputs;
2538  outputs.reserve(output_params.size());
2539 
2540  for (unsigned int idx = 0; idx < output_params.size(); idx++) {
2541  const UniValue& o = output_params[idx].get_obj();
2542 
2543  RPCTypeCheckObj(o,
2544  {
2545  {"txid", UniValueType(UniValue::VSTR)},
2546  {"vout", UniValueType(UniValue::VNUM)},
2547  });
2548 
2549  const std::string& txid = find_value(o, "txid").get_str();
2550  if (!IsHex(txid)) {
2551  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
2552  }
2553 
2554  const int nOutput = find_value(o, "vout").get_int();
2555  if (nOutput < 0) {
2556  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
2557  }
2558 
2559  const COutPoint outpt(uint256S(txid), nOutput);
2560 
2561  const auto it = pwallet->mapWallet.find(outpt.hash);
2562  if (it == pwallet->mapWallet.end()) {
2563  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, unknown transaction");
2564  }
2565 
2566  const CWalletTx& trans = it->second;
2567 
2568  if (outpt.n >= trans.tx->vout.size()) {
2569  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout index out of bounds");
2570  }
2571 
2572  if (pwallet->IsSpent(outpt.hash, outpt.n)) {
2573  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected unspent output");
2574  }
2575 
2576  const bool is_locked = pwallet->IsLockedCoin(outpt.hash, outpt.n);
2577 
2578  if (fUnlock && !is_locked) {
2579  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected locked output");
2580  }
2581 
2582  if (!fUnlock && is_locked) {
2583  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output already locked");
2584  }
2585 
2586  outputs.push_back(outpt);
2587  }
2588 
2589  // Atomically set (un)locked status for the outputs.
2590  for (const COutPoint& outpt : outputs) {
2591  if (fUnlock) pwallet->UnlockCoin(outpt);
2592  else pwallet->LockCoin(outpt);
2593  }
2594 
2595  return true;
2596 }
2597 
2599 {
2600  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2601  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2602  return NullUniValue;
2603  }
2604 
2605  if (request.fHelp || request.params.size() > 0)
2606  throw std::runtime_error(
2607  "listlockunspent\n"
2608  "\nReturns list of temporarily unspendable outputs.\n"
2609  "See the lockunspent call to lock and unlock transactions for spending.\n"
2610  "\nResult:\n"
2611  "[\n"
2612  " {\n"
2613  " \"txid\" : \"transactionid\", (string) The transaction id locked\n"
2614  " \"vout\" : n (numeric) The vout value\n"
2615  " }\n"
2616  " ,...\n"
2617  "]\n"
2618  "\nExamples:\n"
2619  "\nList the unspent transactions\n"
2620  + HelpExampleCli("listunspent", "") +
2621  "\nLock an unspent transaction\n"
2622  + HelpExampleCli("lockunspent", "false \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2623  "\nList the locked transactions\n"
2624  + HelpExampleCli("listlockunspent", "") +
2625  "\nUnlock the transaction again\n"
2626  + HelpExampleCli("lockunspent", "true \"[{\\\"txid\\\":\\\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\\\",\\\"vout\\\":1}]\"") +
2627  "\nAs a json rpc call\n"
2628  + HelpExampleRpc("listlockunspent", "")
2629  );
2630 
2631  ObserveSafeMode();
2632  LOCK2(cs_main, pwallet->cs_wallet);
2633 
2634  std::vector<COutPoint> vOutpts;
2635  pwallet->ListLockedCoins(vOutpts);
2636 
2637  UniValue ret(UniValue::VARR);
2638 
2639  for (COutPoint &outpt : vOutpts) {
2641 
2642  o.push_back(Pair("txid", outpt.hash.GetHex()));
2643  o.push_back(Pair("vout", (int)outpt.n));
2644  ret.push_back(o);
2645  }
2646 
2647  return ret;
2648 }
2649 
2651 {
2652  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2653  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2654  return NullUniValue;
2655  }
2656 
2657  if (request.fHelp || request.params.size() < 1 || request.params.size() > 1)
2658  throw std::runtime_error(
2659  "settxfee amount\n"
2660  "\nSet the transaction fee per kB. Overwrites the paytxfee parameter.\n"
2661  "\nArguments:\n"
2662  "1. amount (numeric or string, required) The transaction fee in " + CURRENCY_UNIT + "/kB\n"
2663  "\nResult:\n"
2664  "true|false (boolean) Returns true if successful\n"
2665  "\nExamples:\n"
2666  + HelpExampleCli("settxfee", "0.00001")
2667  + HelpExampleRpc("settxfee", "0.00001")
2668  );
2669 
2670  LOCK2(cs_main, pwallet->cs_wallet);
2671 
2672  // Amount
2673  CAmount nAmount = AmountFromValue(request.params[0]);
2674 
2675  payTxFee = CFeeRate(nAmount, 1000);
2676  return true;
2677 }
2678 
2680 {
2681  CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
2682  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
2683  return NullUniValue;
2684 
2685  if (request.fHelp || request.params.size() != 1)
2686  throw std::runtime_error(
2687  "setprivatesendrounds rounds\n"
2688  "\nSet the number of rounds for PrivateSend mixing.\n"
2689  "\nArguments:\n"
2690  "1. rounds (numeric, required) The default number of rounds is " + std::to_string(DEFAULT_PRIVATESEND_ROUNDS) +
2691  " Cannot be more than " + std::to_string(MAX_PRIVATESEND_ROUNDS) + " nor less than " + std::to_string(MIN_PRIVATESEND_ROUNDS) +
2692  "\nExamples:\n"
2693  + HelpExampleCli("setprivatesendrounds", "4")
2694  + HelpExampleRpc("setprivatesendrounds", "16")
2695  );
2696 
2697  int nRounds = request.params[0].get_int();
2698 
2699  if (nRounds > MAX_PRIVATESEND_ROUNDS || nRounds < MIN_PRIVATESEND_ROUNDS)
2700  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid number of rounds");
2701 
2703 
2704  return NullUniValue;
2705 }
2706 
2708 {
2709  CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
2710  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
2711  return NullUniValue;
2712 
2713  if (request.fHelp || request.params.size() != 1)
2714  throw std::runtime_error(
2715  "setprivatesendamount amount\n"
2716  "\nSet the goal amount in " + CURRENCY_UNIT + " for PrivateSend mixing.\n"
2717  "\nArguments:\n"
2718  "1. amount (numeric, required) The default amount is " + std::to_string(DEFAULT_PRIVATESEND_AMOUNT) +
2719  " Cannot be more than " + std::to_string(MAX_PRIVATESEND_AMOUNT) + " nor less than " + std::to_string(MIN_PRIVATESEND_AMOUNT) +
2720  "\nExamples:\n"
2721  + HelpExampleCli("setprivatesendamount", "500")
2722  + HelpExampleRpc("setprivatesendamount", "208")
2723  );
2724 
2725  int nAmount = request.params[0].get_int();
2726 
2727  if (nAmount > MAX_PRIVATESEND_AMOUNT || nAmount < MIN_PRIVATESEND_AMOUNT)
2728  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount of " + CURRENCY_UNIT + " as mixing goal amount");
2729 
2731 
2732  return NullUniValue;
2733 }
2734 
2736 {
2737  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2738  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2739  return NullUniValue;
2740  }
2741 
2742  if (request.fHelp || request.params.size() != 0)
2743  throw std::runtime_error(
2744  "getwalletinfo\n"
2745  "Returns an object containing various wallet state info.\n"
2746  "\nResult:\n"
2747  "{\n"
2748  " \"walletname\": xxxxx, (string) the wallet name\n"
2749  " \"walletversion\": xxxxx, (numeric) the wallet version\n"
2750  " \"balance\": xxxxxxx, (numeric) the total confirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2751  " \"privatesend_balance\": xxxxxx, (numeric) the PrivateSend balance in " + CURRENCY_UNIT + "\n"
2752  " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in " + CURRENCY_UNIT + "\n"
2753  " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in " + CURRENCY_UNIT + "\n"
2754  " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n"
2755  " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since Unix epoch) of the oldest pre-generated key in the key pool\n"
2756  " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated (only counts external keys)\n"
2757  " \"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"
2758  " \"keys_left\": xxxx, (numeric) how many new keys are left since last automatic backup\n"
2759  " \"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"
2760  " \"paytxfee\": x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n"
2761  " \"hdchainid\": \"<hash>\", (string) the ID of the HD chain\n"
2762  " \"hdaccountcount\": xxx, (numeric) how many accounts of the HD chain are in this wallet\n"
2763  " [\n"
2764  " {\n"
2765  " \"hdaccountindex\": xxx, (numeric) the index of the account\n"
2766  " \"hdexternalkeyindex\": xxxx, (numeric) current external childkey index\n"
2767  " \"hdinternalkeyindex\": xxxx, (numeric) current internal childkey index\n"
2768  " }\n"
2769  " ,...\n"
2770  " ]\n"
2771  "}\n"
2772  "\nExamples:\n"
2773  + HelpExampleCli("getwalletinfo", "")
2774  + HelpExampleRpc("getwalletinfo", "")
2775  );
2776 
2777  ObserveSafeMode();
2778 
2779  // Make sure the results are valid at least up to the most recent block
2780  // the user could have gotten from another RPC command prior to now
2781  pwallet->BlockUntilSyncedToCurrentChain();
2782 
2783  LOCK2(cs_main, pwallet->cs_wallet);
2784 
2785  CHDChain hdChainCurrent;
2786  bool fHDEnabled = pwallet->GetHDChain(hdChainCurrent);
2787  UniValue obj(UniValue::VOBJ);
2788 
2789  obj.push_back(Pair("walletname", pwallet->GetName()));
2790  obj.push_back(Pair("walletversion", pwallet->GetVersion()));
2791  obj.push_back(Pair("balance", ValueFromAmount(pwallet->GetBalance())));
2792  obj.push_back(Pair("privatesend_balance", ValueFromAmount(pwallet->GetAnonymizedBalance())));
2793  obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwallet->GetUnconfirmedBalance())));
2794  obj.push_back(Pair("immature_balance", ValueFromAmount(pwallet->GetImmatureBalance())));
2795  obj.push_back(Pair("txcount", (int)pwallet->mapWallet.size()));
2796  obj.push_back(Pair("keypoololdest", pwallet->GetOldestKeyPoolTime()));
2797  obj.push_back(Pair("keypoolsize", (int64_t)pwallet->KeypoolCountExternalKeys()));
2798  if (fHDEnabled) {
2799  obj.push_back(Pair("keypoolsize_hd_internal", (int64_t)(pwallet->KeypoolCountInternalKeys())));
2800  }
2801  obj.push_back(Pair("keys_left", pwallet->nKeysLeftSinceAutoBackup));
2802  if (pwallet->IsCrypted())
2803  obj.push_back(Pair("unlocked_until", pwallet->nRelockTime));
2804  obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())));
2805  if (fHDEnabled) {
2806  obj.push_back(Pair("hdchainid", hdChainCurrent.GetID().GetHex()));
2807  obj.push_back(Pair("hdaccountcount", (int64_t)hdChainCurrent.CountAccounts()));
2808  UniValue accounts(UniValue::VARR);
2809  for (size_t i = 0; i < hdChainCurrent.CountAccounts(); ++i)
2810  {
2811  CHDAccount acc;
2812  UniValue account(UniValue::VOBJ);
2813  account.push_back(Pair("hdaccountindex", (int64_t)i));
2814  if(hdChainCurrent.GetAccount(i, acc)) {
2815  account.push_back(Pair("hdexternalkeyindex", (int64_t)acc.nExternalChainCounter));
2816  account.push_back(Pair("hdinternalkeyindex", (int64_t)acc.nInternalChainCounter));
2817  } else {
2818  account.push_back(Pair("error", strprintf("account %d is missing", i)));
2819  }
2820  accounts.push_back(account);
2821  }
2822  obj.push_back(Pair("hdaccounts", accounts));
2823  }
2824  return obj;
2825 }
2826 
2828 {
2829  if (request.fHelp || request.params.size() != 0)
2830  throw std::runtime_error(
2831  "listwallets\n"
2832  "Returns a list of currently loaded wallets.\n"
2833  "For full information on the wallet, use \"getwalletinfo\"\n"
2834  "\nResult:\n"
2835  "[ (json array of strings)\n"
2836  " \"walletname\" (string) the wallet name\n"
2837  " ...\n"
2838  "]\n"
2839  "\nExamples:\n"
2840  + HelpExampleCli("listwallets", "")
2841  + HelpExampleRpc("listwallets", "")
2842  );
2843 
2844  UniValue obj(UniValue::VARR);
2845 
2846  for (CWallet* pwallet : GetWallets()) {
2847  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2848  return NullUniValue;
2849  }
2850 
2851  LOCK(pwallet->cs_wallet);
2852 
2853  obj.push_back(pwallet->GetName());
2854  }
2855 
2856  return obj;
2857 }
2858 
2860 {
2861  CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
2862  if (!EnsureWalletIsAvailable(pwallet, request.fHelp))
2863  return NullUniValue;
2864 
2865  std::string strCommand;
2866 
2867  if (!request.params[0].isNull())
2868  strCommand = request.params[0].get_str();
2869 
2870  if (request.fHelp ||
2871  (strCommand != "genkey" && strCommand != "init" && strCommand != "setpassphrase"))
2872  throw std::runtime_error(
2873  "keepass <genkey|init|setpassphrase>\n");
2874 
2875  if (strCommand == "genkey")
2876  {
2877  SecureString sResult;
2878  // Generate RSA key
2880  sResult = "Generated Key: ";
2881  sResult += sKey;
2882  return sResult.c_str();
2883  }
2884  else if(strCommand == "init")
2885  {
2886  // Generate base64 encoded 256 bit RSA key and associate with KeePassHttp
2887  SecureString sResult;
2888  SecureString sKey;
2889  std::string strId;
2890  keePassInt.rpcAssociate(strId, sKey);
2891  sResult = "Association successful. Id: ";
2892  sResult += strId.c_str();
2893  sResult += " - Key: ";
2894  sResult += sKey.c_str();
2895  return sResult.c_str();
2896  }
2897  else if(strCommand == "setpassphrase")
2898  {
2899  if(request.params.size() != 2) {
2900  return "setlogin: invalid number of parameters. Requires a passphrase";
2901  }
2902 
2903  SecureString sPassphrase = SecureString(request.params[1].get_str().c_str());
2904 
2905  keePassInt.updatePassphrase(sPassphrase);
2906 
2907  return "setlogin: Updated credentials.";
2908  }
2909 
2910  return "Invalid command";
2911 }
2912 
2914 {
2915  if (request.fHelp || request.params.size() != 1)
2916  throw std::runtime_error(
2917  "loadwallet \"filename\"\n"
2918  "\nLoads a wallet from a wallet file or directory."
2919  "\nNote that all wallet command-line options used when starting dashd will be"
2920  "\napplied to the new wallet (eg -zapwallettxes, upgradewallet, rescan, etc).\n"
2921  "\nArguments:\n"
2922  "1. \"filename\" (string, required) The wallet directory or .dat file.\n"
2923  "\nResult:\n"
2924  "{\n"
2925  " \"name\" : <wallet_name>, (string) The wallet name if loaded successfully.\n"
2926  " \"warning\" : <warning>, (string) Warning message if wallet was not loaded cleanly.\n"
2927  "}\n"
2928  "\nExamples:\n"
2929  + HelpExampleCli("loadwallet", "\"test.dat\"")
2930  + HelpExampleRpc("loadwallet", "\"test.dat\"")
2931  );
2932  std::string wallet_file = request.params[0].get_str();
2933  std::string error;
2934 
2935  fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir());
2936  if (fs::symlink_status(wallet_path).type() == fs::file_not_found) {
2937  throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Wallet " + wallet_file + " not found.");
2938  } else if (fs::is_directory(wallet_path)) {
2939  // The given filename is a directory. Check that there's a wallet.dat file.
2940  fs::path wallet_dat_file = wallet_path / "wallet.dat";
2941  if (fs::symlink_status(wallet_dat_file).type() == fs::file_not_found) {
2942  throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Directory " + wallet_file + " does not contain a wallet.dat file.");
2943  }
2944  }
2945 
2946  std::string warning;
2947  if (!CWallet::Verify(wallet_file, false, error, warning)) {
2948  throw JSONRPCError(RPC_WALLET_ERROR, "Wallet file verification failed: " + error);
2949  }
2950 
2951  CWallet * const wallet = CWallet::CreateWalletFromFile(wallet_file, fs::absolute(wallet_file, GetWalletDir()));
2952  if (!wallet) {
2953  throw JSONRPCError(RPC_WALLET_ERROR, "Wallet loading failed.");
2954  }
2955  AddWallet(wallet);
2956 
2957  wallet->postInitProcess();
2958 
2959  UniValue obj(UniValue::VOBJ);
2960  obj.pushKV("name", wallet->GetName());
2961  obj.pushKV("warning", warning);
2962 
2963  return obj;
2964 }
2965 
2967 {
2968  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
2969  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
2970  return NullUniValue;
2971  }
2972 
2973  if (request.fHelp || request.params.size() != 0)
2974  throw std::runtime_error(
2975  "resendwallettransactions\n"
2976  "Immediately re-broadcast unconfirmed wallet transactions to all peers.\n"
2977  "Intended only for testing; the wallet code periodically re-broadcasts\n"
2978  "automatically.\n"
2979  "Returns an RPC error if -walletbroadcast is set to false.\n"
2980  "Returns array of transaction ids that were re-broadcast.\n"
2981  );
2982 
2983  if (!g_connman)
2984  throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
2985 
2986  LOCK2(cs_main, mempool.cs);
2987  LOCK(pwallet->cs_wallet);
2988 
2989  if (!pwallet->GetBroadcastTransactions()) {
2990  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet transaction broadcasting is disabled with -walletbroadcast");
2991  }
2992 
2993  std::vector<uint256> txids = pwallet->ResendWalletTransactionsBefore(GetTime(), g_connman.get());
2994  UniValue result(UniValue::VARR);
2995  for (const uint256& txid : txids)
2996  {
2997  result.push_back(txid.ToString());
2998  }
2999  return result;
3000 }
3001 
3003 {
3004  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3005  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3006  return NullUniValue;
3007  }
3008 
3009  if (request.fHelp || request.params.size() > 5)
3010  throw std::runtime_error(
3011  "listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
3012  "\nReturns array of unspent transaction outputs\n"
3013  "with between minconf and maxconf (inclusive) confirmations.\n"
3014  "Optionally filter to only include txouts paid to specified addresses.\n"
3015  "\nArguments:\n"
3016  "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
3017  "2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
3018  "3. \"addresses\" (string) A json array of dash addresses to filter\n"
3019  " [\n"
3020  " \"address\" (string) dash address\n"
3021  " ,...\n"
3022  " ]\n"
3023  "4. include_unsafe (bool, optional, default=true) Include outputs that are not safe to spend\n"
3024  " See description of \"safe\" attribute below.\n"
3025  "5. query_options (json, optional) JSON with query options\n"
3026  " {\n"
3027  " \"minimumAmount\" (numeric or string, default=0) Minimum value of each UTXO in " + CURRENCY_UNIT + "\n"
3028  " \"maximumAmount\" (numeric or string, default=unlimited) Maximum value of each UTXO in " + CURRENCY_UNIT + "\n"
3029  " \"maximumCount\" (numeric or string, default=unlimited) Maximum number of UTXOs\n"
3030  " \"minimumSumAmount\" (numeric or string, default=unlimited) Minimum sum value of all UTXOs in " + CURRENCY_UNIT + "\n"
3031  " \"coinType\" (numeric, default=0) Filter coinTypes as follows:\n"
3032  " 0=ALL_COINS, 1=ONLY_FULLY_MIXED, 2=ONLY_READY_TO_MIX, 3=ONLY_NONDENOMINATED,\n"
3033  " 4=ONLY_MASTERNODE_COLLATERAL, 5=ONLY_PRIVATESEND_COLLATERAL\n"
3034  " }\n"
3035  "\nResult\n"
3036  "[ (array of json object)\n"
3037  " {\n"
3038  " \"txid\" : \"txid\", (string) the transaction id \n"
3039  " \"vout\" : n, (numeric) the vout value\n"
3040  " \"address\" : \"address\", (string) the dash address\n"
3041  " \"account\" : \"account\", (string) DEPRECATED. The associated account, or \"\" for the default account\n"
3042  " \"scriptPubKey\" : \"key\", (string) the script key\n"
3043  " \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
3044  " \"confirmations\" : n, (numeric) The number of confirmations\n"
3045  " \"redeemScript\" : n (string) The redeemScript if scriptPubKey is P2SH\n"
3046  " \"spendable\" : xxx, (bool) Whether we have the private keys to spend this output\n"
3047  " \"solvable\" : xxx, (bool) Whether we know how to spend this output, ignoring the lack of keys\n"
3048  " \"safe\" : xxx (bool) Whether this output is considered safe to spend. Unconfirmed transactions\n"
3049  " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
3050  " and are not eligible for spending by fundrawtransaction and sendtoaddress.\n"
3051  " \"ps_rounds\" : n (numeric) The number of PS rounds\n"
3052  " }\n"
3053  " ,...\n"
3054  "]\n"
3055 
3056  "\nExamples:\n"
3057  + HelpExampleCli("listunspent", "")
3058  + HelpExampleCli("listunspent", "6 9999999 \"[\\\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\\\",\\\"XuQQkwA4FYkq2XERzMY2CiAZhJTEDAbtcg\\\"]\"")
3059  + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwg\\\",\\\"XuQQkwA4FYkq2XERzMY2CiAZhJTEDAbtcg\\\"]\"")
3060  + HelpExampleCli("listunspent", "6 9999999 '[]' true '{ \"minimumAmount\": 0.005 }'")
3061  + HelpExampleRpc("listunspent", "6, 9999999, [] , true, { \"minimumAmount\": 0.005 } ")
3062  );
3063 
3064  ObserveSafeMode();
3065 
3066  int nMinDepth = 1;
3067  if (!request.params[0].isNull()) {
3069  nMinDepth = request.params[0].get_int();
3070  }
3071 
3072  int nMaxDepth = 9999999;
3073  if (!request.params[1].isNull()) {
3075  nMaxDepth = request.params[1].get_int();
3076  }
3077 
3078  std::set<CTxDestination> destinations;
3079  if (!request.params[2].isNull()) {
3081  UniValue inputs = request.params[2].get_array();
3082  for (unsigned int idx = 0; idx < inputs.size(); idx++) {
3083  const UniValue& input = inputs[idx];
3084  CTxDestination dest = DecodeDestination(input.get_str());
3085  if (!IsValidDestination(dest)) {
3086  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Dash address: ") + input.get_str());
3087  }
3088  if (!destinations.insert(dest).second) {
3089  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + input.get_str());
3090  }
3091  }
3092  }
3093 
3094  bool include_unsafe = true;
3095  if (!request.params[3].isNull()) {
3097  include_unsafe = request.params[3].get_bool();
3098  }
3099 
3100  CAmount nMinimumAmount = 0;
3101  CAmount nMaximumAmount = MAX_MONEY;
3102  CAmount nMinimumSumAmount = MAX_MONEY;
3103  uint64_t nMaximumCount = 0;
3104  CCoinControl coinControl;
3105  coinControl.nCoinType = CoinType::ALL_COINS;
3106 
3107  if (!request.params[4].isNull()) {
3108  const UniValue& options = request.params[4].get_obj();
3109 
3110  // Note: Keep this vector up to date with the options processed below
3111  const std::vector<std::string> vecOptions {
3112  "minimumAmount",
3113  "maximumAmount",
3114  "minimumSumAmount",
3115  "maximumCount",
3116  "coinType"
3117  };
3118 
3119  for (const auto& key : options.getKeys()) {
3120  if (std::find(vecOptions.begin(), vecOptions.end(), key) == vecOptions.end()) {
3121  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid key used in query_options JSON object: ") + key);
3122  }
3123  }
3124 
3125  if (options.exists("minimumAmount"))
3126  nMinimumAmount = AmountFromValue(options["minimumAmount"]);
3127 
3128  if (options.exists("maximumAmount"))
3129  nMaximumAmount = AmountFromValue(options["maximumAmount"]);
3130 
3131  if (options.exists("minimumSumAmount"))
3132  nMinimumSumAmount = AmountFromValue(options["minimumSumAmount"]);
3133 
3134  if (options.exists("maximumCount"))
3135  nMaximumCount = options["maximumCount"].get_int64();
3136 
3137  if (options.exists("coinType")) {
3138  int64_t nCoinType = options["coinType"].get_int64();
3139 
3140  if (nCoinType < static_cast<int64_t>(CoinType::MIN_COIN_TYPE) || nCoinType > static_cast<int64_t>(CoinType::MAX_COIN_TYPE)) {
3141  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid coinType selected. Available range: %d - %d", static_cast<int64_t>(CoinType::MIN_COIN_TYPE), static_cast<int64_t>(CoinType::MAX_COIN_TYPE)));
3142  }
3143 
3144  coinControl.nCoinType = static_cast<CoinType>(nCoinType);
3145  }
3146  }
3147 
3148  // Make sure the results are valid at least up to the most recent block
3149  // the user could have gotten from another RPC command prior to now
3150  pwallet->BlockUntilSyncedToCurrentChain();
3151 
3152  UniValue results(UniValue::VARR);
3153  std::vector<COutput> vecOutputs;
3154  LOCK2(cs_main, pwallet->cs_wallet);
3155 
3156  pwallet->AvailableCoins(vecOutputs, !include_unsafe, &coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
3157  for (const COutput& out : vecOutputs) {
3158  CTxDestination address;
3159  const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
3160  bool fValidAddress = ExtractDestination(scriptPubKey, address);
3161 
3162  if (destinations.size() && (!fValidAddress || !destinations.count(address)))
3163  continue;
3164 
3165  UniValue entry(UniValue::VOBJ);
3166  entry.push_back(Pair("txid", out.tx->GetHash().GetHex()));
3167  entry.push_back(Pair("vout", out.i));
3168 
3169  if (fValidAddress) {
3170  entry.push_back(Pair("address", EncodeDestination(address)));
3171 
3172  if (pwallet->mapAddressBook.count(address)) {
3173  entry.push_back(Pair("account", pwallet->mapAddressBook[address].name));
3174  }
3175 
3176  if (scriptPubKey.IsPayToScriptHash()) {
3177  const CScriptID& hash = boost::get<CScriptID>(address);
3178  CScript redeemScript;
3179  if (pwallet->GetCScript(hash, redeemScript)) {
3180  entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())));
3181  }
3182  }
3183  }
3184 
3185  entry.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
3186  entry.push_back(Pair("amount", ValueFromAmount(out.tx->tx->vout[out.i].nValue)));
3187  entry.push_back(Pair("confirmations", out.nDepth));
3188  entry.push_back(Pair("spendable", out.fSpendable));
3189  entry.push_back(Pair("solvable", out.fSolvable));
3190  entry.push_back(Pair("safe", out.fSafe));
3191  entry.push_back(Pair("ps_rounds", pwallet->GetRealOutpointPrivateSendRounds(COutPoint(out.tx->GetHash(), out.i))));
3192  results.push_back(entry);
3193  }
3194 
3195  return results;
3196 }
3197 
3199 {
3200  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3201  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3202  return NullUniValue;
3203  }
3204 
3205  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
3206  throw std::runtime_error(
3207  "fundrawtransaction \"hexstring\" ( options )\n"
3208  "\nAdd inputs to a transaction until it has enough in value to meet its out value.\n"
3209  "This will not modify existing inputs, and will add at most one change output to the outputs.\n"
3210  "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
3211  "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
3212  "The inputs added will not be signed, use signrawtransaction for that.\n"
3213  "Note that all existing inputs must have their previous output transaction be in the wallet.\n"
3214  "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
3215  "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
3216  "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
3217  "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n"
3218  "\nArguments:\n"
3219  "1. \"hexstring\" (string, required) The hex string of the raw transaction\n"
3220  "2. options (object, optional)\n"
3221  " {\n"
3222  " \"changeAddress\" (string, optional, default pool address) The dash address to receive the change\n"
3223  " \"changePosition\" (numeric, optional, default random) The index of the change output\n"
3224  " \"includeWatching\" (boolean, optional, default false) Also select inputs which are watch only\n"
3225  " \"lockUnspents\" (boolean, optional, default false) Lock selected unspent outputs\n"
3226  " \"feeRate\" (numeric, optional, default not set: makes wallet determine the fee) Set a specific fee rate in " + CURRENCY_UNIT + "/kB\n"
3227  " \"subtractFeeFromOutputs\" (array, optional) A json array of integers.\n"
3228  " The fee will be equally deducted from the amount of each specified output.\n"
3229  " The outputs are specified by their zero-based index, before any change output is added.\n"
3230  " Those recipients will receive less dash than you enter in their corresponding amount field.\n"
3231  " If no outputs are specified here, the sender pays the fee.\n"
3232  " [vout_index,...]\n"
3233  " \"conf_target\" (numeric, optional) Confirmation target (in blocks)\n"
3234  " \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
3235  " \"UNSET\"\n"
3236  " \"ECONOMICAL\"\n"
3237  " \"CONSERVATIVE\"\n"
3238  " }\n"
3239  " for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}\n"
3240  "\nResult:\n"
3241  "{\n"
3242  " \"hex\": \"value\", (string) The resulting raw transaction (hex-encoded string)\n"
3243  " \"fee\": n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n"
3244  " \"changepos\": n (numeric) The position of the added change output, or -1\n"
3245  "}\n"
3246  "\nExamples:\n"
3247  "\nCreate a transaction with no inputs\n"
3248  + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
3249  "\nAdd sufficient unsigned inputs to meet the output value\n"
3250  + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
3251  "\nSign the transaction\n"
3252  + HelpExampleCli("signrawtransaction", "\"fundedtransactionhex\"") +
3253  "\nSend the transaction\n"
3254  + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
3255  );
3256 
3257  ObserveSafeMode();
3258  RPCTypeCheck(request.params, {UniValue::VSTR});
3259 
3260  // Make sure the results are valid at least up to the most recent block
3261  // the user could have gotten from another RPC command prior to now
3262  pwallet->BlockUntilSyncedToCurrentChain();
3263 
3264  CCoinControl coinControl;
3265  int changePosition = -1;
3266  bool lockUnspents = false;
3267  UniValue subtractFeeFromOutputs;
3268  std::set<int> setSubtractFeeFromOutputs;
3269 
3270  if (!request.params[1].isNull()) {
3271  if (request.params[1].type() == UniValue::VBOOL) {
3272  // backward compatibility bool only fallback
3273  coinControl.fAllowWatchOnly = request.params[1].get_bool();
3274  }
3275  else {
3276  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
3277 
3278  UniValue options = request.params[1];
3279 
3280  RPCTypeCheckObj(options,
3281  {
3282  {"changeAddress", UniValueType(UniValue::VSTR)},
3283  {"changePosition", UniValueType(UniValue::VNUM)},
3284  {"includeWatching", UniValueType(UniValue::VBOOL)},
3285  {"lockUnspents", UniValueType(UniValue::VBOOL)},
3286  {"reserveChangeKey", UniValueType(UniValue::VBOOL)}, // DEPRECATED (and ignored), should be removed in 0.16 or so.
3287  {"feeRate", UniValueType()}, // will be checked below
3288  {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
3289  {"conf_target", UniValueType(UniValue::VNUM)},
3290  {"estimate_mode", UniValueType(UniValue::VSTR)},
3291  },
3292  true, true);
3293 
3294  if (options.exists("changeAddress")) {
3295  CTxDestination dest = DecodeDestination(options["changeAddress"].get_str());
3296 
3297  if (!IsValidDestination(dest)) {
3298  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "changeAddress must be a valid dash address");
3299  }
3300 
3301  coinControl.destChange = dest;
3302  }
3303 
3304  if (options.exists("changePosition"))
3305  changePosition = options["changePosition"].get_int();
3306 
3307  if (options.exists("includeWatching"))
3308  coinControl.fAllowWatchOnly = options["includeWatching"].get_bool();
3309 
3310  if (options.exists("lockUnspents"))
3311  lockUnspents = options["lockUnspents"].get_bool();
3312 
3313  if (options.exists("feeRate"))
3314  {
3315  coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"]));
3316  coinControl.fOverrideFeeRate = true;
3317  }
3318 
3319  if (options.exists("subtractFeeFromOutputs"))
3320  subtractFeeFromOutputs = options["subtractFeeFromOutputs"].get_array();
3321  if (options.exists("conf_target")) {
3322  if (options.exists("feeRate")) {
3323  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate");
3324  }
3325  coinControl.m_confirm_target = ParseConfirmTarget(options["conf_target"]);
3326  }
3327  if (options.exists("estimate_mode")) {
3328  if (options.exists("feeRate")) {
3329  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate");
3330  }
3331  if (!FeeModeFromString(options["estimate_mode"].get_str(), coinControl.m_fee_mode)) {
3332  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid estimate_mode parameter");
3333  }
3334  }
3335  }
3336  }
3337 
3338  // parse hex string from parameter
3340  if (!DecodeHexTx(tx, request.params[0].get_str()))
3341  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
3342 
3343  if (tx.vout.size() == 0)
3344  throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
3345 
3346  if (changePosition != -1 && (changePosition < 0 || (unsigned int)changePosition > tx.vout.size()))
3347  throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
3348 
3349  for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
3350  int pos = subtractFeeFromOutputs[idx].get_int();
3351  if (setSubtractFeeFromOutputs.count(pos))
3352  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
3353  if (pos < 0)
3354  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
3355  if (pos >= int(tx.vout.size()))
3356  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
3357  setSubtractFeeFromOutputs.insert(pos);
3358  }
3359 
3360  CAmount nFeeOut;
3361  std::string strFailReason;
3362 
3363  if (!pwallet->FundTransaction(tx, nFeeOut, changePosition, strFailReason, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
3364  throw JSONRPCError(RPC_WALLET_ERROR, strFailReason);
3365  }
3366 
3367  UniValue result(UniValue::VOBJ);
3368  result.push_back(Pair("hex", EncodeHexTx(tx)));
3369  result.push_back(Pair("changepos", changePosition));
3370  result.push_back(Pair("fee", ValueFromAmount(nFeeOut)));
3371 
3372  return result;
3373 }
3374 
3375 #if ENABLE_MINER
3376 UniValue generate(const JSONRPCRequest& request)
3377 {
3378  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3379 
3380  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3381  return NullUniValue;
3382  }
3383 
3384  if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) {
3385  throw std::runtime_error(
3386  "generate nblocks ( maxtries )\n"
3387  "\nMine up to nblocks blocks immediately (before the RPC call returns) to an address in the wallet.\n"
3388  "\nArguments:\n"
3389  "1. nblocks (numeric, required) How many blocks are generated immediately.\n"
3390  "2. maxtries (numeric, optional) How many iterations to try (default = 1000000).\n"
3391  "\nResult:\n"
3392  "[ blockhashes ] (array) hashes of blocks generated\n"
3393  "\nExamples:\n"
3394  "\nGenerate 11 blocks\n"
3395  + HelpExampleCli("generate", "11")
3396  );
3397  }
3398 
3399  int num_generate = request.params[0].get_int();
3400  uint64_t max_tries = 1000000;
3401  if (!request.params[1].isNull()) {
3402  max_tries = request.params[1].get_int();
3403  }
3404 
3405  std::shared_ptr<CReserveScript> coinbase_script;
3406  pwallet->GetScriptForMining(coinbase_script);
3407 
3408  // If the keypool is exhausted, no script is returned at all. Catch this.
3409  if (!coinbase_script) {
3410  throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
3411  }
3412 
3413  //throw an error if no script was provided
3414  if (coinbase_script->reserveScript.empty()) {
3415  throw JSONRPCError(RPC_INTERNAL_ERROR, "No coinbase script available");
3416  }
3417 
3418  return generateBlocks(coinbase_script, num_generate, max_tries, true);
3419 }
3420 #endif //ENABLE_MINING
3421 
3423 {
3424  CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
3425  if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
3426  return NullUniValue;
3427  }
3428 
3429  if (request.fHelp || request.params.size() > 2) {
3430  throw std::runtime_error(
3431  "rescanblockchain (\"start_height\") (\"stop_height\")\n"
3432  "\nRescan the local blockchain for wallet related transactions.\n"
3433  "\nArguments:\n"
3434  "1. \"start_height\" (numeric, optional) block height where the rescan should start\n"
3435  "2. \"stop_height\" (numeric, optional) the last block height that should be scanned\n"
3436  "\nResult:\n"
3437  "{\n"
3438  " \"start_height\" (numeric) The block height where the rescan has started. If omitted, rescan started from the genesis block.\n"
3439  " \"stop_height\" (numeric) The height of the last rescanned block. If omitted, rescan stopped at the chain tip.\n"
3440  "}\n"
3441  "\nExamples:\n"
3442  + HelpExampleCli("rescanblockchain", "100000 120000")
3443  + HelpExampleRpc("rescanblockchain", "100000, 120000")
3444  );
3445  }
3446 
3447  WalletRescanReserver reserver(pwallet);
3448  if (!reserver.reserve()) {
3449  throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");
3450  }
3451 
3452  CBlockIndex *pindexStart = nullptr;
3453  CBlockIndex *pindexStop = nullptr;
3454  CBlockIndex *pChainTip = nullptr;
3455  {
3456  LOCK(cs_main);
3457  pindexStart = chainActive.Genesis();
3458  pChainTip = chainActive.Tip();
3459 
3460  if (!request.params[0].isNull()) {
3461  pindexStart = chainActive[request.params[0].get_int()];
3462  if (!pindexStart) {
3463  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid start_height");
3464  }
3465  }
3466 
3467  if (!request.params[1].isNull()) {
3468  pindexStop = chainActive[request.params[1].get_int()];
3469  if (!pindexStop) {
3470  throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid stop_height");
3471  }
3472  else if (pindexStop->nHeight < pindexStart->nHeight) {
3473  throw JSONRPCError(RPC_INVALID_PARAMETER, "stop_height must be greater then start_height");
3474  }
3475  }
3476  }
3477 
3478  // We can't rescan beyond non-pruned blocks, stop and throw an error
3479  if (fPruneMode) {
3480  LOCK(cs_main);
3481  CBlockIndex *block = pindexStop ? pindexStop : pChainTip;
3482  while (block && block->nHeight >= pindexStart->nHeight) {
3483  if (!(block->nStatus & BLOCK_HAVE_DATA)) {
3484  throw JSONRPCError(RPC_MISC_ERROR, "Can't rescan beyond pruned data. Use RPC call getblockchaininfo to determine your pruned height.");
3485  }
3486  block = block->pprev;
3487  }
3488  }
3489 
3490  CBlockIndex *stopBlock = pwallet->ScanForWalletTransactions(pindexStart, pindexStop, reserver, true);
3491  if (!stopBlock) {
3492  if (pwallet->IsAbortingRescan()) {
3493  throw JSONRPCError(RPC_MISC_ERROR, "Rescan aborted.");
3494  }
3495  // if we got a nullptr returned, ScanForWalletTransactions did rescan up to the requested stopindex
3496  stopBlock = pindexStop ? pindexStop : pChainTip;
3497  }
3498  else {
3499  throw JSONRPCError(RPC_MISC_ERROR, "Rescan failed. Potentially corrupted data files.");
3500  }
3501  UniValue response(UniValue::VOBJ);
3502  response.pushKV("start_height", pindexStart->nHeight);
3503  response.pushKV("stop_height", stopBlock->nHeight);
3504  return response;
3505 }
3506 
3507 extern UniValue abortrescan(const JSONRPCRequest& request); // in rpcdump.cpp
3508 extern UniValue dumpprivkey(const JSONRPCRequest& request); // in rpcdump.cpp
3509 extern UniValue importprivkey(const JSONRPCRequest& request);
3510 extern UniValue importaddress(const JSONRPCRequest& request);
3511 extern UniValue importpubkey(const JSONRPCRequest& request);
3512 extern UniValue dumpwallet(const JSONRPCRequest& request);
3513 extern UniValue importwallet(const JSONRPCRequest& request);
3514 extern UniValue importprunedfunds(const JSONRPCRequest& request);
3515 extern UniValue removeprunedfunds(const JSONRPCRequest& request);
3516 extern UniValue importmulti(const JSONRPCRequest& request);
3517 extern UniValue rescanblockchain(const JSONRPCRequest& request);
3518 
3519 extern UniValue dumphdinfo(const JSONRPCRequest& request);
3520 extern UniValue importelectrumwallet(const JSONRPCRequest& request);
3521 
3522 static const CRPCCommand commands[] =
3523 { // category name actor (function) argNames
3524  // --------------------- ------------------------ ----------------------- ----------
3525  { "rawtransactions", "fundrawtransaction", &fundrawtransaction, {"hexstring","options"} },
3526  { "hidden", "resendwallettransactions", &resendwallettransactions, {} },
3527  { "wallet", "abandontransaction", &abandontransaction, {"txid"} },
3528  { "wallet", "abortrescan", &abortrescan, {} },
3529  { "wallet", "addmultisigaddress", &addmultisigaddress, {"nrequired","keys","account"} },
3530  { "wallet", "backupwallet", &backupwallet, {"destination"} },
3531  { "wallet", "dumpprivkey", &dumpprivkey, {"address"} },
3532  { "wallet", "dumpwallet", &dumpwallet, {"filename"} },
3533  { "wallet", "encryptwallet", &encryptwallet, {"passphrase"} },
3534  { "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
3535  { "wallet", "getaccount", &getaccount, {"address"} },
3536  { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
3537  { "wallet", "getbalance", &getbalance, {"account","minconf","addlocked","include_watchonly"} },
3538  { "wallet", "getnewaddress", &getnewaddress, {"account"} },
3539  { "wallet", "getrawchangeaddress", &getrawchangeaddress, {} },
3540  { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, {"account","minconf","addlocked"} },
3541  { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, {"address","minconf","addlocked"} },
3542  { "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
3543  { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
3544  { "wallet", "getwalletinfo", &getwalletinfo, {} },
3545  { "wallet", "importmulti", &importmulti, {"requests","options"} },
3546  { "wallet", "importprivkey", &importprivkey, {"privkey","label","rescan"} },
3547  { "wallet", "importwallet", &importwallet, {"filename"} },
3548  { "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
3549  { "wallet", "importprunedfunds", &importprunedfunds, {"rawtransaction","txoutproof"} },
3550  { "wallet", "importpubkey", &importpubkey, {"pubkey","label","rescan"} },
3551  { "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
3552  { "wallet", "listaccounts", &listaccounts, {"minconf","addlocked","include_watchonly"} },
3553  { "wallet", "listaddressgroupings", &listaddressgroupings, {} },
3554  { "wallet", "listaddressbalances", &listaddressbalances, {"minamount"} },
3555  { "wallet", "listlockunspent", &listlockunspent, {} },
3556  { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, {"minconf","addlocked","include_empty","include_watchonly"} },
3557  { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","addlocked","include_empty","include_watchonly"} },
3558  { "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
3559  { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
3560  { "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
3561  { "wallet", "listwallets", &listwallets, {} },
3562  { "wallet", "loadwallet", &loadwallet, {"filename"} },
3563  { "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
3564  { "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
3565  { "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","addlocked","comment","comment_to"} },
3566  { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","addlocked","comment","subtractfeefrom","use_is","use_ps","conf_target","estimate_mode"} },
3567  { "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","use_is","use_ps","conf_target","estimate_mode"} },
3568  { "wallet", "setaccount", &setaccount, {"address","account"} },
3569  { "wallet", "settxfee", &settxfee, {"amount"} },
3570  { "wallet", "setprivatesendrounds", &setprivatesendrounds, {"rounds"} },
3571  { "wallet", "setprivatesendamount", &setprivatesendamount, {"amount"} },
3572  { "wallet", "signmessage", &signmessage, {"address","message"} },
3573  { "wallet", "walletlock", &walletlock, {} },
3574  { "wallet", "walletpassphrasechange", &walletpassphrasechange, {"oldpassphrase","newpassphrase"} },
3575  { "wallet", "walletpassphrase", &walletpassphrase, {"passphrase","timeout","mixingonly"} },
3576  { "wallet", "removeprunedfunds", &removeprunedfunds, {"txid"} },
3577  { "wallet", "rescanblockchain", &rescanblockchain, {"start_height", "stop_height"} },
3578 
3579 #if ENABLE_MINER
3580  { "generating", "generate", &generate, {"nblocks","maxtries"} },
3581 #endif //ENABLE_MINER
3582  { "wallet", "keepass", &keepass, {} },
3583  { "hidden", "instantsendtoaddress", &instantsendtoaddress, {} },
3584  { "wallet", "dumphdinfo", &dumphdinfo, {} },
3585  { "wallet", "importelectrumwallet", &importelectrumwallet, {"filename", "index"} },
3586 };
3587 
3589 {
3590  for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
3591  t.appendCommand(commands[vcidx].name, &commands[vcidx]);
3592 }
UniValue getunconfirmedbalance(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:898
No wallet specified (error when there are multiple wallets loaded)
Definition: protocol.h:87
CAmount nValue
Definition: transaction.h:147
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: server.cpp:79
CTxMemPool mempool
void UsePrivateSend(bool fUsePrivateSend)
Definition: coincontrol.h:103
std::set< std::set< CTxDestination > > GetAddressGroupings()
Definition: wallet.cpp:4614
bool GetAccountDestination(CTxDestination &dest, std::string strAccount, bool bForceNew=false)
Definition: wallet.cpp:1043
CScript CreateMultisigRedeemscript(const int required, const std::vector< CPubKey > &pubkeys)
Definition: util.cpp:48
CPubKey AddrToPubKey(CKeyStore *const keystore, const std::string &addr_in)
Definition: util.cpp:27
UniValue listaccounts(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1780
void UnlockAllCoins()
Definition: wallet.cpp:4814
void AcentryToJSON(const CAccountingEntry &acentry, const std::string &strAccount, UniValue &ret)
Definition: rpcwallet.cpp:1626
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:80
bool Lock(bool fForMixing=false)
Definition: crypter.cpp:230
bool fPruneMode
True if we&#39;re running in -prune mode.
Definition: validation.cpp:230
CAmount GetImmatureBalance() const
Definition: wallet.cpp:2666
const std::vector< UniValue > & getValues() const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:158
Keypool ran out, call keypoolrefill first.
Definition: protocol.h:80
bool IsLockedByInstantSend() const
Definition: wallet.cpp:5531
int64_t GetOldestKeyPoolTime()
Definition: wallet.cpp:4553
UniValue listaddressgroupings(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:526
UniValue resendwallettransactions(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2966
UniValue importwallet(const JSONRPCRequest &request)
Definition: rpcdump.cpp:468
UniValue signmessage(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:627
bool fAllowWatchOnly
Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria.
Definition: coincontrol.h:37
static bool Verify(std::string wallet_file, bool salvage_wallet, std::string &error_string, std::string &warning_string)
Verify wallet naming and perform salvage on the wallet if required.
Definition: wallet.cpp:5024
Enter the wallet passphrase with walletpassphrase first.
Definition: protocol.h:81
void updatePassphrase(const SecureString &sWalletPassphrase)
Definition: keepass.cpp:533
Dash RPC command dispatcher.
Definition: server.h:140
bool FeeModeFromString(const std::string &mode_string, FeeEstimateMode &fee_estimate_mode)
Definition: fees.cpp:50
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment="")
Definition: wallet.cpp:1009
CScript scriptPubKey
Definition: transaction.h:148
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:177
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
Definition: chain.h:207
bool get_bool() const
void postInitProcess()
Wallet post-init setup Gives the wallet a chance to register repetitive tasks and complete post-init ...
Definition: wallet.cpp:5302
UniValue setprivatesendamount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2707
UniValue keepass(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2859
UniValue abandontransaction(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2112
Definition: block.h:72
boost::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
Definition: coincontrol.h:45
Wallet is already unlocked.
Definition: protocol.h:85
UniValue keypoolrefill(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2190
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:906
UniValue instantsendtoaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:517
std::set< uint256 > GetConflicts() const
Definition: wallet.cpp:2157
CCriticalSection cs_wallet
Definition: wallet.h:836
static const CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition: amount.h:26
CAmount GetLegacyBalance(const isminefilter &filter, int minDepth, const std::string *account, const bool fAddLocked) const
Definition: wallet.cpp:2723
#define strprintf
Definition: tinyformat.h:1066
bool IsPayToScriptHash() const
Definition: script.cpp:212
UniValue getreceivedbyaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:688
const uint256 & GetHash() const
Definition: wallet.h:272
bool IsFromMe(const isminefilter &filter) const
Definition: wallet.h:496
UniValue getrawchangeaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:224
uint32_t nExternalChainCounter
Definition: hdchain.h:13
bool HasChainLock(int nHeight, const uint256 &blockHash)
std::vector< uint256 > txids
Definition: rpcwallet.cpp:1293
int nIndex
Definition: wallet.h:218
bool IsCrypted() const
Definition: crypter.h:155
bool EnsureWalletIsAvailable(CWallet *const pwallet, bool avoidException)
Definition: rpcwallet.cpp:66
BlockMap & mapBlockIndex
Definition: validation.cpp:215
UniValue getaddressesbyaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:346
std::string strFromAccount
Definition: wallet.h:331
UniValue fundrawtransaction(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:3198
UniValue loadwallet(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2913
TxItems wtxOrdered
Definition: wallet.h:901
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
Definition: wallet.cpp:2169
std::string urlDecode(const std::string &urlEncoded)
Definition: httpserver.cpp:665
static const int DEFAULT_PRIVATESEND_AMOUNT
bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const override
Definition: keystore.cpp:90
static void SendMoney(CWallet *const pwallet, const CTxDestination &address, CAmount nValue, bool fSubtractFeeFromAmount, CWalletTx &wtxNew, const CCoinControl &coin_control)
Definition: rpcwallet.cpp:385
bool FundTransaction(CMutableTransaction &tx, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, bool lockUnspents, const std::set< int > &setSubtractFeeFromOutputs, CCoinControl)
Insert additional inputs into the transaction by calling CreateTransaction();.
Definition: wallet.cpp:3252
int Height() const
Return the maximal height in the chain.
Definition: chain.h:484
void StartShutdown()
Definition: init.cpp:171
uint256 hashBlock
Definition: wallet.h:211
CCriticalSection cs_main
Definition: validation.cpp:213
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:281
std::string AccountFromValue(const UniValue &value)
Definition: rpcwallet.cpp:126
CTxDestination DecodeDestination(const std::string &str)
Definition: base58.cpp:336
UniValue ValueFromAmount(const CAmount &amount)
Definition: core_write.cpp:25
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
uint256 GetID() const
Definition: hdchain.h:110
bool fIsWatchonly
Definition: rpcwallet.cpp:1294
void ListTransactions(CWallet *const pwallet, const CWalletTx &wtx, const std::string &strAccount, int nMinDepth, bool fLong, UniValue &ret, const isminefilter &filter)
List transactions based on the given criteria.
Definition: rpcwallet.cpp:1545
CPubKey HexToPubKey(const std::string &hex_in)
Definition: util.cpp:14
UniValue settxfee(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2650
const std::string & get_str() const
uint8_t isminefilter
used for bitflags of isminetype
Definition: ismine.h:29
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
Definition: chain.h:448
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: server.cpp:583
const UniValue & get_array() const
const std::string CURRENCY_UNIT
Definition: feerate.cpp:10
static const CRPCCommand commands[]
Definition: rpcwallet.cpp:3522
unsigned int GetKeyPoolSize()
Definition: wallet.h:1162
int64_t get_int64() const
UniValue listsinceblock(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1872
bool GetKeyFromPool(CPubKey &key, bool fInternal)
Definition: wallet.cpp:4521
const std::vector< std::string > & getKeys() const
CoinType
Definition: coincontrol.h:14
static CWallet * CreateWalletFromFile(const std::string &name, const fs::path &path)
Definition: wallet.cpp:5075
UniValue getbalance(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:824
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:797
UniValue getnewaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:134
UniValue dumphdinfo(const JSONRPCRequest &request)
Definition: rpcdump.cpp:773
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:345
bool appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:353
void rpcAssociate(std::string &strIdRet, SecureString &sKeyBase64Ret)
Definition: keepass.cpp:460
static const unsigned int DEFAULT_KEYPOOL_SIZE
Definition: wallet.h:54
bool DecodeHexTx(CMutableTransaction &tx, const std::string &strHexTx)
Definition: core_read.cpp:90
void BlockUntilSyncedToCurrentChain()
Blocks until the wallet state is up-to-date to /at least/ the current chain at the time this function...
Definition: wallet.cpp:1517
bool IsSpent(const uint256 &hash, unsigned int n) const
Outpoint is spent if any non-conflicted transaction spends it:
Definition: wallet.cpp:755
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:149
const std::string strMessageMagic
Definition: validation.cpp:257
bool fOverrideFeeRate
Override automatic min/max checks on fee, m_feerate must be set if true.
Definition: coincontrol.h:39
std::string HelpRequiringPassphrase(CWallet *const pwallet)
Definition: rpcwallet.cpp:59
Coin Control Features.
Definition: coincontrol.h:28
CAmount GetBalance() const
Definition: wallet.cpp:2541
void RPCTypeCheck(const UniValue &params, const std::list< UniValue::VType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: server.cpp:54
CTxDestination GetAccountDestination(CWallet *const pwallet, std::string strAccount, bool bForceNew=false)
Definition: rpcwallet.cpp:180
Invalid, missing or duplicate parameter.
Definition: protocol.h:53
std::map< CTxDestination, CAmount > GetAddressBalances()
Definition: wallet.cpp:4574
static SecureString generateKeePassKey()
Definition: keepass.cpp:453
boost::optional< CFeeRate > m_feerate
Override the default payTxFee if set.
Definition: coincontrol.h:41
UniValue listreceivedbyaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1428
const UniValue & find_value(const UniValue &obj, const std::string &name)
Definition: univalue.cpp:236
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: wallet.h:311
bool SignCompact(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Create a compact signature (65 bytes), which allows reconstructing the used public key...
Definition: key.cpp:221
CInstantSendManager * quorumInstantSendManager
void WalletTxToJSON(const CWalletTx &wtx, UniValue &entry)
Definition: rpcwallet.cpp:90
UniValue getwalletinfo(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2735
std::list< CAccountingEntry > laccentries
Definition: wallet.h:897
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
std::multimap< int64_t, TxPair > TxItems
Definition: wallet.h:900
uint256 GetBlockHash() const
Definition: chain.h:292
std::vector< CWallet * > GetWallets()
Definition: wallet.cpp:79
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:4277
UniValue sendmany(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1053
The wallet passphrase entered was incorrect.
Definition: protocol.h:82
iterator end()
Definition: prevector.h:320
int64_t GetTime()
Return system time (or mocked time, if set)
Definition: utiltime.cpp:22
uint32_t nInternalChainCounter
Definition: hdchain.h:14
std::string strComment
Definition: wallet.h:638
#define LOCK2(cs1, cs2)
Definition: sync.h:179
std::string name
Definition: server.h:132
size_t KeypoolCountExternalKeys()
Definition: wallet.cpp:4360
void push_back(const T &value)
Definition: prevector.h:455
static const int DEFAULT_PRIVATESEND_ROUNDS
CChainLocksHandler * chainLocksHandler
static const std::string WALLET_ENDPOINT_BASE
Definition: rpcwallet.cpp:43
bool push_back(const UniValue &val)
Definition: univalue.cpp:110
#define LogPrintf(...)
Definition: util.h:203
UniValue importaddress(const JSONRPCRequest &request)
Definition: rpcdump.cpp:224
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
Definition: validation.cpp:317
fs::path GetWalletDir()
Get the path of the wallet directory.
Definition: walletutil.cpp:7
bool AbandonTransaction(const uint256 &hashTx)
Definition: wallet.cpp:1283
void UnlockCoin(const COutPoint &output)
Definition: wallet.cpp:4803
UniValue getreceivedbyaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:757
UniValue setprivatesendrounds(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2679
UniValue generateBlocks(std::shared_ptr< CReserveScript > coinbaseScript, int nGenerate, uint64_t nMaxTries, bool keepScript)
Generate blocks (mine)
CTransactionRef tx
Definition: wallet.h:210
UniValue params
Definition: server.h:42
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki.
Definition: wallet.cpp:467
bool IsHDEnabled() const
HD Wallet Functions.
Definition: wallet.cpp:1847
CWallet * GetWallet(const std::string &name)
Definition: wallet.cpp:85
#define LOCK(cs)
Definition: sync.h:178
bool exists(const std::string &key) const
Definition: univalue.h:76
UniValue listwallets(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2827
int GetVersion()
get the current wallet format (the oldest client version guaranteed to understand this wallet) ...
Definition: wallet.h:1175
bool GetKey(const CKeyID &address, CKey &keyOut) const override
GetKey implementation that can derive a HD private key on the fly.
Definition: wallet.cpp:300
UniValue setaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:262
CTxDestination destChange
Definition: coincontrol.h:31
void RPCTypeCheckArgument(const UniValue &value, UniValue::VType typeExpected)
Type-check one argument; throws JSONRPCError if wrong type given.
Definition: server.cpp:72
int64_t nKeysLeftSinceAutoBackup
Definition: wallet.h:910
uint256 uint256S(const char *str)
Definition: uint256.h:143
An encapsulated public key.
Definition: pubkey.h:30
virtual bool GetHDChain(CHDChain &hdChainRet) const override
Definition: crypter.cpp:539
bool IsLockedCoin(uint256 hash, unsigned int n) const
Definition: wallet.cpp:4820
UniValue walletpassphrasechange(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2318
std::string GetRejectReason() const
Definition: validation.h:81
uint32_t n
Definition: transaction.h:30
bool IsLocked(const uint256 &txHash)
bool IsHex(const std::string &str)
Unexpected type was passed as parameter.
Definition: protocol.h:50
bool IsCoinBase() const
Definition: wallet.h:273
CAmount GetUnconfirmedBalance() const
Definition: wallet.cpp:2653
Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.)
Definition: protocol.h:83
UniValue ListReceived(CWallet *const pwallet, const UniValue &params, bool fByAccounts)
Definition: rpcwallet.cpp:1303
UniValue importprunedfunds(const JSONRPCRequest &request)
Definition: rpcdump.cpp:302
int GetBlocksToMaturity() const
Definition: wallet.cpp:5546
UniValue dumpwallet(const JSONRPCRequest &request)
Definition: rpcdump.cpp:817
bool AddWallet(CWallet *wallet)
Definition: wallet.cpp:53
UniValue listaddressbalances(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:585
size_t KeypoolCountInternalKeys()
Definition: wallet.cpp:4385
bool IsTrusted() const
Definition: wallet.cpp:2419
UniValue sendfrom(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:973
UniValue getaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:310
General application defined errors.
Definition: protocol.h:48
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:135
An output of a transaction.
Definition: transaction.h:144
int get_int() const
Invalid address or key.
Definition: protocol.h:51
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:256
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: server.cpp:578
static const int MAX_PRIVATESEND_ROUNDS
CoinType nCoinType
Controls which types of coins are allowed to be used (default: ALL_COINS)
Definition: coincontrol.h:49
static std::pair< std::string, UniValue > Pair(const char *cKey, const char *cVal)
Definition: univalue.h:185
Invalid wallet specified.
Definition: protocol.h:86
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
Invalid account name.
Definition: protocol.h:79
std::vector< CTxOut > vout
Definition: transaction.h:294
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
CAmount GetAnonymizedBalance(const CCoinControl *coinControl=nullptr) const
Definition: wallet.cpp:2577
bool IsDeprecatedRPCEnabled(const std::string &method)
Definition: server.cpp:447
bool isNull() const
Definition: univalue.h:78
void LockCoin(const COutPoint &output)
Definition: wallet.cpp:4792
UniValue sendtoaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:424
bool Unlock(const SecureString &strWalletPassphrase, bool fForMixingOnly=false)
Definition: wallet.cpp:524
CCriticalSection cs
Definition: txmempool.h:488
void RPCRunLater(const std::string &name, std::function< void(void)> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:607
UniValue rescanblockchain(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:3422
static const int MAX_PRIVATESEND_AMOUNT
UniValue getaccountaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:190
RAII object to check and reserve a wallet rescan.
Definition: wallet.h:1336
void AvailableCoins(std::vector< COutput > &vCoins, bool fOnlySafe=true, const CCoinControl *coinControl=nullptr, const CAmount &nMinimumAmount=1, const CAmount &nMaximumAmount=MAX_MONEY, const CAmount &nMinimumSumAmount=MAX_MONEY, const uint64_t nMaximumCount=0, const int nMinDepth=0, const int nMaxDepth=9999999) const
populate vCoins with vector of available COutputs.
Definition: wallet.cpp:2775
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:280
void RegisterWalletRPCCommands(CRPCTable &t)
Definition: rpcwallet.cpp:3588
UniValue walletlock(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2369
bool GetBroadcastTransactions() const
Inquire whether this wallet broadcasts transactions.
Definition: wallet.h:1212
Database error.
Definition: protocol.h:54
void KeepKey()
Definition: wallet.cpp:4740
CBlockIndex * ScanForWalletTransactions(CBlockIndex *pindexStart, CBlockIndex *pindexStop, const WalletRescanReserver &reserver, bool fUpdate=false)
Scan the block chain (starting in pindexStart) for transactions from or to us.
Definition: wallet.cpp:2030
uint256 GetHash()
Definition: hash.h:203
Failed to encrypt the wallet.
Definition: protocol.h:84
bool fHelp
Definition: server.h:43
Capture information about block/transaction validation.
Definition: validation.h:22
std::vector< uint256 > ResendWalletTransactionsBefore(int64_t nTime, CConnman *connman)
Definition: wallet.cpp:2461
256-bit opaque blob.
Definition: uint256.h:123
std::set< CTxDestination > GetAccountAddresses(const std::string &strAccount) const
Definition: wallet.cpp:4707
std::string EncodeHexTx(const CTransaction &tx)
Definition: core_write.cpp:130
void GetScriptForMining(std::shared_ptr< CReserveScript > &script)
Definition: wallet.cpp:4781
enum VType type() const
Definition: univalue.h:174
std::vector< CTransactionRef > vtx
Definition: block.h:76
UniValue walletpassphrase(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2237
#define ARRAYLEN(array)
bool setArray()
Definition: univalue.cpp:96
std::string EncodeDestination(const CTxDestination &dest)
Definition: base58.cpp:329
CPrivateSendClientManager privateSendClient
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:567
const std::string & GetName() const
Get a name for this wallet for logging/debugging purposes.
Definition: wallet.h:848
bool IsLocked(bool fForMixing=false) const
Definition: crypter.cpp:209
CAmount GetCredit(const isminefilter &filter) const
Definition: wallet.cpp:2200
int64_t GetTxTime() const
Definition: wallet.cpp:1923
A key allocated from the key pool.
Definition: wallet.h:1273
CAmount nAmount
Definition: rpcwallet.cpp:1291
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:170
const CChainParams & Params()
Return the currently selected parameters.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:389
CKeePassIntegrator keePassInt
Definition: keepass.cpp:33
bool TopUpKeyPool(unsigned int kpSize=0)
Definition: wallet.cpp:4391
Not enough funds in wallet or account.
Definition: protocol.h:78
const UniValue & get_obj() const
bool push_backV(const std::vector< UniValue > &vec)
Definition: univalue.cpp:119
std::string URI
Definition: server.h:44
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
Internal transfers.
Definition: wallet.h:631
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:453
std::string GetHex() const
Definition: uint256.cpp:21
static const int MIN_PRIVATESEND_ROUNDS
bool CreateTransaction(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, bool sign=true, int nExtraPayloadSize=0)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Definition: wallet.cpp:3658
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:715
unsigned int ParseConfirmTarget(const UniValue &value)
Check bounds on a command line confirm target.
Definition: mining.cpp:42
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:19
std::unique_ptr< CConnman > g_connman
Definition: init.cpp:97
const UniValue NullUniValue
Definition: univalue.cpp:15
bool GetAccount(uint32_t nAccountIndex, CHDAccount &hdAccountRet)
Definition: hdchain.cpp:184
CWallet * GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: rpcwallet.cpp:45
UniValue removeprunedfunds(const JSONRPCRequest &request)
Definition: rpcdump.cpp:363
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE)
Transaction fee set by the user.
int GetRealOutpointPrivateSendRounds(const COutPoint &outpoint, int nRounds=0) const
Definition: wallet.cpp:1576
bool error(const char *fmt, const Args &... args)
Definition: util.h:222
Definition: wallet.h:195
iterator begin()
Definition: prevector.h:318
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:896
void ObserveSafeMode()
Definition: safemode.cpp:7
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:22
UniValue backupwallet(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2157
A mutable version of CTransaction.
Definition: transaction.h:291
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:184
Wallet errors.
Definition: protocol.h:77
bool GetReservedKey(CPubKey &pubkey, bool fInternalIn)
Definition: wallet.cpp:4721
bool IsAbortingRescan()
Definition: wallet.h:978
UniValue dumpprivkey(const JSONRPCRequest &request)
Definition: rpcdump.cpp:731
FeeEstimateMode m_fee_mode
Fee estimation mode to control arguments to estimateSmartFee.
Definition: coincontrol.h:47
UniValue JSONRPCError(int code, const std::string &message)
Definition: protocol.cpp:54
void clear()
Definition: univalue.cpp:17
UniValue importelectrumwallet(const JSONRPCRequest &request)
Definition: rpcdump.cpp:593
No valid connection manager instance found.
Definition: protocol.h:74
size_t size() const
Definition: univalue.h:69
unsigned int nTimeReceived
time received by this node
Definition: wallet.h:314
An encapsulated private key.
Definition: key.h:27
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:183
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const
Definition: wallet.cpp:4828
UniValue abortrescan(const JSONRPCRequest &request)
Definition: rpcdump.cpp:163
UniValue listunspent(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:3002
static const int MIN_PRIVATESEND_AMOUNT
full block available in blk*.dat
Definition: chain.h:154
UniValue gettransaction(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2015
static CAmount AmountFromValue(const UniValue &value)
Definition: dash-tx.cpp:486
CChain & chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:217
static void LockWallet(CWallet *pWallet)
Definition: rpcwallet.cpp:2230
AssertLockHeld(g_cs_orphans)
bool BackupWallet(const std::string &strDest)
Definition: wallet.cpp:5320
UniValue importmulti(const JSONRPCRequest &request)
Definition: rpcdump.cpp:1306
bool HasWallets()
Definition: wallet.cpp:73
void SetHex(const char *psz)
Definition: uint256.cpp:27
UniValue lockunspent(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2471
static void MaybePushAddress(UniValue &entry, const CTxDestination &dest)
Definition: rpcwallet.cpp:1527
UniValue importprivkey(const JSONRPCRequest &request)
Definition: rpcdump.cpp:74
UniValue importpubkey(const JSONRPCRequest &request)
Definition: rpcdump.cpp:401
UniValue listtransactions(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1643
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
Definition: chain.cpp:51
std::string strOtherAccount
Definition: wallet.h:637
int GetDepthInMainChain(const CBlockIndex *&pindexRet) const
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
Definition: wallet.cpp:5501
CAmount GetFeePerK() const
Return the fee in satoshis for a size of 1000 bytes.
Definition: feerate.h:41
UniValue listlockunspent(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2598
isminetype IsMine(const CKeyStore &keystore, const CTxDestination &dest)
Definition: ismine.cpp:28
Wrapper for UniValue::VType, which includes typeAny: Used to denote don&#39;t care type.
Definition: server.h:30
UniValue movecmd(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:922
int64_t nRelockTime
Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
Definition: wallet.h:1034
CAmount nCreditDebit
Definition: wallet.h:635
int64_t nTime
Definition: wallet.h:636
size_t CountAccounts()
Definition: hdchain.cpp:203
UniValue encryptwallet(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:2409
std::string itostr(int n)
Error parsing or validating structure in raw format.
Definition: protocol.h:55
std::string EncodeBase64(const unsigned char *pch, size_t len)
void EnsureWalletIsUnlocked(CWallet *const pwallet)
Definition: rpcwallet.cpp:83
bool isAbandoned() const
Definition: wallet.h:269
UniValue listreceivedbyaccount(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1481
uint256 hash
Definition: transaction.h:29
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, CValidationState &state)
Call after CreateTransaction unless you want to abort.
Definition: wallet.cpp:4089
void GetAmounts(std::list< COutputEntry > &listReceived, std::list< COutputEntry > &listSent, CAmount &nFee, std::string &strSentAccount, const isminefilter &filter) const
Definition: wallet.cpp:1929
std::string strAccount
Definition: wallet.h:634
UniValue addmultisigaddress(const JSONRPCRequest &request)
Definition: rpcwallet.cpp:1208
Released under the MIT license