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@ethereum@abi@json.erl
Raw

src/gleeth@ethereum@abi@json.erl

-module(gleeth@ethereum@abi@json).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/ethereum/abi/json.gleam").
-export([find_function/2, find_events/1, input_types/1, output_types/1, parse_abi/1]).
-export_type([abi_entry/0, abi_param/0, event_param/0, raw_entry/0, raw_param/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.
-type abi_entry() :: {function_entry,
binary(),
list(abi_param()),
list(abi_param()),
binary()} |
{event_entry, binary(), list(event_param())}.
-type abi_param() :: {abi_param, binary(), gleeth@ethereum@abi@types:abi_type()}.
-type event_param() :: {event_param,
binary(),
gleeth@ethereum@abi@types:abi_type(),
boolean()}.
-type raw_entry() :: {raw_entry,
binary(),
binary(),
list(raw_param()),
list(raw_param()),
binary()}.
-type raw_param() :: {raw_param, binary(), binary(), boolean()}.
-file("src/gleeth/ethereum/abi/json.gleam", 45).
?DOC(" Find a function entry by name.\n").
-spec find_function(list(abi_entry()), binary()) -> {ok, abi_entry()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
find_function(Entries, Name) ->
case gleam@list:find(Entries, fun(Entry) -> case Entry of
{function_entry, N, _, _, _} ->
N =:= Name;
_ ->
false
end end) of
{ok, Entry@1} ->
{ok, Entry@1};
{error, _} ->
{error,
{invalid_abi_json, <<"Function not found: "/utf8, Name/binary>>}}
end.
-file("src/gleeth/ethereum/abi/json.gleam", 63).
?DOC(" Find all event entries.\n").
-spec find_events(list(abi_entry())) -> list(abi_entry()).
find_events(Entries) ->
gleam@list:filter(Entries, fun(Entry) -> case Entry of
{event_entry, _, _} ->
true;
_ ->
false
end end).
-file("src/gleeth/ethereum/abi/json.gleam", 73).
?DOC(" Get input types from a function entry.\n").
-spec input_types(abi_entry()) -> list(gleeth@ethereum@abi@types:abi_type()).
input_types(Entry) ->
case Entry of
{function_entry, _, Inputs, _, _} ->
gleam@list:map(Inputs, fun(P) -> erlang:element(3, P) end);
{event_entry, _, _} ->
[]
end.
-file("src/gleeth/ethereum/abi/json.gleam", 81).
?DOC(" Get output types from a function entry.\n").
-spec output_types(abi_entry()) -> list(gleeth@ethereum@abi@types:abi_type()).
output_types(Entry) ->
case Entry of
{function_entry, _, _, Outputs, _} ->
gleam@list:map(Outputs, fun(P) -> erlang:element(3, P) end);
{event_entry, _, _} ->
[]
end.
-file("src/gleeth/ethereum/abi/json.gleam", 134).
-spec raw_param_decoder() -> gleam@dynamic@decode:decoder(raw_param()).
raw_param_decoder() ->
gleam@dynamic@decode:optional_field(
<<"name"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Name) ->
gleam@dynamic@decode:field(
<<"type"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Type_string) ->
gleam@dynamic@decode:optional_field(
<<"indexed"/utf8>>,
false,
{decoder, fun gleam@dynamic@decode:decode_bool/1},
fun(Indexed) ->
gleam@dynamic@decode:success(
{raw_param, Name, Type_string, Indexed}
)
end
)
end
)
end
).
-file("src/gleeth/ethereum/abi/json.gleam", 107).
-spec raw_entry_decoder() -> gleam@dynamic@decode:decoder(raw_entry()).
raw_entry_decoder() ->
gleam@dynamic@decode:optional_field(
<<"type"/utf8>>,
<<"function"/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Entry_type) ->
gleam@dynamic@decode:optional_field(
<<"name"/utf8>>,
<<""/utf8>>,
{decoder, fun gleam@dynamic@decode:decode_string/1},
fun(Name) ->
gleam@dynamic@decode:optional_field(
<<"inputs"/utf8>>,
[],
gleam@dynamic@decode:list(raw_param_decoder()),
fun(Inputs) ->
gleam@dynamic@decode:optional_field(
<<"outputs"/utf8>>,
[],
gleam@dynamic@decode:list(raw_param_decoder()),
fun(Outputs) ->
gleam@dynamic@decode:optional_field(
<<"stateMutability"/utf8>>,
<<""/utf8>>,
{decoder,
fun gleam@dynamic@decode:decode_string/1},
fun(State_mutability) ->
gleam@dynamic@decode:success(
{raw_entry,
Entry_type,
Name,
Inputs,
Outputs,
State_mutability}
)
end
)
end
)
end
)
end
)
end
).
-file("src/gleeth/ethereum/abi/json.gleam", 168).
-spec convert_raw_param(raw_param()) -> {ok, abi_param()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
convert_raw_param(Raw) ->
gleam@result:'try'(
gleeth@ethereum@abi@type_parser:parse(erlang:element(3, Raw)),
fun(T) -> {ok, {abi_param, erlang:element(2, Raw), T}} end
).
-file("src/gleeth/ethereum/abi/json.gleam", 173).
-spec convert_raw_event_param(raw_param()) -> {ok, event_param()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
convert_raw_event_param(Raw) ->
gleam@result:'try'(
gleeth@ethereum@abi@type_parser:parse(erlang:element(3, Raw)),
fun(T) ->
{ok,
{event_param, erlang:element(2, Raw), T, erlang:element(4, Raw)}}
end
).
-file("src/gleeth/ethereum/abi/json.gleam", 145).
-spec convert_raw_entry(raw_entry()) -> {ok, abi_entry()} |
{error, gleeth@ethereum@abi@types:abi_error()}.
convert_raw_entry(Raw) ->
case erlang:element(2, Raw) of
<<"function"/utf8>> ->
gleam@result:'try'(
gleam@list:try_map(
erlang:element(4, Raw),
fun convert_raw_param/1
),
fun(Inputs) ->
gleam@result:'try'(
gleam@list:try_map(
erlang:element(5, Raw),
fun convert_raw_param/1
),
fun(Outputs) ->
{ok,
{function_entry,
erlang:element(3, Raw),
Inputs,
Outputs,
erlang:element(6, Raw)}}
end
)
end
);
<<"event"/utf8>> ->
gleam@result:'try'(
gleam@list:try_map(
erlang:element(4, Raw),
fun convert_raw_event_param/1
),
fun(Inputs@1) ->
{ok, {event_entry, erlang:element(3, Raw), Inputs@1}}
end
);
_ ->
{error,
{invalid_abi_json,
<<"Unsupported ABI entry type: "/utf8,
(erlang:element(2, Raw))/binary>>}}
end.
-file("src/gleeth/ethereum/abi/json.gleam", 27).
?DOC(" Parse a Solidity JSON ABI string into a list of ABI entries.\n").
-spec parse_abi(binary()) -> {ok, list(abi_entry())} |
{error, gleeth@ethereum@abi@types:abi_error()}.
parse_abi(Json_string) ->
case gleam@json:parse(
Json_string,
gleam@dynamic@decode:list(raw_entry_decoder())
) of
{ok, Raw_entries} ->
_pipe = gleam@list:try_fold(
Raw_entries,
[],
fun(Acc, Raw) -> case convert_raw_entry(Raw) of
{ok, Entry} ->
{ok, [Entry | Acc]};
{error, _} ->
{ok, Acc}
end end
),
gleam@result:map(_pipe, fun lists:reverse/1);
{error, _} ->
{error, {invalid_abi_json, <<"Failed to parse ABI JSON"/utf8>>}}
end.