in reply to Re^7: Invalid nonce
in thread Invalid nonce

The string you compute for your signature does not match the string from the example code.

For debugging, print out the string you compute the signature over, and compare that to the example code string.

message = 'BITSTAMP ' + api_key + \ 'POST' + \ 'www.bitstamp.net' + \ '/api/v2/user_transactions/' + \ '' + \ content_type + \ nonce + \ timestamp + \ 'v2' + \ payload_string

Your code should be:

my $msg = $apiKey.'POST'.$urlcb.$urlpath.$ContentType.$nonce.$timestam +p.$API_Version.$Query, $apiSecret; print "Computing signature over [$msg]\n"; my $signature = hmac_sha256_hex($msg, $apiSecret);

Then, compare the output of that part with the message as it is constructed in the documentation. There are differences between the two.

Replies are listed 'Best First'.
Re^9: Invalid nonce
by frank1 (Monk) on Jul 20, 2024 at 12:11 UTC

    the problem still persists

    Error: {"status": "error", "reason": "Invalid signature", "code": "API0005"}

    my $apiKey = 'BITSTAMP p25F7aWa'; my $apiSecret = 'gisWNuYX4Q'; my $urlcb = "https://www.bitstamp.net"; my $url = URI->new($urlcb); my $urlpath = $url->path('/api/v2/usdt_withdrawal/'); my @Char = ('a'..'z'); my $Leng = 36; my $RandomChar = ''; for (1..$Leng) { $RandomChar .= $Char[int rand @Char]; } my $timestamp = int (gettimeofday * 1000); my $nonce = $RandomChar; my $Query = URI->new(); $Query->query_form( 'currency' => "USDT", 'network' => "ethereum", 'address' => "Ef4cAwayizMH", 'amount' => "4" ); my $API_Version = 'v2'; my $ContentType = "application/x-www-form-urlencoded"; my $msg = $apiKey.'POST'.$urlcb.$urlpath.$ContentType.$nonce.$timestam +p.$API_Version.$Query, $apiSecret; my $signature = hmac_sha256_hex($msg, $apiSecret); my %payload = ( "X-Auth" => $apiKey, "X-Auth-Signature" => $signature, "X-Auth-Nonce" => $nonce, "X-Auth-Timestamp" => $timestamp, "X-Auth-Version" => $API_Version, "Content-Type" => $ContentType ); my $req = HTTP::Request->new(POST=>$url); $req->header(%payload); $req->content($Query); my $resp = $ua->request($req); if($resp->is_success){ print $resp->content ."\n"; } else{ print "Error: " . $resp->content; }

      So, maybe post what the script outputs, and then tell us part-by-part why/how it is the same. You obviously haven't done this.

      There is a difference in generating the signature string that I spot from reading the documentation and your code, but you will have to find it yourself. This is called "debugging" and I expect you to make a honest try at it.

        i have been able to make this API to work, and am successfully interacting with it now

        Am trying to make a post with this data

        my $url_query = "currency=usdt"."&amount=20"."&address=0x55Dc816924e33 +CA50830A"."&destination_tag=None";

        but am getting this error

        {"status": "error", "reason": {"amount": ["This field is required."]}}
         API Documentation Section : https://www.bitstamp.net/api/#tag/Withdrawals/operation/RequestCryptoWithdrawal

        Full code

        #!/usr/bin/perl use strict; use warnings; use LWP::UserAgent; use Digest::SHA qw(hmac_sha256_hex); use UUID::Tiny ':std'; use URI::Escape; use JSON; use Time::HiRes qw(time); use JSON::XS; sub write_call_back { my ($data, $userp) = @_; ${$userp} .= $data; return length($data); } sub url_encode { my ($data) = @_; return uri_escape($data); } my $api_key = "api_key"; my $api_secret = "api_secret"; my $timestamp = int(time() * 1000); my $nonce = create_uuid_as_string(UUID_V4); my $x_auth = "BITSTAMP $api_key"; my $x_auth_nonce = $nonce; my $x_auth_timestamp = $timestamp; my $x_auth_version = "v2"; my $content_type = "application/x-www-form-urlencoded"; my $payload = url_encode('{"offset":1}'); my $http_method = "POST"; my $url_host = "www.bitstamp.net"; my $url_path = "/api/v2/usdt_withdrawal/?"; my $url_query = "currency=usdt"."&amount=20"."&address=0x55Dc816924e33 +CA50830A"."&destination_tag=None"; my $data_to_sign = join('', $x_auth, $http_method, $url_host, $url_path, $url_query, $content_type, $x_auth_nonce, $x_auth_timestamp, $x_auth_version, +$payload ); my $x_auth_signature = hmac_sha256_hex($data_to_sign, $api_secret); my $ua = LWP::UserAgent->new; my $url = "https://$url_host$url_path$url_query"; my $req = HTTP::Request->new(POST => $url); $req->header('X-Auth' => $x_auth); $req->header('X-Auth-Signature' => $x_auth_signature); $req->header('X-Auth-Nonce' => $x_auth_nonce); $req->header('X-Auth-Timestamp' => $x_auth_timestamp); $req->header('X-Auth-Version' => $x_auth_version); $req->header('Content-Type' => $content_type); $req->content($payload); my $resp = $ua->request($req); if ($resp->is_success) { print $resp->content; } else { print "HTTP POST error code: ", $resp->code, "\n"; print "HTTP POST error message: ", $resp->message, "\n"; }