Skip to main content

Try it Live

Run ABI examples in the interactive playground
Conceptual guide - For encoding rules, see ABI Encoding.

Overview

ABI items describe a contract interface as JSON objects. Voltaire treats them as typed plain objects and provides helpers to encode/decode data safely.
import { Abi } from '@tevm/voltaire/Abi';

const erc20Abi = Abi([
  {
    type: 'function',
    name: 'transfer',
    stateMutability: 'nonpayable',
    inputs: [
      { type: 'address', name: 'to' },
      { type: 'uint256', name: 'amount' }
    ],
    outputs: [{ type: 'bool' }]
  },
  {
    type: 'event',
    name: 'Transfer',
    inputs: [
      { type: 'address', name: 'from', indexed: true },
      { type: 'address', name: 'to', indexed: true },
      { type: 'uint256', name: 'value' }
    ]
  }
] as const);

Function

Functions define callable methods with inputs, outputs, and mutability.
const transfer = {
  type: 'function',
  name: 'transfer',
  stateMutability: 'nonpayable',
  inputs: [
    { type: 'address', name: 'to' },
    { type: 'uint256', name: 'amount' }
  ],
  outputs: [{ type: 'bool' }]
} as const;
Key fields:
  • name - function name
  • inputs - parameter list
  • outputs - return list
  • stateMutability - pure | view | nonpayable | payable

Event

Events define log structures. Indexed parameters become topics.
const Transfer = {
  type: 'event',
  name: 'Transfer',
  inputs: [
    { type: 'address', name: 'from', indexed: true },
    { type: 'address', name: 'to', indexed: true },
    { type: 'uint256', name: 'value' }
  ],
  anonymous: false
} as const;
Key fields:
  • anonymous - if true, no topic0 selector is emitted
  • inputs[].indexed - marks a parameter as a topic

Error

Custom errors encode like functions and surface revert data.
const InsufficientBalance = {
  type: 'error',
  name: 'InsufficientBalance',
  inputs: [
    { type: 'uint256', name: 'balance' },
    { type: 'uint256', name: 'required' }
  ]
} as const;

Constructor

Constructor items define deployment parameters. They have no selector.
const ctor = {
  type: 'constructor',
  stateMutability: 'nonpayable',
  inputs: [
    { type: 'string', name: 'name' },
    { type: 'string', name: 'symbol' },
    { type: 'uint8', name: 'decimals' }
  ]
} as const;

Fallback and Receive

Fallback and receive functions are special, selector-less entries.
const fallback = { type: 'fallback', stateMutability: 'payable' } as const;
const receive = { type: 'receive', stateMutability: 'payable' } as const;

Parameters and Tuples

Parameters describe inputs and outputs. Use components for tuples (structs).
const params = [
  { type: 'address', name: 'owner' },
  {
    type: 'tuple',
    name: 'position',
    components: [
      { type: 'uint256', name: 'amount' },
      { type: 'uint256', name: 'shares' }
    ]
  }
] as const;
Common parameter fields:
  • type - canonical ABI type string
  • name - optional parameter name
  • components - tuple fields
  • indexed - events only
  • internalType - optional Solidity internal type

Canonical Type Names

Selectors and signatures require canonical types:
  • uint -> uint256
  • int -> int256
  • Use bytesN for fixed-size bytes
  • Use tuple for structs, plus components

Type Inference

Use as const to enable strict inference for inputs and outputs.
import { Abi } from '@tevm/voltaire/Abi';

const balanceOf = {
  type: 'function',
  name: 'balanceOf',
  stateMutability: 'view',
  inputs: [{ type: 'address', name: 'account' }],
  outputs: [{ type: 'uint256', name: 'balance' }]
} as const;

// TypeScript infers args and return values
const encoded = Abi.Function.encodeParams(balanceOf, [
  '0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e'
]);
const result = Abi.Function.decodeResult(balanceOf, returnData);
// result is [bigint]

Working With Items

Use helper functions to access and validate items:
const transferFn = erc20Abi.getFunction('transfer');
const transferEvt = erc20Abi.getEvent('Transfer');

if (Abi.Item.isFunction(transferFn)) {
  const selector = Abi.Function.getSelector(transferFn);
}

Overloads and Ambiguity

getFunction and Abi.encode match by name. If your ABI has overloads, select the exact item by signature:
const signature = 'foo(address,uint256)';
const fn = erc20Abi.find(
  (item) =>
    item.type === 'function' &&
    Abi.Function.getSignature(item) === signature
);

const data = Abi.Function.encodeParams(fn, [
  '0x742d35Cc6634C0532925a3b844Bc9e7595f51e3e',
  1n
]);

See Also