Current section

Files

Jump to
bingex lib bingex http request.ex
Raw

lib/bingex/http/request.ex

defmodule Bingex.HTTP.Request do
@moduledoc """
Constructs and signs HTTP requests for the BingX API.
This module provides utilities for creating HTTP requests, adding authentication headers,
and signing parameters when required. It also supports URL building with query parameters
and timestamping to ensure request validity.
"""
alias Bingex.Helpers
alias Bingex.HTTP.Signature
defstruct [:method, :url, :headers, :body]
@type t() :: %__MODULE__{
url: binary(),
method: method(),
headers: [{binary(), binary()}],
body: nil | binary()
}
@type options() :: [sign: nil | binary()]
@type method() :: :get | :put | :post | :delete
@type url() :: binary()
@type path() :: binary()
@type body() :: nil | binary()
@type params() :: [{binary(), term()}]
@type headers() :: [{binary(), binary()}]
@methods [:get, :put, :post, :delete]
@origin Application.compile_env(:bingx, :origin, "https://open-api.bingx.com")
@spec new(method(), url(), headers(), body()) :: t()
def new(method, url, headers, body)
when method in @methods and
is_binary(url) and
is_list(headers) and
(is_binary(body) or is_nil(body)) do
%__MODULE__{method: method, url: url, headers: headers, body: body}
end
@spec auth_headers(headers(), api_key :: binary()) :: headers()
def auth_headers(headers \\ [], api_key)
when is_list(headers) and is_binary(api_key) do
[{"X-BX-APIKEY", api_key} | headers]
end
@spec build_url(path(), params(), options()) :: url :: binary()
def build_url(path \\ "/", params \\ [], options \\ []) do
url = @origin <> path
query =
params
|> Helpers.reject_nils()
|> set_timestamp()
|> set_recv_window()
|> maybe_set_signature(options)
|> URI.encode_query()
url <> "?" <> query
end
@spec maybe_set_signature(params(), options()) :: params()
defp maybe_set_signature(params, options) do
case Keyword.get(options, :sign) do
nil -> params
secret_key -> set_signature(params, secret_key)
end
end
@spec set_recv_window(params(), value :: non_neg_integer()) ::
params()
def set_recv_window(params, value \\ 5000)
when is_list(params) and is_integer(value) do
[{"recvWindow", value} | params]
end
@spec set_timestamp(params()) :: params()
def set_timestamp(params) when is_list(params) do
[{"timestamp", Helpers.timestamp()} | params]
end
@spec set_signature(params(), secret_key :: binary()) :: params()
def set_signature(params, secret_key)
when is_list(params) and is_binary(secret_key) do
signature = Signature.generate(params, secret_key)
params ++ [{"signature", signature}]
end
end