Overview
@ethernauta/abi
The ABI codec. Encode function calls, decode return values, decode logs, generate TypeScript bindings from contract ABIs.
pnpm add @ethernauta/abi What ships
- Codec primitives (
address,bool,string_,uint256,bytes32, …) — one per Solidity type. - Composers —
array(codec),tuple(codecs)for higher-order types. make_codec(fragment)— turn an ABI function fragment into a single encode/decode pair.parse_abi(abi)— parse a raw JSON ABI into the codec-ready shape.decode_logs(events, logs)— match raw logs against event signatures, return typed entries.to_selector(signature)— 4-byte function selector from a Solidity signature string.revert— decode Solidity revert payloads (Error(string),Panic(uint256), custom errors).- Code generation via
@ethernauta/abi/generator— produce method binding files from an ABI.
Codec primitives
Each Solidity static type has a matching codec:
| Codec | Solidity |
|---|---|
address | address |
bool | bool |
string_ | string (underscore to avoid the JS keyword) |
bytes | bytes (dynamic) |
bytes4, bytes8, bytes32, bytes48, bytes65, bytes256 | fixed-length bytesN |
hash32 | semantic alias of bytes32 for hashes |
uint8, uint16, uint24, uint32, uint40, uint48, uint56, uint64, uint96, uint128, uint160, uint192, uint224, uint256, uint | unsigned ints |
Each is an AbiCodec<T>:
import { uint256, address } from "@ethernauta/abi";
const encoded = uint256.encode(42n);
const decoded = uint256.decode(encoded); // → 42n InferCodec<C> extracts the TS type a codec produces; InferArrayElement<C> gets the element type of an array codec.
Composers
import { array, tuple, uint256, address, bool } from "@ethernauta/abi";
// uint256[]
const uint_array = array(uint256);
// (address, uint256, bool)
const trio = tuple([address, uint256, bool]);
// (address, uint256[])
const mixed = tuple([address, array(uint256)]); The codec composes the way the type composes. The codec for a function fragment with (address spender, uint256 amount) is tuple([address, uint256]).
make_codec
The high-level builder. Pass an ABI function fragment, get a codec back:
import { make_codec, parse_abi } from "@ethernauta/abi";
const abi = parse_abi([
"function transfer(address to, uint256 amount) returns (bool)",
]);
const transfer = make_codec(abi[0]);
const calldata = transfer.encode_inputs(["0xabc…", 1000n]);
const result = transfer.decode_outputs(return_bytes); Used internally by packages/erc/src/*/methods/* to bind every ERC method.
Log decoding
import { decode_logs, parse_abi } from "@ethernauta/abi";
const events = parse_abi([
"event Transfer(address indexed from, address indexed to, uint256 value)",
]);
const decoded = decode_logs(events, raw_logs);
// → DecodedLogEntry[]
// each carrying { name, signature, args, log } EventEntry<T> is the typed shape of one decoded event; DecodedLogEntry is the union across all event signatures the caller passed.
Selectors
import { to_selector } from "@ethernauta/abi";
to_selector("transfer(address,uint256)"); // → "0xa9059cbb"
to_selector("balanceOf(address)"); // → "0x70a08231" Used by the registry generator (@ethernauta/erc/registry) and by the wallet’s wallet_sendCalls UI to display human-readable method names from selectors.
Revert decoding
import { revert } from "@ethernauta/abi";
// raw revert bytes from eth_call
const reason = revert.decode(raw_bytes);
// →
// | { kind: "error_string"; message: string }
// | { kind: "panic"; code: bigint }
// | { kind: "custom_error"; selector: Bytes4; data: Bytes }
// | { kind: "raw"; data: Bytes } Picks Error(string), Panic(uint256), or custom-error / raw fallback. The wallet uses this to surface readable revert reasons in its UI; dapps use it for the same purpose.
Code generation
pnpm dlx @ethernauta/cli abi --in ./erc20.abi.json --out ./generated/ Produces one TypeScript file per ABI method. Each file binds the method into a Callable<T> you can use directly:
// generated/balance-of.ts (auto-generated)
import { make_codec, parse_abi } from "@ethernauta/abi";
import type { Callable } from "@ethernauta/transport";
const codec = make_codec(/* fragment */);
export function balance_of(args: { owner: Address }): Callable<Uint256> {
return /* curried codec invocation */;
} @ethernauta/abi/generator exposes the generator primitives (generate, emit_name_for, emit_file_basename_for) if you want to embed codegen in your own tooling.
See also
- @ethernauta/erc — entire ERC catalog generated by this codec.
- @ethernauta/cli — the codegen command-line tool.
- Tooling → ERC codegen — how to regenerate the registry.