defmodule NearApi.HttpClient do use HTTPoison.Base require Logger @retry_attempts 2 @doc """ Performs a "method" call to NEAR RPC API """ def api_call_method(payload, method) do perform_call(method, payload) end def process_request_url(url) do endpoint_url() <> url end def process_response_body(body) do Jason.decode!(body) end def process_request_headers(headers) do headers ++ ["Content-Type": "application/json"] end @doc """ Wraps payload into the NEAR query structure """ def params(method, payload) do %{ id: "dontcare", jsonrpc: "2.0", method: method, params: payload } end defp perform_call(method, payload, retry_attempt \\ 0) defp perform_call(method, payload, retry_attempt) when retry_attempt < @retry_attempts do params_encoded = NearApi.HttpClient.params(method, payload) |> Jason.encode!() recv_timeout = Application.get_env(:near_api, :recv_timeout, 50_000) timeout = Application.get_env(:near_api, :timeout, 50_000) case NearApi.HttpClient.post("/", params_encoded, [], recv_timeout: recv_timeout, timeout: timeout) do {:ok, response} -> response.body {:error, %HTTPoison.Error{reason: :timeout}} -> Logger.warn( "#{__MODULE__}: Timeout making a transaciton call: #{inspect({method, payload})}; attempt: #{retry_attempt}" ) perform_call(method, payload, retry_attempt + 1) error -> error end end defp perform_call(_method, _payload, _retry_attempt) do Logger.error("#{__MODULE__}: Aborted retrying calls to NEAR API because of timeouts") {:error, :timeouted_after_multiple_retries} end defp endpoint_url do System.get_env("NEAR_NODE_URL") end end