Merge #17809: rpc: Auto-format RPCResult

fa6b061fc1 rpc: Auto-format RPCResult (MarcoFalke)
fa7d0503d3 rpc: Move OuterType enum to header (MarcoFalke)

Pull request description:

  This enforces most syntax rules of the RPCResult at compile time (or some at run time during unit and functional tests)

  Apart from normalizing the syntax, by separating stylistic formatting from the structure, we could in theory directly generate the html for e.g. https://bitcoincore.org/en/doc/0.19.0/rpc/wallet/importmulti/

ACKs for top commit:
  Sjors:
    Indeed, re-ACK fa6b061fc1
  ajtowns:
    ACK fa6b061fc1 -- skimmed code changes and differences to rpc help output

Tree-SHA512: 5b510b3aa0b7c7b9189a48c77593159409069f939145b9a00c5478e894cf65f994d44d633eb7bb7dbea40ee820645a2930976c24772379d96929002b120efa28
This commit is contained in:
MarcoFalke 2020-03-04 08:16:46 -05:00
commit a71c34742c
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
11 changed files with 1517 additions and 1250 deletions

View file

@ -177,8 +177,7 @@ static UniValue getblockcount(const JSONRPCRequest& request)
"The genesis block has height 0.\n", "The genesis block has height 0.\n",
{}, {},
RPCResult{ RPCResult{
"n (numeric) The current block count\n" RPCResult::Type::NUM, "", "The current block count"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("getblockcount", "") HelpExampleCli("getblockcount", "")
+ HelpExampleRpc("getblockcount", "") + HelpExampleRpc("getblockcount", "")
@ -195,8 +194,7 @@ static UniValue getbestblockhash(const JSONRPCRequest& request)
"\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n", "\nReturns the hash of the best (tip) block in the most-work fully-validated chain.\n",
{}, {},
RPCResult{ RPCResult{
"\"hex\" (string) the block hash, hex-encoded\n" RPCResult::Type::STR_HEX, "", "the block hash, hex-encoded"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("getbestblockhash", "") HelpExampleCli("getbestblockhash", "")
+ HelpExampleRpc("getbestblockhash", "") + HelpExampleRpc("getbestblockhash", "")
@ -226,11 +224,11 @@ static UniValue waitfornewblock(const JSONRPCRequest& request)
{"timeout", RPCArg::Type::NUM, /* default */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."}, {"timeout", RPCArg::Type::NUM, /* default */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"hash\" : { (string) The blockhash\n" {
" \"height\" : { (numeric) Block height\n" {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
"}\n" {RPCResult::Type::NUM, "height", "Block height"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("waitfornewblock", "1000") HelpExampleCli("waitfornewblock", "1000")
+ HelpExampleRpc("waitfornewblock", "1000") + HelpExampleRpc("waitfornewblock", "1000")
@ -266,11 +264,11 @@ static UniValue waitforblock(const JSONRPCRequest& request)
{"timeout", RPCArg::Type::NUM, /* default */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."}, {"timeout", RPCArg::Type::NUM, /* default */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"hash\" : { (string) The blockhash\n" {
" \"height\" : { (numeric) Block height\n" {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
"}\n" {RPCResult::Type::NUM, "height", "Block height"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") HelpExampleCli("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
+ HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000") + HelpExampleRpc("waitforblock", "\"0000000000079f8ef3d2c688c244eb7a4570b24c9ed7b4a8c619eb02596f8862\", 1000")
@ -310,11 +308,11 @@ static UniValue waitforblockheight(const JSONRPCRequest& request)
{"timeout", RPCArg::Type::NUM, /* default */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."}, {"timeout", RPCArg::Type::NUM, /* default */ "0", "Time in milliseconds to wait for a response. 0 indicates no timeout."},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"hash\" : { (string) The blockhash\n" {
" \"height\" : { (numeric) Block height\n" {RPCResult::Type::STR_HEX, "hash", "The blockhash"},
"}\n" {RPCResult::Type::NUM, "height", "Block height"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("waitforblockheight", "\"100\", 1000") HelpExampleCli("waitforblockheight", "\"100\", 1000")
+ HelpExampleRpc("waitforblockheight", "\"100\", 1000") + HelpExampleRpc("waitforblockheight", "\"100\", 1000")
@ -364,8 +362,7 @@ static UniValue getdifficulty(const JSONRPCRequest& request)
"\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n", "\nReturns the proof-of-work difficulty as a multiple of the minimum difficulty.\n",
{}, {},
RPCResult{ RPCResult{
"n.nnn (numeric) the proof-of-work difficulty as a multiple of the minimum difficulty.\n" RPCResult::Type::NUM, "", "the proof-of-work difficulty as a multiple of the minimum difficulty."},
},
RPCExamples{ RPCExamples{
HelpExampleCli("getdifficulty", "") HelpExampleCli("getdifficulty", "")
+ HelpExampleRpc("getdifficulty", "") + HelpExampleRpc("getdifficulty", "")
@ -376,37 +373,35 @@ static UniValue getdifficulty(const JSONRPCRequest& request)
return GetDifficulty(::ChainActive().Tip()); return GetDifficulty(::ChainActive().Tip());
} }
static std::string EntryDescriptionString() static std::vector<RPCResult> MempoolEntryDescription() { return {
{ RPCResult{RPCResult::Type::NUM, "vsize", "virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted."},
return " \"vsize\" : n, (numeric) virtual transaction size as defined in BIP 141. This is different from actual serialized size for witness transactions as witness data is discounted.\n" RPCResult{RPCResult::Type::NUM, "size", "(DEPRECATED) same as vsize. Only returned if bitcoind is started with -deprecatedrpc=size\n"
" \"size\" : n, (numeric) (DEPRECATED) same as vsize. Only returned if bitcoind is started with -deprecatedrpc=size\n" "size will be completely removed in v0.20."},
" size will be completely removed in v0.20.\n" RPCResult{RPCResult::Type::NUM, "weight", "transaction weight as defined in BIP 141."},
" \"weight\" : n, (numeric) transaction weight as defined in BIP 141.\n" RPCResult{RPCResult::Type::STR_AMOUNT, "fee", "transaction fee in " + CURRENCY_UNIT + " (DEPRECATED)"},
" \"fee\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + " (DEPRECATED)\n" RPCResult{RPCResult::Type::STR_AMOUNT, "modifiedfee", "transaction fee with fee deltas used for mining priority (DEPRECATED)"},
" \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority (DEPRECATED)\n" RPCResult{RPCResult::Type::NUM_TIME, "time", "local time transaction entered pool in seconds since 1 Jan 1970 GMT"},
" \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" RPCResult{RPCResult::Type::NUM, "height", "block height when transaction entered pool"},
" \"height\" : n, (numeric) block height when transaction entered pool\n" RPCResult{RPCResult::Type::NUM, "descendantcount", "number of in-mempool descendant transactions (including this one)"},
" \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" RPCResult{RPCResult::Type::NUM, "descendantsize", "virtual transaction size of in-mempool descendants (including this one)"},
" \"descendantsize\" : n, (numeric) virtual transaction size of in-mempool descendants (including this one)\n" RPCResult{RPCResult::Type::STR_AMOUNT, "descendantfees", "modified fees (see above) of in-mempool descendants (including this one) (DEPRECATED)"},
" \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one) (DEPRECATED)\n" RPCResult{RPCResult::Type::NUM, "ancestorcount", "number of in-mempool ancestor transactions (including this one)"},
" \"ancestorcount\" : n, (numeric) number of in-mempool ancestor transactions (including this one)\n" RPCResult{RPCResult::Type::NUM, "ancestorsize", "virtual transaction size of in-mempool ancestors (including this one)"},
" \"ancestorsize\" : n, (numeric) virtual transaction size of in-mempool ancestors (including this one)\n" RPCResult{RPCResult::Type::STR_AMOUNT, "ancestorfees", "modified fees (see above) of in-mempool ancestors (including this one) (DEPRECATED)"},
" \"ancestorfees\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one) (DEPRECATED)\n" RPCResult{RPCResult::Type::STR_HEX, "wtxid", "hash of serialized transaction, including witness data"},
" \"wtxid\" : hash, (string) hash of serialized transaction, including witness data\n" RPCResult{RPCResult::Type::OBJ, "fees", "",
" \"fees\" : {\n" {
" \"base\" : n, (numeric) transaction fee in " + CURRENCY_UNIT + "\n" RPCResult{RPCResult::Type::STR_AMOUNT, "base", "transaction fee in " + CURRENCY_UNIT},
" \"modified\" : n, (numeric) transaction fee with fee deltas used for mining priority in " + CURRENCY_UNIT + "\n" RPCResult{RPCResult::Type::STR_AMOUNT, "modified", "transaction fee with fee deltas used for mining priority in " + CURRENCY_UNIT},
" \"ancestor\" : n, (numeric) modified fees (see above) of in-mempool ancestors (including this one) in " + CURRENCY_UNIT + "\n" RPCResult{RPCResult::Type::STR_AMOUNT, "ancestor", "modified fees (see above) of in-mempool ancestors (including this one) in " + CURRENCY_UNIT},
" \"descendant\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one) in " + CURRENCY_UNIT + "\n" RPCResult{RPCResult::Type::STR_AMOUNT, "descendant", "modified fees (see above) of in-mempool descendants (including this one) in " + CURRENCY_UNIT},
" }\n" }},
" \"depends\" : [ (json array) unconfirmed transactions used as inputs for this transaction\n" RPCResult{RPCResult::Type::ARR, "depends", "unconfirmed transactions used as inputs for this transaction",
" \"transactionid\", (string) parent transaction id\n" {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "parent transaction id"}}},
" ... ]\n" RPCResult{RPCResult::Type::ARR, "spentby", "unconfirmed transactions spending outputs from this transaction",
" \"spentby\" : [ (json array) unconfirmed transactions spending outputs from this transaction\n" {RPCResult{RPCResult::Type::STR_HEX, "transactionid", "child transaction id"}}},
" \"transactionid\", (string) child transaction id\n" RPCResult{RPCResult::Type::BOOL, "bip125-replaceable", "Whether this transaction could be replaced due to BIP125 (replace-by-fee)"},
" ... ]\n" };}
" \"bip125-replaceable\" : true|false, (boolean) Whether this transaction could be replaced due to BIP125 (replace-by-fee)\n";
}
static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPoolEntry& e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs) static void entryToJSON(const CTxMemPool& pool, UniValue& info, const CTxMemPoolEntry& e) EXCLUSIVE_LOCKS_REQUIRED(pool.cs)
{ {
@ -505,17 +500,17 @@ static UniValue getrawmempool(const JSONRPCRequest& request)
{ {
{"verbose", RPCArg::Type::BOOL, /* default */ "false", "True for a json object, false for array of transaction ids"}, {"verbose", RPCArg::Type::BOOL, /* default */ "false", "True for a json object, false for array of transaction ids"},
}, },
RPCResult{"for verbose = false", {
"[ (json array of string)\n" RPCResult{"for verbose = false",
" \"transactionid\" (string) The transaction id\n" RPCResult::Type::ARR, "", "",
" ,...\n" {
"]\n" {RPCResult::Type::STR_HEX, "", "The transaction id"},
"\nResult: (for verbose = true):\n" }},
"{ (json object)\n" RPCResult{"for verbose = true",
" \"transactionid\" : { (json object)\n" RPCResult::Type::OBJ, "", "",
+ EntryDescriptionString() {
+ " }, ...\n" {RPCResult::Type::OBJ_DYN, "transactionid", "", MempoolEntryDescription()},
"}\n" }},
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getrawmempool", "true") HelpExampleCli("getrawmempool", "true")
@ -540,18 +535,10 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
}, },
{ {
RPCResult{"for verbose = false", RPCResult{"for verbose = false",
"[ (json array of strings)\n" RPCResult::Type::ARR, "", "",
" \"transactionid\" (string) The transaction id of an in-mempool ancestor transaction\n" {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool ancestor transaction"}}},
" ,...\n"
"]\n"
},
RPCResult{"for verbose = true", RPCResult{"for verbose = true",
"{ (json object)\n" RPCResult::Type::OBJ_DYN, "transactionid", "", MempoolEntryDescription()},
" \"transactionid\" : { (json object)\n"
+ EntryDescriptionString()
+ " }, ...\n"
"}\n"
},
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getmempoolancestors", "\"mytxid\"") HelpExampleCli("getmempoolancestors", "\"mytxid\"")
@ -608,18 +595,13 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
}, },
{ {
RPCResult{"for verbose = false", RPCResult{"for verbose = false",
"[ (json array of strings)\n" RPCResult::Type::ARR, "", "",
" \"transactionid\" (string) The transaction id of an in-mempool descendant transaction\n" {{RPCResult::Type::STR_HEX, "", "The transaction id of an in-mempool descendant transaction"}}},
" ,...\n"
"]\n"
},
RPCResult{"for verbose = true", RPCResult{"for verbose = true",
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"transactionid\" : { (json object)\n" {
+ EntryDescriptionString() {RPCResult::Type::OBJ_DYN, "transactionid", "", MempoolEntryDescription()},
+ " }, ...\n" }},
"}\n"
},
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getmempooldescendants", "\"mytxid\"") HelpExampleCli("getmempooldescendants", "\"mytxid\"")
@ -674,10 +656,7 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"}, {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id (must be in mempool)"},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ_DYN, "", "", MempoolEntryDescription()},
+ EntryDescriptionString()
+ "}\n"
},
RPCExamples{ RPCExamples{
HelpExampleCli("getmempoolentry", "\"mytxid\"") HelpExampleCli("getmempoolentry", "\"mytxid\"")
+ HelpExampleRpc("getmempoolentry", "\"mytxid\"") + HelpExampleRpc("getmempoolentry", "\"mytxid\"")
@ -708,8 +687,7 @@ static UniValue getblockhash(const JSONRPCRequest& request)
{"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"}, {"height", RPCArg::Type::NUM, RPCArg::Optional::NO, "The height index"},
}, },
RPCResult{ RPCResult{
"\"hash\" (string) The block hash\n" RPCResult::Type::STR_HEX, "", "The block hash"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("getblockhash", "1000") HelpExampleCli("getblockhash", "1000")
+ HelpExampleRpc("getblockhash", "1000") + HelpExampleRpc("getblockhash", "1000")
@ -737,27 +715,26 @@ static UniValue getblockheader(const JSONRPCRequest& request)
}, },
{ {
RPCResult{"for verbose = true", RPCResult{"for verbose = true",
"{\n" RPCResult::Type::OBJ, "", "",
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n" {
" \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"},
" \"height\" : n, (numeric) The block height or index\n" {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"},
" \"version\" : n, (numeric) The block version\n" {RPCResult::Type::NUM, "height", "The block height or index"},
" \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" {RPCResult::Type::NUM, "version", "The block version"},
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n" {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"},
" \"time\" : ttt, (numeric) The block time expressed in " + UNIX_EPOCH_TIME + "\n" {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"},
" \"mediantime\" : ttt, (numeric) The median block time expressed in " + UNIX_EPOCH_TIME + "\n" {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
" \"nonce\" : n, (numeric) The nonce\n" {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
" \"bits\" : \"1d00ffff\", (string) The bits\n" {RPCResult::Type::NUM, "nonce", "The nonce"},
" \"difficulty\" : x.xxx, (numeric) The difficulty\n" {RPCResult::Type::STR_HEX, "bits", "The bits"},
" \"chainwork\" : \"0000...1f3\" (string) Expected number of hashes required to produce the current chain (in hex)\n" {RPCResult::Type::NUM, "difficulty", "The difficulty"},
" \"nTx\" : n, (numeric) The number of transactions in the block.\n" {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the current chain"},
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
" \"nextblockhash\" : \"hash\", (string) The hash of the next block\n" {RPCResult::Type::STR_HEX, "previousblockhash", "The hash of the previous block"},
"}\n" {RPCResult::Type::STR_HEX, "nextblockhash", "The hash of the next block"},
}, }},
RPCResult{"for verbose=false", RPCResult{"for verbose=false",
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"},
},
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") HelpExampleCli("getblockheader", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
@ -839,44 +816,45 @@ static UniValue getblock(const JSONRPCRequest& request)
}, },
{ {
RPCResult{"for verbosity = 0", RPCResult{"for verbosity = 0",
"\"data\" (string) A string that is serialized, hex-encoded data for block 'hash'.\n" RPCResult::Type::STR_HEX, "", "A string that is serialized, hex-encoded data for block 'hash'"},
},
RPCResult{"for verbosity = 1", RPCResult{"for verbosity = 1",
"{\n" RPCResult::Type::OBJ, "", "",
" \"hash\" : \"hash\", (string) the block hash (same as provided)\n" {
" \"confirmations\" : n, (numeric) The number of confirmations, or -1 if the block is not on the main chain\n" {RPCResult::Type::STR_HEX, "hash", "the block hash (same as provided)"},
" \"size\" : n, (numeric) The block size\n" {RPCResult::Type::NUM, "confirmations", "The number of confirmations, or -1 if the block is not on the main chain"},
" \"strippedsize\" : n, (numeric) The block size excluding witness data\n" {RPCResult::Type::NUM, "size", "The block size"},
" \"weight\" : n (numeric) The block weight as defined in BIP 141\n" {RPCResult::Type::NUM, "strippedsize", "The block size excluding witness data"},
" \"height\" : n, (numeric) The block height or index\n" {RPCResult::Type::NUM, "weight", "The block weight as defined in BIP 141"},
" \"version\" : n, (numeric) The block version\n" {RPCResult::Type::NUM, "height", "The block height or index"},
" \"versionHex\" : \"00000000\", (string) The block version formatted in hexadecimal\n" {RPCResult::Type::NUM, "version", "The block version"},
" \"merkleroot\" : \"xxxx\", (string) The merkle root\n" {RPCResult::Type::STR_HEX, "versionHex", "The block version formatted in hexadecimal"},
" \"tx\" : [ (array of string) The transaction ids\n" {RPCResult::Type::STR_HEX, "merkleroot", "The merkle root"},
" \"transactionid\" (string) The transaction id\n" {RPCResult::Type::ARR, "tx", "The transaction ids",
" ,...\n" {{RPCResult::Type::STR_HEX, "", "The transaction id"}}},
" ],\n" {RPCResult::Type::NUM_TIME, "time", "The block time expressed in " + UNIX_EPOCH_TIME},
" \"time\" : ttt, (numeric) The block time expressed in " + UNIX_EPOCH_TIME + "\n" {RPCResult::Type::NUM_TIME, "mediantime", "The median block time expressed in " + UNIX_EPOCH_TIME},
" \"mediantime\" : ttt, (numeric) The median block time expressed in " + UNIX_EPOCH_TIME + "\n" {RPCResult::Type::NUM, "nonce", "The nonce"},
" \"nonce\" : n, (numeric) The nonce\n" {RPCResult::Type::STR_HEX, "bits", "The bits"},
" \"bits\" : \"1d00ffff\", (string) The bits\n" {RPCResult::Type::NUM, "difficulty", "The difficulty"},
" \"difficulty\" : x.xxx, (numeric) The difficulty\n" {RPCResult::Type::STR_HEX, "chainwork", "Expected number of hashes required to produce the chain up to this block (in hex)"},
" \"chainwork\" : \"xxxx\", (string) Expected number of hashes required to produce the chain up to this block (in hex)\n" {RPCResult::Type::NUM, "nTx", "The number of transactions in the block"},
" \"nTx\" : n, (numeric) The number of transactions in the block.\n" {RPCResult::Type::STR_HEX, "previousblockhash", "The hash of the previous block"},
" \"previousblockhash\" : \"hash\", (string) The hash of the previous block\n" {RPCResult::Type::STR_HEX, "nextblockhash", "The hash of the next block"},
" \"nextblockhash\" : \"hash\" (string) The hash of the next block\n" }},
"}\n"
},
RPCResult{"for verbosity = 2", RPCResult{"for verbosity = 2",
"{\n" RPCResult::Type::OBJ, "", "",
" ..., Same output as verbosity = 1.\n" {
" \"tx\" : [ (array of Objects) The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result.\n" {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
" ,...\n" {RPCResult::Type::ARR, "tx", "",
" ],\n" {
" ,... Same output as verbosity = 1.\n" {RPCResult::Type::OBJ, "", "",
"}\n" {
}, {RPCResult::Type::ELISION, "", "The transactions in the format of the getrawtransaction RPC. Different from verbosity = 1 \"tx\" result"},
}, }},
}},
{RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
}},
},
RPCExamples{ RPCExamples{
HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") HelpExampleCli("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
+ HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"") + HelpExampleRpc("getblock", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\"")
@ -927,8 +905,7 @@ static UniValue pruneblockchain(const JSONRPCRequest& request)
" to prune blocks whose block time is at least 2 hours older than the provided timestamp."}, " to prune blocks whose block time is at least 2 hours older than the provided timestamp."},
}, },
RPCResult{ RPCResult{
"n (numeric) Height of the last block pruned.\n" RPCResult::Type::NUM, "", "Height of the last block pruned"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("pruneblockchain", "1000") HelpExampleCli("pruneblockchain", "1000")
+ HelpExampleRpc("pruneblockchain", "1000") + HelpExampleRpc("pruneblockchain", "1000")
@ -982,17 +959,17 @@ static UniValue gettxoutsetinfo(const JSONRPCRequest& request)
"Note this call may take some time.\n", "Note this call may take some time.\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"height\" : n, (numeric) The current block height (index)\n" {
" \"bestblock\" : \"hex\", (string) The hash of the block at the tip of the chain\n" {RPCResult::Type::NUM, "height", "The current block height (index)"},
" \"transactions\" : n, (numeric) The number of transactions with unspent outputs\n" {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
" \"txouts\" : n, (numeric) The number of unspent transaction outputs\n" {RPCResult::Type::NUM, "transactions", "The number of transactions with unspent outputs"},
" \"bogosize\" : n, (numeric) A meaningless metric for UTXO set size\n" {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs"},
" \"hash_serialized_2\": \"hash\", (string) The serialized hash\n" {RPCResult::Type::NUM, "bogosize", "A meaningless metric for UTXO set size"},
" \"disk_size\" : n, (numeric) The estimated size of the chainstate on disk\n" {RPCResult::Type::STR_HEX, "hash_serialized_2", "The serialized hash"},
" \"total_amount\" : x.xxx (numeric) The total amount\n" {RPCResult::Type::NUM, "disk_size", "The estimated size of the chainstate on disk"},
"}\n" {RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("gettxoutsetinfo", "") HelpExampleCli("gettxoutsetinfo", "")
+ HelpExampleRpc("gettxoutsetinfo", "") + HelpExampleRpc("gettxoutsetinfo", "")
@ -1030,23 +1007,22 @@ UniValue gettxout(const JSONRPCRequest& request)
{"include_mempool", RPCArg::Type::BOOL, /* default */ "true", "Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."}, {"include_mempool", RPCArg::Type::BOOL, /* default */ "true", "Whether to include the mempool. Note that an unspent output that is spent in the mempool won't appear."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"bestblock\" : \"hash\", (string) The hash of the block at the tip of the chain\n" {
" \"confirmations\" : n, (numeric) The number of confirmations\n" {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
" \"value\" : x.xxx, (numeric) The transaction value in " + CURRENCY_UNIT + "\n" {RPCResult::Type::NUM, "confirmations", "The number of confirmations"},
" \"scriptPubKey\" : { (json object)\n" {RPCResult::Type::STR_AMOUNT, "value", "The transaction value in " + CURRENCY_UNIT},
" \"asm\" : \"code\", (string) \n" {RPCResult::Type::OBJ, "scriptPubKey", "",
" \"hex\" : \"hex\", (string) \n" {
" \"reqSigs\" : n, (numeric) Number of required signatures\n" {RPCResult::Type::STR_HEX, "asm", ""},
" \"type\" : \"pubkeyhash\", (string) The type, eg pubkeyhash\n" {RPCResult::Type::STR_HEX, "hex", ""},
" \"addresses\" : [ (array of string) array of bitcoin addresses\n" {RPCResult::Type::NUM, "reqSigs", "Number of required signatures"},
" \"address\" (string) bitcoin address\n" {RPCResult::Type::STR_HEX, "type", "The type, eg pubkeyhash"},
" ,...\n" {RPCResult::Type::ARR, "addresses", "array of bitcoin addresses",
" ]\n" {{RPCResult::Type::STR, "address", "bitcoin address"}}},
" },\n" }},
" \"coinbase\" : true|false (boolean) Coinbase or not\n" {RPCResult::Type::BOOL, "coinbase", "Coinbase or not"},
"}\n" }},
},
RPCExamples{ RPCExamples{
"\nGet unspent transactions\n" "\nGet unspent transactions\n"
+ HelpExampleCli("listunspent", "") + + HelpExampleCli("listunspent", "") +
@ -1111,8 +1087,7 @@ static UniValue verifychain(const JSONRPCRequest& request)
{"nblocks", RPCArg::Type::NUM, /* default */ strprintf("%d, 0=all", nCheckDepth), "The number of blocks to check."}, {"nblocks", RPCArg::Type::NUM, /* default */ strprintf("%d, 0=all", nCheckDepth), "The number of blocks to check."},
}, },
RPCResult{ RPCResult{
"true|false (boolean) Verified or not\n" RPCResult::Type::BOOL, "", "Verified or not"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("verifychain", "") HelpExampleCli("verifychain", "")
+ HelpExampleRpc("verifychain", "") + HelpExampleRpc("verifychain", "")
@ -1202,45 +1177,49 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
"Returns an object containing various state info regarding blockchain processing.\n", "Returns an object containing various state info regarding blockchain processing.\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"chain\" : \"xxxx\", (string) current network name (main, test, regtest)\n" {
" \"blocks\" : xxxxxx, (numeric) the height of the most-work fully-validated chain. The genesis block has height 0\n" {RPCResult::Type::STR, "chain", "current network name (main, test, regtest)"},
" \"headers\" : xxxxxx, (numeric) the current number of headers we have validated\n" {RPCResult::Type::NUM, "blocks", "the height of the most-work fully-validated chain. The genesis block has height 0"},
" \"bestblockhash\" : \"...\", (string) the hash of the currently best block\n" {RPCResult::Type::NUM, "headers", "the current number of headers we have validated"},
" \"difficulty\" : xxxxxx, (numeric) the current difficulty\n" {RPCResult::Type::STR, "bestblockhash", "the hash of the currently best block"},
" \"mediantime\" : xxxxxx, (numeric) median time for the current best block\n" {RPCResult::Type::NUM, "difficulty", "the current difficulty"},
" \"verificationprogress\" : xxxx, (numeric) estimate of verification progress [0..1]\n" {RPCResult::Type::NUM, "mediantime", "median time for the current best block"},
" \"initialblockdownload\" : xxxx, (boolean) (debug information) estimate of whether this node is in Initial Block Download mode.\n" {RPCResult::Type::NUM, "verificationprogress", "estimate of verification progress [0..1]"},
" \"chainwork\" : \"xxxx\" (string) total amount of work in active chain, in hexadecimal\n" {RPCResult::Type::BOOL, "initialblockdownload", "(debug information) estimate of whether this node is in Initial Block Download mode"},
" \"size_on_disk\" : xxxxxx, (numeric) the estimated size of the block and undo files on disk\n" {RPCResult::Type::STR_HEX, "chainwork", "total amount of work in active chain, in hexadecimal"},
" \"pruned\" : xx, (boolean) if the blocks are subject to pruning\n" {RPCResult::Type::NUM, "size_on_disk", "the estimated size of the block and undo files on disk"},
" \"pruneheight\" : xxxxxx, (numeric) lowest-height complete block stored (only present if pruning is enabled)\n" {RPCResult::Type::BOOL, "pruned", "if the blocks are subject to pruning"},
" \"automatic_pruning\" : xx, (boolean) whether automatic pruning is enabled (only present if pruning is enabled)\n" {RPCResult::Type::NUM, "pruneheight", "lowest-height complete block stored (only present if pruning is enabled)"},
" \"prune_target_size\" : xxxxxx, (numeric) the target size used by pruning (only present if automatic pruning is enabled)\n" {RPCResult::Type::BOOL, "automatic_pruning", "whether automatic pruning is enabled (only present if pruning is enabled)"},
" \"softforks\" : { (json object) status of softforks\n" {RPCResult::Type::NUM, "prune_target_size", "the target size used by pruning (only present if automatic pruning is enabled)"},
" \"xxxx\" : { (string) name of the softfork\n" {RPCResult::Type::OBJ_DYN, "softforks", "status of softforks",
" \"type\" : \"xxxx\", (string) one of \"buried\", \"bip9\"\n" {
" \"bip9\": { (json object) status of bip9 softforks (only for \"bip9\" type)\n" {RPCResult::Type::OBJ, "xxxx", "name of the softfork",
" \"status\" : \"xxxx\", (string) one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\"\n" {
" \"bit\" : xx, (numeric) the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)\n" {RPCResult::Type::STR, "type", "one of \"buried\", \"bip9\""},
" \"start_time\" : xx, (numeric) the minimum median time past of a block at which the bit gains its meaning\n" {RPCResult::Type::OBJ, "bip9", "status of bip9 softforks (only for \"bip9\" type)",
" \"timeout\" : xx, (numeric) the median time past of a block at which the deployment is considered failed if not yet locked in\n" {
" \"since\" : xx, (numeric) height of the first block to which the status applies\n" {RPCResult::Type::STR, "status", "one of \"defined\", \"started\", \"locked_in\", \"active\", \"failed\""},
" \"statistics\" : { (json object) numeric statistics about BIP9 signalling for a softfork\n" {RPCResult::Type::NUM, "bit", "the bit (0-28) in the block version field used to signal this softfork (only for \"started\" status)"},
" \"period\" : xx, (numeric) the length in blocks of the BIP9 signalling period \n" {RPCResult::Type::NUM_TIME, "start_time", "the minimum median time past of a block at which the bit gains its meaning"},
" \"threshold\" : xx, (numeric) the number of blocks with the version bit set required to activate the feature \n" {RPCResult::Type::NUM_TIME, "timeout", "the median time past of a block at which the deployment is considered failed if not yet locked in"},
" \"elapsed\" : xx, (numeric) the number of blocks elapsed since the beginning of the current period \n" {RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
" \"count\" : xx, (numeric) the number of blocks with the version bit set in the current period \n" {RPCResult::Type::OBJ, "statistics", "numeric statistics about BIP9 signalling for a softfork",
" \"possible\" : xx (boolean) returns false if there are not enough blocks left in this period to pass activation threshold \n" {
" }\n" {RPCResult::Type::NUM, "period", "the length in blocks of the BIP9 signalling period"},
" },\n" {RPCResult::Type::NUM, "threshold", "the number of blocks with the version bit set required to activate the feature"},
" \"height\" : \"xxxxxx\", (numeric) height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)\n" {RPCResult::Type::NUM, "elapsed", "the number of blocks elapsed since the beginning of the current period"},
" \"active\" : xx, (boolean) true if the rules are enforced for the mempool and the next block\n" {RPCResult::Type::NUM, "count", "the number of blocks with the version bit set in the current period"},
" }\n" {RPCResult::Type::BOOL, "possible", "returns false if there are not enough blocks left in this period to pass activation threshold"},
" }\n" }},
" \"warnings\" : \"...\", (string) any network and blockchain warnings.\n" }},
"}\n" {RPCResult::Type::NUM, "height", "height of the first block which the rules are or will be enforced (only for \"buried\" type, or \"bip9\" type with \"active\" status)"},
}, {RPCResult::Type::BOOL, "active", "true if the rules are enforced for the mempool and the next block"},
}},
}},
{RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
}},
RPCExamples{ RPCExamples{
HelpExampleCli("getblockchaininfo", "") HelpExampleCli("getblockchaininfo", "")
+ HelpExampleRpc("getblockchaininfo", "") + HelpExampleRpc("getblockchaininfo", "")
@ -1315,27 +1294,20 @@ static UniValue getchaintips(const JSONRPCRequest& request)
" including the main chain as well as orphaned branches.\n", " including the main chain as well as orphaned branches.\n",
{}, {},
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {{RPCResult::Type::OBJ, "", "",
" \"height\" : xxxx, (numeric) height of the chain tip\n" {
" \"hash\" : \"xxxx\", (string) block hash of the tip\n" {RPCResult::Type::NUM, "height", "height of the chain tip"},
" \"branchlen\" : 0 (numeric) zero for main chain\n" {RPCResult::Type::STR_HEX, "hash", "block hash of the tip"},
" \"status\" : \"active\" (string) \"active\" for the main chain\n" {RPCResult::Type::NUM, "branchlen", "zero for main chain, otherwise length of branch connecting the tip to the main chain"},
" },\n" {RPCResult::Type::STR, "status", "status of the chain, \"active\" for the main chain\n"
" {\n"
" \"height\" : xxxx,\n"
" \"hash\" : \"xxxx\",\n"
" \"branchlen\" : 1 (numeric) length of branch connecting the tip to the main chain\n"
" \"status\" : \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
" }\n"
"]\n"
"Possible values for status:\n" "Possible values for status:\n"
"1. \"invalid\" This branch contains at least one invalid block\n" "1. \"invalid\" This branch contains at least one invalid block\n"
"2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n" "2. \"headers-only\" Not all blocks for this branch are available, but the headers are valid\n"
"3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n" "3. \"valid-headers\" All blocks are available for this branch, but they were never fully validated\n"
"4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n" "4. \"valid-fork\" This branch is not part of the active chain, but is fully validated\n"
"5. \"active\" This is the tip of the active main chain, which is certainly valid\n" "5. \"active\" This is the tip of the active main chain, which is certainly valid"},
}, }}}},
RPCExamples{ RPCExamples{
HelpExampleCli("getchaintips", "") HelpExampleCli("getchaintips", "")
+ HelpExampleRpc("getchaintips", "") + HelpExampleRpc("getchaintips", "")
@ -1435,16 +1407,16 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
"\nReturns details on the active state of the TX memory pool.\n", "\nReturns details on the active state of the TX memory pool.\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"loaded\" : true|false (boolean) True if the mempool is fully loaded\n" {
" \"size\" : xxxxx, (numeric) Current tx count\n" {RPCResult::Type::BOOL, "loaded", "True if the mempool is fully loaded"},
" \"bytes\" : xxxxx, (numeric) Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted\n" {RPCResult::Type::NUM, "size", "Current tx count"},
" \"usage\" : xxxxx, (numeric) Total memory usage for the mempool\n" {RPCResult::Type::NUM, "bytes", "Sum of all virtual transaction sizes as defined in BIP 141. Differs from actual serialized size because witness data is discounted"},
" \"maxmempool\" : xxxxx, (numeric) Maximum memory usage for the mempool\n" {RPCResult::Type::NUM, "usage", "Total memory usage for the mempool"},
" \"mempoolminfee\" : xxxxx (numeric) Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee\n" {RPCResult::Type::NUM, "maxmempool", "Maximum memory usage for the mempool"},
" \"minrelaytxfee\" : xxxxx (numeric) Current minimum relay fee for transactions\n" {RPCResult::Type::STR_AMOUNT, "mempoolminfee", "Minimum fee rate in " + CURRENCY_UNIT + "/kB for tx to be accepted. Is the maximum of minrelaytxfee and minimum mempool fee"},
"}\n" {RPCResult::Type::STR_AMOUNT, "minrelaytxfee", "Current minimum relay fee for transactions"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("getmempoolinfo", "") HelpExampleCli("getmempoolinfo", "")
+ HelpExampleRpc("getmempoolinfo", "") + HelpExampleRpc("getmempoolinfo", "")
@ -1575,17 +1547,17 @@ static UniValue getchaintxstats(const JSONRPCRequest& request)
{"blockhash", RPCArg::Type::STR_HEX, /* default */ "chain tip", "The hash of the block that ends the window."}, {"blockhash", RPCArg::Type::STR_HEX, /* default */ "chain tip", "The hash of the block that ends the window."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"time\" : xxxxx, (numeric) The timestamp for the final block in the window, expressed in " + UNIX_EPOCH_TIME + ".\n" {
" \"txcount\" : xxxxx, (numeric) The total number of transactions in the chain up to that point.\n" {RPCResult::Type::NUM_TIME, "time", "The timestamp for the final block in the window, expressed in " + UNIX_EPOCH_TIME},
" \"window_final_block_hash\" : \"...\", (string) The hash of the final block in the window.\n" {RPCResult::Type::NUM, "txcount", "The total number of transactions in the chain up to that point"},
" \"window_final_block_height\" : xxxxx, (numeric) The height of the final block in the window.\n" {RPCResult::Type::STR_HEX, "window_final_block_hash", "The hash of the final block in the window"},
" \"window_block_count\" : xxxxx, (numeric) Size of the window in number of blocks.\n" {RPCResult::Type::NUM, "window_final_block_height", "The height of the final block in the window."},
" \"window_tx_count\" : xxxxx, (numeric) The number of transactions in the window. Only returned if \"window_block_count\" is > 0.\n" {RPCResult::Type::NUM, "window_block_count", "Size of the window in number of blocks"},
" \"window_interval\" : xxxxx, (numeric) The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0.\n" {RPCResult::Type::NUM, "window_tx_count", "The number of transactions in the window. Only returned if \"window_block_count\" is > 0"},
" \"txrate\" : x.xx, (numeric) The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0.\n" {RPCResult::Type::NUM, "window_interval", "The elapsed time in the window in seconds. Only returned if \"window_block_count\" is > 0"},
"}\n" {RPCResult::Type::NUM, "txrate", "The average rate of transactions per second in the window. Only returned if \"window_interval\" is > 0"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("getchaintxstats", "") HelpExampleCli("getchaintxstats", "")
+ HelpExampleRpc("getchaintxstats", "2016") + HelpExampleRpc("getchaintxstats", "2016")
@ -1714,44 +1686,45 @@ static UniValue getblockstats(const JSONRPCRequest& request)
"stats"}, "stats"},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"avgfee\" : xxxxx, (numeric) Average fee in the block\n" {
" \"avgfeerate\" : xxxxx, (numeric) Average feerate (in satoshis per virtual byte)\n" {RPCResult::Type::NUM, "avgfee", "Average fee in the block"},
" \"avgtxsize\" : xxxxx, (numeric) Average transaction size\n" {RPCResult::Type::NUM, "avgfeerate", "Average feerate (in satoshis per virtual byte)"},
" \"blockhash\" : xxxxx, (string) The block hash (to check for potential reorgs)\n" {RPCResult::Type::NUM, "avgtxsize", "Average transaction size"},
" \"feerate_percentiles\" : [ (array of numeric) Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per virtual byte)\n" {RPCResult::Type::STR_HEX, "blockhash", "The block hash (to check for potential reorgs)"},
" \"10th_percentile_feerate\", (numeric) The 10th percentile feerate\n" {RPCResult::Type::ARR_FIXED, "feerate_percentiles", "Feerates at the 10th, 25th, 50th, 75th, and 90th percentile weight unit (in satoshis per virtual byte)",
" \"25th_percentile_feerate\", (numeric) The 25th percentile feerate\n" {
" \"50th_percentile_feerate\", (numeric) The 50th percentile feerate\n" {RPCResult::Type::NUM, "10th_percentile_feerate", "The 10th percentile feerate"},
" \"75th_percentile_feerate\", (numeric) The 75th percentile feerate\n" {RPCResult::Type::NUM, "25th_percentile_feerate", "The 25th percentile feerate"},
" \"90th_percentile_feerate\", (numeric) The 90th percentile feerate\n" {RPCResult::Type::NUM, "50th_percentile_feerate", "The 50th percentile feerate"},
" ],\n" {RPCResult::Type::NUM, "75th_percentile_feerate", "The 75th percentile feerate"},
" \"height\" : xxxxx, (numeric) The height of the block\n" {RPCResult::Type::NUM, "90th_percentile_feerate", "The 90th percentile feerate"},
" \"ins\" : xxxxx, (numeric) The number of inputs (excluding coinbase)\n" }},
" \"maxfee\" : xxxxx, (numeric) Maximum fee in the block\n" {RPCResult::Type::NUM, "height", "The height of the block"},
" \"maxfeerate\" : xxxxx, (numeric) Maximum feerate (in satoshis per virtual byte)\n" {RPCResult::Type::NUM, "ins", "The number of inputs (excluding coinbase)"},
" \"maxtxsize\" : xxxxx, (numeric) Maximum transaction size\n" {RPCResult::Type::NUM, "maxfee", "Maximum fee in the block"},
" \"medianfee\" : xxxxx, (numeric) Truncated median fee in the block\n" {RPCResult::Type::NUM, "maxfeerate", "Maximum feerate (in satoshis per virtual byte)"},
" \"mediantime\" : xxxxx, (numeric) The block median time past\n" {RPCResult::Type::NUM, "maxtxsize", "Maximum transaction size"},
" \"mediantxsize\" : xxxxx, (numeric) Truncated median transaction size\n" {RPCResult::Type::NUM, "medianfee", "Truncated median fee in the block"},
" \"minfee\" : xxxxx, (numeric) Minimum fee in the block\n" {RPCResult::Type::NUM, "mediantime", "The block median time past"},
" \"minfeerate\" : xxxxx, (numeric) Minimum feerate (in satoshis per virtual byte)\n" {RPCResult::Type::NUM, "mediantxsize", "Truncated median transaction size"},
" \"mintxsize\" : xxxxx, (numeric) Minimum transaction size\n" {RPCResult::Type::NUM, "minfee", "Minimum fee in the block"},
" \"outs\" : xxxxx, (numeric) The number of outputs\n" {RPCResult::Type::NUM, "minfeerate", "Minimum feerate (in satoshis per virtual byte)"},
" \"subsidy\" : xxxxx, (numeric) The block subsidy\n" {RPCResult::Type::NUM, "mintxsize", "Minimum transaction size"},
" \"swtotal_size\" : xxxxx, (numeric) Total size of all segwit transactions\n" {RPCResult::Type::NUM, "outs", "The number of outputs"},
" \"swtotal_weight\" : xxxxx, (numeric) Total weight of all segwit transactions divided by segwit scale factor (4)\n" {RPCResult::Type::NUM, "subsidy", "The block subsidy"},
" \"swtxs\" : xxxxx, (numeric) The number of segwit transactions\n" {RPCResult::Type::NUM, "swtotal_size", "Total size of all segwit transactions"},
" \"time\" : xxxxx, (numeric) The block time\n" {RPCResult::Type::NUM, "swtotal_weight", "Total weight of all segwit transactions divided by segwit scale factor (4)"},
" \"total_out\" : xxxxx, (numeric) Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])\n" {RPCResult::Type::NUM, "swtxs", "The number of segwit transactions"},
" \"total_size\" : xxxxx, (numeric) Total size of all non-coinbase transactions\n" {RPCResult::Type::NUM, "time", "The block time"},
" \"total_weight\" : xxxxx, (numeric) Total weight of all non-coinbase transactions divided by segwit scale factor (4)\n" {RPCResult::Type::NUM, "total_out", "Total amount in all outputs (excluding coinbase and thus reward [ie subsidy + totalfee])"},
" \"totalfee\" : xxxxx, (numeric) The fee total\n" {RPCResult::Type::NUM, "total_size", "Total size of all non-coinbase transactions"},
" \"txs\" : xxxxx, (numeric) The number of transactions (excluding coinbase)\n" {RPCResult::Type::NUM, "total_weight", "Total weight of all non-coinbase transactions divided by segwit scale factor (4)"},
" \"utxo_increase\" : xxxxx, (numeric) The increase/decrease in the number of unspent outputs\n" {RPCResult::Type::NUM, "totalfee", "The fee total"},
" \"utxo_size_inc\" : xxxxx, (numeric) The increase/decrease in size for the utxo index (not discounting op_return and similar)\n" {RPCResult::Type::NUM, "txs", "The number of transactions (excluding coinbase)"},
"}\n" {RPCResult::Type::NUM, "utxo_increase", "The increase/decrease in the number of unspent outputs"},
}, {RPCResult::Type::NUM, "utxo_size_inc", "The increase/decrease in size for the utxo index (not discounting op_return and similar)"},
}},
RPCExamples{ RPCExamples{
HelpExampleCli("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'") HelpExampleCli("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'")
+ HelpExampleRpc("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'") + HelpExampleRpc("getblockstats", "1000 '[\"minfeerate\",\"avgfeerate\"]'")
@ -2074,24 +2047,26 @@ UniValue scantxoutset(const JSONRPCRequest& request)
"[scanobjects,...]"}, "[scanobjects,...]"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"success\" : true|false, (boolean) Whether the scan was completed\n" {
" \"txouts\" : n, (numeric) The number of unspent transaction outputs scanned\n" {RPCResult::Type::BOOL, "success", "Whether the scan was completed"},
" \"height\" : n, (numeric) The current block height (index)\n" {RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs scanned"},
" \"bestblock\" : \"hex\", (string) The hash of the block at the tip of the chain\n" {RPCResult::Type::NUM, "height", "The current block height (index)"},
" \"unspents\" : [\n" {RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
" {\n" {RPCResult::Type::ARR, "unspents", "",
" \"txid\" : \"hash\", (string) The transaction id\n" {
" \"vout\" : n, (numeric) The vout value\n" {RPCResult::Type::OBJ, "", "",
" \"scriptPubKey\" : \"script\", (string) The script key\n" {
" \"desc\" : \"descriptor\", (string) A specialized descriptor for the matched scriptPubKey\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
" \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " of the unspent output\n" {RPCResult::Type::NUM, "vout", "The vout value"},
" \"height\" : n, (numeric) Height of the unspent transaction output\n" {RPCResult::Type::STR_HEX, "scriptPubKey", "The script key"},
" }\n" {RPCResult::Type::STR, "desc", "A specialized descriptor for the matched scriptPubKey"},
" ,...],\n" {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"},
" \"total_amount\" : x.xxx, (numeric) The total amount of all found unspent outputs in " + CURRENCY_UNIT + "\n" {RPCResult::Type::NUM, "height", "Height of the unspent transaction output"},
"]\n" }},
}, }},
{RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT},
}},
RPCExamples{""}, RPCExamples{""},
}.Check(request); }.Check(request);
@ -2197,11 +2172,11 @@ static UniValue getblockfilter(const JSONRPCRequest& request)
{"filtertype", RPCArg::Type::STR, /*default*/ "basic", "The type name of the filter"}, {"filtertype", RPCArg::Type::STR, /*default*/ "basic", "The type name of the filter"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"filter\" : (string) the hex-encoded filter data\n" {
" \"header\" : (string) the hex-encoded filter header\n" {RPCResult::Type::STR_HEX, "filter", "the hex-encoded filter data"},
"}\n" {RPCResult::Type::STR_HEX, "header", "the hex-encoded filter header"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"") HelpExampleCli("getblockfilter", "\"00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09\" \"basic\"")
} }
@ -2282,12 +2257,13 @@ UniValue dumptxoutset(const JSONRPCRequest& request)
"path to the output file. If relative, will be prefixed by datadir."}, "path to the output file. If relative, will be prefixed by datadir."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"coins_written\" : n, (numeric) the number of coins written in the snapshot\n" {
" \"base_hash\" : \"...\", (string) the hash of the base of the snapshot\n" {RPCResult::Type::NUM, "coins_written", "the number of coins written in the snapshot"},
" \"base_height\" : n, (string) the height of the base of the snapshot\n" {RPCResult::Type::STR_HEX, "base_hash", "the hash of the base of the snapshot"},
" \"path\" : \"...\" (string) the absolute path that the snapshot was written to\n" {RPCResult::Type::NUM, "base_height", "the height of the base of the snapshot"},
"]\n" {RPCResult::Type::STR, "path", "the absolute path that the snapshot was written to"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("dumptxoutset", "utxo.dat") HelpExampleCli("dumptxoutset", "utxo.dat")

View file

@ -89,8 +89,7 @@ static UniValue getnetworkhashps(const JSONRPCRequest& request)
{"height", RPCArg::Type::NUM, /* default */ "-1", "To estimate at the time of the given height."}, {"height", RPCArg::Type::NUM, /* default */ "-1", "To estimate at the time of the given height."},
}, },
RPCResult{ RPCResult{
"x (numeric) Hashes per second estimated\n" RPCResult::Type::NUM, "", "Hashes per second estimated"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("getnetworkhashps", "") HelpExampleCli("getnetworkhashps", "")
+ HelpExampleRpc("getnetworkhashps", "") + HelpExampleRpc("getnetworkhashps", "")
@ -153,7 +152,11 @@ static UniValue generatetodescriptor(const JSONRPCRequest& request)
{"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."}, {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."},
}, },
RPCResult{ RPCResult{
"[ blockhashes ] (json array) hashes of blocks generated\n"}, RPCResult::Type::ARR, "", "hashes of blocks generated",
{
{RPCResult::Type::STR_HEX, "", "blockhash"},
}
},
RPCExamples{ RPCExamples{
"\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")}, "\nGenerate 11 blocks to mydesc\n" + HelpExampleCli("generatetodescriptor", "11 \"mydesc\"")},
} }
@ -195,8 +198,10 @@ static UniValue generatetoaddress(const JSONRPCRequest& request)
{"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."}, {"maxtries", RPCArg::Type::NUM, /* default */ "1000000", "How many iterations to try."},
}, },
RPCResult{ RPCResult{
"[ blockhashes ] (json array) hashes of blocks generated\n" RPCResult::Type::ARR, "", "hashes of blocks generated",
}, {
{RPCResult::Type::STR_HEX, "", "blockhash"},
}},
RPCExamples{ RPCExamples{
"\nGenerate 11 blocks to myaddress\n" "\nGenerate 11 blocks to myaddress\n"
+ HelpExampleCli("generatetoaddress", "11 \"myaddress\"") + HelpExampleCli("generatetoaddress", "11 \"myaddress\"")
@ -229,17 +234,17 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
"\nReturns a json object containing mining-related information.", "\nReturns a json object containing mining-related information.",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"blocks\" : nnn, (numeric) The current block\n" {
" \"currentblockweight\" : nnn, (numeric, optional) The block weight of the last assembled block (only present if a block was ever assembled)\n" {RPCResult::Type::NUM, "blocks", "The current block"},
" \"currentblocktx\" : nnn, (numeric, optional) The number of block transactions of the last assembled block (only present if a block was ever assembled)\n" {RPCResult::Type::NUM, "currentblockweight", /* optional */ true, "The block weight of the last assembled block (only present if a block was ever assembled)"},
" \"difficulty\" : xxx.xxxxx (numeric) The current difficulty\n" {RPCResult::Type::NUM, "currentblocktx", /* optional */ true, "The number of block transactions of the last assembled block (only present if a block was ever assembled)"},
" \"networkhashps\" : nnn, (numeric) The network hashes per second\n" {RPCResult::Type::NUM, "difficulty", "The current difficulty"},
" \"pooledtx\" : n (numeric) The size of the mempool\n" {RPCResult::Type::NUM, "networkhashps", "The network hashes per second"},
" \"chain\" : \"xxxx\", (string) current network name (main, test, regtest)\n" {RPCResult::Type::NUM, "pooledtx", "The size of the mempool"},
" \"warnings\" : \"...\" (string) any network and blockchain warnings\n" {RPCResult::Type::STR, "chain", "current network name (main, test, regtest)"},
"}\n" {RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("getmininginfo", "") HelpExampleCli("getmininginfo", "")
+ HelpExampleRpc("getmininginfo", "") + HelpExampleRpc("getmininginfo", "")
@ -277,8 +282,7 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
" considers the transaction as it would have paid a higher (or lower) fee."}, " considers the transaction as it would have paid a higher (or lower) fee."},
}, },
RPCResult{ RPCResult{
"true (boolean) Returns true\n" RPCResult::Type::BOOL, "", "Returns true"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000") HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000")
+ HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000") + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000")
@ -355,48 +359,58 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
"\"template_request\""}, "\"template_request\""},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"version\" : n, (numeric) The preferred block version\n" {
" \"rules\" : [ \"rulename\", ... ], (array of strings) specific block rules that are to be enforced\n" {RPCResult::Type::NUM, "version", "The preferred block version"},
" \"vbavailable\" : { (json object) set of pending, supported versionbit (BIP 9) softfork deployments\n" {RPCResult::Type::ARR, "rules", "specific block rules that are to be enforced",
" \"rulename\" : bitnumber (numeric) identifies the bit number as indicating acceptance and readiness for the named softfork rule\n" {
" ,...\n" {RPCResult::Type::STR, "", "rulename"},
" },\n" }},
" \"vbrequired\" : n, (numeric) bit mask of versionbits the server requires set in submissions\n" {RPCResult::Type::OBJ_DYN, "vbavailable", "set of pending, supported versionbit (BIP 9) softfork deployments",
" \"previousblockhash\" : \"xxxx\", (string) The hash of current highest block\n" {
" \"transactions\" : [ (json array) contents of non-coinbase transactions that should be included in the next block\n" {RPCResult::Type::NUM, "rulename", "identifies the bit number as indicating acceptance and readiness for the named softfork rule"},
" {\n" }},
" \"data\" : \"xxxx\", (string) transaction data encoded in hexadecimal (byte-for-byte)\n" {RPCResult::Type::NUM, "vbrequired", "bit mask of versionbits the server requires set in submissions"},
" \"txid\" : \"xxxx\", (string) transaction id encoded in little-endian hexadecimal\n" {RPCResult::Type::STR, "previousblockhash", "The hash of current highest block"},
" \"hash\" : \"xxxx\", (string) hash encoded in little-endian hexadecimal (including witness data)\n" {RPCResult::Type::ARR, "", "contents of non-coinbase transactions that should be included in the next block",
" \"depends\" : [ (json array) array of numbers \n" {
" n (numeric) transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is\n" {RPCResult::Type::OBJ, "", "",
" ,...\n" {
" ],\n" {RPCResult::Type::STR_HEX, "data", "transaction data encoded in hexadecimal (byte-for-byte)"},
" \"fee\" : n, (numeric) difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one\n" {RPCResult::Type::STR_HEX, "txid", "transaction id encoded in little-endian hexadecimal"},
" \"sigops\" : n, (numeric) total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero\n" {RPCResult::Type::STR_HEX, "hash", "hash encoded in little-endian hexadecimal (including witness data)"},
" \"weight\" : n, (numeric) total transaction weight, as counted for purposes of block limits\n" {RPCResult::Type::ARR, "depends", "array of numbers",
" }\n" {
" ,...\n" {RPCResult::Type::NUM, "", "transactions before this one (by 1-based index in 'transactions' list) that must be present in the final block if this one is"},
" ],\n" }},
" \"coinbaseaux\" : { ... }, (json object) data that should be included in the coinbase's scriptSig content\n" {RPCResult::Type::NUM, "fee", "difference in value between transaction inputs and outputs (in satoshis); for coinbase transactions, this is a negative Number of the total collected block fees (ie, not including the block subsidy); if key is not present, fee is unknown and clients MUST NOT assume there isn't one"},
" \"coinbasevalue\" : n, (numeric) maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)\n" {RPCResult::Type::NUM, "sigops", "total SigOps cost, as counted for purposes of block limits; if key is not present, sigop cost is unknown and clients MUST NOT assume it is zero"},
" \"coinbasetxn\" : { ... }, (json object) information for coinbase transaction\n" {RPCResult::Type::NUM, "weight", "total transaction weight, as counted for purposes of block limits"},
" \"target\" : \"xxxx\", (string) The hash target\n" }},
" \"mintime\" : xxx, (numeric) The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME + "\n" }},
" \"mutable\" : [ (array of string) list of ways the block template may be changed \n" {RPCResult::Type::OBJ, "coinbaseaux", "data that should be included in the coinbase's scriptSig content",
" \"value\" (string) A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'\n" {
" ,...\n" {RPCResult::Type::ELISION, "", ""},
" ],\n" }},
" \"noncerange\" : \"00000000ffffffff\",(string) A range of valid nonces\n" {RPCResult::Type::NUM, "coinbasevalue", "maximum allowable input to coinbase transaction, including the generation award and transaction fees (in satoshis)"},
" \"sigoplimit\" : n, (numeric) limit of sigops in blocks\n" {RPCResult::Type::OBJ, "coinbasetxn", "information for coinbase transaction",
" \"sizelimit\" : n, (numeric) limit of block size\n" {
" \"weightlimit\" : n, (numeric) limit of block weight\n" {RPCResult::Type::ELISION, "", ""},
" \"curtime\" : ttt, (numeric) current timestamp in " + UNIX_EPOCH_TIME + "\n" }},
" \"bits\" : \"xxxxxxxx\", (string) compressed target of next block\n" {RPCResult::Type::STR, "target", "The hash target"},
" \"height\" : n (numeric) The height of the next block\n" {RPCResult::Type::NUM_TIME, "mintime", "The minimum timestamp appropriate for the next block time, expressed in " + UNIX_EPOCH_TIME},
"}\n" {RPCResult::Type::ARR, "mutable", "list of ways the block template may be changed",
}, {
{RPCResult::Type::STR, "value", "A way the block template may be changed, e.g. 'time', 'transactions', 'prevblock'"},
}},
{RPCResult::Type::STR_HEX, "noncerange", "A range of valid nonces"},
{RPCResult::Type::NUM, "sigoplimit", "limit of sigops in blocks"},
{RPCResult::Type::NUM, "sizelimit", "limit of block size"},
{RPCResult::Type::NUM, "weightlimit", "limit of block weight"},
{RPCResult::Type::NUM_TIME, "curtime", "current timestamp in " + UNIX_EPOCH_TIME},
{RPCResult::Type::STR, "bits", "compressed target of next block"},
{RPCResult::Type::NUM, "height", "The height of the next block"},
}},
RPCExamples{ RPCExamples{
HelpExampleCli("getblocktemplate", "'{\"rules\": [\"segwit\"]}'") HelpExampleCli("getblocktemplate", "'{\"rules\": [\"segwit\"]}'")
+ HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}") + HelpExampleRpc("getblocktemplate", "{\"rules\": [\"segwit\"]}")
@ -799,8 +813,7 @@ static UniValue submitheader(const JSONRPCRequest& request)
{"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"}, {"hexdata", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded block header data"},
}, },
RPCResult{ RPCResult{
"None" RPCResult::Type::NONE, "", "None"},
},
RPCExamples{ RPCExamples{
HelpExampleCli("submitheader", "\"aabbcc\"") + HelpExampleCli("submitheader", "\"aabbcc\"") +
HelpExampleRpc("submitheader", "\"aabbcc\"") HelpExampleRpc("submitheader", "\"aabbcc\"")
@ -847,17 +860,19 @@ static UniValue estimatesmartfee(const JSONRPCRequest& request)
" \"CONSERVATIVE\""}, " \"CONSERVATIVE\""},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"feerate\" : x.x, (numeric, optional) estimate fee rate in " + CURRENCY_UNIT + "/kB\n" {
" \"errors\" : [ str... ] (json array of strings, optional) Errors encountered during processing\n" {RPCResult::Type::NUM, "feerate", /* optional */ true, "estimate fee rate in " + CURRENCY_UNIT + "/kB (only present if no errors were encountered)"},
" \"blocks\" : n (numeric) block number where estimate was found\n" {RPCResult::Type::ARR, "errors", "Errors encountered during processing",
"}\n" {
"\n" {RPCResult::Type::STR, "", "error"},
}},
{RPCResult::Type::NUM, "blocks", "block number where estimate was found\n"
"The request target will be clamped between 2 and the highest target\n" "The request target will be clamped between 2 and the highest target\n"
"fee estimation is able to return based on how long it has been running.\n" "fee estimation is able to return based on how long it has been running.\n"
"An error is returned if not enough transactions and blocks\n" "An error is returned if not enough transactions and blocks\n"
"have been observed to make an estimate for any number of blocks.\n" "have been observed to make an estimate for any number of blocks."},
}, }},
RPCExamples{ RPCExamples{
HelpExampleCli("estimatesmartfee", "6") HelpExampleCli("estimatesmartfee", "6")
}, },
@ -907,36 +922,40 @@ static UniValue estimaterawfee(const JSONRPCRequest& request)
" lower buckets."}, " lower buckets."},
}, },
RPCResult{ RPCResult{
"{ (json object) Results are returned for any horizon which tracks blocks up to the confirmation target\n" RPCResult::Type::OBJ, "", "Results are returned for any horizon which tracks blocks up to the confirmation target",
" \"short\" : { (json object, optional) estimate for short time horizon\n" {
" \"feerate\" : x.x, (numeric, optional) estimate fee rate in " + CURRENCY_UNIT + "/kB\n" {RPCResult::Type::OBJ, "short", /* optional */ true, "estimate for short time horizon",
" \"decay\" : x.x, (numeric) exponential decay (per block) for historical moving average of confirmation data\n" {
" \"scale\" : x, (numeric) The resolution of confirmation targets at this time horizon\n" {RPCResult::Type::NUM, "feerate", /* optional */ true, "estimate fee rate in " + CURRENCY_UNIT + "/kB"},
" \"pass\" : { (json object, optional) information about the lowest range of feerates to succeed in meeting the threshold\n" {RPCResult::Type::NUM, "decay", "exponential decay (per block) for historical moving average of confirmation data"},
" \"startrange\" : x.x, (numeric) start of feerate range\n" {RPCResult::Type::NUM, "scale", "The resolution of confirmation targets at this time horizon"},
" \"endrange\" : x.x, (numeric) end of feerate range\n" {RPCResult::Type::OBJ, "pass", /* optional */ true, "information about the lowest range of feerates to succeed in meeting the threshold",
" \"withintarget\" : x.x, (numeric) number of txs over history horizon in the feerate range that were confirmed within target\n" {
" \"totalconfirmed\" : x.x, (numeric) number of txs over history horizon in the feerate range that were confirmed at any point\n" {RPCResult::Type::NUM, "startrange", "start of feerate range"},
" \"inmempool\" : x.x, (numeric) current number of txs in mempool in the feerate range unconfirmed for at least target blocks\n" {RPCResult::Type::NUM, "endrange", "end of feerate range"},
" \"leftmempool\" : x.x, (numeric) number of txs over history horizon in the feerate range that left mempool unconfirmed after target\n" {RPCResult::Type::NUM, "withintarget", "number of txs over history horizon in the feerate range that were confirmed within target"},
" },\n" {RPCResult::Type::NUM, "totalconfirmed", "number of txs over history horizon in the feerate range that were confirmed at any point"},
" \"fail\" : { (json object, optional) information about the highest range of feerates to fail to meet the threshold\n" {RPCResult::Type::NUM, "inmempool", "current number of txs in mempool in the feerate range unconfirmed for at least target blocks"},
" ...\n" {RPCResult::Type::NUM, "leftmempool", "number of txs over history horizon in the feerate range that left mempool unconfirmed after target"},
" },\n" }},
" \"errors\" : [ (json array, optional) Errors encountered during processing\n" {RPCResult::Type::OBJ, "fail", /* optional */ true, "information about the highest range of feerates to fail to meet the threshold",
" \"str\", (string)\n" {
" ...\n" {RPCResult::Type::ELISION, "", ""},
" ],\n" }},
" },\n" {RPCResult::Type::ARR, "errors", /* optional */ true, "Errors encountered during processing",
" \"medium\" : { (json object, optional) estimate for medium time horizon\n" {
" ...\n" {RPCResult::Type::STR, "error", ""},
" },\n" }},
" \"long\" : { (json object, optional) estimate for long time horizon\n" }},
" ...\n" {RPCResult::Type::OBJ, "medium", /* optional */ true, "estimate for medium time horizon",
" },\n" {
"}\n" {RPCResult::Type::ELISION, "", ""},
"\n" }},
}, {RPCResult::Type::OBJ, "long", /* optional */ true, "estimate for long time horizon",
{
{RPCResult::Type::ELISION, "", ""},
}},
}},
RPCExamples{ RPCExamples{
HelpExampleCli("estimaterawfee", "6 0.9") HelpExampleCli("estimaterawfee", "6 0.9")
}, },

View file

@ -33,15 +33,16 @@ static UniValue validateaddress(const JSONRPCRequest& request)
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to validate"}, {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to validate"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"isvalid\" : true|false, (boolean) If the address is valid or not. If not, this is the only property returned.\n" {
" \"address\" : \"address\", (string) The bitcoin address validated\n" {RPCResult::Type::BOOL, "isvalid", "If the address is valid or not. If not, this is the only property returned."},
" \"scriptPubKey\" : \"hex\", (string) The hex-encoded scriptPubKey generated by the address\n" {RPCResult::Type::STR, "address", "The bitcoin address validated"},
" \"isscript\" : true|false, (boolean) If the key is a script\n" {RPCResult::Type::STR_HEX, "scriptPubKey", "The hex-encoded scriptPubKey generated by the address"},
" \"iswitness\" : true|false, (boolean) If the address is a witness address\n" {RPCResult::Type::BOOL, "isscript", "If the key is a script"},
" \"witness_version\" : version (numeric, optional) The version number of the witness program\n" {RPCResult::Type::BOOL, "iswitness", "If the address is a witness address"},
" \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program\n" {RPCResult::Type::NUM, "witness_version", /* optional */ true, "The version number of the witness program"},
"}\n" {RPCResult::Type::STR_HEX, "witness_program", /* optional */ true, "The hex value of the witness program"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("validateaddress", EXAMPLE_ADDRESS) + HelpExampleCli("validateaddress", EXAMPLE_ADDRESS) +
@ -82,11 +83,12 @@ static UniValue createmultisig(const JSONRPCRequest& request)
{"address_type", RPCArg::Type::STR, /* default */ "legacy", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."}, {"address_type", RPCArg::Type::STR, /* default */ "legacy", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"address\" : \"multisigaddress\", (string) The value of the new multisig address.\n" {
" \"redeemScript\" : \"script\" (string) The string value of the hex-encoded redemption script.\n" {RPCResult::Type::STR, "address", "The value of the new multisig address."},
" \"descriptor\" : \"descriptor\" (string) The descriptor for this multisig\n" {RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script."},
"}\n" {RPCResult::Type::STR, "descriptor", "The descriptor for this multisig"},
}
}, },
RPCExamples{ RPCExamples{
"\nCreate a multisig address from 2 public keys\n" "\nCreate a multisig address from 2 public keys\n"
@ -141,13 +143,14 @@ UniValue getdescriptorinfo(const JSONRPCRequest& request)
{"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor."}, {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"descriptor\" : \"desc\", (string) The descriptor in canonical form, without private keys\n" {
" \"checksum\" : \"chksum\", (string) The checksum for the input descriptor\n" {RPCResult::Type::STR, "descriptor", "The descriptor in canonical form, without private keys"},
" \"isrange\" : true|false, (boolean) Whether the descriptor is ranged\n" {RPCResult::Type::STR, "checksum", "The checksum for the input descriptor"},
" \"issolvable\" : true|false, (boolean) Whether the descriptor is solvable\n" {RPCResult::Type::BOOL, "isrange", "Whether the descriptor is ranged"},
" \"hasprivatekeys\" : true|false, (boolean) Whether the input descriptor contained at least one private key\n" {RPCResult::Type::BOOL, "issolvable", "Whether the descriptor is solvable"},
"}\n" {RPCResult::Type::BOOL, "hasprivatekeys", "Whether the input descriptor contained at least one private key"},
}
}, },
RPCExamples{ RPCExamples{
"Analyse a descriptor\n" + "Analyse a descriptor\n" +
@ -189,7 +192,10 @@ UniValue deriveaddresses(const JSONRPCRequest& request)
{"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."}, {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."},
}, },
RPCResult{ RPCResult{
"[ address ] (json array) the derived addresses\n" RPCResult::Type::ARR, "", "",
{
{RPCResult::Type::STR, "address", "the derived addresses"},
}
}, },
RPCExamples{ RPCExamples{
"First three native segwit receive addresses\n" + "First three native segwit receive addresses\n" +
@ -258,7 +264,7 @@ static UniValue verifymessage(const JSONRPCRequest& request)
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."}, {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."},
}, },
RPCResult{ RPCResult{
"true|false (boolean) If the signature is verified or not.\n" RPCResult::Type::BOOL, "", "If the signature is verified or not."
}, },
RPCExamples{ RPCExamples{
"\nUnlock the wallet for 30 seconds\n" "\nUnlock the wallet for 30 seconds\n"
@ -304,7 +310,7 @@ static UniValue signmessagewithprivkey(const JSONRPCRequest& request)
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
}, },
RPCResult{ RPCResult{
"\"signature\" (string) The signature of the message encoded in base 64\n" RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
}, },
RPCExamples{ RPCExamples{
"\nCreate the signature\n" "\nCreate the signature\n"
@ -437,19 +443,21 @@ static UniValue getmemoryinfo(const JSONRPCRequest& request)
}, },
{ {
RPCResult{"mode \"stats\"", RPCResult{"mode \"stats\"",
"{\n" RPCResult::Type::OBJ, "", "",
" \"locked\" : { (json object) Information about locked memory manager\n" {
" \"used\" : xxxxx, (numeric) Number of bytes used\n" {RPCResult::Type::OBJ, "locked", "Information about locked memory manager",
" \"free\" : xxxxx, (numeric) Number of bytes available in current arenas\n" {
" \"total\" : xxxxxxx, (numeric) Total number of bytes managed\n" {RPCResult::Type::NUM, "used", "Number of bytes used"},
" \"locked\" : xxxxxx, (numeric) Amount of bytes that succeeded locking. If this number is smaller than total, locking pages failed at some point and key data could be swapped to disk.\n" {RPCResult::Type::NUM, "free", "Number of bytes available in current arenas"},
" \"chunks_used\" : xxxxx, (numeric) Number allocated chunks\n" {RPCResult::Type::NUM, "total", "Total number of bytes managed"},
" \"chunks_free\" : xxxxx, (numeric) Number unused chunks\n" {RPCResult::Type::NUM, "locked", "Amount of bytes that succeeded locking. If this number is smaller than total, locking pages failed at some point and key data could be swapped to disk."},
" }\n" {RPCResult::Type::NUM, "chunks_used", "Number allocated chunks"},
"}\n" {RPCResult::Type::NUM, "chunks_free", "Number unused chunks"},
}},
}
}, },
RPCResult{"mode \"mallocinfo\"", RPCResult{"mode \"mallocinfo\"",
"\"<malloc version=\"1\">...\"\n" RPCResult::Type::STR, "", "\"<malloc version=\"1\">...\""
}, },
}, },
RPCExamples{ RPCExamples{
@ -516,10 +524,10 @@ UniValue logging(const JSONRPCRequest& request)
}}, }},
}, },
RPCResult{ RPCResult{
"{ (json object where keys are the logging categories, and values indicates its status\n" RPCResult::Type::OBJ_DYN, "", "keys are the logging categories, and values indicates its status",
" \"category\" : true|false, (boolean) if being debug logged or not. false:inactive, true:active\n" {
" ...\n" {RPCResult::Type::BOOL, "category", "if being debug logged or not. false:inactive, true:active"},
"}\n" }
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"") HelpExampleCli("logging", "\"[\\\"all\\\"]\" \"[\\\"http\\\"]\"")

View file

@ -33,7 +33,7 @@ static UniValue getconnectioncount(const JSONRPCRequest& request)
"\nReturns the number of connections to other nodes.\n", "\nReturns the number of connections to other nodes.\n",
{}, {},
RPCResult{ RPCResult{
"n (numeric) The connection count\n" RPCResult::Type::NUM, "", "The connection count"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getconnectioncount", "") HelpExampleCli("getconnectioncount", "")
@ -77,57 +77,59 @@ static UniValue getpeerinfo(const JSONRPCRequest& request)
"\nReturns data about each connected network node as a json array of objects.\n", "\nReturns data about each connected network node as a json array of objects.\n",
{}, {},
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"id\" : n, (numeric) Peer index\n" {RPCResult::Type::OBJ, "", "",
" \"addr\" : \"host:port\", (string) The IP address and port of the peer\n" {
" \"addrbind\" : \"ip:port\", (string) Bind address of the connection to the peer\n" {
" \"addrlocal\" : \"ip:port\", (string) Local address as reported by the peer\n" {RPCResult::Type::NUM, "id", "Peer index"},
" \"mapped_as\" : \"mapped_as\", (string) The AS in the BGP route to the peer used for diversifying peer selection\n" {RPCResult::Type::STR, "addr", "(host:port) The IP address and port of the peer"},
" \"services\" : \"xxxxxxxxxxxxxxxx\", (string) The services offered\n" {RPCResult::Type::STR, "addrbind", "(ip:port) Bind address of the connection to the peer"},
" \"servicesnames\" : [ (json array) the services offered, in human-readable form\n" {RPCResult::Type::STR, "addrlocal", "(ip:port) Local address as reported by the peer"},
" \"SERVICE_NAME\", (string) the service name if it is recognised\n" {RPCResult::Type::STR, "mapped_as", "The AS in the BGP route to the peer used for diversifying peer selection"},
" ...\n" {RPCResult::Type::STR_HEX, "services", "The services offered"},
" ],\n" {RPCResult::Type::ARR, "servicesnames", "the services offered, in human-readable form",
" \"relaytxes\" : true|false, (boolean) Whether peer has asked us to relay transactions to it\n" {
" \"lastsend\" : ttt, (numeric) The " + UNIX_EPOCH_TIME + " of the last send\n" {RPCResult::Type::STR, "SERVICE_NAME", "the service name if it is recognised"}
" \"lastrecv\" : ttt, (numeric) The " + UNIX_EPOCH_TIME + " of the last receive\n" }},
" \"bytessent\" : n, (numeric) The total bytes sent\n" {RPCResult::Type::BOOL, "relaytxes", "Whether peer has asked us to relay transactions to it"},
" \"bytesrecv\" : n, (numeric) The total bytes received\n" {RPCResult::Type::NUM_TIME, "lastsend", "The " + UNIX_EPOCH_TIME + " of the last send"},
" \"conntime\" : ttt, (numeric) The " + UNIX_EPOCH_TIME + " of the connection\n" {RPCResult::Type::NUM_TIME, "lastrecv", "The " + UNIX_EPOCH_TIME + " of the last receive"},
" \"timeoffset\" : ttt, (numeric) The time offset in seconds\n" {RPCResult::Type::NUM, "bytessent", "The total bytes sent"},
" \"pingtime\" : n, (numeric) ping time (if available)\n" {RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
" \"minping\" : n, (numeric) minimum observed ping time (if any at all)\n" {RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
" \"pingwait\" : n, (numeric) ping wait (if non-zero)\n" {RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
" \"version\" : v, (numeric) The peer version, such as 70001\n" {RPCResult::Type::NUM, "pingtime", "ping time (if available)"},
" \"subver\" : \"/Satoshi:0.8.5/\", (string) The string version\n" {RPCResult::Type::NUM, "minping", "minimum observed ping time (if any at all)"},
" \"inbound\" : true|false, (boolean) Inbound (true) or Outbound (false)\n" {RPCResult::Type::NUM, "pingwait", "ping wait (if non-zero)"},
" \"addnode\" : true|false, (boolean) Whether connection was due to addnode/-connect or if it was an automatic/inbound connection\n" {RPCResult::Type::NUM, "version", "The peer version, such as 70001"},
" \"startingheight\" : n, (numeric) The starting height (block) of the peer\n" {RPCResult::Type::STR, "subver", "The string version"},
" \"banscore\" : n, (numeric) The ban score\n" {RPCResult::Type::BOOL, "inbound", "Inbound (true) or Outbound (false)"},
" \"synced_headers\" : n, (numeric) The last header we have in common with this peer\n" {RPCResult::Type::BOOL, "addnode", "Whether connection was due to addnode/-connect or if it was an automatic/inbound connection"},
" \"synced_blocks\" : n, (numeric) The last block we have in common with this peer\n" {RPCResult::Type::NUM, "startingheight", "The starting height (block) of the peer"},
" \"inflight\" : [\n" {RPCResult::Type::NUM, "banscore", "The ban score"},
" n, (numeric) The heights of blocks we're currently asking from this peer\n" {RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
" ...\n" {RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
" ],\n" {RPCResult::Type::ARR, "inflight", "",
" \"whitelisted\" : true|false, (boolean) Whether the peer is whitelisted\n" {
" \"minfeefilter\" : n, (numeric) The minimum fee rate for transactions this peer accepts\n" {RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
" \"bytessent_per_msg\" : {\n" }},
" \"msg\" : n, (numeric) The total bytes sent aggregated by message type\n" {RPCResult::Type::BOOL, "whitelisted", "Whether the peer is whitelisted"},
" When a message type is not listed in this json object, the bytes sent are 0.\n" {RPCResult::Type::NUM, "minfeefilter", "The minimum fee rate for transactions this peer accepts"},
" Only known message types can appear as keys in the object.\n" {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "",
" ...\n" {
" },\n" {RPCResult::Type::NUM, "msg", "The total bytes sent aggregated by message type\n"
" \"bytesrecv_per_msg\" : {\n" "When a message type is not listed in this json object, the bytes sent are 0.\n"
" \"msg\" : n, (numeric) The total bytes received aggregated by message type\n" "Only known message types can appear as keys in the object."}
" When a message type is not listed in this json object, the bytes received are 0.\n" }},
" Only known message types can appear as keys in the object and all bytes received of unknown message types are listed under '"+NET_MESSAGE_COMMAND_OTHER+"'.\n" {RPCResult::Type::OBJ, "bytesrecv_per_msg", "",
" ...\n" {
" }\n" {RPCResult::Type::NUM, "msg", "The total bytes received aggregated by message type\n"
" }\n" "When a message type is not listed in this json object, the bytes received are 0.\n"
" ,...\n" "Only known message types can appear as keys in the object and all bytes received of unknown message types are listed under '"+NET_MESSAGE_COMMAND_OTHER+"'."}
"]\n" }},
}},
}},
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getpeerinfo", "") HelpExampleCli("getpeerinfo", "")
@ -320,19 +322,22 @@ static UniValue getaddednodeinfo(const JSONRPCRequest& request)
{"node", RPCArg::Type::STR, /* default */ "all nodes", "If provided, return information about this specific node, otherwise all nodes are returned."}, {"node", RPCArg::Type::STR, /* default */ "all nodes", "If provided, return information about this specific node, otherwise all nodes are returned."},
}, },
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"addednode\" : \"192.168.0.201\", (string) The node IP address or name (as provided to addnode)\n" {RPCResult::Type::OBJ, "", "",
" \"connected\" : true|false, (boolean) If connected\n" {
" \"addresses\" : [ (list of objects) Only when connected = true\n" {RPCResult::Type::STR, "addednode", "The node IP address or name (as provided to addnode)"},
" {\n" {RPCResult::Type::BOOL, "connected", "If connected"},
" \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server IP and port we're connected to\n" {RPCResult::Type::ARR, "addresses", "Only when connected = true",
" \"connected\" : \"outbound\" (string) connection, inbound or outbound\n" {
" }\n" {RPCResult::Type::OBJ, "", "",
" ]\n" {
" }\n" {RPCResult::Type::STR, "address", "The bitcoin server IP and port we're connected to"},
" ,...\n" {RPCResult::Type::STR, "connected", "connection, inbound or outbound"},
"]\n" }},
}},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"") HelpExampleCli("getaddednodeinfo", "\"192.168.0.201\"")
@ -386,20 +391,21 @@ static UniValue getnettotals(const JSONRPCRequest& request)
"and current time.\n", "and current time.\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"totalbytesrecv\" : n, (numeric) Total bytes received\n" {
" \"totalbytessent\" : n, (numeric) Total bytes sent\n" {RPCResult::Type::NUM, "totalbytesrecv", "Total bytes received"},
" \"timemillis\" : t, (numeric) Current UNIX time in milliseconds\n" {RPCResult::Type::NUM, "totalbytessent", "Total bytes sent"},
" \"uploadtarget\" : \n" {RPCResult::Type::NUM_TIME, "timemillis", "Current UNIX time in milliseconds"},
" {\n" {RPCResult::Type::OBJ, "uploadtarget", "",
" \"timeframe\" : n, (numeric) Length of the measuring timeframe in seconds\n" {
" \"target\" : n, (numeric) Target in bytes\n" {RPCResult::Type::NUM, "timeframe", "Length of the measuring timeframe in seconds"},
" \"target_reached\" : true|false, (boolean) True if target is reached\n" {RPCResult::Type::NUM, "target", "Target in bytes"},
" \"serve_historical_blocks\" : true|false, (boolean) True if serving historical blocks\n" {RPCResult::Type::BOOL, "target_reached", "True if target is reached"},
" \"bytes_left_in_cycle\" : t, (numeric) Bytes left in current time cycle\n" {RPCResult::Type::BOOL, "serve_historical_blocks", "True if serving historical blocks"},
" \"time_left_in_cycle\" : t (numeric) Seconds left in current time cycle\n" {RPCResult::Type::NUM, "bytes_left_in_cycle", "Bytes left in current time cycle"},
" }\n" {RPCResult::Type::NUM, "time_left_in_cycle", "Seconds left in current time cycle"},
"}\n" }},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getnettotals", "") HelpExampleCli("getnettotals", "")
@ -452,41 +458,44 @@ static UniValue getnetworkinfo(const JSONRPCRequest& request)
"Returns an object containing various state info regarding P2P networking.\n", "Returns an object containing various state info regarding P2P networking.\n",
{}, {},
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"version\" : xxxxx, (numeric) the server version\n" {
" \"subversion\" : \"str\", (string) the server subversion string\n" {RPCResult::Type::NUM, "version", "the server version"},
" \"protocolversion\" : xxxxx, (numeric) the protocol version\n" {RPCResult::Type::STR, "subversion", "the server subversion string"},
" \"localservices\" : \"hex\", (string) the services we offer to the network\n" {RPCResult::Type::NUM, "protocolversion", "the protocol version"},
" \"localservicesnames\" : [ (json array) the services we offer to the network, in human-readable form\n" {RPCResult::Type::STR_HEX, "localservices", "the services we offer to the network"},
" \"SERVICE_NAME\", (string) the service name\n" {RPCResult::Type::ARR, "localservicesnames", "the services we offer to the network, in human-readable form",
" ...\n" {
" ],\n" {RPCResult::Type::STR, "SERVICE_NAME", "the service name"},
" \"localrelay\" : true|false, (boolean) true if transaction relay is requested from peers\n" }},
" \"timeoffset\" : xxxxx, (numeric) the time offset\n" {RPCResult::Type::BOOL, "localrelay", "true if transaction relay is requested from peers"},
" \"connections\" : xxxxx, (numeric) the number of connections\n" {RPCResult::Type::NUM, "timeoffset", "the time offset"},
" \"networkactive\" : true|false, (boolean) whether p2p networking is enabled\n" {RPCResult::Type::NUM, "connections", "the number of connections"},
" \"networks\" : [ (json array) information per network\n" {RPCResult::Type::BOOL, "networkactive", "whether p2p networking is enabled"},
" { (json object)\n" {RPCResult::Type::ARR, "networks", "information per network",
" \"name\" : \"str\", (string) network (ipv4, ipv6 or onion)\n" {
" \"limited\" : true|false, (boolean) is the network limited using -onlynet?\n" {RPCResult::Type::OBJ, "", "",
" \"reachable\" : true|false, (boolean) is the network reachable?\n" {
" \"proxy\" : \"str\" (string) (\"host:port\") the proxy that is used for this network, or empty if none\n" {RPCResult::Type::STR, "name", "network (ipv4, ipv6 or onion)"},
" \"proxy_randomize_credentials\" : true|false, (boolean) Whether randomized credentials are used\n" {RPCResult::Type::BOOL, "limited", "is the network limited using -onlynet?"},
" },\n" {RPCResult::Type::BOOL, "reachable", "is the network reachable?"},
" ...\n" {RPCResult::Type::STR, "proxy", "(\"host:port\") the proxy that is used for this network, or empty if none"},
" ],\n" {RPCResult::Type::BOOL, "proxy_randomize_credentials", "Whether randomized credentials are used"},
" \"relayfee\" : x.xxxxxxxx, (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB\n" }},
" \"incrementalfee\" : x.xxxxxxxx, (numeric) minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB\n" }},
" \"localaddresses\" : [ (json array) list of local addresses\n" {RPCResult::Type::NUM, "relayfee", "minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB"},
" { (json object)\n" {RPCResult::Type::NUM, "incrementalfee", "minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB"},
" \"address\" : \"xxxx\", (string) network address\n" {RPCResult::Type::ARR, "localaddresses", "list of local addresses",
" \"port\" : xxx, (numeric) network port\n" {
" \"score\" : xxx (numeric) relative score\n" {RPCResult::Type::OBJ, "", "",
" },\n" {
" ...\n" {RPCResult::Type::STR, "address", "network address"},
" ],\n" {RPCResult::Type::NUM, "port", "network port"},
" \"warnings\" : \"str\", (string) any network and blockchain warnings\n" {RPCResult::Type::NUM, "score", "relative score"},
"}\n" }},
}},
{RPCResult::Type::STR, "warnings", "any network and blockchain warnings"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getnetworkinfo", "") HelpExampleCli("getnetworkinfo", "")
@ -693,15 +702,16 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
{"count", RPCArg::Type::NUM, /* default */ "1", "How many addresses to return. Limited to the smaller of " + std::to_string(ADDRMAN_GETADDR_MAX) + " or " + std::to_string(ADDRMAN_GETADDR_MAX_PCT) + "% of all known addresses."}, {"count", RPCArg::Type::NUM, /* default */ "1", "How many addresses to return. Limited to the smaller of " + std::to_string(ADDRMAN_GETADDR_MAX) + " or " + std::to_string(ADDRMAN_GETADDR_MAX_PCT) + "% of all known addresses."},
}, },
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"time\" : ttt, (numeric) The " + UNIX_EPOCH_TIME + " of when the node was last seen\n" {RPCResult::Type::OBJ, "", "",
" \"services\" : n, (numeric) The services offered\n" {
" \"address\" : \"host\", (string) The address of the node\n" {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " of when the node was last seen"},
" \"port\" : n (numeric) The port of the node\n" {RPCResult::Type::NUM, "services", "The services offered"},
" }\n" {RPCResult::Type::STR, "address", "The address of the node"},
" ,....\n" {RPCResult::Type::NUM, "port", "The port of the node"},
"]\n" }},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getnodeaddresses", "8") HelpExampleCli("getnodeaddresses", "8")

View file

@ -94,54 +94,62 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
}, },
{ {
RPCResult{"if verbose is not set or set to false", RPCResult{"if verbose is not set or set to false",
"\"data\" (string) The serialized, hex-encoded data for 'txid'\n" RPCResult::Type::STR, "data", "The serialized, hex-encoded data for 'txid'"
}, },
RPCResult{"if verbose is set to true", RPCResult{"if verbose is set to true",
"{\n" RPCResult::Type::OBJ, "", "",
" \"in_active_chain\" : b, (boolean) Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)\n" {
" \"hex\" : \"data\", (string) The serialized, hex-encoded data for 'txid'\n" {RPCResult::Type::BOOL, "in_active_chain", "Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)"},
" \"txid\" : \"id\", (string) The transaction id (same as provided)\n" {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded data for 'txid'"},
" \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id (same as provided)"},
" \"size\" : n, (numeric) The serialized transaction size\n" {RPCResult::Type::STR_HEX, "hash", "The transaction hash (differs from txid for witness transactions)"},
" \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n" {RPCResult::Type::NUM, "size", "The serialized transaction size"},
" \"weight\" : n, (numeric) The transaction's weight (between vsize*4-3 and vsize*4)\n" {RPCResult::Type::NUM, "vsize", "The virtual transaction size (differs from size for witness transactions)"},
" \"version\" : n, (numeric) The version\n" {RPCResult::Type::NUM, "weight", "The transaction's weight (between vsize*4-3 and vsize*4)"},
" \"locktime\" : ttt, (numeric) The lock time\n" {RPCResult::Type::NUM, "version", "The version"},
" \"vin\" : [ (array of json objects)\n" {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
" {\n" {RPCResult::Type::ARR, "vin", "",
" \"txid\" : \"id\", (string) The transaction id\n" {
" \"vout\" : n, (numeric) \n" {RPCResult::Type::OBJ, "", "",
" \"scriptSig\" : { (json object) The script\n" {
" \"asm\" : \"asm\", (string) asm\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
" \"hex\" : \"hex\" (string) hex\n" {RPCResult::Type::STR, "vout", ""},
" },\n" {RPCResult::Type::OBJ, "scriptSig", "The script",
" \"sequence\" : n (numeric) The script sequence number\n" {
" \"txinwitness\" : [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n" {RPCResult::Type::STR, "asm", "asm"},
" }\n" {RPCResult::Type::STR_HEX, "hex", "hex"},
" ,...\n" }},
" ],\n" {RPCResult::Type::NUM, "sequence", "The script sequence number"},
" \"vout\" : [ (array of json objects)\n" {RPCResult::Type::ARR, "txinwitness", "",
" {\n" {
" \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" {RPCResult::Type::STR_HEX, "hex", "hex-encoded witness data (if any)"},
" \"n\" : n, (numeric) index\n" }},
" \"scriptPubKey\" : { (json object)\n" }},
" \"asm\" : \"asm\", (string) the asm\n" }},
" \"hex\" : \"hex\", (string) the hex\n" {RPCResult::Type::ARR, "vout", "",
" \"reqSigs\" : n, (numeric) The required sigs\n" {
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" {RPCResult::Type::OBJ, "", "",
" \"addresses\" : [ (json array of string)\n" {
" \"address\" (string) bitcoin address\n" {RPCResult::Type::NUM, "value", "The value in " + CURRENCY_UNIT},
" ,...\n" {RPCResult::Type::NUM, "n", "index"},
" ]\n" {RPCResult::Type::OBJ, "scriptPubKey", "",
" }\n" {
" }\n" {RPCResult::Type::STR, "asm", "the asm"},
" ,...\n" {RPCResult::Type::STR, "hex", "the hex"},
" ],\n" {RPCResult::Type::NUM, "reqSigs", "The required sigs"},
" \"blockhash\" : \"hash\", (string) the block hash\n" {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
" \"confirmations\" : n, (numeric) The confirmations\n" {RPCResult::Type::ARR, "addresses", "",
" \"blocktime\" : ttt (numeric) The block time expressed in " + UNIX_EPOCH_TIME + "\n" {
" \"time\" : ttt, (numeric) Same as \"blocktime\"\n" {RPCResult::Type::STR, "address", "bitcoin address"},
"}\n" }},
}},
}},
}},
{RPCResult::Type::STR_HEX, "blockhash", "the block hash"},
{RPCResult::Type::NUM, "confirmations", "The confirmations"},
{RPCResult::Type::NUM_TIME, "blocktime", "The block time expressed in " + UNIX_EPOCH_TIME},
{RPCResult::Type::NUM, "time", "Same as \"blocktime\""},
}
}, },
}, },
RPCExamples{ RPCExamples{
@ -230,7 +238,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
{"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "If specified, looks for txid in the block with this hash"}, {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED_NAMED_ARG, "If specified, looks for txid in the block with this hash"},
}, },
RPCResult{ RPCResult{
"\"data\" (string) A string that is a serialized, hex-encoded data for the proof.\n" RPCResult::Type::STR, "data", "A string that is a serialized, hex-encoded data for the proof."
}, },
RPCExamples{""}, RPCExamples{""},
}.Check(request); }.Check(request);
@ -315,7 +323,10 @@ static UniValue verifytxoutproof(const JSONRPCRequest& request)
{"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded proof generated by gettxoutproof"}, {"proof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex-encoded proof generated by gettxoutproof"},
}, },
RPCResult{ RPCResult{
"[\"txid\"] (array, strings) The txid(s) which the proof commits to, or empty array if the proof can not be validated.\n" RPCResult::Type::ARR, "", "",
{
{RPCResult::Type::STR_HEX, "txid", "The txid(s) which the proof commits to, or empty array if the proof can not be validated."},
}
}, },
RPCExamples{""}, RPCExamples{""},
}.Check(request); }.Check(request);
@ -390,7 +401,7 @@ static UniValue createrawtransaction(const JSONRPCRequest& request)
" Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."}, " Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
}, },
RPCResult{ RPCResult{
"\"transaction\" (string) hex string of the transaction\n" RPCResult::Type::STR_HEX, "transaction", "hex string of the transaction"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"") HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"")
@ -432,45 +443,53 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
}, },
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"txid\" : \"id\", (string) The transaction id\n" {
" \"hash\" : \"id\", (string) The transaction hash (differs from txid for witness transactions)\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
" \"size\" : n, (numeric) The transaction size\n" {RPCResult::Type::STR_HEX, "hash", "The transaction hash (differs from txid for witness transactions)"},
" \"vsize\" : n, (numeric) The virtual transaction size (differs from size for witness transactions)\n" {RPCResult::Type::NUM, "size", "The transaction size"},
" \"weight\" : n, (numeric) The transaction's weight (between vsize*4 - 3 and vsize*4)\n" {RPCResult::Type::NUM, "vsize", "The virtual transaction size (differs from size for witness transactions)"},
" \"version\" : n, (numeric) The version\n" {RPCResult::Type::NUM, "weight", "The transaction's weight (between vsize*4 - 3 and vsize*4)"},
" \"locktime\" : ttt, (numeric) The lock time\n" {RPCResult::Type::NUM, "version", "The version"},
" \"vin\" : [ (array of json objects)\n" {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
" {\n" {RPCResult::Type::ARR, "vin", "",
" \"txid\" : \"id\", (string) The transaction id\n" {
" \"vout\" : n, (numeric) The output number\n" {RPCResult::Type::OBJ, "", "",
" \"scriptSig\" : { (json object) The script\n" {
" \"asm\" : \"asm\", (string) asm\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id"},
" \"hex\" : \"hex\" (string) hex\n" {RPCResult::Type::NUM, "vout", "The output number"},
" },\n" {RPCResult::Type::OBJ, "scriptSig", "The script",
" \"txinwitness\" : [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n" {
" \"sequence\" : n (numeric) The script sequence number\n" {RPCResult::Type::STR, "asm", "asm"},
" }\n" {RPCResult::Type::STR_HEX, "hex", "hex"},
" ,...\n" }},
" ],\n" {RPCResult::Type::ARR, "txinwitness", "",
" \"vout\" : [ (array of json objects)\n" {
" {\n" {RPCResult::Type::STR_HEX, "hex", "hex-encoded witness data (if any)"},
" \"value\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" }},
" \"n\" : n, (numeric) index\n" {RPCResult::Type::NUM, "sequence", "The script sequence number"},
" \"scriptPubKey\" : { (json object)\n" }},
" \"asm\" : \"asm\", (string) the asm\n" }},
" \"hex\" : \"hex\", (string) the hex\n" {RPCResult::Type::ARR, "vout", "",
" \"reqSigs\" : n, (numeric) The required sigs\n" {
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" {RPCResult::Type::OBJ, "", "",
" \"addresses\" : [ (json array of string)\n" {
" \"12tvKAXCxZjSmdNbao16dKXC8tRWfcF5oc\" (string) bitcoin address\n" {RPCResult::Type::NUM, "value", "The value in " + CURRENCY_UNIT},
" ,...\n" {RPCResult::Type::NUM, "n", "index"},
" ]\n" {RPCResult::Type::OBJ, "scriptPubKey", "",
" }\n" {
" }\n" {RPCResult::Type::STR, "asm", "the asm"},
" ,...\n" {RPCResult::Type::STR_HEX, "hex", "the hex"},
" ],\n" {RPCResult::Type::NUM, "reqSigs", "The required sigs"},
"}\n" {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
{RPCResult::Type::ARR, "addresses", "",
{
{RPCResult::Type::STR, "address", "bitcoin address"},
}},
}},
}},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("decoderawtransaction", "\"hexstring\"") HelpExampleCli("decoderawtransaction", "\"hexstring\"")
@ -513,26 +532,29 @@ static UniValue decodescript(const JSONRPCRequest& request)
{"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"}, {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"asm\" : \"asm\", (string) Script public key\n" {
" \"type\" : \"type\", (string) The output type (e.g. "+GetAllOutputTypes()+")\n" {RPCResult::Type::STR, "asm", "Script public key"},
" \"reqSigs\" : n, (numeric) The required signatures\n" {RPCResult::Type::STR, "type", "The output type (e.g. "+GetAllOutputTypes()+")"},
" \"addresses\" : [ (json array of string)\n" {RPCResult::Type::NUM, "reqSigs", "The required signatures"},
" \"address\" (string) bitcoin address\n" {RPCResult::Type::ARR, "addresses", "",
" ,...\n" {
" ],\n" {RPCResult::Type::STR, "address", "bitcoin address"},
" \"p2sh\":\"str\" (string) address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH).\n" }},
" \"segwit\" : { (json object) Result of a witness script public key wrapping this redeem script (not returned if the script is a P2SH or witness).\n" {RPCResult::Type::STR, "p2sh", "address of P2SH script wrapping this redeem script (not returned if the script is already a P2SH)"},
" \"asm\" : \"str\", (string) String representation of the script public key\n" {RPCResult::Type::OBJ, "segwit", "Result of a witness script public key wrapping this redeem script (not returned if the script is a P2SH or witness)",
" \"hex\" : \"hexstr\", (string) Hex string of the script public key\n" {
" \"type\" : \"str\", (string) The type of the script public key (e.g. witness_v0_keyhash or witness_v0_scripthash)\n" {RPCResult::Type::STR, "asm", "String representation of the script public key"},
" \"reqSigs\" : n, (numeric) The required signatures (always 1)\n" {RPCResult::Type::STR_HEX, "hex", "Hex string of the script public key"},
" \"addresses\" : [ (json array of string) (always length 1)\n" {RPCResult::Type::STR, "type", "The type of the script public key (e.g. witness_v0_keyhash or witness_v0_scripthash)"},
" \"address\" (string) segwit address\n" {RPCResult::Type::NUM, "reqSigs", "The required signatures (always 1)"},
" ,...\n" {RPCResult::Type::ARR, "addresses", "(always length 1)",
" ],\n" {
" \"p2sh-segwit\":\"str\" (string) address of the P2SH script wrapping this witness redeem script.\n" {RPCResult::Type::STR, "address", "segwit address"},
"}\n" }},
{RPCResult::Type::STR, "p2sh-segwit", "address of the P2SH script wrapping this witness redeem script"},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("decodescript", "\"hexstring\"") HelpExampleCli("decodescript", "\"hexstring\"")
@ -607,7 +629,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
}, },
}, },
RPCResult{ RPCResult{
"\"hex\" (string) The hex-encoded raw transaction with signature(s)\n" RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')") HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')")
@ -715,20 +737,22 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
}, },
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n" {
" \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"},
" \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n" {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
" {\n" {RPCResult::Type::ARR, "errors", "Script verification errors (if there are any)",
" \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n" {
" \"vout\" : n, (numeric) The index of the output to spent and used as input\n" {RPCResult::Type::OBJ, "", "",
" \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n" {
" \"sequence\" : n, (numeric) Script sequence number\n" {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"},
" \"error\" : \"text\" (string) Verification or signing error related to the input\n" {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"},
" }\n" {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"},
" ,...\n" {RPCResult::Type::NUM, "sequence", "Script sequence number"},
" ]\n" {RPCResult::Type::STR, "error", "Verification or signing error related to the input"},
"}\n" }},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"") HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"")
@ -784,7 +808,7 @@ static UniValue sendrawtransaction(const JSONRPCRequest& request)
"/kB.\nSet to 0 to accept any fee rate.\n"}, "/kB.\nSet to 0 to accept any fee rate.\n"},
}, },
RPCResult{ RPCResult{
"\"hex\" (string) The transaction hash in hex\n" RPCResult::Type::STR_HEX, "", "The transaction hash in hex"
}, },
RPCExamples{ RPCExamples{
"\nCreate a transaction\n" "\nCreate a transaction\n"
@ -846,14 +870,16 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
{"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK()), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"}, {"maxfeerate", RPCArg::Type::AMOUNT, /* default */ FormatMoney(DEFAULT_MAX_RAW_TX_FEE_RATE.GetFeePerK()), "Reject transactions whose fee rate is higher than the specified value, expressed in " + CURRENCY_UNIT + "/kB\n"},
}, },
RPCResult{ RPCResult{
"[ (json array) The result of the mempool acceptance test for each raw transaction in the input array.\n" RPCResult::Type::ARR, "", "The result of the mempool acceptance test for each raw transaction in the input array.\n"
" Length is exactly one for now.\n" "Length is exactly one for now.",
" {\n" {
" \"txid\" (string) The transaction hash in hex\n" {RPCResult::Type::OBJ, "", "",
" \"allowed\" (boolean) If the mempool allows this tx to be inserted\n" {
" \"reject-reason\" (string) Rejection string (only present when 'allowed' is false)\n" {RPCResult::Type::STR_HEX, "txid", "The transaction hash in hex"},
" }\n" {RPCResult::Type::BOOL, "allowed", "If the mempool allows this tx to be inserted"},
"]\n" {RPCResult::Type::STR, "reject-reason", "Rejection string (only present when 'allowed' is false)"},
}},
}
}, },
RPCExamples{ RPCExamples{
"\nCreate a transaction\n" "\nCreate a transaction\n"
@ -950,92 +976,108 @@ UniValue decodepsbt(const JSONRPCRequest& request)
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"}, {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"tx\" : { (json object) The decoded network-serialized unsigned transaction.\n" {
" ... The layout is the same as the output of decoderawtransaction.\n" {RPCResult::Type::OBJ, "tx", "The decoded network-serialized unsigned transaction.",
" },\n" {
" \"unknown\" : { (json object) The unknown global fields\n" {RPCResult::Type::ELISION, "", "The layout is the same as the output of decoderawtransaction."},
" \"key\" : \"value\" (key-value pair) An unknown key-value pair\n" }},
" ...\n" {RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields",
" },\n" {
" \"inputs\" : [ (array of json objects)\n" {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
" {\n" }},
" \"non_witness_utxo\" : { (json object, optional) Decoded network transaction for non-witness UTXOs\n" {RPCResult::Type::ARR, "inputs", "",
" ...\n" {
" },\n" {RPCResult::Type::OBJ, "", "",
" \"witness_utxo\" : { (json object, optional) Transaction output for witness UTXOs\n" {
" \"amount\" : x.xxx, (numeric) The value in " + CURRENCY_UNIT + "\n" {RPCResult::Type::OBJ, "non_witness_utxo", /* optional */ true, "Decoded network transaction for non-witness UTXOs",
" \"scriptPubKey\" : { (json object)\n" {
" \"asm\" : \"asm\", (string) The asm\n" {RPCResult::Type::ELISION, "",""},
" \"hex\" : \"hex\", (string) The hex\n" }},
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" {RPCResult::Type::OBJ, "witness_utxo", /* optional */ true, "Transaction output for witness UTXOs",
" \"address\" : \"address\" (string) Bitcoin address if there is one\n" {
" }\n" {RPCResult::Type::NUM, "amount", "The value in " + CURRENCY_UNIT},
" },\n" {RPCResult::Type::OBJ, "scriptPubKey", "",
" \"partial_signatures\" : { (json object, optional)\n" {
" \"pubkey\" : \"signature\", (string) The public key and signature that corresponds to it.\n" {RPCResult::Type::STR, "asm", "The asm"},
" ,...\n" {RPCResult::Type::STR_HEX, "hex", "The hex"},
" }\n" {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
" \"sighash\" : \"type\", (string, optional) The sighash type to be used\n" {RPCResult::Type::STR, "address"," Bitcoin address if there is one"},
" \"redeem_script\" : { (json object, optional)\n" }},
" \"asm\" : \"asm\", (string) The asm\n" }},
" \"hex\" : \"hex\", (string) The hex\n" {RPCResult::Type::OBJ_DYN, "partial_signatures", /* optional */ true, "",
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" {
" }\n" {RPCResult::Type::STR, "pubkey", "The public key and signature that corresponds to it."},
" \"witness_script\" : { (json object, optional)\n" }},
" \"asm\" : \"asm\", (string) The asm\n" {RPCResult::Type::STR, "sighash", /* optional */ true, "The sighash type to be used"},
" \"hex\" : \"hex\", (string) The hex\n" {RPCResult::Type::OBJ, "redeem_script", /* optional */ true, "",
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" {
" }\n" {RPCResult::Type::STR, "asm", "The asm"},
" \"bip32_derivs\" : { (json object, optional)\n" {RPCResult::Type::STR_HEX, "hex", "The hex"},
" \"pubkey\" : { (json object, optional) The public key with the derivation path as the value.\n" {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
" \"master_fingerprint\" : \"fingerprint\" (string) The fingerprint of the master key\n" }},
" \"path\" : \"path\", (string) The path\n" {RPCResult::Type::OBJ, "witness_script", /* optional */ true, "",
" }\n" {
" ,...\n" {RPCResult::Type::STR, "asm", "The asm"},
" }\n" {RPCResult::Type::STR_HEX, "hex", "The hex"},
" \"final_scriptsig\" : { (json object, optional)\n" {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
" \"asm\" : \"asm\", (string) The asm\n" }},
" \"hex\" : \"hex\", (string) The hex\n" {RPCResult::Type::ARR, "bip32_derivs", /* optional */ true, "",
" }\n" {
" \"final_scriptwitness\" : [\"hex\", ...] (array of string) hex-encoded witness data (if any)\n" {RPCResult::Type::OBJ, "pubkey", /* optional */ true, "The public key with the derivation path as the value.",
" \"unknown\" : { (json object) The unknown global fields\n" {
" \"key\" : \"value\" (key-value pair) An unknown key-value pair\n" {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
" ...\n" {RPCResult::Type::STR, "path", "The path"},
" },\n" }},
" }\n" }},
" ,...\n" {RPCResult::Type::OBJ, "final_scriptsig", /* optional */ true, "",
" ]\n" {
" \"outputs\" : [ (array of json objects)\n" {RPCResult::Type::STR, "asm", "The asm"},
" {\n" {RPCResult::Type::STR, "hex", "The hex"},
" \"redeem_script\" : { (json object, optional)\n" }},
" \"asm\" : \"asm\", (string) The asm\n" {RPCResult::Type::ARR, "final_scriptwitness", "",
" \"hex\" : \"hex\", (string) The hex\n" {
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" {RPCResult::Type::STR_HEX, "", "hex-encoded witness data (if any)"},
" }\n" }},
" \"witness_script\" : { (json object, optional)\n" {RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields",
" \"asm\" : \"asm\", (string) The asm\n" {
" \"hex\" : \"hex\", (string) The hex\n" {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
" \"type\" : \"pubkeyhash\", (string) The type, eg 'pubkeyhash'\n" }},
" }\n" }},
" \"bip32_derivs\" : [ (array of json objects, optional)\n" }},
" {\n" {RPCResult::Type::ARR, "outputs", "",
" \"pubkey\" : \"pubkey\", (string) The public key this path corresponds to\n" {
" \"master_fingerprint\" : \"fingerprint\" (string) The fingerprint of the master key\n" {RPCResult::Type::OBJ, "", "",
" \"path\" : \"path\", (string) The path\n" {
" }\n" {RPCResult::Type::OBJ, "redeem_script", /* optional */ true, "",
" }\n" {
" ,...\n" {RPCResult::Type::STR, "asm", "The asm"},
" ],\n" {RPCResult::Type::STR_HEX, "hex", "The hex"},
" \"unknown\" : { (json object) The unknown global fields\n" {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
" \"key\" : \"value\" (key-value pair) An unknown key-value pair\n" }},
" ...\n" {RPCResult::Type::OBJ, "witness_script", /* optional */ true, "",
" },\n" {
" }\n" {RPCResult::Type::STR, "asm", "The asm"},
" ,...\n" {RPCResult::Type::STR_HEX, "hex", "The hex"},
" ]\n" {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
" \"fee\" : fee (numeric, optional) The transaction fee paid if all UTXOs slots in the PSBT have been filled.\n" }},
"}\n" {RPCResult::Type::ARR, "bip32_derivs", /* optional */ true, "",
{
{RPCResult::Type::OBJ, "", "",
{
{RPCResult::Type::STR, "pubkey", "The public key this path corresponds to"},
{RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
{RPCResult::Type::STR, "path", "The path"},
}},
}},
{RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields",
{
{RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
}},
}},
}},
{RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true, "The transaction fee paid if all UTXOs slots in the PSBT have been filled."},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("decodepsbt", "\"psbt\"") HelpExampleCli("decodepsbt", "\"psbt\"")
@ -1244,7 +1286,7 @@ UniValue combinepsbt(const JSONRPCRequest& request)
}, },
}, },
RPCResult{ RPCResult{
" \"psbt\" (string) The base64-encoded partially signed transaction\n" RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')") HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")
@ -1292,11 +1334,12 @@ UniValue finalizepsbt(const JSONRPCRequest& request)
" extract and return the complete transaction in normal network serialization instead of the PSBT."}, " extract and return the complete transaction in normal network serialization instead of the PSBT."},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"psbt\" : \"str\", (string) The base64-encoded partially signed transaction if not extracted\n" {
" \"hex\" : \"hex\", (string) The hex-encoded network transaction if extracted\n" {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction if not extracted"},
" \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" {RPCResult::Type::STR_HEX, "hex", "The hex-encoded network transaction if extracted"},
"}\n" {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("finalizepsbt", "\"psbt\"") HelpExampleCli("finalizepsbt", "\"psbt\"")
@ -1374,7 +1417,7 @@ UniValue createpsbt(const JSONRPCRequest& request)
" Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."}, " Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
}, },
RPCResult{ RPCResult{
" \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n" RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
@ -1431,7 +1474,7 @@ UniValue converttopsbt(const JSONRPCRequest& request)
}, },
}, },
RPCResult{ RPCResult{
" \"psbt\" (string) The resulting raw transaction (base64-encoded string)\n" RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
}, },
RPCExamples{ RPCExamples{
"\nCreate a transaction\n" "\nCreate a transaction\n"
@ -1495,7 +1538,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
}}, }},
}, },
RPCResult { RPCResult {
" \"psbt\" (string) The base64-encoded partially signed transaction with inputs updated\n" RPCResult::Type::STR, "", "The base64-encoded partially signed transaction with inputs updated"
}, },
RPCExamples { RPCExamples {
HelpExampleCli("utxoupdatepsbt", "\"psbt\"") HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
@ -1580,7 +1623,7 @@ UniValue joinpsbts(const JSONRPCRequest& request)
}} }}
}, },
RPCResult { RPCResult {
" \"psbt\" (string) The base64-encoded partially signed transaction\n" RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
}, },
RPCExamples { RPCExamples {
HelpExampleCli("joinpsbts", "\"psbt\"") HelpExampleCli("joinpsbts", "\"psbt\"")
@ -1669,31 +1712,36 @@ UniValue analyzepsbt(const JSONRPCRequest& request)
{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"} {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
}, },
RPCResult { RPCResult {
"{\n" RPCResult::Type::OBJ, "", "",
" \"inputs\" : [ (array of json objects)\n" {
" {\n" {RPCResult::Type::ARR, "inputs", "",
" \"has_utxo\" : true|false (boolean) Whether a UTXO is provided\n" {
" \"is_final\" : true|false (boolean) Whether the input is finalized\n" {RPCResult::Type::OBJ, "", "",
" \"missing\" : { (json object, optional) Things that are missing that are required to complete this input\n" {
" \"pubkeys\" : [ (array, optional)\n" {RPCResult::Type::BOOL, "has_utxo", "Whether a UTXO is provided"},
" \"keyid\" (string) Public key ID, hash160 of the public key, of a public key whose BIP 32 derivation path is missing\n" {RPCResult::Type::BOOL, "is_final", "Whether the input is finalized"},
" ]\n" {RPCResult::Type::OBJ, "missing", /* optional */ true, "Things that are missing that are required to complete this input",
" \"signatures\" : [ (array, optional)\n" {
" \"keyid\" (string) Public key ID, hash160 of the public key, of a public key whose signature is missing\n" {RPCResult::Type::ARR, "pubkeys", /* optional */ true, "",
" ]\n" {
" \"redeemscript\" : \"hash\" (string, optional) Hash160 of the redeemScript that is missing\n" {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose BIP 32 derivation path is missing"},
" \"witnessscript\" : \"hash\" (string, optional) SHA256 of the witnessScript that is missing\n" }},
" }\n" {RPCResult::Type::ARR, "signatures", /* optional */ true, "",
" \"next\" : \"role\" (string, optional) Role of the next person that this input needs to go to\n" {
" }\n" {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose signature is missing"},
" ,...\n" }},
" ]\n" {RPCResult::Type::STR_HEX, "redeemscript", /* optional */ true, "Hash160 of the redeemScript that is missing"},
" \"estimated_vsize\" : vsize (numeric, optional) Estimated vsize of the final signed transaction\n" {RPCResult::Type::STR_HEX, "witnessscript", /* optional */ true, "SHA256 of the witnessScript that is missing"},
" \"estimated_feerate\" : feerate (numeric, optional) Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled.\n" }},
" \"fee\" : fee (numeric, optional) The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled.\n" {RPCResult::Type::STR, "next", /* optional */ true, "Role of the next person that this input needs to go to"},
" \"next\" : \"role\" (string) Role of the next person that this psbt needs to go to\n" }},
" \"error\" : \"error\" (string) Error message if there is one\n" }},
"}\n" {RPCResult::Type::NUM, "estimated_vsize", /* optional */ true, "Estimated vsize of the final signed transaction"},
{RPCResult::Type::STR_AMOUNT, "estimated_feerate", /* optional */ true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kB. Shown only if all UTXO slots in the PSBT have been filled"},
{RPCResult::Type::STR_AMOUNT, "fee", /* optional */ true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"},
{RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"},
{RPCResult::Type::STR, "error", "Error message if there is one"},
}
}, },
RPCExamples { RPCExamples {
HelpExampleCli("analyzepsbt", "\"psbt\"") HelpExampleCli("analyzepsbt", "\"psbt\"")

View file

@ -137,7 +137,7 @@ UniValue help(const JSONRPCRequest& jsonRequest)
{"command", RPCArg::Type::STR, /* default */ "all commands", "The command to get help on"}, {"command", RPCArg::Type::STR, /* default */ "all commands", "The command to get help on"},
}, },
RPCResult{ RPCResult{
"\"text\" (string) The help text\n" RPCResult::Type::STR, "", "The help text"
}, },
RPCExamples{""}, RPCExamples{""},
}.ToString() }.ToString()
@ -180,7 +180,7 @@ static UniValue uptime(const JSONRPCRequest& jsonRequest)
"\nReturns the total uptime of the server.\n", "\nReturns the total uptime of the server.\n",
{}, {},
RPCResult{ RPCResult{
"ttt (numeric) The number of seconds that the server has been running\n" RPCResult::Type::NUM, "", "The number of seconds that the server has been running"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("uptime", "") HelpExampleCli("uptime", "")
@ -197,16 +197,18 @@ static UniValue getrpcinfo(const JSONRPCRequest& request)
"\nReturns details of the RPC server.\n", "\nReturns details of the RPC server.\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"active_commands\" (json array) All active commands\n" {
" [\n" {RPCResult::Type::ARR, "active_commands", "All active commands",
" { (json object) Information about an active command\n" {
" \"method\" (string) The name of the RPC command \n" {RPCResult::Type::OBJ, "", "Information about an active command",
" \"duration\" (numeric) The running time in microseconds\n" {
" },...\n" {RPCResult::Type::STR, "method", "The name of the RPC command"},
" ],\n" {RPCResult::Type::NUM, "duration", "The running time in microseconds"},
" \"logpath\" : \"xxx\" (string) The complete file path to the debug log\n" }},
"}\n" }},
{RPCResult::Type::STR, "logpath", "The complete file path to the debug log"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getrpcinfo", "") HelpExampleCli("getrpcinfo", "")

View file

@ -311,21 +311,10 @@ struct Sections {
m_sections.push_back(s); m_sections.push_back(s);
} }
/**
* Serializing RPCArgs depends on the outer type. Only arrays and
* dictionaries can be nested in json. The top-level outer type is "named
* arguments", a mix between a dictionary and arrays.
*/
enum class OuterType {
ARR,
OBJ,
NAMED_ARG, // Only set on first recursion
};
/** /**
* Recursive helper to translate an RPCArg into sections * Recursive helper to translate an RPCArg into sections
*/ */
void Push(const RPCArg& arg, const size_t current_indent = 5, const OuterType outer_type = OuterType::NAMED_ARG) void Push(const RPCArg& arg, const size_t current_indent = 5, const OuterType outer_type = OuterType::NONE)
{ {
const auto indent = std::string(current_indent, ' '); const auto indent = std::string(current_indent, ' ');
const auto indent_next = std::string(current_indent + 2, ' '); const auto indent_next = std::string(current_indent + 2, ' ');
@ -338,7 +327,7 @@ struct Sections {
case RPCArg::Type::AMOUNT: case RPCArg::Type::AMOUNT:
case RPCArg::Type::RANGE: case RPCArg::Type::RANGE:
case RPCArg::Type::BOOL: { case RPCArg::Type::BOOL: {
if (outer_type == OuterType::NAMED_ARG) return; // Nothing more to do for non-recursive types on first recursion if (outer_type == OuterType::NONE) return; // Nothing more to do for non-recursive types on first recursion
auto left = indent; auto left = indent;
if (arg.m_type_str.size() != 0 && push_name) { if (arg.m_type_str.size() != 0 && push_name) {
left += "\"" + arg.m_name + "\": " + arg.m_type_str.at(0); left += "\"" + arg.m_name + "\": " + arg.m_type_str.at(0);
@ -351,7 +340,7 @@ struct Sections {
} }
case RPCArg::Type::OBJ: case RPCArg::Type::OBJ:
case RPCArg::Type::OBJ_USER_KEYS: { case RPCArg::Type::OBJ_USER_KEYS: {
const auto right = outer_type == OuterType::NAMED_ARG ? "" : arg.ToDescriptionString(); const auto right = outer_type == OuterType::NONE ? "" : arg.ToDescriptionString();
PushSection({indent + (push_name ? "\"" + arg.m_name + "\": " : "") + "{", right}); PushSection({indent + (push_name ? "\"" + arg.m_name + "\": " : "") + "{", right});
for (const auto& arg_inner : arg.m_inner) { for (const auto& arg_inner : arg.m_inner) {
Push(arg_inner, current_indent + 2, OuterType::OBJ); Push(arg_inner, current_indent + 2, OuterType::OBJ);
@ -359,20 +348,20 @@ struct Sections {
if (arg.m_type != RPCArg::Type::OBJ) { if (arg.m_type != RPCArg::Type::OBJ) {
PushSection({indent_next + "...", ""}); PushSection({indent_next + "...", ""});
} }
PushSection({indent + "}" + (outer_type != OuterType::NAMED_ARG ? "," : ""), ""}); PushSection({indent + "}" + (outer_type != OuterType::NONE ? "," : ""), ""});
break; break;
} }
case RPCArg::Type::ARR: { case RPCArg::Type::ARR: {
auto left = indent; auto left = indent;
left += push_name ? "\"" + arg.m_name + "\": " : ""; left += push_name ? "\"" + arg.m_name + "\": " : "";
left += "["; left += "[";
const auto right = outer_type == OuterType::NAMED_ARG ? "" : arg.ToDescriptionString(); const auto right = outer_type == OuterType::NONE ? "" : arg.ToDescriptionString();
PushSection({left, right}); PushSection({left, right});
for (const auto& arg_inner : arg.m_inner) { for (const auto& arg_inner : arg.m_inner) {
Push(arg_inner, current_indent + 2, OuterType::ARR); Push(arg_inner, current_indent + 2, OuterType::ARR);
} }
PushSection({indent_next + "...", ""}); PushSection({indent_next + "...", ""});
PushSection({indent + "]" + (outer_type != OuterType::NAMED_ARG ? "," : ""), ""}); PushSection({indent + "]" + (outer_type != OuterType::NONE ? "," : ""), ""});
break; break;
} }
@ -444,7 +433,9 @@ std::string RPCResults::ToDescriptionString() const
} else { } else {
result += "\nResult (" + r.m_cond + "):\n"; result += "\nResult (" + r.m_cond + "):\n";
} }
result += r.m_result; Sections sections;
r.ToSections(sections);
result += sections.ToString();
} }
return result; return result;
} }
@ -591,6 +582,93 @@ std::string RPCArg::ToDescriptionString() const
return ret; return ret;
} }
void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const int current_indent) const
{
// Indentation
const std::string indent(current_indent, ' ');
const std::string indent_next(current_indent + 2, ' ');
// Elements in a JSON structure (dictionary or array) are separated by a comma
const std::string maybe_separator{outer_type != OuterType::NONE ? "," : ""};
// The key name if recursed into an dictionary
const std::string maybe_key{
outer_type == OuterType::OBJ ?
"\"" + this->m_key_name + "\" : " :
""};
// Format description with type
const auto Description = [&](const std::string& type) {
return "(" + type + (this->m_optional ? ", optional" : "") + ")" +
(this->m_description.empty() ? "" : " " + this->m_description);
};
switch (m_type) {
case Type::ELISION: {
// If the inner result is empty, use three dots for elision
sections.PushSection({indent_next + "...", m_description});
return;
}
case Type::NONE: {
sections.PushSection({indent + "None", Description("json null")});
return;
}
case Type::STR: {
sections.PushSection({indent + maybe_key + "\"str\"" + maybe_separator, Description("string")});
return;
}
case Type::STR_AMOUNT: {
sections.PushSection({indent + maybe_key + "n" + maybe_separator, Description("numeric")});
return;
}
case Type::STR_HEX: {
sections.PushSection({indent + maybe_key + "\"hex\"" + maybe_separator, Description("string")});
return;
}
case Type::NUM: {
sections.PushSection({indent + maybe_key + "n" + maybe_separator, Description("numeric")});
return;
}
case Type::NUM_TIME: {
sections.PushSection({indent + maybe_key + "xxx" + maybe_separator, Description("numeric")});
return;
}
case Type::BOOL: {
sections.PushSection({indent + maybe_key + "true|false" + maybe_separator, Description("boolean")});
return;
}
case Type::ARR_FIXED:
case Type::ARR: {
sections.PushSection({indent + maybe_key + "[", Description("json array")});
for (const auto& i : m_inner) {
i.ToSections(sections, OuterType::ARR, current_indent + 2);
}
if (m_type == Type::ARR) {
sections.PushSection({indent_next + "...", ""});
}
sections.PushSection({indent + "]" + maybe_separator, ""});
return;
}
case Type::OBJ_DYN:
case Type::OBJ: {
sections.PushSection({indent + maybe_key + "{", Description("json object")});
for (const auto& i : m_inner) {
i.ToSections(sections, OuterType::OBJ, current_indent + 2);
}
if (m_type == Type::OBJ_DYN) {
// If the dictionary keys are dynamic, use three dots for continuation
sections.PushSection({indent_next + "...", ""});
}
sections.PushSection({indent + "}" + maybe_separator, ""});
return;
}
// no default case, so the compiler can warn about missing cases
}
CHECK_NONFATAL(false);
}
std::string RPCArg::ToStringObj(const bool oneline) const std::string RPCArg::ToStringObj(const bool oneline) const
{ {
std::string res; std::string res;

View file

@ -37,6 +37,7 @@ extern const std::string EXAMPLE_ADDRESS;
class FillableSigningProvider; class FillableSigningProvider;
class CPubKey; class CPubKey;
class CScript; class CScript;
struct Sections;
/** Wrapper for UniValue::VType, which includes typeAny: /** Wrapper for UniValue::VType, which includes typeAny:
* Used to denote don't care type. */ * Used to denote don't care type. */
@ -101,6 +102,16 @@ std::vector<CScript> EvalDescriptorStringOrObject(const UniValue& scanobject, Fl
/** Returns, given services flags, a list of humanly readable (known) network services */ /** Returns, given services flags, a list of humanly readable (known) network services */
UniValue GetServicesNames(ServiceFlags services); UniValue GetServicesNames(ServiceFlags services);
/**
* Serializing JSON objects depends on the outer type. Only arrays and
* dictionaries can be nested in json. The top-level outer type is "NONE".
*/
enum class OuterType {
ARR,
OBJ,
NONE, // Only set on first recursion
};
struct RPCArg { struct RPCArg {
enum class Type { enum class Type {
OBJ, OBJ,
@ -140,37 +151,37 @@ struct RPCArg {
const std::vector<std::string> m_type_str; //!< Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_type_str.at(0) will override the type of the value in a key-value pair, m_type_str.at(1) will override the type in the argument description. const std::vector<std::string> m_type_str; //!< Should be empty unless it is supposed to override the auto-generated type strings. Vector length is either 0 or 2, m_type_str.at(0) will override the type of the value in a key-value pair, m_type_str.at(1) will override the type in the argument description.
RPCArg( RPCArg(
const std::string& name, const std::string name,
const Type& type, const Type type,
const Fallback& fallback, const Fallback fallback,
const std::string& description, const std::string description,
const std::string& oneline_description = "", const std::string oneline_description = "",
const std::vector<std::string>& type_str = {}) const std::vector<std::string> type_str = {})
: m_name{name}, : m_name{std::move(name)},
m_type{type}, m_type{std::move(type)},
m_fallback{fallback}, m_fallback{std::move(fallback)},
m_description{description}, m_description{std::move(description)},
m_oneline_description{oneline_description}, m_oneline_description{std::move(oneline_description)},
m_type_str{type_str} m_type_str{std::move(type_str)}
{ {
CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ); CHECK_NONFATAL(type != Type::ARR && type != Type::OBJ);
} }
RPCArg( RPCArg(
const std::string& name, const std::string name,
const Type& type, const Type type,
const Fallback& fallback, const Fallback fallback,
const std::string& description, const std::string description,
const std::vector<RPCArg>& inner, const std::vector<RPCArg> inner,
const std::string& oneline_description = "", const std::string oneline_description = "",
const std::vector<std::string>& type_str = {}) const std::vector<std::string> type_str = {})
: m_name{name}, : m_name{std::move(name)},
m_type{type}, m_type{std::move(type)},
m_inner{inner}, m_inner{std::move(inner)},
m_fallback{fallback}, m_fallback{std::move(fallback)},
m_description{description}, m_description{std::move(description)},
m_oneline_description{oneline_description}, m_oneline_description{std::move(oneline_description)},
m_type_str{type_str} m_type_str{std::move(type_str)}
{ {
CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ); CHECK_NONFATAL(type == Type::ARR || type == Type::OBJ);
} }
@ -195,21 +206,85 @@ struct RPCArg {
}; };
struct RPCResult { struct RPCResult {
enum class Type {
OBJ,
ARR,
STR,
NUM,
BOOL,
NONE,
STR_AMOUNT, //!< Special string to represent a floating point amount
STR_HEX, //!< Special string with only hex chars
OBJ_DYN, //!< Special dictionary with keys that are not literals
ARR_FIXED, //!< Special array that has a fixed number of entries
NUM_TIME, //!< Special numeric to denote unix epoch time
ELISION, //!< Special type to denote elision (...)
};
const Type m_type;
const std::string m_key_name; //!< Only used for dicts
const std::vector<RPCResult> m_inner; //!< Only used for arrays or dicts
const bool m_optional;
const std::string m_description;
const std::string m_cond; const std::string m_cond;
const std::string m_result;
explicit RPCResult(std::string result) RPCResult(
: m_cond{}, m_result{std::move(result)} const std::string cond,
{ const Type type,
CHECK_NONFATAL(!m_result.empty()); const std::string m_key_name,
} const bool optional,
const std::string description,
RPCResult(std::string cond, std::string result) const std::vector<RPCResult> inner = {})
: m_cond{std::move(cond)}, m_result{std::move(result)} : m_type{std::move(type)},
m_key_name{std::move(m_key_name)},
m_inner{std::move(inner)},
m_optional{optional},
m_description{std::move(description)},
m_cond{std::move(cond)}
{ {
CHECK_NONFATAL(!m_cond.empty()); CHECK_NONFATAL(!m_cond.empty());
CHECK_NONFATAL(!m_result.empty()); const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN};
CHECK_NONFATAL(inner_needed != inner.empty());
} }
RPCResult(
const std::string cond,
const Type type,
const std::string m_key_name,
const std::string description,
const std::vector<RPCResult> inner = {})
: RPCResult{cond, type, m_key_name, false, description, inner} {}
RPCResult(
const Type type,
const std::string m_key_name,
const bool optional,
const std::string description,
const std::vector<RPCResult> inner = {})
: m_type{std::move(type)},
m_key_name{std::move(m_key_name)},
m_inner{std::move(inner)},
m_optional{optional},
m_description{std::move(description)},
m_cond{}
{
const bool inner_needed{type == Type::ARR || type == Type::ARR_FIXED || type == Type::OBJ || type == Type::OBJ_DYN};
CHECK_NONFATAL(inner_needed != inner.empty());
}
RPCResult(
const Type type,
const std::string m_key_name,
const std::string description,
const std::vector<RPCResult> inner = {})
: RPCResult{type, m_key_name, false, description, inner} {}
/** Append the sections of the result. */
void ToSections(Sections& sections, OuterType outer_type = OuterType::NONE, const int current_indent = 0) const;
/** Return the type string of the result when it is in an object (dict). */
std::string ToStringObj() const;
/** Return the description string, including the result type. */
std::string ToDescriptionString() const;
}; };
struct RPCResults { struct RPCResults {

View file

@ -688,7 +688,7 @@ UniValue dumpprivkey(const JSONRPCRequest& request)
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for the private key"}, {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for the private key"},
}, },
RPCResult{ RPCResult{
"\"key\" (string) The private key\n" RPCResult::Type::STR, "key", "The private key"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("dumpprivkey", "\"myaddress\"") HelpExampleCli("dumpprivkey", "\"myaddress\"")
@ -738,9 +738,10 @@ UniValue dumpwallet(const JSONRPCRequest& request)
{"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The filename with path (either absolute or relative to bitcoind)"}, {"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The filename with path (either absolute or relative to bitcoind)"},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"filename\" : { (string) The filename with full absolute path\n" {
"}\n" {RPCResult::Type::STR, "filename", "The filename with full absolute path"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("dumpwallet", "\"test\"") HelpExampleCli("dumpwallet", "\"test\"")
@ -1321,19 +1322,21 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
"\"options\""}, "\"options\""},
}, },
RPCResult{ RPCResult{
"[ (json array) Response is an array with the same size as the input that has the execution result\n" RPCResult::Type::ARR, "", "Response is an array with the same size as the input that has the execution result",
" { (json object)\n" {
" \"success\" : true|false, (boolean)\n" {RPCResult::Type::OBJ, "", "",
" \"warnings\" : [ (json array, optional)\n" {
" \"str\", (string)\n" {RPCResult::Type::BOOL, "success", ""},
" ...\n" {RPCResult::Type::ARR, "warnings", /* optional */ true, "",
" ],\n" {
" \"error\" : { (json object, optional)\n" {RPCResult::Type::STR, "", ""},
" ... JSONRPC error\n" }},
" },\n" {RPCResult::Type::OBJ, "error", /* optional */ true, "",
" },\n" {
" ...\n" {RPCResult::Type::ELISION, "", "JSONRPC error"},
"]\n" }},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("importmulti", "'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }, " HelpExampleCli("importmulti", "'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, \"timestamp\":1455191478 }, "

View file

@ -24,6 +24,7 @@
#include <util/string.h> #include <util/string.h>
#include <util/system.h> #include <util/system.h>
#include <util/url.h> #include <util/url.h>
#include <util/vector.h>
#include <wallet/coincontrol.h> #include <wallet/coincontrol.h>
#include <wallet/feebumper.h> #include <wallet/feebumper.h>
#include <wallet/psbtwallet.h> #include <wallet/psbtwallet.h>
@ -205,7 +206,7 @@ static UniValue getnewaddress(const JSONRPCRequest& request)
{"address_type", RPCArg::Type::STR, /* default */ "set by -addresstype", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."}, {"address_type", RPCArg::Type::STR, /* default */ "set by -addresstype", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
}, },
RPCResult{ RPCResult{
"\"address\" (string) The new bitcoin address\n" RPCResult::Type::STR, "address", "The new bitcoin address"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getnewaddress", "") HelpExampleCli("getnewaddress", "")
@ -256,7 +257,7 @@ static UniValue getrawchangeaddress(const JSONRPCRequest& request)
{"address_type", RPCArg::Type::STR, /* default */ "set by -changetype", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."}, {"address_type", RPCArg::Type::STR, /* default */ "set by -changetype", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
}, },
RPCResult{ RPCResult{
"\"address\" (string) The address\n" RPCResult::Type::STR, "address", "The address"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getrawchangeaddress", "") HelpExampleCli("getrawchangeaddress", "")
@ -390,7 +391,7 @@ static UniValue sendtoaddress(const JSONRPCRequest& request)
" dirty if they have previously been used in a transaction."}, " dirty if they have previously been used in a transaction."},
}, },
RPCResult{ RPCResult{
"\"txid\" (string) The transaction id.\n" RPCResult::Type::STR_HEX, "txid", "The transaction id."
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1") HelpExampleCli("sendtoaddress", "\"1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" 0.1")
@ -469,17 +470,18 @@ static UniValue listaddressgroupings(const JSONRPCRequest& request)
"in past transactions\n", "in past transactions\n",
{}, {},
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" [\n" {
" [\n" {RPCResult::Type::ARR, "", "",
" \"address\", (string) The bitcoin address\n" {
" amount, (numeric) The amount in " + CURRENCY_UNIT + "\n" {RPCResult::Type::ARR, "", "",
" \"label\" (string, optional) The label\n" {
" ]\n" {RPCResult::Type::STR, "address", "The bitcoin address"},
" ,...\n" {RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT},
" ]\n" {RPCResult::Type::STR, "label", /* optional */ true, "The label"},
" ,...\n" }},
"]\n" }},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("listaddressgroupings", "") HelpExampleCli("listaddressgroupings", "")
@ -532,7 +534,7 @@ static UniValue signmessage(const JSONRPCRequest& request)
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
}, },
RPCResult{ RPCResult{
"\"signature\" (string) The signature of the message encoded in base 64\n" RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
}, },
RPCExamples{ RPCExamples{
"\nUnlock the wallet for 30 seconds\n" "\nUnlock the wallet for 30 seconds\n"
@ -601,7 +603,7 @@ static UniValue getreceivedbyaddress(const JSONRPCRequest& request)
{"minconf", RPCArg::Type::NUM, /* default */ "1", "Only include transactions confirmed at least this many times."}, {"minconf", RPCArg::Type::NUM, /* default */ "1", "Only include transactions confirmed at least this many times."},
}, },
RPCResult{ RPCResult{
"amount (numeric) The total amount in " + CURRENCY_UNIT + " received at this address.\n" RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received at this address."
}, },
RPCExamples{ RPCExamples{
"\nThe amount from transactions with at least 1 confirmation\n" "\nThe amount from transactions with at least 1 confirmation\n"
@ -671,7 +673,7 @@ static UniValue getreceivedbylabel(const JSONRPCRequest& request)
{"minconf", RPCArg::Type::NUM, /* default */ "1", "Only include transactions confirmed at least this many times."}, {"minconf", RPCArg::Type::NUM, /* default */ "1", "Only include transactions confirmed at least this many times."},
}, },
RPCResult{ RPCResult{
"amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this label.\n" RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received for this label."
}, },
RPCExamples{ RPCExamples{
"\nAmount received by the default label with at least 1 confirmation\n" "\nAmount received by the default label with at least 1 confirmation\n"
@ -743,7 +745,7 @@ static UniValue getbalance(const JSONRPCRequest& request)
{"avoid_reuse", RPCArg::Type::BOOL, /* default */ "true", "(only available if avoid_reuse wallet flag is set) Do not include balance in dirty outputs; addresses are considered dirty if they have previously been used in a transaction."}, {"avoid_reuse", RPCArg::Type::BOOL, /* default */ "true", "(only available if avoid_reuse wallet flag is set) Do not include balance in dirty outputs; addresses are considered dirty if they have previously been used in a transaction."},
}, },
RPCResult{ RPCResult{
"amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this wallet.\n" RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received for this wallet."
}, },
RPCExamples{ RPCExamples{
"\nThe total amount in the wallet with 1 or more confirmations\n" "\nThe total amount in the wallet with 1 or more confirmations\n"
@ -845,8 +847,8 @@ static UniValue sendmany(const JSONRPCRequest& request)
" \"CONSERVATIVE\""}, " \"CONSERVATIVE\""},
}, },
RPCResult{ RPCResult{
"\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n" RPCResult::Type::STR_HEX, "txid", "The transaction id for the send. Only 1 transaction is created regardless of\n"
" the number of addresses.\n" "the number of addresses."
}, },
RPCExamples{ RPCExamples{
"\nSend two amounts to two different addresses:\n" "\nSend two amounts to two different addresses:\n"
@ -969,11 +971,12 @@ static UniValue addmultisigaddress(const JSONRPCRequest& request)
{"address_type", RPCArg::Type::STR, /* default */ "set by -addresstype", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."}, {"address_type", RPCArg::Type::STR, /* default */ "set by -addresstype", "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"address\" : \"multisigaddress\", (string) The value of the new multisig address.\n" {
" \"redeemScript\" : \"script\" (string) The string value of the hex-encoded redemption script.\n" {RPCResult::Type::STR, "address", "The value of the new multisig address"},
" \"descriptor\" : \"descriptor\" (string) The descriptor for this multisig\n" {RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script"},
"}\n" {RPCResult::Type::STR, "descriptor", "The descriptor for this multisig"},
}
}, },
RPCExamples{ RPCExamples{
"\nAdd a multisig address from 2 addresses\n" "\nAdd a multisig address from 2 addresses\n"
@ -1202,20 +1205,21 @@ static UniValue listreceivedbyaddress(const JSONRPCRequest& request)
{"address_filter", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "If present, only return information on this address."}, {"address_filter", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "If present, only return information on this address."},
}, },
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"involvesWatchonly\" : true, (boolean) Only returns true if imported addresses were involved in transaction.\n" {RPCResult::Type::OBJ, "", "",
" \"address\" : \"receivingaddress\", (string) The receiving address\n" {
" \"amount\" : x.xxx, (numeric) The total amount in " + CURRENCY_UNIT + " received by the address\n" {RPCResult::Type::BOOL, "involvesWatchonly", "Only returns true if imported addresses were involved in transaction"},
" \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n" {RPCResult::Type::STR, "address", "The receiving address"},
" \"label\" : \"label\", (string) The label of the receiving address. The default label is \"\".\n" {RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received by the address"},
" \"txids\" : [\n" {RPCResult::Type::NUM, "confirmations", "The number of confirmations of the most recent transaction included"},
" \"txid\", (string) The ids of transactions received with the address \n" {RPCResult::Type::STR, "label", "The label of the receiving address. The default label is \"\""},
" ...\n" {RPCResult::Type::ARR, "txids", "",
" ]\n" {
" }\n" {RPCResult::Type::STR_HEX, "txid", "The ids of transactions received with the address"},
" ,...\n" }},
"]\n" }},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("listreceivedbyaddress", "") HelpExampleCli("listreceivedbyaddress", "")
@ -1252,15 +1256,16 @@ static UniValue listreceivedbylabel(const JSONRPCRequest& request)
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Whether to include watch-only addresses (see 'importaddress')"}, {"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Whether to include watch-only addresses (see 'importaddress')"},
}, },
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"involvesWatchonly\" : true, (boolean) Only returns true if imported addresses were involved in transaction.\n" {RPCResult::Type::OBJ, "", "",
" \"amount\" : x.xxx, (numeric) The total amount received by addresses with this label\n" {
" \"confirmations\" : n, (numeric) The number of confirmations of the most recent transaction included\n" {RPCResult::Type::BOOL, "involvesWatchonly", "Only returns true if imported addresses were involved in transaction"},
" \"label\" : \"label\" (string) The label of the receiving address. The default label is \"\".\n" {RPCResult::Type::STR_AMOUNT, "amount", "The total amount received by addresses with this label"},
" }\n" {RPCResult::Type::NUM, "confirmations", "The number of confirmations of the most recent transaction included"},
" ,...\n" {RPCResult::Type::STR, "label", "The label of the receiving address. The default label is \"\""},
"]\n" }},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("listreceivedbylabel", "") HelpExampleCli("listreceivedbylabel", "")
@ -1372,26 +1377,26 @@ static void ListTransactions(interfaces::Chain::Lock& locked_chain, CWallet* con
} }
} }
static const std::string TransactionDescriptionString() static const std::vector<RPCResult> TransactionDescriptionString()
{ {
return " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Negative confirmations means the\n" return{{RPCResult::Type::NUM, "confirmations", "The number of confirmations for the transaction. Negative confirmations means the\n"
" transaction conflicted that many blocks ago.\n" "transaction conflicted that many blocks ago."},
" \"generated\" : xxx, (boolean) Only present if transaction only input is a coinbase one.\n" {RPCResult::Type::BOOL, "generated", "Only present if transaction only input is a coinbase one."},
" \"trusted\" : xxx, (boolean) Only present if we consider transaction to be trusted and so safe to spend from.\n" {RPCResult::Type::BOOL, "trusted", "Only present if we consider transaction to be trusted and so safe to spend from."},
" \"blockhash\" : \"hashvalue\", (string) The block hash containing the transaction.\n" {RPCResult::Type::STR_HEX, "blockhash", "The block hash containing the transaction."},
" \"blockheight\" : n, (numeric) The block height containing the transaction.\n" {RPCResult::Type::NUM, "blockheight", "The block height containing the transaction."},
" \"blockindex\" : n, (numeric) The index of the transaction in the block that includes it.\n" {RPCResult::Type::NUM, "blockindex", "The index of the transaction in the block that includes it."},
" \"blocktime\" : xxx, (numeric) The block time expressed in " + UNIX_EPOCH_TIME + ".\n" {RPCResult::Type::NUM_TIME, "blocktime", "The block time expressed in " + UNIX_EPOCH_TIME + "."},
" \"txid\" : \"transactionid\", (string) The transaction id.\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id."},
" \"walletconflicts\" : [ (json array) Conflicting transaction ids.\n" {RPCResult::Type::ARR, "walletconflicts", "Conflicting transaction ids.",
" \"txid\", (string) The transaction id.\n" {
" ...\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id."},
" ],\n" }},
" \"time\" : xxx, (numeric) The transaction time expressed in " + UNIX_EPOCH_TIME + ".\n" {RPCResult::Type::NUM_TIME, "time", "The transaction time expressed in " + UNIX_EPOCH_TIME + "."},
" \"timereceived\" : xxx, (numeric) The time received expressed in " + UNIX_EPOCH_TIME + ".\n" {RPCResult::Type::NUM_TIME, "timereceived", "The time received expressed in " + UNIX_EPOCH_TIME + "."},
" \"comment\" : \"...\", (string) If a comment is associated with the transaction, only present if not empty.\n" {RPCResult::Type::STR, "comment", "If a comment is associated with the transaction, only present if not empty."},
" \"bip125-replaceable\" : \"str\", (string) (\"yes|no|unknown\") Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" {RPCResult::Type::STR, "bip125-replaceable", "(\"yes|no|unknown\") Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
" may be unknown for unconfirmed transactions not in the mempool\n"; "may be unknown for unconfirmed transactions not in the mempool"}};
} }
UniValue listtransactions(const JSONRPCRequest& request) UniValue listtransactions(const JSONRPCRequest& request)
@ -1414,27 +1419,31 @@ UniValue listtransactions(const JSONRPCRequest& request)
{"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Include transactions to watch-only addresses (see 'importaddress')"}, {"include_watchonly", RPCArg::Type::BOOL, /* default */ "true for watch-only wallets, otherwise false", "Include transactions to watch-only addresses (see 'importaddress')"},
}, },
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"involvesWatchonly\" : xxx, (boolean) Only returns true if imported addresses were involved in transaction.\n" {RPCResult::Type::OBJ, "", "", Cat(Cat<std::vector<RPCResult>>(
" \"address\" : \"address\", (string) The bitcoin address of the transaction.\n" {
" \"category\" : (string) The transaction category.\n" {RPCResult::Type::BOOL, "involvesWatchonly", "Only returns true if imported addresses were involved in transaction."},
" \"send\" Transactions sent.\n" {RPCResult::Type::STR, "address", "The bitcoin address of the transaction."},
" \"receive\" Non-coinbase transactions received.\n" {RPCResult::Type::STR, "category", "The transaction category.\n"
" \"generate\" Coinbase transactions received with more than 100 confirmations.\n" "\"send\" Transactions sent.\n"
" \"immature\" Coinbase transactions received with 100 or fewer confirmations.\n" "\"receive\" Non-coinbase transactions received.\n"
" \"orphan\" Orphaned coinbase transactions received.\n" "\"generate\" Coinbase transactions received with more than 100 confirmations.\n"
" \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and is positive\n" "\"immature\" Coinbase transactions received with 100 or fewer confirmations.\n"
" for all other categories\n" "\"orphan\" Orphaned coinbase transactions received."},
" \"label\" : \"label\", (string) A comment for the address/transaction, if any\n" {RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and is positive\n"
" \"vout\" : n, (numeric) the vout value\n" "for all other categories"},
" \"fee\" : x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" {RPCResult::Type::STR, "label", "A comment for the address/transaction, if any"},
" 'send' category of transactions.\n" {RPCResult::Type::NUM, "vout", "the vout value"},
+ TransactionDescriptionString() {RPCResult::Type::STR_AMOUNT, "fee", "The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the\n"
+ " \"abandoned\": xxx (boolean) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n" "'send' category of transactions."},
" 'send' category of transactions.\n" },
" }\n" TransactionDescriptionString()),
"]\n" {
{RPCResult::Type::BOOL, "abandoned", "'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
"'send' category of transactions."},
})},
}
}, },
RPCExamples{ RPCExamples{
"\nList the most recent 10 transactions in the systems\n" "\nList the most recent 10 transactions in the systems\n"
@ -1525,34 +1534,39 @@ static UniValue listsinceblock(const JSONRPCRequest& request)
" (not guaranteed to work on pruned nodes)"}, " (not guaranteed to work on pruned nodes)"},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"transactions\" : [ (json array)\n" {
" { (json object)\n" {RPCResult::Type::ARR, "transactions", "",
" \"involvesWatchonly\" : xxx, (boolean) Only returns true if imported addresses were involved in transaction.\n" {
" \"address\" : \"str\", (string) The bitcoin address of the transaction.\n" {RPCResult::Type::OBJ, "", "", Cat(Cat<std::vector<RPCResult>>(
" \"category\" : \"str\", (string) The transaction category.\n" {
" \"send\" Transactions sent.\n" {RPCResult::Type::BOOL, "involvesWatchonly", "Only returns true if imported addresses were involved in transaction."},
" \"receive\" Non-coinbase transactions received.\n" {RPCResult::Type::STR, "address", "The bitcoin address of the transaction."},
" \"generate\" Coinbase transactions received with more than 100 confirmations.\n" {RPCResult::Type::STR, "category", "The transaction category.\n"
" \"immature\" Coinbase transactions received with 100 or fewer confirmations.\n" "\"send\" Transactions sent.\n"
" \"orphan\" Orphaned coinbase transactions received.\n" "\"receive\" Non-coinbase transactions received.\n"
" \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and is positive\n" "\"generate\" Coinbase transactions received with more than 100 confirmations.\n"
" for all other categories\n" "\"immature\" Coinbase transactions received with 100 or fewer confirmations.\n"
" \"vout\" : n, (numeric) the vout value\n" "\"orphan\" Orphaned coinbase transactions received."},
" \"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" {RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and is positive\n"
+ TransactionDescriptionString() "for all other categories"},
+ " \"abandoned\": xxx, (boolean) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the 'send' category of transactions.\n" {RPCResult::Type::NUM, "vout", "the vout value"},
" \"label\" : \"label\" (string) A comment for the address/transaction, if any\n" {RPCResult::Type::STR_AMOUNT, "fee", "The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the\n"
" \"to\" : \"...\", (string) If a comment to is associated with the transaction.\n" "'send' category of transactions."},
" },\n" },
" ...\n" TransactionDescriptionString()),
" ],\n" {
" \"removed\" : [ (json array)\n" {RPCResult::Type::BOOL, "abandoned", "'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
" <structure is the same as \"transactions\" above, only present if include_removed=true>\n" "'send' category of transactions."},
" Note: transactions that were re-added in the active chain will appear as-is in this array, and may thus have a positive confirmation count.\n" {RPCResult::Type::STR, "label", "A comment for the address/transaction, if any"},
" ],\n" {RPCResult::Type::STR, "to", "If a comment to is associated with the transaction."},
" \"lastblock\" : \"hex\" (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" })},
"}\n" }},
{RPCResult::Type::ARR, "removed", "<structure is the same as \"transactions\" above, only present if include_removed=true>\n"
"Note: transactions that were re-added in the active chain will appear as-is in this array, and may thus have a positive confirmation count."
, {{RPCResult::Type::ELISION, "", ""},}},
{RPCResult::Type::STR_HEX, "lastblock", "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"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("listsinceblock", "") HelpExampleCli("listsinceblock", "")
@ -1660,35 +1674,41 @@ static UniValue gettransaction(const JSONRPCRequest& request)
"Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction)"}, "Whether to include a `decoded` field containing the decoded transaction (equivalent to RPC decoderawtransaction)"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "", Cat(Cat<std::vector<RPCResult>>(
" \"amount\" : x.xxx, (numeric) The transaction amount in " + CURRENCY_UNIT + "\n" {
" \"fee\" : x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" {RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT},
" 'send' category of transactions.\n" {RPCResult::Type::STR_AMOUNT, "fee", "The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the\n"
+ TransactionDescriptionString() "'send' category of transactions."},
+ " \"details\" : [\n" },
" {\n" TransactionDescriptionString()),
" \"involvesWatchonly\" : xxx, (boolean) Only returns true if imported addresses were involved in transaction.\n" {
" \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n" {RPCResult::Type::ARR, "details", "",
" \"category\" : (string) The transaction category.\n" {
" \"send\" Transactions sent.\n" {RPCResult::Type::OBJ, "", "",
" \"receive\" Non-coinbase transactions received.\n" {
" \"generate\" Coinbase transactions received with more than 100 confirmations.\n" {RPCResult::Type::BOOL, "involvesWatchonly", "Only returns true if imported addresses were involved in transaction."},
" \"immature\" Coinbase transactions received with 100 or fewer confirmations.\n" {RPCResult::Type::STR, "address", "The bitcoin address involved in the transaction."},
" \"orphan\" Orphaned coinbase transactions received.\n" {RPCResult::Type::STR, "category", "The transaction category.\n"
" \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n" "\"send\" Transactions sent.\n"
" \"label\" : \"label\", (string) A comment for the address/transaction, if any\n" "\"receive\" Non-coinbase transactions received.\n"
" \"vout\" : n, (numeric) the vout value\n" "\"generate\" Coinbase transactions received with more than 100 confirmations.\n"
" \"fee\" : x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" "\"immature\" Coinbase transactions received with 100 or fewer confirmations.\n"
" 'send' category of transactions.\n" "\"orphan\" Orphaned coinbase transactions received."},
" \"abandoned\" : xxx (boolean) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n" {RPCResult::Type::STR_AMOUNT, "amount", "The amount in " + CURRENCY_UNIT},
" 'send' category of transactions.\n" {RPCResult::Type::STR, "label", "A comment for the address/transaction, if any"},
" }\n" {RPCResult::Type::NUM, "vout", "the vout value"},
" ,...\n" {RPCResult::Type::STR_AMOUNT, "fee", "The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
" ],\n" "'send' category of transactions."},
" \"hex\" : \"data\" (string) Raw data for transaction\n" {RPCResult::Type::BOOL, "abandoned", "'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
" \"decoded\" : transaction (json object) Optional, the decoded transaction (only present when `verbose` is passed), equivalent to the\n" "'send' category of transactions."},
" RPC decoderawtransaction method, or the RPC getrawtransaction method when `verbose` is passed.\n" }},
"}\n" }},
{RPCResult::Type::STR_HEX, "hex", "Raw data for transaction"},
{RPCResult::Type::OBJ, "decoded", "Optional, the decoded transaction (only present when `verbose` is passed)",
{
{RPCResult::Type::ELISION, "", "Equivalent to the RPC decoderawtransaction method, or the RPC getrawtransaction method when `verbose` is passed."},
}},
})
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"")
@ -2147,7 +2167,7 @@ static UniValue lockunspent(const JSONRPCRequest& request)
}, },
}, },
RPCResult{ RPCResult{
"true|false (boolean) Whether the command was successful or not\n" RPCResult::Type::BOOL, "", "Whether the command was successful or not"
}, },
RPCExamples{ RPCExamples{
"\nList the unspent transactions\n" "\nList the unspent transactions\n"
@ -2257,13 +2277,14 @@ static UniValue listlockunspent(const JSONRPCRequest& request)
"See the lockunspent call to lock and unlock transactions for spending.\n", "See the lockunspent call to lock and unlock transactions for spending.\n",
{}, {},
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"txid\" : \"transactionid\", (string) The transaction id locked\n" {RPCResult::Type::OBJ, "", "",
" \"vout\" : n (numeric) The vout value\n" {
" }\n" {RPCResult::Type::STR_HEX, "txid", "The transaction id locked"},
" ,...\n" {RPCResult::Type::NUM, "vout", "The vout value"},
"]\n" }},
}
}, },
RPCExamples{ RPCExamples{
"\nList the unspent transactions\n" "\nList the unspent transactions\n"
@ -2313,7 +2334,7 @@ static UniValue settxfee(const JSONRPCRequest& request)
{"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee in " + CURRENCY_UNIT + "/kB"}, {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee in " + CURRENCY_UNIT + "/kB"},
}, },
RPCResult{ RPCResult{
"true|false (boolean) Returns true if successful\n" RPCResult::Type::BOOL, "", "Returns true if successful"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("settxfee", "0.00001") HelpExampleCli("settxfee", "0.00001")
@ -2351,19 +2372,23 @@ static UniValue getbalances(const JSONRPCRequest& request)
"Returns an object with all balances in " + CURRENCY_UNIT + ".\n", "Returns an object with all balances in " + CURRENCY_UNIT + ".\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"mine\" : { (json object) balances from outputs that the wallet can sign\n" {
" \"trusted\" : xxx (numeric) trusted balance (outputs created by the wallet or confirmed outputs)\n" {RPCResult::Type::OBJ, "mine", "balances from outputs that the wallet can sign",
" \"untrusted_pending\" : xxx (numeric) untrusted pending balance (outputs created by others that are in the mempool)\n" {
" \"immature\" : xxx (numeric) balance from immature coinbase outputs\n" {RPCResult::Type::STR_AMOUNT, "trusted", "trusted balance (outputs created by the wallet or confirmed outputs)"},
" \"used\" : xxx (numeric) (only present if avoid_reuse is set) balance from coins sent to addresses that were previously spent from (potentially privacy violating)\n" {RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"},
" },\n" {RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"},
" \"watchonly\" : { (json object) watchonly balances (not present if wallet does not watch anything)\n" {RPCResult::Type::STR_AMOUNT, "used", "(only present if avoid_reuse is set) balance from coins sent to addresses that were previously spent from (potentially privacy violating)"},
" \"trusted\" : xxx (numeric) trusted balance (outputs created by the wallet or confirmed outputs)\n" }},
" \"untrusted_pending\" : xxx (numeric) untrusted pending balance (outputs created by others that are in the mempool)\n" {RPCResult::Type::OBJ, "watchonly", "watchonly balances (not present if wallet does not watch anything)",
" \"immature\" : xxx (numeric) balance from immature coinbase outputs\n" {
" },\n" {RPCResult::Type::STR_AMOUNT, "trusted", "trusted balance (outputs created by the wallet or confirmed outputs)"},
"}\n"}, {RPCResult::Type::STR_AMOUNT, "untrusted_pending", "untrusted pending balance (outputs created by others that are in the mempool)"},
{RPCResult::Type::STR_AMOUNT, "immature", "balance from immature coinbase outputs"},
}},
}
},
RPCExamples{ RPCExamples{
HelpExampleCli("getbalances", "") + HelpExampleCli("getbalances", "") +
HelpExampleRpc("getbalances", "")}, HelpExampleRpc("getbalances", "")},
@ -2417,27 +2442,29 @@ static UniValue getwalletinfo(const JSONRPCRequest& request)
"Returns an object containing various wallet state info.\n", "Returns an object containing various wallet state info.\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"walletname\" : xxxxx, (string) the wallet name\n" {
" \"walletversion\" : xxxxx, (numeric) the wallet version\n" {
" \"balance\" : xxxxxxx, (numeric) DEPRECATED. Identical to getbalances().mine.trusted\n" {RPCResult::Type::STR, "walletname", "the wallet name"},
" \"unconfirmed_balance\" : xxx, (numeric) DEPRECATED. Identical to getbalances().mine.untrusted_pending\n" {RPCResult::Type::NUM, "walletversion", "the wallet version"},
" \"immature_balance\" : xxxxxx, (numeric) DEPRECATED. Identical to getbalances().mine.immature\n" {RPCResult::Type::STR_AMOUNT, "balance", "DEPRECATED. Identical to getbalances().mine.trusted"},
" \"txcount\" : xxxxxxx, (numeric) the total number of transactions in the wallet\n" {RPCResult::Type::STR_AMOUNT, "unconfirmed_balance", "DEPRECATED. Identical to getbalances().mine.untrusted_pending"},
" \"keypoololdest\" : xxxxxx, (numeric) the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool\n" {RPCResult::Type::STR_AMOUNT, "immature_balance", "DEPRECATED. Identical to getbalances().mine.immature"},
" \"keypoolsize\" : xxxx, (numeric) how many new keys are pre-generated (only counts external keys)\n" {RPCResult::Type::NUM, "txcount", "the total number of transactions in the wallet"},
" \"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" {RPCResult::Type::NUM_TIME, "keypoololdest", "the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool"},
" \"unlocked_until\" : ttt, (numeric) the " + UNIX_EPOCH_TIME + " until which the wallet is unlocked for transfers, or 0 if the wallet is locked\n" {RPCResult::Type::NUM, "keypoolsize", "how many new keys are pre-generated (only counts external keys)"},
" \"paytxfee\" : x.xxxx, (numeric) the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB\n" {RPCResult::Type::NUM, "keypoolsize_hd_internal", "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)"},
" \"hdseedid\" : \"<hash160>\" (string, optional) the Hash160 of the HD seed (only present when HD is enabled)\n" {RPCResult::Type::NUM_TIME, "unlocked_until", "the " + UNIX_EPOCH_TIME + " until which the wallet is unlocked for transfers, or 0 if the wallet is locked"},
" \"private_keys_enabled\" : true|false (boolean) false if privatekeys are disabled for this wallet (enforced watch-only wallet)\n" {RPCResult::Type::STR_AMOUNT, "paytxfee", "the transaction fee configuration, set in " + CURRENCY_UNIT + "/kB"},
" \"avoid_reuse\" : true|false (boolean) whether this wallet tracks clean/dirty coins in terms of reuse\n" {RPCResult::Type::STR_HEX, "hdseedid", /* optional */ true, "the Hash160 of the HD seed (only present when HD is enabled)"},
" \"scanning\" : (json object) current scanning details, or false if no scan is in progress\n" {RPCResult::Type::BOOL, "private_keys_enabled", "false if privatekeys are disabled for this wallet (enforced watch-only wallet)"},
" {\n" {RPCResult::Type::BOOL, "avoid_reuse", "whether this wallet tracks clean/dirty coins in terms of reuse"},
" \"duration\" : xxxx (numeric) elapsed seconds since scan start\n" {RPCResult::Type::OBJ, "scanning", "current scanning details, or false if no scan is in progress",
" \"progress\" : x.xxxx, (numeric) scanning progress percentage [0.0, 1.0]\n" {
" }\n" {RPCResult::Type::NUM, "duration", "elapsed seconds since scan start"},
"}\n" {RPCResult::Type::NUM, "progress", "scanning progress percentage [0.0, 1.0]"},
}},
}},
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getwalletinfo", "") HelpExampleCli("getwalletinfo", "")
@ -2499,14 +2526,16 @@ static UniValue listwalletdir(const JSONRPCRequest& request)
"Returns a list of wallets in the wallet directory.\n", "Returns a list of wallets in the wallet directory.\n",
{}, {},
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"wallets\" : [ (json array of objects)\n" {
" {\n" {RPCResult::Type::ARR, "wallets", "",
" \"name\" : \"name\" (string) The wallet name\n" {
" }\n" {RPCResult::Type::OBJ, "", "",
" ,...\n" {
" ]\n" {RPCResult::Type::STR, "name", "The wallet name"},
"}\n" }},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("listwalletdir", "") HelpExampleCli("listwalletdir", "")
@ -2533,10 +2562,10 @@ static UniValue listwallets(const JSONRPCRequest& request)
"For full information on the wallet, use \"getwalletinfo\"\n", "For full information on the wallet, use \"getwalletinfo\"\n",
{}, {},
RPCResult{ RPCResult{
"[ (json array of strings)\n" RPCResult::Type::ARR, "", "",
" \"walletname\" (string) the wallet name\n" {
" ...\n" {RPCResult::Type::STR, "walletname", "the wallet name"},
"]\n" }
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("listwallets", "") HelpExampleCli("listwallets", "")
@ -2569,10 +2598,11 @@ static UniValue loadwallet(const JSONRPCRequest& request)
{"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The wallet directory or .dat file."}, {"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The wallet directory or .dat file."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"name\" : <wallet_name>, (string) The wallet name if loaded successfully.\n" {
" \"warning\" : <warning>, (string) Warning message if wallet was not loaded cleanly.\n" {RPCResult::Type::STR, "name", "The wallet name if loaded successfully."},
"}\n" {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("loadwallet", "\"test.dat\"") HelpExampleCli("loadwallet", "\"test.dat\"")
@ -2624,11 +2654,12 @@ static UniValue setwalletflag(const JSONRPCRequest& request)
{"value", RPCArg::Type::BOOL, /* default */ "true", "The new state."}, {"value", RPCArg::Type::BOOL, /* default */ "true", "The new state."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"flag_name\" : string (string) The name of the flag that was modified\n" {
" \"flag_state\" : bool (boolean) The new state of the flag\n" {RPCResult::Type::STR, "flag_name", "The name of the flag that was modified"},
" \"warnings\" : string (string) Any warnings associated with the change\n" {RPCResult::Type::BOOL, "flag_state", "The new state of the flag"},
"}\n" {RPCResult::Type::STR, "warnings", "Any warnings associated with the change"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("setwalletflag", "avoid_reuse") HelpExampleCli("setwalletflag", "avoid_reuse")
@ -2684,10 +2715,11 @@ static UniValue createwallet(const JSONRPCRequest& request)
{"avoid_reuse", RPCArg::Type::BOOL, /* default */ "false", "Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind."}, {"avoid_reuse", RPCArg::Type::BOOL, /* default */ "false", "Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"name\" : <wallet_name>, (string) The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path.\n" {
" \"warning\" : <warning>, (string) Warning message if wallet was not loaded cleanly.\n" {RPCResult::Type::STR, "name", "The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path."},
"}\n" {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("createwallet", "\"testwallet\"") HelpExampleCli("createwallet", "\"testwallet\"")
@ -2813,27 +2845,28 @@ static UniValue listunspent(const JSONRPCRequest& request)
"query_options"}, "query_options"},
}, },
RPCResult{ RPCResult{
"[ (array of json object)\n" RPCResult::Type::ARR, "", "",
" {\n" {
" \"txid\" : \"txid\", (string) the transaction id \n" {RPCResult::Type::OBJ, "", "",
" \"vout\" : n, (numeric) the vout value\n" {
" \"address\" : \"address\", (string) the bitcoin address\n" {RPCResult::Type::STR_HEX, "txid", "the transaction id"},
" \"label\" : \"label\", (string) The associated label, or \"\" for the default label\n" {RPCResult::Type::NUM, "vout", "the vout value"},
" \"scriptPubKey\" : \"key\", (string) the script key\n" {RPCResult::Type::STR, "address", "the bitcoin address"},
" \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n" {RPCResult::Type::STR, "label", "The associated label, or \"\" for the default label"},
" \"confirmations\" : n, (numeric) The number of confirmations\n" {RPCResult::Type::STR, "scriptPubKey", "the script key"},
" \"redeemScript\" : \"script\" (string) The redeemScript if scriptPubKey is P2SH\n" {RPCResult::Type::STR_AMOUNT, "amount", "the transaction output amount in " + CURRENCY_UNIT},
" \"witnessScript\" : \"script\" (string) witnessScript if the scriptPubKey is P2WSH or P2SH-P2WSH\n" {RPCResult::Type::NUM, "confirmations", "The number of confirmations"},
" \"spendable\" : xxx, (boolean) Whether we have the private keys to spend this output\n" {RPCResult::Type::STR_HEX, "redeemScript", "The redeemScript if scriptPubKey is P2SH"},
" \"solvable\" : xxx, (boolean) Whether we know how to spend this output, ignoring the lack of keys\n" {RPCResult::Type::STR, "witnessScript", "witnessScript if the scriptPubKey is P2WSH or P2SH-P2WSH"},
" \"reused\" : xxx, (boolean) (only present if avoid_reuse is set) Whether this output is reused/dirty (sent to an address that was previously spent from)\n" {RPCResult::Type::BOOL, "spendable", "Whether we have the private keys to spend this output"},
" \"desc\" : xxx, (string, only when solvable) A descriptor for spending this output\n" {RPCResult::Type::BOOL, "solvable", "Whether we know how to spend this output, ignoring the lack of keys"},
" \"safe\" : xxx (boolean) Whether this output is considered safe to spend. Unconfirmed transactions\n" {RPCResult::Type::BOOL, "reused", "(only present if avoid_reuse is set) Whether this output is reused/dirty (sent to an address that was previously spent from)"},
{RPCResult::Type::STR, "desc", "(only when solvable) A descriptor for spending this output"},
{RPCResult::Type::BOOL, "safe", "Whether this output is considered safe to spend. Unconfirmed transactions"
" from outside keys and unconfirmed replacement transactions are considered unsafe\n" " from outside keys and unconfirmed replacement transactions are considered unsafe\n"
" and are not eligible for spending by fundrawtransaction and sendtoaddress.\n" "and are not eligible for spending by fundrawtransaction and sendtoaddress."},
" }\n" }},
" ,...\n" }
"]\n"
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("listunspent", "") HelpExampleCli("listunspent", "")
@ -3171,11 +3204,12 @@ static UniValue fundrawtransaction(const JSONRPCRequest& request)
}, },
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"hex\" : \"value\", (string) The resulting raw transaction (hex-encoded string)\n" {
" \"fee\" : n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n" {RPCResult::Type::STR_HEX, "hex", "The resulting raw transaction (hex-encoded string)"},
" \"changepos\" : n (numeric) The position of the added change output, or -1\n" {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"},
"}\n" {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"},
}
}, },
RPCExamples{ RPCExamples{
"\nCreate a transaction with no inputs\n" "\nCreate a transaction with no inputs\n"
@ -3250,20 +3284,22 @@ UniValue signrawtransactionwithwallet(const JSONRPCRequest& request)
" \"SINGLE|ANYONECANPAY\""}, " \"SINGLE|ANYONECANPAY\""},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"hex\" : \"value\", (string) The hex-encoded raw transaction with signature(s)\n" {
" \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"},
" \"errors\" : [ (json array of objects) Script verification errors (if there are any)\n" {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
" {\n" {RPCResult::Type::ARR, "errors", "Script verification errors (if there are any)",
" \"txid\" : \"hash\", (string) The hash of the referenced, previous transaction\n" {
" \"vout\" : n, (numeric) The index of the output to spent and used as input\n" {RPCResult::Type::OBJ, "", "",
" \"scriptSig\" : \"hex\", (string) The hex-encoded signature script\n" {
" \"sequence\" : n, (numeric) Script sequence number\n" {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"},
" \"error\" : \"text\" (string) Verification or signing error related to the input\n" {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"},
" }\n" {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"},
" ,...\n" {RPCResult::Type::NUM, "sequence", "Script sequence number"},
" ]\n" {RPCResult::Type::STR, "error", "Verification or signing error related to the input"},
"}\n" }},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"")
@ -3360,13 +3396,16 @@ static UniValue bumpfee(const JSONRPCRequest& request)
"options"}, "options"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "", {
" \"psbt\" : \"psbt\", (string) The base64-encoded unsigned PSBT of the new transaction. Only returned when wallet private keys are disabled.\n" {RPCResult::Type::STR, "psbt", "The base64-encoded unsigned PSBT of the new transaction. Only returned when wallet private keys are disabled."},
" \"txid\" : \"value\", (string) The id of the new transaction. Only returned when wallet private keys are enabled.\n" {RPCResult::Type::STR_HEX, "txid", "The id of the new transaction. Only returned when wallet private keys are enabled."},
" \"origfee\" : n, (numeric) The fee of the replaced transaction.\n" {RPCResult::Type::STR_AMOUNT, "origfee", "The fee of the replaced transaction."},
" \"fee\" : n, (numeric) The fee of the new transaction.\n" {RPCResult::Type::STR_AMOUNT, "fee", "The fee of the new transaction."},
" \"errors\" : [ str... ] (json array of strings) Errors encountered during processing (may be empty).\n" {RPCResult::Type::ARR, "errors", "Errors encountered during processing (may be empty).",
"}\n" {
{RPCResult::Type::STR, "", ""},
}},
}
}, },
RPCExamples{ RPCExamples{
"\nBump the fee, get the new transaction\'s txid\n" + "\nBump the fee, get the new transaction\'s txid\n" +
@ -3521,10 +3560,11 @@ UniValue rescanblockchain(const JSONRPCRequest& request)
{"stop_height", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "the last block height that should be scanned. If none is provided it will rescan up to the tip at return time of this call."}, {"stop_height", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "the last block height that should be scanned. If none is provided it will rescan up to the tip at return time of this call."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"start_height\" (numeric) The block height where the rescan started (the requested height or 0)\n" {
" \"stop_height\" (numeric) The height of the last rescanned block. May be null in rare cases if there was a reorg and the call didn't scan any blocks because they were already scanned in the background.\n" {RPCResult::Type::NUM, "start_height", "The block height where the rescan started (the requested height or 0)"},
"}\n" {RPCResult::Type::NUM, "stop_height", "The height of the last rescanned block. May be null in rare cases if there was a reorg and the call didn't scan any blocks because they were already scanned in the background."},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("rescanblockchain", "100000 120000") HelpExampleCli("rescanblockchain", "100000 120000")
@ -3729,49 +3769,52 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for which to get information."}, {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for which to get information."},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"address\" : \"address\", (string) The bitcoin address validated.\n" {
" \"scriptPubKey\" : \"hex\", (string) The hex-encoded scriptPubKey generated by the address.\n" {RPCResult::Type::STR, "address", "The bitcoin address validated."},
" \"ismine\" : true|false, (boolean) If the address is yours.\n" {RPCResult::Type::STR_HEX, "scriptPubKey", "The hex-encoded scriptPubKey generated by the address."},
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly.\n" {RPCResult::Type::BOOL, "ismine", "If the address is yours."},
" \"solvable\" : true|false, (boolean) If we know how to spend coins sent to this address, ignoring the possible lack of private keys.\n" {RPCResult::Type::BOOL, "iswatchonly", "If the address is watchonly."},
" \"desc\" : \"desc\", (string, optional) A descriptor for spending coins sent to this address (only when solvable).\n" {RPCResult::Type::BOOL, "solvable", "If we know how to spend coins sent to this address, ignoring the possible lack of private keys."},
" \"isscript\" : true|false, (boolean) If the key is a script.\n" {RPCResult::Type::STR, "desc", /* optional */ true, "A descriptor for spending coins sent to this address (only when solvable)."},
" \"ischange\" : true|false, (boolean) If the address was used for change output.\n" {RPCResult::Type::BOOL, "isscript", "If the key is a script."},
" \"iswitness\" : true|false, (boolean) If the address is a witness address.\n" {RPCResult::Type::BOOL, "ischange", "If the address was used for change output."},
" \"witness_version\" : version (numeric, optional) The version number of the witness program.\n" {RPCResult::Type::BOOL, "iswitness", "If the address is a witness address."},
" \"witness_program\" : \"hex\" (string, optional) The hex value of the witness program.\n" {RPCResult::Type::NUM, "witness_version", /* optional */ true, "The version number of the witness program."},
" \"script\" : \"type\" (string, optional) The output script type. Only if isscript is true and the redeemscript is known. Possible\n" {RPCResult::Type::STR_HEX, "witness_program", /* optional */ true, "The hex value of the witness program."},
{RPCResult::Type::STR, "script", /* optional */ true, "The output script type. Only if isscript is true and the redeemscript is known. Possible\n"
" types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash,\n" " types: nonstandard, pubkey, pubkeyhash, scripthash, multisig, nulldata, witness_v0_keyhash,\n"
" witness_v0_scripthash, witness_unknown.\n" "witness_v0_scripthash, witness_unknown."},
" \"hex\" : \"hex\", (string, optional) The redeemscript for the p2sh address.\n" {RPCResult::Type::STR_HEX, "hex", /* optional */ true, "The redeemscript for the p2sh address."},
" \"pubkeys\" (array, optional) Array of pubkeys associated with the known redeemscript (only if script is multisig).\n" {RPCResult::Type::ARR, "pubkeys", /* optional */ true, "Array of pubkeys associated with the known redeemscript (only if script is multisig).",
" [\n" {
" \"pubkey\" (string)\n" {RPCResult::Type::STR, "pubkey", ""},
" ,...\n" }},
" ]\n" {RPCResult::Type::NUM, "sigsrequired", /* optional */ true, "The number of signatures required to spend multisig output (only if script is multisig)."},
" \"sigsrequired\" : xxxxx (numeric, optional) The number of signatures required to spend multisig output (only if script is multisig).\n" {RPCResult::Type::STR_HEX, "pubkey", /* optional */ true, "The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH)."},
" \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key for single-key addresses (possibly embedded in P2SH or P2WSH).\n" {RPCResult::Type::OBJ, "embedded", /* optional */ true, "Information about the address embedded in P2SH or P2WSH, if relevant and known.",
" \"embedded\" : {...}, (object, optional) Information about the address embedded in P2SH or P2WSH, if relevant and known. Includes all\n" {
{RPCResult::Type::ELISION, "", "Includes all\n"
" getaddressinfo output fields for the embedded address, excluding metadata (timestamp, hdkeypath,\n" " getaddressinfo output fields for the embedded address, excluding metadata (timestamp, hdkeypath,\n"
" hdseedid) and relation to the wallet (ismine, iswatchonly).\n" "hdseedid) and relation to the wallet (ismine, iswatchonly)."},
" \"iscompressed\" : true|false, (boolean, optional) If the pubkey is compressed.\n" }},
" \"label\" : \"label\" (string) DEPRECATED. The label associated with the address. Defaults to \"\". Replaced by the labels array below.\n" {RPCResult::Type::BOOL, "iscompressed", /* optional */ true, "If the pubkey is compressed."},
" \"timestamp\" : timestamp, (number, optional) The creation time of the key, if available, expressed in " + UNIX_EPOCH_TIME + ".\n" {RPCResult::Type::STR, "label", "DEPRECATED. The label associated with the address. Defaults to \"\". Replaced by the labels array below."},
" \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath, if the key is HD and available.\n" {RPCResult::Type::NUM_TIME, "timestamp", /* optional */ true, "The creation time of the key, if available, expressed in " + UNIX_EPOCH_TIME + "."},
" \"hdseedid\" : \"<hash160>\" (string, optional) The Hash160 of the HD seed.\n" {RPCResult::Type::STR, "hdkeypath", /* optional */ true, "The HD keypath, if the key is HD and available."},
" \"hdmasterfingerprint\" : \"<hash160>\" (string, optional) The fingerprint of the master key.\n" {RPCResult::Type::STR_HEX, "hdseedid", /* optional */ true, "The Hash160 of the HD seed."},
" \"labels\" (json array) Array of labels associated with the address. Currently limited to one label but returned\n" {RPCResult::Type::STR_HEX, "hdmasterfingerprint", /* optional */ true, "The fingerprint of the master key."},
" as an array to keep the API stable if multiple labels are enabled in the future.\n" {RPCResult::Type::ARR, "labels", "Array of labels associated with the address. Currently limited to one label but returned\n"
" [\n" "as an array to keep the API stable if multiple labels are enabled in the future.",
" \"label name\" (string) The label name. Defaults to \"\".\n" {
" DEPRECATED, will be removed in 0.21. To re-enable, launch bitcoind with `-deprecatedrpc=labelspurpose`:\n" {RPCResult::Type::STR, "label name", "The label name. Defaults to \"\"."},
" {\n" {RPCResult::Type::OBJ, "", "label data, DEPRECATED, will be removed in 0.21. To re-enable, launch bitcoind with `-deprecatedrpc=labelspurpose`",
" \"name\" : \"label name\" (string) The label name. Defaults to \"\".\n" {
" \"purpose\" : \"purpose\" (string) The purpose of the associated address (send or receive).\n" {RPCResult::Type::STR, "name", "The label name. Defaults to \"\"."},
" }\n" {RPCResult::Type::STR, "purpose", "The purpose of the associated address (send or receive)."},
" ]\n" }},
"}\n" }},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getaddressinfo", EXAMPLE_ADDRESS) + HelpExampleCli("getaddressinfo", EXAMPLE_ADDRESS) +
@ -3868,11 +3911,13 @@ static UniValue getaddressesbylabel(const JSONRPCRequest& request)
{"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The label."}, {"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The label."},
}, },
RPCResult{ RPCResult{
"{ (json object with addresses as keys)\n" RPCResult::Type::OBJ_DYN, "", "json object with addresses as keys",
" \"address\" : { (json object with information about address)\n" {
" \"purpose\" : \"string\" (string) Purpose of address (\"send\" for sending address, \"receive\" for receiving address)\n" {RPCResult::Type::OBJ, "address", "json object with information about address",
" },...\n" {
"}\n" {RPCResult::Type::STR, "purpose", "Purpose of address (\"send\" for sending address, \"receive\" for receiving address)"},
}},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getaddressesbylabel", "\"tabby\"") HelpExampleCli("getaddressesbylabel", "\"tabby\"")
@ -3925,10 +3970,10 @@ static UniValue listlabels(const JSONRPCRequest& request)
{"purpose", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Address purpose to list labels for ('send','receive'). An empty string is the same as not providing this argument."}, {"purpose", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Address purpose to list labels for ('send','receive'). An empty string is the same as not providing this argument."},
}, },
RPCResult{ RPCResult{
"[ (json array of string)\n" RPCResult::Type::ARR, "", "",
" \"label\", (string) Label name\n" {
" ...\n" {RPCResult::Type::STR, "label", "Label name"},
"]\n" }
}, },
RPCExamples{ RPCExamples{
"\nList all labels\n" "\nList all labels\n"
@ -4069,10 +4114,11 @@ UniValue walletprocesspsbt(const JSONRPCRequest& request)
{"bip32derivs", RPCArg::Type::BOOL, /* default */ "true", "Include BIP 32 derivation paths for public keys if we know them"}, {"bip32derivs", RPCArg::Type::BOOL, /* default */ "true", "Include BIP 32 derivation paths for public keys if we know them"},
}, },
RPCResult{ RPCResult{
"{ (json object)\n" RPCResult::Type::OBJ, "", "",
" \"psbt\" : \"str\", (string) The base64-encoded partially signed transaction\n" {
" \"complete\" : true|false, (boolean) If the transaction has a complete set of signatures\n" {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"},
"}\n" {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("walletprocesspsbt", "\"psbt\"") HelpExampleCli("walletprocesspsbt", "\"psbt\"")
@ -4179,11 +4225,12 @@ UniValue walletcreatefundedpsbt(const JSONRPCRequest& request)
{"bip32derivs", RPCArg::Type::BOOL, /* default */ "true", "Include BIP 32 derivation paths for public keys if we know them"}, {"bip32derivs", RPCArg::Type::BOOL, /* default */ "true", "Include BIP 32 derivation paths for public keys if we know them"},
}, },
RPCResult{ RPCResult{
"{\n" RPCResult::Type::OBJ, "", "",
" \"psbt\" : \"value\", (string) The resulting raw transaction (base64-encoded string)\n" {
" \"fee\" : n, (numeric) Fee in " + CURRENCY_UNIT + " the resulting transaction pays\n" {RPCResult::Type::STR, "psbt", "The resulting raw transaction (base64-encoded string)"},
" \"changepos\" : n (numeric) The position of the added change output, or -1\n" {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"},
"}\n" {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"},
}
}, },
RPCExamples{ RPCExamples{
"\nCreate a transaction with no inputs\n" "\nCreate a transaction with no inputs\n"

View file

@ -19,14 +19,15 @@ UniValue getzmqnotifications(const JSONRPCRequest& request)
"\nReturns information about the active ZeroMQ notifications.\n", "\nReturns information about the active ZeroMQ notifications.\n",
{}, {},
RPCResult{ RPCResult{
"[\n" RPCResult::Type::ARR, "", "",
" { (json object)\n" {
" \"type\" : \"pubhashtx\", (string) Type of notification\n" {RPCResult::Type::OBJ, "", "",
" \"address\" : \"...\", (string) Address of the publisher\n" {
" \"hwm\" : n (numeric) Outbound message high water mark\n" {RPCResult::Type::STR, "type", "Type of notification"},
" },\n" {RPCResult::Type::STR, "address", "Address of the publisher"},
" ...\n" {RPCResult::Type::NUM, "hwm", "Outbound message high water mark"},
"]\n" }},
}
}, },
RPCExamples{ RPCExamples{
HelpExampleCli("getzmqnotifications", "") HelpExampleCli("getzmqnotifications", "")