message: cli: lift -rpcwallet logic up to CommandLineRPC()
  to allow passing rpcwallet independently from the -rpcwallet user option, and to
  move the logic to the top-level layer where most of the other option args are
  handled.
diff: #include <chainparamsbase.h>
  #include <clientversion.h>
  +#include <optional.h>
  #include <rpc/client.h>
  #include <rpc/protocol.h>
  #include <rpc/request.h>
  @@ -304,7 +305,7 @@ public:
  }
  };
  -static UniValue CallRPC(BaseRequestHandler *rh, const std::string& strMethod, const std::vector<std::string>& args)
  +static UniValue CallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const Optional<std::string>& rpcwallet = {})
  {
  std::string host;
  // In preference order, we choose the following for the port:
  @@ -369,14 +370,12 @@ static UniValue CallRPC(BaseRequestHandler *rh, const std::string& strMethod, co
  // check if we should use a special wallet endpoint
  std::string endpoint = "/";
  - if (!gArgs.GetArgs("-rpcwallet").empty()) {
  - std::string walletName = gArgs.GetArg("-rpcwallet", "");
  - char *encodedURI = evhttp_uriencode(walletName.data(), walletName.size(), false);
  + if (rpcwallet) {
  + char* encodedURI = evhttp_uriencode(rpcwallet->data(), rpcwallet->size(), false);
  if (encodedURI) {
  endpoint = "/wallet/" + std::string(encodedURI);
  free(encodedURI);
  - }
  - else {
  + } else {
  throw CConnectionFailed("uri-encode failed");
  }
  }
  @@ -423,17 +422,18 @@ static UniValue CallRPC(BaseRequestHandler *rh, const std::string& strMethod, co
  *
  * @param[in] rh Pointer to RequestHandler.
  * @param[in] strMethod Reference to const string method to forward to CallRPC.
  + * @param[in] rpcwallet Reference to const optional string wallet name to forward to CallRPC.
  * @returns the RPC response as a UniValue object.
  * @throws a CConnectionFailed std::runtime_error if connection failed or RPC server still in warmup.
  */
  -static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args)
  +static UniValue ConnectAndCallRPC(BaseRequestHandler* rh, const std::string& strMethod, const std::vector<std::string>& args, const Optional<std::string>& rpcwallet = {})
  {
  UniValue response(UniValue::VOBJ);
  // Execute and handle connection failures with -rpcwait.
  const bool fWait = gArgs.GetBoolArg("-rpcwait", false);
  do {
  try {
  - response = CallRPC(rh, strMethod, args);
  + response = CallRPC(rh, strMethod, args, rpcwallet);
  if (fWait) {
  const UniValue& error = find_value(response, "error");
  if (!error.isNull() && error["code"].get_int() == RPC_IN_WARMUP) {
  @@ -519,7 +519,9 @@ static int CommandLineRPC(int argc, char *argv[])
  method = args[0];
  args.erase(args.begin()); // Remove trailing method name from arguments vector
  }
  - const UniValue reply = ConnectAndCallRPC(rh.get(), method, args);
  + Optional<std::string> wallet_name{};
  + if (gArgs.IsArgSet("-rpcwallet")) wallet_name = gArgs.GetArg("-rpcwallet", "");
  + const UniValue reply = ConnectAndCallRPC(rh.get(), method, args, wallet_name);
  // Parse reply
  UniValue result = find_value(reply, "result");
  