Repository: bitcoin/bitcoin
File: src/rpc/client.cpp (C++)

Code before:
    std::string paramName;  //!< parameter name
    ParamFormat format{ParamFormat::JSON}; //!< parameter format
};

// clang-format off
/**
 * Specify a (method, idx, name, format) here if the argument is a non-string RPC
 * argument and needs to be converted from JSON, or if it is a string argument
 * passed to a method that accepts '=' characters in string arguments.
 *
 * JSON parameters need to be listed here to make bitcoin-cli treat command line
 * arguments as JSON values instead of strings.
 *
 * String parameters need to be listed here for methods accepting string
 * arguments with '=' characters, to make bitcoin-cli treat these command line
 * arguments as positional parameters instead of named parameters when -named is
 * used. For example, passing "key=store" as a parameter for some method would split
 * "key" as a param name and "store" as a param value rather than passing "key=store"
 * as a whole positional parameter when -named is used. This is useful when we want to pass the
 * params as positional even if we are specifying -named. This special handling is not
 * needed for string parameters that are guaranteed not to contain an '=' character.
 *
 * IMPORTANT: If one string parameter is listed for a method, other string
 * parameters for that method need to be listed as well so bitcoin-cli does not
 * make the opposite mistake and pass other arguments by position instead of
 * name because it does not recognize their names.
 *
 * @note Parameter indexes start from 0.
 */
static const CRPCConvertParam vRPCConvertParams[] =
{
    { "setmocktime", 0, "timestamp" },
    { "mockscheduler", 0, "delta_time" },
    { "utxoupdatepsbt", 0, "psbt", ParamFormat::STRING },
    { "utxoupdatepsbt", 1, "descriptors" },
    { "generatetoaddress", 0, "nblocks" },
    { "generatetoaddress", 2, "maxtries" },
    { "generatetodescriptor", 0, "num_blocks" },
    { "generatetodescriptor", 2, "maxtries" },
    { "generateblock", 1, "transactions" },
    { "generateblock", 2, "submit" },
    { "getnetworkhashps", 0, "nblocks" },
    { "getnetworkhashps", 1, "height" },
    { "sendtoaddress", 0, "address", ParamFormat::STRING },
    { "sendtoaddress", 1, "amount" },
    { "sendtoaddress", 2, "comment", ParamFormat::STRING },
    { "sendtoaddress", 3, "comment_to", ParamFormat::STRING },
    { "sendtoaddress", 4, "subtractfeefromamount" },
    { "sendtoaddress", 5 , "replaceable" },
    { "sendtoaddress", 6 , "conf_target" },
    { "sendtoaddress", 7, "estimate_mode", ParamFormat::STRING },

Review comment (suggestion):
In commit "rpc: Handle -named argument parsing where '=' character is used" (fbeacfabe802c24b427bee2cd82da1f12ef9899d)

Just IMO, but I feel like the example is confusing because "key=store" looks like a case where "key" actually is a named parameter and = sign should be parsed, not a case where it shouldn't be parsed. Also the next two sentences seem to just be repeating what the first two sentences say without out adding anything new. And I'm not sure the "IMPORTANT" section is really so important. I think the comment starts with a good one-line summary, and after that things listed go from most to least important. The important requirement is to list JSON parameters, everything else just provides nicer behavior when ambiguous -named command lines are used.

I suggested some documentation edits addressing this in da919fb63c519ac91c9704c58f1bbe522d7a8879 ([tag](https://github.com/ryanofsky/bitcoin/commits/review.32821.7-edit.3)) in case it might be useful.

Code after:
    std::string methodName; //!< method whose params want conversion
    int paramIdx;           //!< 0-based idx of param to convert
    std::string paramName;  //!< parameter name
    ParamFormat format{ParamFormat::JSON}; //!< parameter format
};

// clang-format off
/**
 * Specify a (method, idx, name, format) here if the argument is a non-string RPC
 * argument and needs to be converted from JSON, or if it is a string argument
 * passed to a method that accepts '=' characters in any string arguments.
 *
 * JSON parameters need to be listed here to make bitcoin-cli parse command line
 * arguments as JSON, instead of passing them as raw strings. `JSON` and
 * `JSON_OR_STRING` formats both make `bitcoin-cli` attempt to parse the
 * argument as JSON. But if parsing fails, the former triggers an error while
 * the latter falls back to passing the argument as a raw string. This is
 * useful for arguments like hash_or_height, allowing invocations such as
 * `bitcoin-cli getblockstats <hash>` without needing to quote the hash string
 * as JSON (`'"<hash>"'`).
 *
 * String parameters that may contain an '=' character (e.g. base64 strings,
 * filenames, or labels) need to be listed here with format `ParamFormat::STRING`
 * to make bitcoin-cli treat them as positional parameters when `-named` is used.
 * This prevents `bitcoin-cli` from splitting strings like "my=wallet" into a named
 * argument "my" and value "wallet" when the whole string is intended to be a
 * single positional argument. And if one string parameter is listed for a method,
 * other string parameters for that method need to be listed as well so bitcoin-cli
 * does not make the opposite mistake and pass other arguments by position instead of
 * name because it does not recognize their names. See \ref RPCConvertNamedValues
 * for more information on how named and positional arguments are distinguished with
 * -named.
 *
 * @note Parameter indexes start from 0.
 */
static const CRPCConvertParam vRPCConvertParams[] =
{
    { "setmocktime", 0, "timestamp" },
    { "mockscheduler", 0, "delta_time" },
    { "utxoupdatepsbt", 0, "psbt", ParamFormat::STRING },
    { "utxoupdatepsbt", 1, "descriptors" },
    { "generatetoaddress", 0, "nblocks" },
    { "generatetoaddress", 2, "maxtries" },
    { "generatetodescriptor", 0, "num_blocks" },
    { "generatetodescriptor", 2, "maxtries" },
    { "generateblock", 1, "transactions" },
    { "generateblock", 2, "submit" },
    { "getnetworkhashps", 0, "nblocks" },
    { "getnetworkhashps", 1, "height" },
    { "sendtoaddress", 0, "address", ParamFormat::STRING },
    { "sendtoaddress", 1, "amount" },