-module(gleeth@ethereum@abi@types). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/gleeth/ethereum/abi/types.gleam"). -export([is_dynamic/1, head_size/1, to_string/1]). -export_type([abi_type/0, abi_value/0, abi_error/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( " Solidity ABI type system for encoding and decoding.\n" "\n" " `AbiType` describes the shape of a value (e.g. `Uint(256)`, `Address`,\n" " `Array(Bool)`). `AbiValue` carries an actual value of that shape. Use\n" " these with `abi/encode` and `abi/decode` to produce and consume raw\n" " calldata.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " // Describe a transfer(address, uint256) signature\n" " let types = [Address, Uint(256)]\n" "\n" " // Construct the values\n" " let values = [\n" " AddressValue(\"0x70997970C51812dc3A010C7d01b50e0d17dc79C8\"),\n" " UintValue(1000000),\n" " ]\n" " ```\n" ). -type abi_type() :: {uint, integer()} | {int, integer()} | address | bool | {fixed_bytes, integer()} | bytes | string | {array, abi_type()} | {fixed_array, abi_type(), integer()} | {tuple, list(abi_type())}. -type abi_value() :: {uint_value, integer()} | {int_value, integer()} | {address_value, binary()} | {bool_value, boolean()} | {fixed_bytes_value, bitstring()} | {bytes_value, bitstring()} | {string_value, binary()} | {array_value, list(abi_value())} | {tuple_value, list(abi_value())}. -type abi_error() :: {type_parse_error, binary()} | {encode_error, binary()} | {decode_error, binary()} | {invalid_abi_json, binary()}. -file("src/gleeth/ethereum/abi/types.gleam", 91). ?DOC( " Returns `True` if the type uses dynamic (offset-based) ABI encoding.\n" "\n" " Static types (`uint`, `int`, `address`, `bool`, `bytesN`) are encoded\n" " inline. Dynamic types (`bytes`, `string`, `T[]`) use a 32-byte offset\n" " pointer in the head region.\n" ). -spec is_dynamic(abi_type()) -> boolean(). is_dynamic(T) -> case T of {uint, _} -> false; {int, _} -> false; address -> false; bool -> false; {fixed_bytes, _} -> false; bytes -> true; string -> true; {array, _} -> true; {fixed_array, Element, _} -> is_dynamic(Element); {tuple, Elements} -> gleam@list:any(Elements, fun is_dynamic/1) end. -file("src/gleeth/ethereum/abi/types.gleam", 112). ?DOC(" Fixed encoding size for static types.\n"). -spec enc_size(abi_type()) -> integer(). enc_size(T) -> case T of {uint, _} -> 32; {int, _} -> 32; address -> 32; bool -> 32; {fixed_bytes, _} -> 32; {fixed_array, Element, Size} -> Size * enc_size(Element); {tuple, Elements} -> gleam@list:fold(Elements, 0, fun(Acc, El) -> Acc + enc_size(El) end); _ -> 32 end. -file("src/gleeth/ethereum/abi/types.gleam", 104). ?DOC( " Number of bytes this type occupies in the head region of a tuple encoding.\n" " Static types are encoded inline (possibly > 32 bytes for arrays/tuples).\n" " Dynamic types get a 32-byte offset pointer.\n" ). -spec head_size(abi_type()) -> integer(). head_size(T) -> case is_dynamic(T) of true -> 32; false -> enc_size(T) end. -file("src/gleeth/ethereum/abi/types.gleam", 137). ?DOC( " Canonical ABI type string used for function signatures and selectors.\n" "\n" " ## Examples\n" "\n" " ```gleam\n" " types.to_string(Uint(256))\n" " // -> \"uint256\"\n" "\n" " types.to_string(Array(Address))\n" " // -> \"address[]\"\n" "\n" " types.to_string(Tuple([Address, Uint(256)]))\n" " // -> \"(address,uint256)\"\n" " ```\n" ). -spec to_string(abi_type()) -> binary(). to_string(T) -> case T of {uint, Size} -> <<"uint"/utf8, (erlang:integer_to_binary(Size))/binary>>; {int, Size@1} -> <<"int"/utf8, (erlang:integer_to_binary(Size@1))/binary>>; address -> <<"address"/utf8>>; bool -> <<"bool"/utf8>>; {fixed_bytes, Size@2} -> <<"bytes"/utf8, (erlang:integer_to_binary(Size@2))/binary>>; bytes -> <<"bytes"/utf8>>; string -> <<"string"/utf8>>; {array, Element} -> <<(to_string(Element))/binary, "[]"/utf8>>; {fixed_array, Element@1, Size@3} -> <<<<<<(to_string(Element@1))/binary, "["/utf8>>/binary, (erlang:integer_to_binary(Size@3))/binary>>/binary, "]"/utf8>>; {tuple, Elements} -> <<<<"("/utf8, (gleam@string:join( gleam@list:map(Elements, fun to_string/1), <<","/utf8>> ))/binary>>/binary, ")"/utf8>> end.