Current section

Files

Jump to
soroban lib rpc request.ex
Raw

lib/rpc/request.ex

defmodule Soroban.RPC.Request do
@moduledoc """
A module to work with Soroban RPC requests.
Requests are composed in a functional manner.
The request does not happen until it is configured and passed to `perform/1`.
"""
alias Soroban.RPC.{Client, Error, HTTPError}
@base_urls [
test: "https://soroban-testnet.stellar.org",
future: "https://rpc-futurenet.stellar.org",
local: "http://localhost:8000"
]
@type endpoint :: String.t()
@type headers :: [{binary(), binary()}]
@type params :: map() | nil
@type opts :: Keyword.t()
@type response :: {:ok, map()} | {:error, Error.t()} | {:error, HTTPError.t()}
@type parsed_response :: {:ok, struct()} | {:error, Error.t()} | {:error, HTTPError.t()}
@type url :: String.t()
@type t :: %__MODULE__{
endpoint: endpoint(),
url: url(),
params: params(),
headers: headers()
}
defstruct [
:endpoint,
:url,
:params,
:headers
]
@spec new(endpoint :: endpoint(), opts :: opts()) :: t()
def new(endpoint, opts \\ []) do
default = @base_urls[:future]
url = Keyword.get(opts, :url) || Keyword.get(@base_urls, current_network(), default)
%__MODULE__{
endpoint: endpoint,
url: url,
params: nil,
headers: []
}
end
@spec add_headers(request :: t(), headers :: headers()) :: t()
def add_headers(%__MODULE__{} = request, headers), do: %{request | headers: headers}
@spec add_params(request :: t(), params :: params()) :: t()
def add_params(%__MODULE__{} = request, params),
do: %{request | params: params}
@spec perform(request :: t()) :: response()
def perform(%__MODULE__{endpoint: endpoint, url: url, headers: headers, params: params}),
do: Client.request(endpoint, url, headers, params)
@spec results(response :: response(), opts :: opts()) :: parsed_response()
def results({:ok, results}, as: resource), do: {:ok, resource.new(results)}
def results({:error, error}, _resource), do: {:error, error}
@spec current_network() :: atom()
defp current_network, do: Application.get_env(:stellar_sdk, :network, :future)
end