Current section
Files
Jump to
Current section
Files
src/gleeth@provider.erl
-module(gleeth@provider).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/provider.gleam").
-export([default_retry/0, no_retry/0, new/1, rpc_url/1, chain_id/1, with_chain_id/2, mainnet/0, sepolia/0, with_retry/2, retry_config/1]).
-export_type([retry_config/0, provider/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(
" Provider is the main entry point for interacting with an Ethereum network.\n"
" It wraps a validated JSON-RPC URL and an optional chain ID, giving library\n"
" consumers a safe handle they can pass to RPC calls, contract interactions,\n"
" and transaction builders.\n"
"\n"
" **Warning**: gleeth has not been audited. Recommended for testnet and\n"
" development use only.\n"
"\n"
" Because `Provider` is opaque, the only way to construct one is through\n"
" `new`, `mainnet`, or `sepolia` - all of which guarantee the URL is valid.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(local) = provider.new(\"http://localhost:8545\")\n"
" let url = provider.rpc_url(local)\n"
"\n"
" let eth = provider.mainnet()\n"
" let eth = provider.with_chain_id(eth, 1)\n"
" ```\n"
).
-type retry_config() :: {retry_config, integer(), integer(), integer()}.
-opaque provider() :: {provider,
binary(),
gleam@option:option(integer()),
retry_config()}.
-file("src/gleeth/provider.gleam", 39).
?DOC(" Default retry config: 3 retries, 1s initial backoff, 8s max.\n").
-spec default_retry() -> retry_config().
default_retry() ->
{retry_config, 3, 1000, 8000}.
-file("src/gleeth/provider.gleam", 44).
?DOC(" No retries - fail immediately on error.\n").
-spec no_retry() -> retry_config().
no_retry() ->
{retry_config, 0, 0, 0}.
-file("src/gleeth/provider.gleam", 69).
?DOC(
" Create a new provider from the given RPC URL.\n"
"\n"
" The URL must be non-empty and start with `http://` or `https://`.\n"
" Returns `Error(InvalidRpcUrl(...))` if validation fails.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(p) = provider.new(\"http://localhost:8545\")\n"
" let assert Error(_) = provider.new(\"\")\n"
" let assert Error(_) = provider.new(\"ws://bad-scheme\")\n"
" ```\n"
).
-spec new(binary()) -> {ok, provider()} |
{error, gleeth@rpc@types:gleeth_error()}.
new(Rpc_url) ->
case Rpc_url of
<<""/utf8>> ->
{error, {invalid_rpc_url, <<"RPC URL cannot be empty"/utf8>>}};
_ ->
case gleam_stdlib:string_starts_with(Rpc_url, <<"http://"/utf8>>)
orelse gleam_stdlib:string_starts_with(Rpc_url, <<"https://"/utf8>>) of
true ->
{ok, {provider, Rpc_url, none, no_retry()}};
false ->
{error,
{invalid_rpc_url,
<<"RPC URL must start with http:// or https://"/utf8>>}}
end
end.
-file("src/gleeth/provider.gleam", 96).
?DOC(
" Return the RPC URL held by this provider.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(p) = provider.new(\"http://localhost:8545\")\n"
" provider.rpc_url(p)\n"
" // -> \"http://localhost:8545\"\n"
" ```\n"
).
-spec rpc_url(provider()) -> binary().
rpc_url(Provider) ->
erlang:element(2, Provider).
-file("src/gleeth/provider.gleam", 109).
?DOC(
" Return the chain ID if one has been set, or `None` otherwise.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(p) = provider.new(\"http://localhost:8545\")\n"
" provider.chain_id(p)\n"
" // -> None\n"
" ```\n"
).
-spec chain_id(provider()) -> gleam@option:option(integer()).
chain_id(Provider) ->
erlang:element(3, Provider).
-file("src/gleeth/provider.gleam", 125).
?DOC(
" Return a new provider with the given chain ID attached.\n"
"\n"
" This does not mutate the original provider - a fresh copy is returned.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(p) = provider.new(\"http://localhost:8545\")\n"
" let p = provider.with_chain_id(p, 1)\n"
" provider.chain_id(p)\n"
" // -> Some(1)\n"
" ```\n"
).
-spec with_chain_id(provider(), integer()) -> provider().
with_chain_id(Provider, Id) ->
{provider,
erlang:element(2, Provider),
{some, Id},
erlang:element(4, Provider)}.
-file("src/gleeth/provider.gleam", 138).
?DOC(
" Convenience constructor for Ethereum mainnet using a public RPC endpoint.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let eth = provider.mainnet()\n"
" provider.rpc_url(eth)\n"
" // -> \"https://eth.llamarpc.com\"\n"
" ```\n"
).
-spec mainnet() -> provider().
mainnet() ->
{provider, <<"https://eth.llamarpc.com"/utf8>>, none, default_retry()}.
-file("src/gleeth/provider.gleam", 155).
?DOC(
" Convenience constructor for the Sepolia testnet using a public RPC endpoint.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let sep = provider.sepolia()\n"
" provider.rpc_url(sep)\n"
" // -> \"https://ethereum-sepolia.publicnode.com\"\n"
" ```\n"
).
-spec sepolia() -> provider().
sepolia() ->
{provider,
<<"https://ethereum-sepolia.publicnode.com"/utf8>>,
none,
default_retry()}.
-file("src/gleeth/provider.gleam", 171).
?DOC(
" Attach retry configuration to the provider.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let p = provider.new(\"http://localhost:8545\")\n"
" |> result.map(provider.with_retry(_, provider.default_retry()))\n"
" ```\n"
).
-spec with_retry(provider(), retry_config()) -> provider().
with_retry(Provider, Config) ->
{provider, erlang:element(2, Provider), erlang:element(3, Provider), Config}.
-file("src/gleeth/provider.gleam", 176).
?DOC(" Get the retry configuration from the provider.\n").
-spec retry_config(provider()) -> retry_config().
retry_config(Provider) ->
erlang:element(4, Provider).