Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 228 Lines • ▼ Show 20 Lines | if (!pwallet->GetLabelDestination(dest, label, bForceNew)) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_WALLET_KEYPOOL_RAN_OUT, | RPC_WALLET_KEYPOOL_RAN_OUT, | ||||
"Error: Keypool ran out, please call keypoolrefill first"); | "Error: Keypool ran out, please call keypoolrefill first"); | ||||
} | } | ||||
return dest; | return dest; | ||||
} | } | ||||
static UniValue getlabeladdress(const Config &config, | static UniValue getaccountaddress(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | ||||
CWallet *const pwallet = wallet.get(); | CWallet *const pwallet = wallet.get(); | ||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
if (!IsDeprecatedRPCEnabled(gArgs, "accounts") && | if (!IsDeprecatedRPCEnabled(gArgs, "accounts")) { | ||||
request.strMethod == "getaccountaddress") { | |||||
if (request.fHelp) { | if (request.fHelp) { | ||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"getaccountaddress (Deprecated, will be removed in v0.21. To " | "getaccountaddress (Deprecated, will be removed in v0.21. To " | ||||
"use this command, start bitcoind with " | "use this command, start bitcoind with " | ||||
"-deprecatedrpc=accounts)"); | "-deprecatedrpc=accounts)"); | ||||
} | } | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_METHOD_DEPRECATED, | RPC_METHOD_DEPRECATED, | ||||
"getaccountaddress is deprecated and will be removed in v0.21. To " | "getaccountaddress is deprecated and will be removed in v0.21. To " | ||||
"use this command, start bitcoind with -deprecatedrpc=accounts."); | "use this command, start bitcoind with -deprecatedrpc=accounts."); | ||||
} | } | ||||
if (request.fHelp || request.params.size() < 1 || | if (request.fHelp || request.params.size() != 1) { | ||||
request.params.size() > 2) { | |||||
throw std::runtime_error( | throw std::runtime_error( | ||||
"getlabeladdress \"label\" ( force ) \n" | "getaccountaddress \"account\"\n" | ||||
"\nReturns the default receiving address for this label. This will " | "\n\nDEPRECATED. Returns the current Bitcoin address for receiving" | ||||
"reset to a fresh address once there's a transaction that spends " | "payments to this account.\n" | ||||
"to it.\n" | |||||
"\nArguments:\n" | "\nArguments:\n" | ||||
"1. \"label\" (string, required) The label for the " | "1. \"account\" (string, required) The account for the " | ||||
"address. It can also be set to the empty string \"\" to represent " | "address. It can also be set to the empty string \"\" to represent " | ||||
"the default label.\n" | "the default account. The account does not need to exist, it will " | ||||
"2. \"force\" (bool, optional) Whether the label should be " | "be created and a new address created if there is no account by " | ||||
"created if it does not yet exist. If False, the RPC will return " | "the given name.\n" | ||||
"an error if called with a label that doesn't exist.\n" | |||||
" Defaults to false (unless the " | |||||
"getaccountaddress method alias is being called, in which case " | |||||
"defaults to true for backwards compatibility).\n" | |||||
"\nResult:\n" | "\nResult:\n" | ||||
"\"address\" (string) The current receiving address for " | "\"address\" (string) The account bitcoin address\n" | ||||
"the label.\n" | |||||
"\nExamples:\n" + | "\nExamples:\n" + | ||||
HelpExampleCli("getlabeladdress", "") + | HelpExampleCli("getaccountaddress", "") + | ||||
HelpExampleCli("getlabeladdress", "\"\"") + | HelpExampleCli("getaccountaddress", "\"\"") + | ||||
HelpExampleCli("getlabeladdress", "\"mylabel\"") + | HelpExampleCli("getaccountaddress", "\"myaccount\"") + | ||||
HelpExampleRpc("getlabeladdress", "\"mylabel\"")); | HelpExampleRpc("getaccountaddress", "\"myaccount\"")); | ||||
} | } | ||||
LOCK2(cs_main, pwallet->cs_wallet); | LOCK2(cs_main, pwallet->cs_wallet); | ||||
// Parse the label first so we don't generate a key if there's an error | // Parse the account first so we don't generate a key if there's an error | ||||
std::string label = LabelFromValue(request.params[0]); | std::string account = LabelFromValue(request.params[0]); | ||||
bool force = request.strMethod == "getaccountaddress"; | |||||
if (!request.params[1].isNull()) { | |||||
force = request.params[1].get_bool(); | |||||
} | |||||
bool label_found = false; | |||||
for (const std::pair<const CTxDestination, CAddressBookData> &item : | |||||
pwallet->mapAddressBook) { | |||||
if (item.second.name == label) { | |||||
label_found = true; | |||||
break; | |||||
} | |||||
} | |||||
if (!force && !label_found) { | |||||
throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, | |||||
std::string("No addresses with label " + label)); | |||||
} | |||||
UniValue ret(UniValue::VSTR); | UniValue ret(UniValue::VSTR); | ||||
ret = EncodeDestination(GetLabelDestination(pwallet, label), config); | ret = EncodeDestination(GetLabelDestination(pwallet, account), config); | ||||
return ret; | return ret; | ||||
} | } | ||||
static UniValue getrawchangeaddress(const Config &config, | static UniValue getrawchangeaddress(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | ||||
CWallet *const pwallet = wallet.get(); | CWallet *const pwallet = wallet.get(); | ||||
▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | static UniValue setlabel(const Config &config, const JSONRPCRequest &request) { | ||||
CTxDestination dest = | CTxDestination dest = | ||||
DecodeDestination(request.params[0].get_str(), config.GetChainParams()); | DecodeDestination(request.params[0].get_str(), config.GetChainParams()); | ||||
if (!IsValidDestination(dest)) { | if (!IsValidDestination(dest)) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Invalid Bitcoin address"); | "Invalid Bitcoin address"); | ||||
} | } | ||||
std::string old_label = pwallet->mapAddressBook[dest].name; | |||||
std::string label = LabelFromValue(request.params[1]); | std::string label = LabelFromValue(request.params[1]); | ||||
if (IsMine(*pwallet, dest)) { | if (IsMine(*pwallet, dest)) { | ||||
// Detect when changing the label of an address that is the receiving | pwallet->SetAddressBook(dest, label, "receive"); | ||||
// address of another label. If so, delete the account record for it. | if (request.strMethod == "setaccount" && old_label != label && | ||||
// Labels, unlike addresses, can be deleted, and if we wouldn't do this, | |||||
// the record would stick around forever. | |||||
if (pwallet->mapAddressBook.count(dest)) { | |||||
std::string old_label = pwallet->mapAddressBook[dest].name; | |||||
if (old_label != label && | |||||
dest == GetLabelDestination(pwallet, old_label)) { | dest == GetLabelDestination(pwallet, old_label)) { | ||||
pwallet->DeleteLabel(old_label); | // for setaccount, call GetLabelDestination so a new receive address | ||||
} | // is created for the old account | ||||
GetLabelDestination(pwallet, old_label, true); | |||||
} | } | ||||
pwallet->SetAddressBook(dest, label, "receive"); | |||||
} else { | } else { | ||||
pwallet->SetAddressBook(dest, label, "send"); | pwallet->SetAddressBook(dest, label, "send"); | ||||
} | } | ||||
// Detect when there are no addresses using this label. | |||||
// If so, delete the account record for it. Labels, unlike addresses, can be | |||||
// deleted, and if we wouldn't do this, the record would stick around | |||||
// forever. | |||||
bool found_address = false; | |||||
for (const std::pair<CTxDestination, CAddressBookData> &item : | |||||
pwallet->mapAddressBook) { | |||||
if (item.second.name == label) { | |||||
found_address = true; | |||||
break; | |||||
} | |||||
} | |||||
if (!found_address) { | |||||
pwallet->DeleteLabel(old_label); | |||||
} | |||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
static UniValue getaccount(const Config &config, | static UniValue getaccount(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | ||||
CWallet *const pwallet = wallet.get(); | CWallet *const pwallet = wallet.get(); | ||||
▲ Show 20 Lines • Show All 4,971 Lines • ▼ Show 20 Lines | static const ContextFreeRPCCommand commands[] = { | ||||
{ "wallet", "signmessage", signmessage, {"address","message"} }, | { "wallet", "signmessage", signmessage, {"address","message"} }, | ||||
{ "wallet", "signrawtransactionwithwallet", signrawtransactionwithwallet, {"hextring","prevtxs","sighashtype"} }, | { "wallet", "signrawtransactionwithwallet", signrawtransactionwithwallet, {"hextring","prevtxs","sighashtype"} }, | ||||
{ "wallet", "unloadwallet", unloadwallet, {"wallet_name"} }, | { "wallet", "unloadwallet", unloadwallet, {"wallet_name"} }, | ||||
{ "wallet", "walletlock", walletlock, {} }, | { "wallet", "walletlock", walletlock, {} }, | ||||
{ "wallet", "walletpassphrasechange", walletpassphrasechange, {"oldpassphrase","newpassphrase"} }, | { "wallet", "walletpassphrasechange", walletpassphrasechange, {"oldpassphrase","newpassphrase"} }, | ||||
{ "wallet", "walletpassphrase", walletpassphrase, {"passphrase","timeout"} }, | { "wallet", "walletpassphrase", walletpassphrase, {"passphrase","timeout"} }, | ||||
/** Account functions (deprecated) */ | /** Account functions (deprecated) */ | ||||
{ "wallet", "getaccountaddress", getlabeladdress, {"account"} }, | { "wallet", "getaccountaddress", getaccountaddress, {"account"} }, | ||||
{ "wallet", "getaccount", getaccount, {"address"} }, | { "wallet", "getaccount", getaccount, {"address"} }, | ||||
{ "wallet", "getaddressesbyaccount", getaddressesbyaccount, {"account"} }, | { "wallet", "getaddressesbyaccount", getaddressesbyaccount, {"account"} }, | ||||
{ "wallet", "getreceivedbyaccount", getreceivedbylabel, {"account","minconf"} }, | { "wallet", "getreceivedbyaccount", getreceivedbylabel, {"account","minconf"} }, | ||||
{ "wallet", "listaccounts", listaccounts, {"minconf","include_watchonly"} }, | { "wallet", "listaccounts", listaccounts, {"minconf","include_watchonly"} }, | ||||
{ "wallet", "listreceivedbyaccount", listreceivedbylabel, {"minconf","include_empty","include_watchonly"} }, | { "wallet", "listreceivedbyaccount", listreceivedbylabel, {"minconf","include_empty","include_watchonly"} }, | ||||
{ "wallet", "setaccount", setlabel, {"address","account"} }, | { "wallet", "setaccount", setlabel, {"address","account"} }, | ||||
{ "wallet", "move", movecmd, {"fromaccount","toaccount","amount","minconf","comment"} }, | { "wallet", "move", movecmd, {"fromaccount","toaccount","amount","minconf","comment"} }, | ||||
/** Label functions (to replace non-balance account functions) */ | /** Label functions (to replace non-balance account functions) */ | ||||
{ "wallet", "getlabeladdress", getlabeladdress, {"label","force"} }, | |||||
{ "wallet", "getaddressesbylabel", getaddressesbylabel, {"label"} }, | { "wallet", "getaddressesbylabel", getaddressesbylabel, {"label"} }, | ||||
{ "wallet", "getreceivedbylabel", getreceivedbylabel, {"label","minconf"} }, | { "wallet", "getreceivedbylabel", getreceivedbylabel, {"label","minconf"} }, | ||||
{ "wallet", "listlabels", listlabels, {"purpose"} }, | { "wallet", "listlabels", listlabels, {"purpose"} }, | ||||
{ "wallet", "listreceivedbylabel", listreceivedbylabel, {"minconf","include_empty","include_watchonly"} }, | { "wallet", "listreceivedbylabel", listreceivedbylabel, {"minconf","include_empty","include_watchonly"} }, | ||||
{ "wallet", "setlabel", setlabel, {"address","label"} }, | { "wallet", "setlabel", setlabel, {"address","label"} }, | ||||
{ "generating", "generate", generate, {"nblocks","maxtries"} }, | { "generating", "generate", generate, {"nblocks","maxtries"} }, | ||||
}; | }; | ||||
// clang-format on | // clang-format on | ||||
void RegisterWalletRPCCommands(CRPCTable &t) { | void RegisterWalletRPCCommands(CRPCTable &t) { | ||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { | for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { | ||||
t.appendCommand(commands[vcidx].name, &commands[vcidx]); | t.appendCommand(commands[vcidx].name, &commands[vcidx]); | ||||
} | } | ||||
} | } |