Docs

Examples

Runnable code examples for eth.zig -- address derivation, signing, ERC-20, HD wallets, and more.

The examples/ directory in the repo contains self-contained programs for each major feature.

ExampleDescriptionRequires RPC
01_derive_addressDerive address from private keyNo
02_check_balanceQuery ETH balance via JSON-RPCYes
03_sign_messageEIP-191 personal message signingNo
04_send_transactionSend ETH with WalletYes (Anvil)
05_read_erc20ERC-20 module API showcaseYes
06_hd_walletBIP-44 HD wallet derivationNo
07_comptime_selectorsComptime function selectorsNo

Run any example:

cd examples && zig build && ./zig-out/bin/01_derive_address

Derive an Address

const eth = @import("eth");

// WARNING: This is the default Anvil/Hardhat test key. Never use it for real funds.
const private_key = try eth.hex.hexToBytesFixed(
    32,
    "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
);
const signer = eth.signer.Signer.init(private_key);
const addr = try signer.address();
const checksum = eth.primitives.addressToChecksum(&addr);
// "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"

Sign and Send a Transaction

const eth = @import("eth");

var transport = eth.http_transport.HttpTransport.init(allocator, "https://rpc.example.com");
defer transport.deinit();
var provider = eth.provider.Provider.init(allocator, &transport);

var wallet = eth.wallet.Wallet.init(allocator, private_key, &provider);
const tx_hash = try wallet.sendTransaction(.{
    .to = recipient_address,
    .value = eth.units.parseEther(1.0),
});

Read an ERC-20 Token

const eth = @import("eth");

// Comptime selectors -- zero runtime cost
const balance_sel = eth.erc20.selectors.balanceOf;

// Or use the typed wrapper
var token = eth.erc20.ERC20.init(allocator, token_addr, &provider);
const balance = try token.balanceOf(holder_addr);
const name = try token.name();
defer allocator.free(name);

Comptime Function Selectors

const eth = @import("eth");

// Computed at compile time -- zero runtime cost
const transfer_sel = eth.abi_comptime.comptimeSelector("transfer(address,uint256)");
// transfer_sel == [4]u8{ 0xa9, 0x05, 0x9c, 0xbb }

const transfer_topic = eth.abi_comptime.comptimeTopic("Transfer(address,address,uint256)");
// transfer_topic == keccak256("Transfer(address,address,uint256)")

HD Wallet from Mnemonic

const eth = @import("eth");

const words = [_][]const u8{
    "abandon", "abandon", "abandon", "abandon",
    "abandon", "abandon", "abandon", "abandon",
    "abandon", "abandon", "abandon", "about",
};
const seed = try eth.mnemonic.toSeed(&words, "");
const key = try eth.hd_wallet.deriveEthAccount(seed, 0);
const addr = key.toAddress();

Multicall3 Batch Reads

const eth = @import("eth");

var mc = eth.multicall.Multicall3.init(allocator, &provider);
try mc.addCall(token_addr, eth.erc20.selectors.balanceOf, .{holder_addr});
try mc.addCall(token_addr, eth.erc20.selectors.totalSupply, .{});
const results = try mc.execute();