If I want to call the Wallet RPC functions from C++ is there an example of how I can do this. I have something using libcurl but I am unsure if I am doing it correctly.

static size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp) {
  ((std::string *) userp)->append((char *) contents, size * nmemb);
  return size * nmemb;

int main() {

  std::string method = "get_balance";
  std::string params = "{"account_index":0,"address_indicies":[0,1]}";

  CURL *curl;
  CURLcode res;
  std::string readBuffer;

  curl = curl_easy_init();
  if (curl) {
    curl_easy_setopt(curl, CURLOPT_URL, "");
    curl_easy_setopt(curl, CURLOPT_POST, 1L);
    const std::string &postField = R"({"jsonrpc":"2.0","id":"0","method":")" + method +
                                   R"(","params":)" + params + "}";

    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postField.c_str());

    auto userPassword =  "test:test";

    // Set the authorization to use the username and password.
    curl_easy_setopt(curl, CURLOPT_USERPWD, userPassword.c_str());
    curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);

    // Give a call back function and a string to write the callback data into.
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, true);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);

    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 3);

    // Set the content type to be application json.
    struct curl_slist *hs=NULL;
    hs = curl_slist_append(hs, "Accept: application/json");
    hs = curl_slist_append(hs, "Content-Type: application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hs);

    res = curl_easy_perform(curl);

Right now, this just repeatedly retries and the verbose looks like the following.

*   Trying
* Connected to () port 8080 (#0)
* Server auth using Digest with user 'test'
> POST /json_rpc HTTP/1.1
Accept: */*
Content-Length: 0
Content-Type: application/x-www-form-urlencoded

* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Unauthorized
< Server: Epee-based
< Content-Length: 98
< Content-Type: text/html
< Last-Modified: Sat, 14 Nov 2020 19:22:09 GMT
< Accept-Ranges: bytes
< WWW-authenticate: Digest qop="auth",algorithm=MD5,realm="monero-rpc",nonce="FRml5Rcf3sdumCrp0VyFzg==",stale=false
* Ignoring duplicate digest auth header.
< WWW-authenticate: Digest qop="auth",algorithm=MD5-sess,realm="monero-rpc",nonce="FRml5Rcf3sdumCrp0VyFzg==",stale=false
* Ignoring the response-body
* Connection #0 to host left intact
* Issue another request to this URL: ''
* Found bundle for host 0x562551d5ca00 [serially]
* Connection #0 is still name resolving, can't reuse
* Hostname was found in DNS cache
  • I suspect part of your problem is the fact you use CURLOPT_CUSTOMREQUEST rather than CURLOPT_POST. From the curl docs: "Many people have wrongly used this option to replace the entire request with their own, including multiple headers and POST contents. While that might work in many cases, it will cause libcurl to send invalid requests and it could possibly confuse the remote server badly.".
    – jtgrassie
    Commented Nov 14, 2020 at 19:55
  • Okay I have fixed that bit. I am still getting the 401 unauthorized. I checked and my code works if I do --disable-rpc-login but I assume that is fairly unsafe.
    – Keiros
    Commented Nov 14, 2020 at 20:13
  • You also don't have any redirect/location handling in your code. When auth is used, you will get a redirection for authentication.
    – jtgrassie
    Commented Nov 14, 2020 at 20:21
  • You mean a READDATA?
    – Keiros
    Commented Nov 14, 2020 at 20:24
  • No. That is a read data option that has nothing to do with redirection. See options like CURLOPT_POSTREDIR / CURLOPT_FOLLOWLOCATION.
    – jtgrassie
    Commented Nov 14, 2020 at 20:27


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.