1

I'm trying to send POST request to LocalBitcoins API server but I'm only receiving errors (41 and 43) despite the GET request works perfectly even with parameters (arguments).

Sub initrequest()

'this is a POST request with no arguments  that results in error  
JsonResponse = PrivateLocalBTC("POST", "/api/notifications/mark_as_read/9b9c2b5a16a3/")

'this is a GET request, with "ads=.." parameter, that works
'JsonResponse = PrivateLocalBTC("GET", "/api/ad-get/", "ads=771318")

Debug.Print JsonResponse

End Sub

and there is the HTTP request sub:

Function PrivateLocalBTC(Method As String, endpoint As String, Optional params As String) As String

Dim NonceUnique As String
NonceUnique = CreateNonce(13)
TradeApiSite = "https://localbitcoins.com"
apikey = "..............."
secretkey = "............"

Message = NonceUnique & apikey & endpoint & params
apisign = ComputeHash_C("SHA256", Message, secretkey, "STRHEX")
If params <> "" Then urlparams = "?" & params
Url = TradeApiSite & endpoint & urlparams

Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
objHTTP.Open Method, Url, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objHTTP.setRequestHeader "Apiauth-Key", apikey
objHTTP.setRequestHeader "Apiauth-Nonce", NonceUnique
objHTTP.setRequestHeader "Apiauth-Signature", apisign
objHTTP.Send ("")

objHTTP.waitForResponse
PrivateLocalBTC = objHTTP.ResponseText
Set objHTTP = Nothing
End Function

I've tried many variation putting endpoint, nonce, apikey in the request body at .Send command , urlencoding, but no positive result.

ComputeHash_C, CreateNonce are separate functions. The code is inspired by the great shared work of https://github.com/krijnsent/crypto_vba !

LocalBitcoins API doc is here: https://localbitcoins.com/api-docs/

bluequasi
  • 11
  • 1
  • 3

2 Answers2

0

It appears that after braking brains over an issue, one have to post the question on stackoverflow in order to have the revelation for the answer... I realized that I'm using an apikey that only can read from server so, naturally, cannot modify server data by a POST request. Creating and using the right key, with write rights, solved the issue! The working code is:

Function PrivateLocalBTC(Method As String, endpoint As String, Optional params As String) As String
'Method "GET', "POST"
'params format: "argument1=value&argument2=value&...."

Dim NonceUnique As String
NonceUnique = CreateNonce(13)
TradeApiSite = "https://localbitcoins.com"
apikey = "..............."
secretkey = "............"

Message = NonceUnique & apikey & endpoint & params
apisign = ComputeHash_C("SHA256", Message, secretkey, "STRHEX")
If params <> "" Then urlparams = "?" & params
Url = TradeApiSite & endpoint & urlparams

Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
objHTTP.Open Method, Url, False
objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
objHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
objHTTP.setRequestHeader "Apiauth-Key", apikey
objHTTP.setRequestHeader "Apiauth-Nonce", NonceUnique
objHTTP.setRequestHeader "Apiauth-Signature", apisign
objHTTP.Send params

objHTTP.waitForResponse
PrivateLocalBTC = objHTTP.ResponseText
Set objHTTP = Nothing
End Function

The only modification is "objHTTP.Send params". Be sure to use the correct api keys!

bluequasi
  • 11
  • 1
  • 3
0

I fixed error no. 41. I modified this example enter link description here to show that works, (read my NOTE: comments to understand better where is the problem) Read my NOTE: comments.

<?php
function localbitcoins_query($path, array $req = Array()) { 
   $key='yourkey';
   $secret='yoursecret';      

   $array_mt = explode(' ', microtime());   
   $nonce = $array_mt[1].substr($array_mt[0], 2, 6);   

   $get = "";
   if ($req) {
      $get=http_build_query($req);
   }
   $postdata=$nonce.$key.$path.$get; // NOTE: here $postdata goes without '?' char before the parameters!

   $sign = strtoupper(hash_hmac('sha256', $postdata, $secret)); 

   $headers = array(
      'Apiauth-Signature:'.$sign,
      'Apiauth-Key:'.$key,
      'Apiauth-Nonce:'.$nonce
   );
   $ch = null;
   $ch = curl_init('https://localbitcoins.com'.$path.( $get=="" ? "" : "?".$get)); // NOTE:  here it's necesary '?' char before the parameters!
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
   curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
   curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);

   $res = curl_exec($ch);
   if ($res === false) throw new Exception('Curl error: '.curlerror($ch));
   $dec = json_decode($res, true);   
   if (!$dec) throw new Exception('Invalid data: '.$res);
   curl_close($ch);   
   return $dec;
}

$getinfo = array();
$api_endpoint = '/api/dashboard/closed/';
$array_params = array(    "order_by" => "-closed_at"
                        , "start_at" => "2019-08-14 18:00:26+00:00" 
                        );
$getinfo = localbitcoins_query($api_endpoint,$array_params);
echo "<pre>"; print_r($getinfo); echo "</pre>"; 
?>
NOLUP
  • 1
  • 2