-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).