Binance-API

 view release on metacpan or  search on metacpan

lib/Binance/API/Request.pm  view on Meta::CPAN


=head1 NAME

Binance::API::Request -- LWP::UserAgent wrapper for L<Binance::API>

=head1 DESCRIPTION

This module provides a wrapper for LWP::UserAgent. Generates required parameters
for Binance API requests.

=cut

sub new {
    my $class = shift;
    my %params = @_;

    my $self = $class->SUPER::new;

    $self->{apiKey}     = $params{'apiKey'};
    $self->{secretKey}  = $params{'secretKey'};
    $self->{recvWindow} = $params{'recvWindow'};
    $self->{baseUrl}    = $params{'baseUrl'};
    $self->{logger}     = $params{'logger'};

    bless $self, $class;
}

sub get {
    my ($self, $url, $params) = @_;

    my ($path, %data) = $self->_init($url, $params);
    return $self->_exec('get', $path, %data);
}

sub post {
    my ($self, $url, $params) = @_;

    my ($path, %data) = $self->_init($url, $params);
    return $self->_exec('post', $path, %data);
}

sub delete {
    my ($self, $url, $params) = @_;

    my ($path, %data) = $self->_init($url, $params);
    return $self->_exec('delete', $path, %data);
}

sub _exec {
    my ($self, $method, $url, %data) = @_;

    $self->{logger}->debug("New request: $url");
    $method = "SUPER::$method";
    my $response;
    if (keys %data > 0) {
        $response = $self->$method($url, %data);
    } else {
        $response = $self->$method($url);
    }
    if ($response->is_success) {
        $response = eval { decode_json($response->decoded_content); };
        if ($@) {
            $self->{logger}->error(
                "Error decoding response. \nStatus => " . $response->code . ",\n"
                . 'Content => ' . ($response->content ? $response->content : '')
            );
        }
    } else {
        $self->{logger}->error(
            "Unsuccessful request. \nStatus => " . $response->code . ",\n"
            . 'Content => ' . ($response->content ? $response->content : '')
        );
    }
    return $response;
}

sub _init {
    my ($self, $path, $params) = @_;

    unless ($path) {
        Binance::Exception::Parameter::Required->throw(
            error => 'Parameter "path" required',
            parameters => ['path']
        );
    }

    my $timestamp = $params->{'timestamp'};
    delete $params->{'timestamp'};
    # Delete undefined query parameters
    my $query = $params->{'query'};
    foreach my $param (keys %$query) {
        delete $query->{$param} unless defined $query->{$param};
    }

    # Delete undefined body parameters
    my $body = $params->{'body'};
    foreach my $param (keys %$body) {
        delete $body->{$param} unless defined $body->{$param};
    }

    my $recvWindow;
    if ($params->{signed}) {
        $recvWindow = $query->{'recvWindow'} // $body->{'recvWindow'} //
            defined $self->{'recvWindow'} ? $self->{'recvWindow'} : undef;
    }

    $timestamp //= int Time::HiRes::time * 1000 if $params->{'signed'};

    my $base_url = defined $self->{'baseUrl'} ? $self->{'baseUrl'} : BASE_URL;
    my $uri = URI->new( $base_url . $path );
    my $full_path = $uri->as_string;

    my %data;
    # Mixed request (both query params & body params)
    if (keys %$body && keys %$query) {
        if (!defined $body->{'recvWindow'} && defined $recvWindow) {
            $query->{'recvWindow'} = $recvWindow;
        }
        elsif (!defined $query->{'recvWindow'} && defined $recvWindow) {
            $body->{'recvWindow'} = $recvWindow;
        }



( run in 2.109 seconds using v1.01-cache-2.11-cpan-e1769b4cff6 )