diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c6ca52127b..300e8003b1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3891,6 +3891,97 @@ UniValue reissueasset(const JSONRPCRequest& request) return obj; } +UniValue listissuances(const JSONRPCRequest& request) +{ + if (!EnsureWalletIsAvailable(request.fHelp)) + return NullUniValue; + + if (request.fHelp || request.params.size() > 1) + throw runtime_error( + "listissuances ( asset ) \n" + "\nList all issuances known to the wallet for the given asset, or for all issued assets if none provided.\n" + "\nArguments:\n" + "1. \"asset\" (string, optional) The asset whose issaunces you wish to list.\n" + "\nResult:\n" + "[ (json array of objects)\n" + " {\n" + " \"txid\":\"\", (string) Transaction id for issuance.\n" + " \"entropy\":\"\" (string) Entropy of the asset type.\n" + " \"asset\":\"\", (string) Asset type for issuance if known.\n" + " \"assetlabel\":\"\", (string) Asset label for issuance if set.\n" + " \"token\":\"\", (string) Token type for issuance.\n" + " \"vin\":\"\", (numeric) The vin for the issuance.\n" + " \"assetamount\":\"X.XX\", (numeric) The amount of asset issued. Is -1 if blinded and unknown to wallet.\n" + " \"tokenamount\":\"X.XX\", (numeric) The reissuance token amount issued. Is -1 if blinded and unknown to wallet.\n" + " \"isreissuance\":\"\", (bool) True if this is a reissuance.\n" + " \"assetblinds\":\"\" (string) Hex blinding factor for asset amounts.\n" + " \"tokenblinds\":\"\" (string) Hex blinding factor for token amounts.\n" + " }\n" + " ,...\n" + "]\n" + "\"\" (array) List of transaction issuances and information in wallet\n" + + HelpExampleCli("listissuances", "") + + HelpExampleRpc("listissuances", "") + ); + RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VSTR)); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + std::string assetstr; + CAsset assetfilter; + if (request.params.size() > 0) { + assetstr = request.params[0].get_str(); + if (!IsHex(assetstr) || assetstr.size() != 64) + throw JSONRPCError(RPC_TYPE_ERROR, "Asset must be a hex string of length 64"); + assetfilter.SetHex(assetstr); + } + + UniValue issuancelist(UniValue::VARR); + for (const auto& it : pwalletMain->mapWallet) { + const CWalletTx* pcoin = &it.second; + CAsset asset; + CAsset token; + uint256 entropy; + for (uint64_t vinIndex = 0; vinIndex < pcoin->tx->vin.size(); vinIndex++) { + UniValue item(UniValue::VOBJ); + const CAssetIssuance& issuance = pcoin->tx->vin[vinIndex].assetIssuance; + if (issuance.IsNull()) { + continue; + } + if (issuance.assetBlindingNonce.IsNull()) { + GenerateAssetEntropy(entropy, pcoin->tx->vin[vinIndex].prevout, issuance.assetEntropy); + CalculateAsset(asset, entropy); + // Null is considered explicit + CalculateReissuanceToken(token, entropy, issuance.nAmount.IsCommitment()); + item.push_back(Pair("isreissuance", false)); + item.push_back(Pair("token", token.GetHex())); + item.push_back(Pair("tokenamount", ValueFromAmount(pcoin->GetIssuanceAmount(vinIndex, true)))); + item.push_back(Pair("tokenblinds", pcoin->GetIssuanceBlindingFactor(vinIndex, true).GetHex())); + item.push_back(Pair("entropy", entropy.GetHex())); + } else { + CalculateAsset(asset, issuance.assetEntropy); + item.push_back(Pair("isreissuance", true)); + item.push_back(Pair("entropy", issuance.assetEntropy.GetHex())); + } + item.push_back(Pair("txid", pcoin->tx->GetHash().GetHex())); + item.push_back(Pair("vin", vinIndex)); + item.push_back(Pair("asset", asset.GetHex())); + const std::string label = gAssetsDir.GetLabel(asset); + if (label != "") { + item.push_back(Pair("assetlabel", label)); + } + item.push_back(Pair("assetamount", ValueFromAmount(pcoin->GetIssuanceAmount(vinIndex, false)))); + item.push_back(Pair("assetblinds", pcoin->GetIssuanceBlindingFactor(vinIndex, false).GetHex())); + if (!assetfilter.IsNull() && assetfilter != asset) { + continue; + } + issuancelist.push_back(item); + } + } + return issuancelist; + +} + UniValue dumpassetlabels(const JSONRPCRequest& request) { if (!EnsureWalletIsAvailable(request.fHelp)) @@ -3961,6 +4052,7 @@ static const CRPCCommand commands[] = { "wallet", "listaccounts", &listaccounts, false, {"minconf","include_watchonly"} }, { "wallet", "listaddressgroupings", &listaddressgroupings, false, {} }, { "wallet", "listlockunspent", &listlockunspent, false, {} }, + { "wallet", "listissuances", &listissuances, false, {"asset"} }, { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, {"minconf","include_empty","include_watchonly"} }, { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, {"minconf","include_empty","include_watchonly"} }, { "wallet", "listsinceblock", &listsinceblock, false, {"blockhash","target_confirmations","include_watchonly"} },