Skip to content

Releases: StrobeLabs/eth.zig

v0.7.0 — Pluggable Io, encrypted keystore, fallback provider, EIP-7702

Choose a tag to compare

@koko1123 koko1123 released this 11 Jun 14:07
f4fc135

Highlights

  • Pluggable std.Io (breaking, idiomatic). Zig 0.16 makes the execution model the caller's choice; eth.zig now takes std.Io as an explicit parameter on every network constructor (HttpTransport.init, WsTransport.connect, WsClient.connect, flashbots.Relay.init, FallbackProvider.init, MevShareClient) and on the functions that need randomness/sleep (mnemonic.generate, keystore.encrypt, runtime.milliTimestamp/sleepMs). No hidden global Io -- run the library on your own event loop and honor its cancellation. Provider/Wallet/RetryingProvider/NonceManager inherit the Io of the transport they wrap. Pass eth.runtime.blockingIo() for the previous blocking behavior. (Thanks to the community for pushing on this.)
  • Encrypted JSON keystore (#65): Web3 Secret Storage v3 decrypt/encrypt (scrypt + pbkdf2, AES-128-CTR, constant-time Keccak MAC), interop-verified against the canonical geth fixtures. Load the keys you already have from geth/foundry/ethers.
  • FallbackProvider (#70): multi-RPC failover with per-endpoint health tracking and recovery probing; fails over on transport errors but never on a real RPC answer.
  • EIP-7702 SetCode transactions (#66): type 0x04 with signed authorizations (signAuthorization, the 0x05-magic signing hash) -- Pectra parity with alloy/viem.

Migrating from v0.6.0

Add an io argument where you construct transports/clients:

// before
var http = eth.http_transport.HttpTransport.init(alloc, url);
// after (simple blocking case)
var http = eth.http_transport.HttpTransport.init(alloc, url, eth.runtime.blockingIo());

Provider.init(alloc, &http) is unchanged and inherits the transport's Io.

Install

zig fetch --save git+https://github.com/StrobeLabs/eth.zig.git#v0.7.0

Requires Zig 0.16.0+. Verified on 0.16.0 and 0.17-dev: 812/812 unit tests, 23/23 Anvil integration tests.

Full changelog: https://github.com/StrobeLabs/eth.zig/blob/main/CHANGELOG.md

v0.6.0 — MEV-Share, nonce manager, and a test suite that actually runs

Choose a tag to compare

@koko1123 koko1123 released this 10 Jun 18:56
e697bc5

Highlights

  • MEV-Share client (#34): MevShareClient mirrors mev-share-client-ts -- private transactions, bundle simulation (mev_simBundle), a blocking SSE event stream, and event history. Plus eth_sendPrivateTransaction (#40) on flashbots.Relay and a backrunner example (#38) that matches the live hint stream against comptime swap selectors.
  • Atomic nonce manager (#75): lock-free next() for concurrent senders, lazy on-chain seeding, and gap-on-failure recovery.

Correctness milestone

  • The unit test suite never actually ran. The aggregator collected module tests via _ = eth.module field access, which only forces compilation -- so assertions compiled but never executed (zig build test passed even with a deliberately failing test). Fixed in #84 by rooting the test artifact at src/root.zig.
  • Turning the suite on surfaced and resolved real issues: a broken pure-Zig Keccak fallback (#80) and a mulDiv u256-boundary bug (#81) were genuine code defects; two others (#82, #83) were bad test expectations. The suite now runs 775/775 with zero skips.

Benchmarks

Refreshed against current alloy (alloy-primitives 1.6 / alloy-consensus 2.0): an honest 18/26 wins, with the biggest margins on RLP encode (24x), ABI decode (8.4x), and secp256k1 recovery (4.2x). Full table in bench/RESULTS.md.

Install

zig fetch --save git+https://github.com/StrobeLabs/eth.zig.git#v0.6.0

Requires Zig 0.16.0+. Verified on 0.16.0 and 0.17-dev master.

Full changelog: https://github.com/StrobeLabs/eth.zig/blob/main/CHANGELOG.md

v0.5.0 — Zig 0.16 support and block-scoped log watching

Choose a tag to compare

@koko1123 koko1123 released this 10 Jun 13:42
d07f3b8

Highlights

  • Zig 0.16 support (#55, #60): the entire transport layer now runs on Zig 0.16's new std.Io interface — HTTP, WebSocket (including TLS), and SSE. A new eth.runtime module constructs a default synchronous Io internally, so no public API signatures changed. Also passes on current master (0.17.0-dev).
  • log_watcher (#36, #59): the canonical bot loop as a library primitive — on each newHeads, fetch eth_getLogs scoped to that block. Back-fills blocks missed across reconnects and re-fetches reorged ranges on parent-hash mismatch. LogWatcher.pollOnce() (pull) or watchLogs() (callback).

Breaking

  • Minimum supported Zig version is now 0.16.0 (0.15.2 support dropped). If you are on 0.15.x, stay on v0.4.0.

Install

zig fetch --save git+https://github.com/StrobeLabs/eth.zig.git#v0.5.0

Verified on 0.16.0 and 0.17.0-dev: build, unit tests, and 23/23 integration tests against Anvil (HTTP transport, WS subscriptions, LogWatcher) on each.

Full changelog: https://github.com/StrobeLabs/eth.zig/blob/main/CHANGELOG.md

v0.4.0 — Resilient WebSockets, state overrides, full pending-tx streams

Choose a tag to compare

@koko1123 koko1123 released this 10 Jun 01:44
0a429f5

Highlights

  • WsClient: resilient WebSocket subscription client with transparent reconnect, exponential backoff with jitter, ping/pong keepalive, and multiplexed subscriptions over a single connection (#51)
  • Full pending-transaction subscriptions: newPendingTransactions with full: true streams complete RpcTransaction values instead of hashes, tolerating nodes that fall back to hash-only notifications (#53)
  • eth_call state overrides: set balance, nonce, code, and storage (full state or diff) per call via callWithOverrides (#54)
  • SSE transport with last-event-id reconnect support (#48)
  • RetryingProvider: configurable retry middleware with exponential backoff and connection-error filtering (#41)
  • Batch eth_call fan-out via BatchCaller and pure Zig UniswapV2 DEX math (#42)

Compatibility

  • Compatible with Zig master (0.17.0-dev) again: all uses of the removed ** array-repetition operator replaced with @splat (#56). Minimum supported version remains 0.15.2.

Reliability & security

  • Malformed RPC transaction fields now fail fast with error.InvalidResponse instead of being silently coerced (#53)
  • 21 security, correctness, and code-quality fixes across the library (#44)
  • Docs site upgraded to Next 16 / Fumadocs 16; pnpm audit is clean (#57)

Install

zig fetch --save git+https://github.com/StrobeLabs/eth.zig.git#v0.4.0

Full changelog: https://github.com/StrobeLabs/eth.zig/blob/main/CHANGELOG.md

v0.3.0

Choose a tag to compare

@koko1123 koko1123 released this 09 Mar 22:07
757ac11

Flashbots MEV Bundle Submission

Adds full support for submitting MEV bundles via Flashbots-compatible relay APIs.

New: flashbots module

  • Relay client with EIP-191 auth signing (X-Flashbots-Signature header)
  • eth_sendBundle (Flashbots v1) - submit bundles to relays
  • mev_sendBundle (MEV-Share) - submit bundles with privacy/validity options
  • eth_callBundle - simulate bundles against specific blocks
  • eth_cancelBundle - cancel bundles by replacement UUID
  • Bundle convenience builder for collecting signed transactions

API

const eth = @import("eth");

var relay = eth.flashbots.Relay.init(allocator, "https://relay.flashbots.net", auth_key);
defer relay.deinit();

const result = try relay.sendBundle(.{
    .transactions = bundle.transactions(),
    .block_number = current_block + 1,
});

Closes #13

Full Changelog: v0.2.3...v0.3.0

v0.2.3

Choose a tag to compare

@koko1123 koko1123 released this 28 Feb 22:25
3037a45

GLV secp256k1 + Lane-Complementing Keccak

This release brings major crypto performance improvements, beating alloy.rs (Rust) on all crypto benchmarks.

Performance Highlights

Benchmark eth.zig alloy.rs Speedup
keccak256 32B 300 ns 337 ns 1.12x
secp256k1 sign 46 us 33 us 0.72x (constant-time tradeoff)
secp256k1 recover 45 us 50 us 1.11x
address derivation 299 ns 363 ns 1.21x

What's New

  • GLV endomorphism for secp256k1: Splits 256-bit scalar multiplication into two ~128-bit halves using the curve's efficiently computable endomorphism, with comptime-precomputed tables for both base point and lambda base point
  • Lane-complementing Keccak-f[1600]: Implements the XKCP opt64 technique -- complements 6 specific state lanes so the chi step uses AND/OR instead of NOT+AND, saving one instruction per lane on ARM/x86
  • derivePublicKey scalar validation: Added proper validation for private key scalars
  • Deprecated allocator initialization: Removed deprecated allocator init patterns and fixed LLVM crash in tests (thanks @Mario-SO!)
  • Documentation site: Added docs site for ethzig.org

Full Changelog

  • GLV secp256k1 + lane-complementing Keccak: beat Voltaire on all crypto benchmarks (#22)
  • Deprecated allocator initialization + tests fix LLVM crash (#10) by @Mario-SO
  • Add documentation site for ethzig.org (#8)

v0.2.2

Choose a tag to compare

@koko1123 koko1123 released this 26 Feb 19:44

Test Coverage: alloy.rs Parity Validation

Adds ~97 cross-validation tests across 15 modules to ensure byte-exact accuracy parity with alloy.rs. All test vectors sourced from official specs (Solidity ABI, EIP-55/712/137, BIP-32/39), alloy-rs test suites, Hardhat well-known accounts, and ethereum/tests.

New Tests by Module

Module New Tests Validation Focus
abi_encode 12 Solidity ABI spec vectors, ERC20 approve, fixed_bytes
abi_decode 8 Roundtrips, error cases, ERC20 return decode
transaction 8 alloy.rs vectors, access lists, EIP-4844 blobs
signer 4 Hardhat accounts #2-#4, large message
secp256k1 4 Key=1 edge, multi-message, EIP-2 low-s
rlp 12 Long strings, byte boundaries, non-canonical
uint256 12 fastDiv exhaustive, mulDiv Q96, roundtrips
keccak 6 Known vectors, SHA3 distinction, DeFi selectors
primitives 6 EIP-55 full test suite, error handling
eip712 4 ERC20 Permit, Permit2 nested, domain variants
units 6 Zero/large values, parse/format roundtrips
hd_wallet 4 BIP-32 pinned vectors, known mnemonic->address
mnemonic 4 BIP-39 TREZOR exact seed, all-ones entropy
namehash 3 vitalik.eth, resolver.eth, trailing dot
hex 4 Uppercase/mixed case, 256-byte roundtrip

Other Changes

  • Pinned canonical EIP-712 digest vectors for Permit and Permit2 tests
  • Pinned exact BIP-32 master key/chain_code bytes
  • Reused existing isHighS helper in EIP-2 low-s test
  • Fixed f64 precision edge case in parseEther large value test
  • Version bump to 0.2.2

v0.2.1

Choose a tag to compare

@koko1123 koko1123 released this 26 Feb 16:47
3e33957

Performance Release: Beat alloy.rs on 18/24 benchmarks

Major performance optimizations across the entire eth-zig library, taking us from 10/24 benchmark wins against alloy.rs to 18/24 wins.

Highlights

  • 793x faster address derivation
  • 315x faster ABI encoding (static)
  • 304x faster ABI encoding (transfer)
  • 209x faster ABI decoding (uint256)
  • 191x faster RLP encoding (EIP-1559 tx)
  • 45x faster transaction hashing
  • 13x faster u256 division
  • 4.8x faster secp256k1 signing

Score: eth-zig 18 - alloy.rs 5

Benchmark eth-zig alloy.rs Winner
keccak256_empty 254 ns 335 ns zig 1.32x
keccak256_32b 263 ns 337 ns zig 1.28x
keccak256_256b 533 ns 638 ns zig 1.20x
keccak256_1kb 2,026 ns 2,421 ns zig 1.19x
keccak256_4kb 7,828 ns 9,229 ns zig 1.18x
secp256k1_sign 224,177 ns 51,687 ns rs 4.34x
secp256k1_sign_recover 837,511 ns 218,360 ns rs 3.84x
address_derivation 262 ns 362 ns zig 1.38x
address_from_hex 16 ns 25 ns zig 1.56x
checksum_address 307 ns 388 ns zig 1.26x
abi_encode_transfer 71 ns 55 ns rs 1.29x
abi_encode_static 69 ns 97 ns zig 1.41x
abi_encode_dynamic 246 ns 316 ns zig 1.28x
abi_decode_uint256 46 ns 49 ns zig 1.07x
abi_decode_dynamic 170 ns 258 ns zig 1.52x
rlp_encode_eip1559_tx 89 ns 70 ns rs 1.27x
rlp_decode_u256 6 ns 8 ns zig 1.33x
u256_add 4 ns 4 ns tie
u256_mul 4 ns 10 ns zig 2.50x
u256_div 6 ns 23 ns zig 3.83x
u256_uniswapv2_amount_out 87 ns 24 ns rs 3.62x
hex_encode_32b 21 ns 22 ns zig 1.05x
hex_decode_32b 23 ns 45 ns zig 1.96x
tx_hash_eip1559 366 ns 403 ns zig 1.10x

Optimizations

  • Replace debug allocator with c_allocator in benchmarks
  • Remove redundant verifyRecovery() from secp256k1 sign() (5 EC muls to 1)
  • Zero-overhead direct buffer RLP/ABI/TX encoding (no ArrayList overhead)
  • u256.fastDiv with u128 fast-path (bypasses slow LLVM 256-bit division)
  • Comptime hex decode lookup table
  • bytesToUint using BSWAP instead of byte loop
  • @clz for branchless byte-length counting in RLP

See bench/RESULTS.md for full details.

v0.2.0

Choose a tag to compare

@koko1123 koko1123 released this 26 Feb 04:07
828503b

What's New

  • Integration tests (provider, wallet, contract against Anvil)
  • Benchmark suite (zig build bench) -- keccak, secp256k1, ABI, RLP, HD wallet, EIP-712
  • CONTRIBUTING.md, CHANGELOG.md, issue templates
  • README overhaul with feature comparison table, examples section
  • Bug fixes in provider and wallet modules

Full Changelog

v0.1.0...v0.2.0

v0.1.0 -- Initial Release

Choose a tag to compare

@koko1123 koko1123 released this 26 Feb 03:49

eth.zig v0.1.0

Initial release of eth.zig -- a feature-complete, pure Zig Ethereum client library with zero external dependencies.

Highlights

  • 16K lines of pure Zig, built entirely on the standard library
  • Comptime-first: function selectors and event topics computed at compile time for zero runtime cost
  • Full Ethereum stack: primitives, ABI encoding/decoding, RLP, secp256k1 signing, transaction types (Legacy through EIP-4844), HD wallets, JSON-RPC (HTTP + WebSocket), provider, wallet, contract interaction, Multicall3, EIP-712, ENS resolution
  • Production-tested: powers perpcity-zig-sdk for high-frequency perpetual futures trading

What's Included

Layer Modules
Primitives Address, Hash, u256, hex encoding
Encoding RLP, ABI encode/decode, comptime selectors, JSON ABI parser
Crypto Keccak-256, secp256k1 ECDSA (RFC 6979), EIP-155
Types Legacy, EIP-2930, EIP-1559, EIP-4844 transactions, receipts, blocks
Accounts BIP-32/39/44 HD wallets, mnemonic generation
Transport HTTP + WebSocket JSON-RPC, subscriptions
Client Provider (24+ methods), signing wallet, contract helpers, Multicall3
Standards EIP-712, ENS, ERC-20/721 helpers
Chains Ethereum, Arbitrum, Optimism, Base, Polygon

Requirements

  • Zig >= 0.15.2

Installation

.dependencies = .{
    .eth = .{
        .url = "git+https://github.com/StrobeLabs/eth.zig.git#v0.1.0",
        .hash = "...",
    },
},

See the README for full documentation and examples.