问题
I am trying to use POST method in perl to send information to an API.
I would like to call the below api which requires following inputs: URI: https://www.cryptopia.co.nz/api/SubmitTrade
Input Parameters are:-
Market: The market symbol of the trade e.g. 'DOT/BTC' (not required if 'TradePairId' supplied)
TradePairId: The Cryptopia tradepair identifier of trade e.g. '100' (not required if 'Market' supplied)
Type: the type of trade e.g. 'Buy' or 'Sell'
Rate: the rate or price to pay for the coins e.g. 0.00000034
Amount: the amount of coins to buy e.g. 123.00000000
Please can you tell me how I can call this api from perl ? Request Structure:
REQUEST_SIGNATURE: API_KEY + "POST" + URI + NONCE + HASHED_POST_PARAMS
API_KEY: Your Cryptopia api key
URI: the request uri. e.g. https://www.cryptopia.co.nz/Api/SubmitTrade
HASHED_POST_PARAMS: Base64 encoded MD5 hash of the post parameters
NONCE: unique indicator for each request.
So question is how do I join this api https://www.cryptopia.co.nz/api/SubmitTrade and pass the arguments to it with authentication and check if returned result is success?
Result Example:
{
"Success":true,
"Error":null,
"Data":
{
"OrderId": 23467,
"FilledOrders": [44310,44311]
}
}
回答1:
I don't have a Cryptopia account to test this, but this might at least get you closer to a working prototype.
Setup
Load the required modules and create a LWP::UserAgent
object.
use strict;
use warnings;
use LWP::UserAgent;
use JSON;
use Digest::MD5 qw(md5);
use Digest::SHA qw(hmac_sha256);
use MIME::Base64;
use URI::Encode qw(uri_encode);
my $api_key = 'PUBLIC KEY';
my $api_private_key = 'PRIVATE KEY';
my $ua = LWP::UserAgent->new;
Generating the request
The tricky part is generating the authorization header. The API keys for your account will be base64-encoded - hence the call to decode_base64()
when using it to sign the request.
my $url = "https://www.cryptopia.co.nz/api/GetTradeHistory";
my %req = (
Market => 'DOT/BTC',
);
my $nonce = int(rand(1000000));
my $post_data = encode_json(\%req);
my $post_data_enc = encode_base64(md5($post_data), "");
my $encoded_url = lc(uri_encode($url, encode_reserved => 1));
my $req_signature = sprintf("%sPOST%s%s%s", $api_key, $encoded_url, $nonce, $post_data_enc);
# Sign request signature with private key.
my $req_signature_hmac = encode_base64(hmac_sha256($req_signature, decode_base64($api_private_key)));
# Generate value for 'Authorization' header field.
my $auth_header_value = sprintf("amx %s:%s:%s", $api_key, $req_signature_hmac, $nonce);
Notes ...
- An empty string is passed as the second argument to
encode_base64()
- to prevent it from appending a new-line to the output. uri_encode()
from theURI::Encode
module is used the encode the URL.- You might want to use an alternative source or random generator for the nonce.
Sending the request
You could create a HTTP::Request
object explicitly and pass that to LWP::UserAgent
's request()
method, but there is a post()
convenience method which does all this for you.
The example here uses the Content
parameter to set the content of the post body, and sets the Authorization
and Content-Type
headers at the same time.
my $response = $ua->post($url,
Content => $post_data,
'Content-Type' => 'application/json',
Authorization => $auth_header_value
);
die "Request failed: ", $response->content unless $response->is_success();
print $response->content, $/;
Checking the response
It may be enough to check the LWP Response object as above - by invoking the $response->is_success()
method. Nonetheless, if you want to explicitly check for success, just decode the JSON response - using $resp = decode_json($response->decoded_content)
. Then examine the relevant keys in the resulting hash.
来源:https://stackoverflow.com/questions/48347611/post-api-in-perl-using-lwpuseragent-with-authentication