Packages

Ethereum library for Gleam - JSON-RPC client, transaction signing, ABI encoding, and wallet management on the BEAM

Current section

Files

Jump to
gleeth src gleeth@events.erl
Raw

src/gleeth@events.erl

-module(gleeth@events).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/events.gleam").
-export([decode_logs/2, get_events/5, compute_event_topic/2, get_events_by_name/6]).
-export_type([event_result/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(
" Query and decode contract events in a single call.\n"
"\n"
" Combines `methods.get_logs` with ABI event decoding so you don't have\n"
" to manually match topic hashes and decode parameters.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(abi) = json.parse_abi(erc20_abi_json)\n"
" let assert Ok(decoded) = events.get_events(\n"
" provider,\n"
" \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\n"
" abi,\n"
" \"0x100000\",\n"
" \"latest\",\n"
" )\n"
" // decoded: List(EventResult) - each with event name and typed params\n"
" ```\n"
).
-type event_result() :: {decoded,
gleeth@ethereum@abi@events:decoded_log(),
gleeth@ethereum@types:log()} |
{unknown, gleeth@ethereum@types:log()}.
-file("src/gleeth/events.gleam", 102).
?DOC(
" Decode a list of raw logs against an ABI. Useful when you already\n"
" have logs from another source (e.g. a transaction receipt).\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let results = events.decode_logs(receipt.logs, abi)\n"
" ```\n"
).
-spec decode_logs(
list(gleeth@ethereum@types:log()),
list(gleeth@ethereum@abi@json:abi_entry())
) -> list(event_result()).
decode_logs(Logs, Abi) ->
gleam@list:map(
Logs,
fun(Log) -> case gleeth@ethereum@abi@events:decode_log(Log, Abi) of
{ok, Decoded} ->
{decoded, Decoded, Log};
{error, _} ->
{unknown, Log}
end end
).
-file("src/gleeth/events.gleam", 48).
?DOC(
" Query logs for a contract and decode them against the provided ABI.\n"
" Logs that match an event in the ABI are decoded; unmatched logs are\n"
" returned as `Unknown` so no data is lost.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(events) = events.get_events(\n"
" provider, \"0xA0b8...\", abi, \"0x100000\", \"latest\",\n"
" )\n"
" ```\n"
).
-spec get_events(
gleeth@provider:provider(),
binary(),
list(gleeth@ethereum@abi@json:abi_entry()),
binary(),
binary()
) -> {ok, list(event_result())} | {error, gleeth@rpc@types:gleeth_error()}.
get_events(Provider, Address, Abi, From_block, To_block) ->
gleam@result:'try'(
gleeth@rpc@methods:get_logs(Provider, From_block, To_block, Address, []),
fun(Logs) -> {ok, decode_logs(Logs, Abi)} end
).
-file("src/gleeth/events.gleam", 118).
-spec compute_event_topic(list(gleeth@ethereum@abi@json:abi_entry()), binary()) -> binary().
compute_event_topic(Abi, Event_name) ->
Found = gleam@list:find(Abi, fun(Entry) -> case Entry of
{event_entry, Name, _} ->
Name =:= Event_name;
_ ->
false
end end),
case Found of
{ok, {event_entry, Name@1, Inputs}} ->
Types = gleam@list:map(Inputs, fun(P) -> erlang:element(3, P) end),
gleeth@ethereum@abi@events:event_topic_hex(Name@1, Types);
_ ->
<<""/utf8>>
end.
-file("src/gleeth/events.gleam", 71).
?DOC(
" Query logs for a specific event name. Filters by the event's topic0 hash,\n"
" so only matching logs are returned from the RPC.\n"
"\n"
" ## Examples\n"
"\n"
" ```gleam\n"
" let assert Ok(transfers) = events.get_events_by_name(\n"
" provider, \"0xA0b8...\", abi, \"Transfer\", \"0x100000\", \"latest\",\n"
" )\n"
" ```\n"
).
-spec get_events_by_name(
gleeth@provider:provider(),
binary(),
list(gleeth@ethereum@abi@json:abi_entry()),
binary(),
binary(),
binary()
) -> {ok, list(event_result())} | {error, gleeth@rpc@types:gleeth_error()}.
get_events_by_name(Provider, Address, Abi, Event_name, From_block, To_block) ->
Topic0 = compute_event_topic(Abi, Event_name),
Topics = case Topic0 of
<<""/utf8>> ->
[];
T ->
[T]
end,
gleam@result:'try'(
gleeth@rpc@methods:get_logs(
Provider,
From_block,
To_block,
Address,
Topics
),
fun(Logs) -> {ok, decode_logs(Logs, Abi)} end
).