Closes #2910. Add z_listunspent RPC call.
This commit is contained in:
@@ -2428,6 +2428,138 @@ UniValue listunspent(const UniValue& params, bool fHelp)
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() > 4)
|
||||
throw runtime_error(
|
||||
"z_listunspent ( minconf maxconf includeWatchonly [\"zaddr\",...] )\n"
|
||||
"\nReturns array of unspent shielded notes with between minconf and maxconf (inclusive) confirmations.\n"
|
||||
"Optionally filter to only include notes sent to specified addresses.\n"
|
||||
"When minconf is 0, unspent notes with zero confirmations are returned, even though they are not immediately spendable.\n"
|
||||
"Results are an array of Objects, each of which has:\n"
|
||||
"{txid, jsindex, jsoutindex, confirmations, address, amount, memo}\n"
|
||||
"\nArguments:\n"
|
||||
"1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
|
||||
"2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
|
||||
"3. includeWatchonly (bool, optional, default=false) Also include watchonly addresses (see 'z_importviewingkey')\n"
|
||||
"4. \"addresses\" (string) A json array of zaddrs to filter on. Duplicate addresses not allowed.\n"
|
||||
" [\n"
|
||||
" \"address\" (string) zaddr\n"
|
||||
" ,...\n"
|
||||
" ]\n"
|
||||
"\nResult\n"
|
||||
"[ (array of json object)\n"
|
||||
" {\n"
|
||||
" \"txid\" : \"txid\", (string) the transaction id \n"
|
||||
" \"jsindex\" : n (numeric) the joinsplit index\n"
|
||||
" \"jsoutindex\" : n (numeric) the output index of the joinsplit\n"
|
||||
" \"confirmations\" : n (numeric) the number of confirmations\n"
|
||||
" \"spendable\" : true|false (boolean) true if note can be spent by wallet, false if note has zero confirmations, false if address is watchonly\n"
|
||||
" \"address\" : \"address\", (string) the shielded address\n"
|
||||
" \"amount\": xxxxx, (numeric) the amount of value in the note\n"
|
||||
" \"memo\": xxxxx, (string) hexademical string representation of memo field\n"
|
||||
" }\n"
|
||||
" ,...\n"
|
||||
"]\n"
|
||||
|
||||
"\nExamples\n"
|
||||
+ HelpExampleCli("z_listunspent", "")
|
||||
+ HelpExampleCli("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"")
|
||||
+ HelpExampleRpc("z_listunspent", "6 9999999 false \"[\\\"ztbx5DLDxa5ZLFTchHhoPNkKs57QzSyib6UqXpEdy76T1aUdFxJt1w9318Z8DJ73XzbnWHKEZP9Yjg712N5kMmP4QzS9iC9\\\",\\\"ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf\\\"]\"")
|
||||
);
|
||||
|
||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VBOOL)(UniValue::VARR));
|
||||
|
||||
int nMinDepth = 1;
|
||||
if (params.size() > 0) {
|
||||
nMinDepth = params[0].get_int();
|
||||
}
|
||||
if (nMinDepth < 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Minimum number of confirmations cannot be less than 0");
|
||||
}
|
||||
|
||||
int nMaxDepth = 9999999;
|
||||
if (params.size() > 1) {
|
||||
nMaxDepth = params[1].get_int();
|
||||
}
|
||||
if (nMaxDepth < nMinDepth) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Maximum number of confirmations must be greater or equal to the minimum number of confirmations");
|
||||
}
|
||||
|
||||
std::set<libzcash::PaymentAddress> zaddrs = {};
|
||||
|
||||
bool fIncludeWatchonly = false;
|
||||
if (params.size() > 2) {
|
||||
fIncludeWatchonly = params[2].get_bool();
|
||||
}
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
// User has supplied zaddrs to filter on
|
||||
if (params.size() > 3) {
|
||||
UniValue addresses = params[3].get_array();
|
||||
if (addresses.size()==0)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, addresses array is empty.");
|
||||
|
||||
// Keep track of addresses to spot duplicates
|
||||
set<std::string> setAddress;
|
||||
|
||||
// Sources
|
||||
for (const UniValue& o : addresses.getValues()) {
|
||||
if (!o.isStr()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected string");
|
||||
}
|
||||
string address = o.get_str();
|
||||
try {
|
||||
CZCPaymentAddress zaddr(address);
|
||||
libzcash::PaymentAddress addr = zaddr.Get();
|
||||
if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address);
|
||||
}
|
||||
zaddrs.insert(addr);
|
||||
} catch (const std::runtime_error&) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, address is not a valid zaddr: ") + address);
|
||||
}
|
||||
|
||||
if (setAddress.count(address)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ") + address);
|
||||
}
|
||||
setAddress.insert(address);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// User did not provide zaddrs, so use default i.e. all addresses
|
||||
pwalletMain->GetPaymentAddresses(zaddrs);
|
||||
}
|
||||
|
||||
UniValue results(UniValue::VARR);
|
||||
|
||||
if (zaddrs.size() > 0) {
|
||||
std::vector<CUnspentNotePlaintextEntry> entries;
|
||||
pwalletMain->GetUnspentFilteredNotes(entries, zaddrs, nMinDepth, nMaxDepth, !fIncludeWatchonly);
|
||||
for (CUnspentNotePlaintextEntry & entry : entries) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("txid",entry.jsop.hash.ToString()));
|
||||
obj.push_back(Pair("jsindex", (int)entry.jsop.js ));
|
||||
obj.push_back(Pair("jsoutindex", (int)entry.jsop.n));
|
||||
obj.push_back(Pair("confirmations", entry.nHeight));
|
||||
obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(entry.address)));
|
||||
obj.push_back(Pair("address", CZCPaymentAddress(entry.address).ToString()));
|
||||
obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value))));
|
||||
std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end());
|
||||
obj.push_back(Pair("memo", HexStr(data)));
|
||||
results.push_back(obj);
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
UniValue fundrawtransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
|
||||
Reference in New Issue
Block a user