rpc: Add RPCHelpMan for machine-generated help
This commit is contained in:
parent
fa0d36f712
commit
fa483e13b3
4 changed files with 327 additions and 10 deletions
|
@ -206,7 +206,16 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
|
if (request.fHelp || (request.params.size() != 1 && request.params.size() != 2))
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"gettxoutproof [\"txid\",...] ( blockhash )\n"
|
RPCHelpMan{"gettxoutproof",
|
||||||
|
{
|
||||||
|
{"txids", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"txid", RPCArg::Type::STR_HEX, false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
{"blockhash", RPCArg::Type::STR_HEX, true},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
|
"\nReturns a hex-encoded proof that \"txid\" was included in a block.\n"
|
||||||
"\nNOTE: By default this function only works sometimes. This is when there is an\n"
|
"\nNOTE: By default this function only works sometimes. This is when there is an\n"
|
||||||
"unspent output in the utxo for this transaction. To make it always work,\n"
|
"unspent output in the utxo for this transaction. To make it always work,\n"
|
||||||
|
@ -673,10 +682,17 @@ static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::
|
||||||
|
|
||||||
static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (request.fHelp || request.params.size() != 1)
|
if (request.fHelp || request.params.size() != 1)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"combinerawtransaction [\"hexstring\",...]\n"
|
RPCHelpMan{"combinerawtransaction",
|
||||||
|
{
|
||||||
|
{"txs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"hexstring", RPCArg::Type::STR_HEX, false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nCombine multiple partially signed transactions into one transaction.\n"
|
"\nCombine multiple partially signed transactions into one transaction.\n"
|
||||||
"The combined transaction may be another partially signed transaction or a \n"
|
"The combined transaction may be another partially signed transaction or a \n"
|
||||||
"fully signed transaction."
|
"fully signed transaction."
|
||||||
|
@ -899,7 +915,30 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
|
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"signrawtransactionwithkey \"hexstring\" [\"privatekey1\",...] ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] sighashtype )\n"
|
RPCHelpMan{"signrawtransactionwithkey",
|
||||||
|
{
|
||||||
|
{"hexstring", RPCArg::Type::STR, false},
|
||||||
|
{"privkyes", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"privatekey", RPCArg::Type::STR_HEX, false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
{"prevtxs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"txid", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"vout", RPCArg::Type::NUM, false},
|
||||||
|
{"scriptPubKey", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"redeemScript", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"amount", RPCArg::Type::AMOUNT, false},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
{"sighashtype", RPCArg::Type::STR, true},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nSign inputs for raw transaction (serialized, hex-encoded).\n"
|
"\nSign inputs for raw transaction (serialized, hex-encoded).\n"
|
||||||
"The second argument is an array of base58-encoded private\n"
|
"The second argument is an array of base58-encoded private\n"
|
||||||
"keys that will be the only keys used to sign the transaction.\n"
|
"keys that will be the only keys used to sign the transaction.\n"
|
||||||
|
@ -1454,7 +1493,15 @@ UniValue combinepsbt(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
if (request.fHelp || request.params.size() != 1)
|
if (request.fHelp || request.params.size() != 1)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"combinepsbt [\"psbt\",...]\n"
|
RPCHelpMan{"combinepsbt",
|
||||||
|
{
|
||||||
|
{"txs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"psbt", RPCArg::Type::STR_HEX, false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nCombine multiple partially signed Bitcoin transactions into one transaction.\n"
|
"\nCombine multiple partially signed Bitcoin transactions into one transaction.\n"
|
||||||
"Implements the Combiner role.\n"
|
"Implements the Combiner role.\n"
|
||||||
"\nArguments:\n"
|
"\nArguments:\n"
|
||||||
|
@ -1570,7 +1617,37 @@ UniValue createpsbt(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
|
if (request.fHelp || request.params.size() < 2 || request.params.size() > 4)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"createpsbt [{\"txid\":\"id\",\"vout\":n},...] [{\"address\":amount},{\"data\":\"hex\"},...] ( locktime ) ( replaceable )\n"
|
RPCHelpMan{"createpsbt",
|
||||||
|
{
|
||||||
|
{"inputs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"txid", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"vout", RPCArg::Type::NUM, false},
|
||||||
|
{"sequence", RPCArg::Type::NUM, true},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
{"outputs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"address", RPCArg::Type::AMOUNT, false},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"data", RPCArg::Type::STR_HEX, false},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
{"locktime", RPCArg::Type::NUM, true},
|
||||||
|
{"replaceable", RPCArg::Type::BOOL, true},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nCreates a transaction in the Partially Signed Transaction format.\n"
|
"\nCreates a transaction in the Partially Signed Transaction format.\n"
|
||||||
"Implements the Creator role.\n"
|
"Implements the Creator role.\n"
|
||||||
"\nArguments:\n"
|
"\nArguments:\n"
|
||||||
|
|
|
@ -128,3 +128,95 @@ UniValue DescribeAddress(const CTxDestination& dest)
|
||||||
{
|
{
|
||||||
return boost::apply_visitor(DescribeAddressVisitor(), dest);
|
return boost::apply_visitor(DescribeAddressVisitor(), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string RPCHelpMan::ToString() const
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
|
||||||
|
ret += m_name;
|
||||||
|
bool is_optional{false};
|
||||||
|
for (const auto& arg : m_args) {
|
||||||
|
ret += " ";
|
||||||
|
if (arg.m_optional) {
|
||||||
|
if (!is_optional) ret += "( ";
|
||||||
|
is_optional = true;
|
||||||
|
} else {
|
||||||
|
// Currently we still support unnamed arguments, so any argument following an optional argument must also be optional
|
||||||
|
// If support for positional arguments is deprecated in the future, remove this line
|
||||||
|
assert(!is_optional);
|
||||||
|
}
|
||||||
|
ret += arg.ToString();
|
||||||
|
}
|
||||||
|
if (is_optional) ret += " )";
|
||||||
|
ret += "\n";
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RPCArg::ToStringObj() const
|
||||||
|
{
|
||||||
|
std::string res = "\"" + m_name + "\":";
|
||||||
|
switch (m_type) {
|
||||||
|
case Type::STR:
|
||||||
|
return res + "\"str\"";
|
||||||
|
case Type::STR_HEX:
|
||||||
|
return res + "\"hex\"";
|
||||||
|
case Type::NUM:
|
||||||
|
return res + "n";
|
||||||
|
case Type::AMOUNT:
|
||||||
|
return res + "amount";
|
||||||
|
case Type::BOOL:
|
||||||
|
return res + "bool";
|
||||||
|
case Type::ARR:
|
||||||
|
res += "[";
|
||||||
|
for (const auto& i : m_inner) {
|
||||||
|
res += i.ToString() + ",";
|
||||||
|
}
|
||||||
|
return res + "...]";
|
||||||
|
case Type::OBJ:
|
||||||
|
case Type::OBJ_USER_KEYS:
|
||||||
|
// Currently unused, so avoid writing dead code
|
||||||
|
assert(false);
|
||||||
|
|
||||||
|
// no default case, so the compiler can warn about missing cases
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string RPCArg::ToString() const
|
||||||
|
{
|
||||||
|
switch (m_type) {
|
||||||
|
case Type::STR_HEX:
|
||||||
|
case Type::STR: {
|
||||||
|
return "\"" + m_name + "\"";
|
||||||
|
}
|
||||||
|
case Type::NUM:
|
||||||
|
case Type::AMOUNT:
|
||||||
|
case Type::BOOL: {
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
case Type::OBJ:
|
||||||
|
case Type::OBJ_USER_KEYS: {
|
||||||
|
std::string res;
|
||||||
|
for (size_t i = 0; i < m_inner.size();) {
|
||||||
|
res += m_inner[i].ToStringObj();
|
||||||
|
if (++i < m_inner.size()) res += ",";
|
||||||
|
}
|
||||||
|
if (m_type == Type::OBJ) {
|
||||||
|
return "{" + res + "}";
|
||||||
|
} else {
|
||||||
|
return "{" + res + ",...}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Type::ARR: {
|
||||||
|
std::string res;
|
||||||
|
for (const auto& i : m_inner) {
|
||||||
|
res += i.ToString() + ",";
|
||||||
|
}
|
||||||
|
return "[" + res + "...]";
|
||||||
|
}
|
||||||
|
|
||||||
|
// no default case, so the compiler can warn about missing cases
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
|
@ -30,4 +30,53 @@ CScript CreateMultisigRedeemscript(const int required, const std::vector<CPubKey
|
||||||
|
|
||||||
UniValue DescribeAddress(const CTxDestination& dest);
|
UniValue DescribeAddress(const CTxDestination& dest);
|
||||||
|
|
||||||
|
struct RPCArg {
|
||||||
|
enum class Type {
|
||||||
|
OBJ,
|
||||||
|
ARR,
|
||||||
|
STR,
|
||||||
|
NUM,
|
||||||
|
BOOL,
|
||||||
|
OBJ_USER_KEYS, //!< Special type where the user must set the keys e.g. to define multiple addresses; as opposed to e.g. an options object where the keys are predefined
|
||||||
|
AMOUNT, //!< Special type representing a floating point amount (can be either NUM or STR)
|
||||||
|
STR_HEX, //!< Special type that is a STR with only hex chars
|
||||||
|
};
|
||||||
|
const std::string m_name; //!< The name of the arg (can be empty for inner args)
|
||||||
|
const Type m_type;
|
||||||
|
const std::vector<RPCArg> m_inner; //!< Only used for arrays or dicts
|
||||||
|
const bool m_optional;
|
||||||
|
|
||||||
|
RPCArg(const std::string& name, const Type& type, const bool optional)
|
||||||
|
: m_name{name}, m_type{type}, m_optional{optional}
|
||||||
|
{
|
||||||
|
assert(type != Type::ARR && type != Type::OBJ);
|
||||||
|
}
|
||||||
|
|
||||||
|
RPCArg(const std::string& name, const Type& type, const std::vector<RPCArg>& inner, const bool optional)
|
||||||
|
: m_name{name}, m_type{type}, m_inner{inner}, m_optional{optional}
|
||||||
|
{
|
||||||
|
assert(type == Type::ARR || type == Type::OBJ);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string ToStringObj() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RPCHelpMan
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RPCHelpMan(const std::string& name, const std::vector<RPCArg>& args)
|
||||||
|
: m_name{name}, m_args{args}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ToString() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string m_name;
|
||||||
|
const std::vector<RPCArg> m_args;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_RPC_UTIL_H
|
#endif // BITCOIN_RPC_UTIL_H
|
||||||
|
|
|
@ -2075,7 +2075,21 @@ static UniValue lockunspent(const JSONRPCRequest& request)
|
||||||
|
|
||||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
|
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"lockunspent unlock ([{\"txid\":\"txid\",\"vout\":n},...])\n"
|
RPCHelpMan{"lockunspent",
|
||||||
|
{
|
||||||
|
{"unlock", RPCArg::Type::BOOL, false},
|
||||||
|
{"transactions", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"txid", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"vout", RPCArg::Type::NUM, false},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nUpdates list of temporarily unspendable outputs.\n"
|
"\nUpdates list of temporarily unspendable outputs.\n"
|
||||||
"Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
|
"Temporarily lock (unlock=false) or unlock (unlock=true) specified transaction outputs.\n"
|
||||||
"If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
|
"If no transaction outputs are specified when unlocking then all current locked transaction outputs are unlocked.\n"
|
||||||
|
@ -2620,7 +2634,26 @@ static UniValue listunspent(const JSONRPCRequest& request)
|
||||||
|
|
||||||
if (request.fHelp || request.params.size() > 5)
|
if (request.fHelp || request.params.size() > 5)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"listunspent ( minconf maxconf [\"addresses\",...] [include_unsafe] [query_options])\n"
|
RPCHelpMan{"listunspent",
|
||||||
|
{
|
||||||
|
{"minconf", RPCArg::Type::NUM, true},
|
||||||
|
{"maxconf", RPCArg::Type::NUM, true},
|
||||||
|
{"addresses", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"address", RPCArg::Type::STR_HEX, true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
{"include_unsafe", RPCArg::Type::BOOL, true},
|
||||||
|
{"query_options", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"minimumAmount", RPCArg::Type::AMOUNT, true},
|
||||||
|
{"maximumAmount", RPCArg::Type::AMOUNT, true},
|
||||||
|
{"maximumCount", RPCArg::Type::NUM, true},
|
||||||
|
{"minimumSumAmount", RPCArg::Type::AMOUNT, true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nReturns array of unspent transaction outputs\n"
|
"\nReturns array of unspent transaction outputs\n"
|
||||||
"with between minconf and maxconf (inclusive) confirmations.\n"
|
"with between minconf and maxconf (inclusive) confirmations.\n"
|
||||||
"Optionally filter to only include txouts paid to specified addresses.\n"
|
"Optionally filter to only include txouts paid to specified addresses.\n"
|
||||||
|
@ -2995,7 +3028,25 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request)
|
||||||
|
|
||||||
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
|
if (request.fHelp || request.params.size() < 1 || request.params.size() > 3)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"signrawtransactionwithwallet \"hexstring\" ( [{\"txid\":\"id\",\"vout\":n,\"scriptPubKey\":\"hex\",\"redeemScript\":\"hex\"},...] sighashtype )\n"
|
RPCHelpMan{"signrawtransactionwithwallet",
|
||||||
|
{
|
||||||
|
{"hexstring", RPCArg::Type::STR, false},
|
||||||
|
{"prevtxs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"txid", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"vout", RPCArg::Type::NUM, false},
|
||||||
|
{"scriptPubKey", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"redeemScript", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"amount", RPCArg::Type::AMOUNT, false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
{"sighashtype", RPCArg::Type::STR, true},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nSign inputs for raw transaction (serialized, hex-encoded).\n"
|
"\nSign inputs for raw transaction (serialized, hex-encoded).\n"
|
||||||
"The second optional argument (may be null) is an array of previous transaction outputs that\n"
|
"The second optional argument (may be null) is an array of previous transaction outputs that\n"
|
||||||
"this transaction depends on but may not yet be in the block chain.\n"
|
"this transaction depends on but may not yet be in the block chain.\n"
|
||||||
|
@ -3896,7 +3947,55 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request)
|
||||||
|
|
||||||
if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
|
if (request.fHelp || request.params.size() < 2 || request.params.size() > 5)
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"walletcreatefundedpsbt [{\"txid\":\"id\",\"vout\":n},...] [{\"address\":amount},{\"data\":\"hex\"},...] ( locktime ) ( replaceable ) ( options bip32derivs )\n"
|
RPCHelpMan{"walletcreatefundedpsbt",
|
||||||
|
{
|
||||||
|
{"inputs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"txid", RPCArg::Type::STR_HEX, false},
|
||||||
|
{"vout", RPCArg::Type::NUM, false},
|
||||||
|
{"sequence", RPCArg::Type::NUM, false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
{"outputs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"address", RPCArg::Type::AMOUNT, true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
{"", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"data", RPCArg::Type::STR_HEX, true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
},
|
||||||
|
false},
|
||||||
|
{"locktime", RPCArg::Type::NUM, true},
|
||||||
|
{"options", RPCArg::Type::OBJ,
|
||||||
|
{
|
||||||
|
{"changeAddress", RPCArg::Type::STR_HEX, true},
|
||||||
|
{"changePosition", RPCArg::Type::NUM, true},
|
||||||
|
{"change_type", RPCArg::Type::STR, true},
|
||||||
|
{"includeWatching", RPCArg::Type::BOOL, true},
|
||||||
|
{"lockUnspents", RPCArg::Type::BOOL, true},
|
||||||
|
{"feeRate", RPCArg::Type::NUM, true},
|
||||||
|
{"subtractFeeFromOutputs", RPCArg::Type::ARR,
|
||||||
|
{
|
||||||
|
{"int", RPCArg::Type::NUM, true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
{"replaceable", RPCArg::Type::BOOL, true},
|
||||||
|
{"conf_target", RPCArg::Type::NUM, true},
|
||||||
|
{"estimate_mode", RPCArg::Type::STR, true},
|
||||||
|
},
|
||||||
|
true},
|
||||||
|
{"bip32derivs", RPCArg::Type::BOOL, true},
|
||||||
|
}}
|
||||||
|
.ToString() +
|
||||||
"\nCreates and funds a transaction in the Partially Signed Transaction format. Inputs will be added if supplied inputs are not enough\n"
|
"\nCreates and funds a transaction in the Partially Signed Transaction format. Inputs will be added if supplied inputs are not enough\n"
|
||||||
"Implements the Creator and Updater roles.\n"
|
"Implements the Creator and Updater roles.\n"
|
||||||
"\nArguments:\n"
|
"\nArguments:\n"
|
||||||
|
|
Loading…
Reference in a new issue