diff options
-rw-r--r-- | src/rpc/util.cpp | 52 | ||||
-rw-r--r-- | src/rpc/util.h | 1 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 2 |
3 files changed, 55 insertions, 0 deletions
diff --git a/src/rpc/util.cpp b/src/rpc/util.cpp index b4533c14d0..d844074601 100644 --- a/src/rpc/util.cpp +++ b/src/rpc/util.cpp @@ -113,11 +113,63 @@ std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey) return ParseHexV(find_value(o, strKey), strKey); } +namespace { + +/** + * Quote an argument for shell. + * + * @note This is intended for help, not for security-sensitive purposes. + */ +std::string ShellQuote(const std::string& s) +{ + std::string result; + result.reserve(s.size() * 2); + for (const char ch: s) { + if (ch == '\'') { + result += "'\''"; + } else { + result += ch; + } + } + return "'" + result + "'"; +} + +/** + * Shell-quotes the argument if it needs quoting, else returns it literally, to save typing. + * + * @note This is intended for help, not for security-sensitive purposes. + */ +std::string ShellQuoteIfNeeded(const std::string& s) +{ + for (const char ch: s) { + if (ch == ' ' || ch == '\'' || ch == '"') { + return ShellQuote(s); + } + } + + return s; +} + +} + std::string HelpExampleCli(const std::string& methodname, const std::string& args) { return "> bitcoin-cli " + methodname + " " + args + "\n"; } +std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args) +{ + std::string result = "> bitcoin-cli -named " + methodname; + for (const auto& argpair: args) { + const auto& value = argpair.second.isStr() + ? argpair.second.get_str() + : argpair.second.write(); + result += " " + argpair.first + "=" + ShellQuoteIfNeeded(value); + } + result += "\n"; + return result; +} + std::string HelpExampleRpc(const std::string& methodname, const std::string& args) { return "> curl --user myusername --data-binary '{\"jsonrpc\": \"1.0\", \"id\": \"curltest\", " diff --git a/src/rpc/util.h b/src/rpc/util.h index 184dfc2940..c87c3db6f0 100644 --- a/src/rpc/util.h +++ b/src/rpc/util.h @@ -81,6 +81,7 @@ extern CAmount AmountFromValue(const UniValue& value); using RPCArgList = std::vector<std::pair<std::string, UniValue>>; extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); +extern std::string HelpExampleCliNamed(const std::string& methodname, const RPCArgList& args); extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); extern std::string HelpExampleRpcNamed(const std::string& methodname, const RPCArgList& args); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bfc42ac1b0..f065332c99 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2738,6 +2738,8 @@ static RPCHelpMan createwallet() RPCExamples{ HelpExampleCli("createwallet", "\"testwallet\"") + HelpExampleRpc("createwallet", "\"testwallet\"") + + HelpExampleCliNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}}) + + HelpExampleRpcNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}}) }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { |