Deposit ETH to run an Ethereum validator — safely, from the command line.
ethernal walks you through the whole deposit, one clear step at a time: create
your keys, produce the Launchpad deposit data, build and sign the deposit
transaction (hardware wallet recommended), and broadcast it. It can also create
ordinary wallet (EOA) keystores that geth, Foundry, and MetaMask can import.
create keys → deposit data → unsigned tx → signed tx → broadcast
validator new deposit gen deposit build tx sign tx send
└────────── tx run ──────────┘
New here? This page is the introduction — start below, then follow the User Guide for the full walkthrough, every flag, and the security details.
Use ethernal if you want to run one or more Ethereum validators and would
rather stay on the command line — with your validator mnemonic written down
offline and your deposit signed on a Ledger — than paste keys into a website.
You'll want:
- A testnet to practice on first (Hoodi). Never rehearse on mainnet.
- ~32 ETH per validator plus gas, held by the account that signs the deposit.
- A Ledger for any real deposit (a local key is available, but for testing only).
- Rust installed (the tool builds from source — see below).
Already have EIP-2335 validator keystores from another tool? Skip key creation
and hand them straight to ethernal deposit gen.
A validator deposit moves through three artifacts:
- Keystores — your encrypted BLS validator keys (
ethernal validator new). - Deposit data — the Launchpad JSON, signed by your validator key (
ethernal deposit gen). - A signed transaction — sends 32 ETH to the deposit contract, signed by
your wallet (
ethernal deposit build+tx sign, ortx run), then broadcast (tx send).
Two different keys are involved, and they never mix: the BLS validator key stays inside its keystore and only signs the deposit message; the secp256k1 wallet key (on your Ledger) signs the transaction that pays the 32 ETH. The User Guide explains this model in full.
| Command | What it does |
|---|---|
ethernal validator new / validator recover |
Create / recover BLS validator keystores (EIP-2335) from a mnemonic |
ethernal account new / account recover |
Create / recover wallet (EOA) keystores (Web3 v3) for geth / Foundry / MetaMask |
ethernal deposit gen |
Keystores → Launchpad deposit_data JSON |
ethernal deposit build |
Deposit data → unsigned deposit transaction |
ethernal tx sign |
Sign the transaction (Ledger, or a local key for testing) |
ethernal tx run |
deposit build + tx sign in one step |
ethernal tx send |
Broadcast the signed transaction |
Full flags, examples, and exit codes are in the User Guide.
Commands are grouped into four namespaces:
| Namespace | Groups |
|---|---|
validator |
EIP-2335 BLS keystores by role (new / recover) |
account |
Web3 v3 EOA keystores by role (new / recover) |
deposit |
Launchpad deposit_data (gen) and unsigned deposit-tx construction (build) |
tx |
Sign (sign), build+sign convenience (run), and broadcast (send) |
Non-secret ETHERNAL_TX_* flag fallbacks (ETHERNAL_TX_RPC_URL, _FROM, _GAS_LIMIT) stay. Passphrases and the local private key come from files (or a TTY prompt), not env-var-name flags.
Builds from source; no prebuilt binaries yet.
git clone https://github.com/rootwarp/ethernal.git
cd ethernal
make build # → target/release/ethernalFor a real deposit, build with Ledger support:
cargo build --release --features ledgerYou need a stable Rust toolchain and a C compiler (for the blst BLS library).
Windows is not supported. Linux needs libudev-dev (or equivalent) and
Ledger udev rules before the ledger
feature will build. Platform-by-platform notes are in the
User Guide.
The shortest path is the guide's Quick start
(Hoodi) — create a keystore,
generate deposit data, then tx run and tx send. Practice the whole flow on Hoodi
before you ever point it at mainnet.
A one-look preview of the core steps:
umask 077
printf '%s' 'my-keystore-passphrase' > ./keystore.pw # or: chmod 600 after writing
ethernal validator new --output-dir ./keystores --count 1 --passphrase-file ./keystore.pw
ethernal deposit gen --network hoodi --keystore-dir ./keystores --pubkeys 0x<pubkey> \
--withdrawal-address 0x<your-eip55-address> --output-dir ./out --passphrase-file ./keystore.pw
ethernal tx run --network hoodi --signer ledger --input-file ./out/deposit_data-*.json --output signed.json
ethernal tx send --input signed.json --rpc-url https://your-hoodi-rpc--signer ledger needs the --features ledger build; to rehearse on testnet
from the quick make build, use --signer local with a throwaway key (see the
guide's local-signer note).
ethernal has guardrails, but the irreversible parts are on you:
- Mainnet deposits cannot be undone.
deposit gen --network mainnetrefuses to run without--i-understand-this-is-mainnet. Rehearse on Hoodi first. - Your mnemonic is the master key.
validator new/account newshow it once, on the terminal only, and clear the screen afterward. Write it down offline — never screenshot it, paste it into chat, or store it in the cloud. - Verify on the Ledger screen before you confirm. Check the chain ID, the deposit-contract address, and that the value is exactly 32 ETH. If anything looks off, reject on the device.
- The local signer is for testing only — use a Ledger for real funds.
The Security section covers the threat model, key handling, and air-gapped signing.
- User Guide — the comprehensive reference: full walkthrough, every command and flag, networks, exit codes, security, recipes, and troubleshooting.
- Key creation: BLS validator keys · EOA keystores · which to use
- CHANGELOG.md — history, and divergences from the retired Go port.
make build # release binary at target/release/ethernal
make test # workspace unit + integration tests
make lint # clippy -D warnings + rustfmt check
make e2e-mock # build+sign+send via mock broadcaster (no real RPC)Without --features ledger, --signer ledger exits 3 with a message pointing
at the flag. The HID/APDU path is compile-verified only — validate on real
hardware before any real-fund use.
| Path | Contents |
|---|---|
bins/ethernal |
CLI: subcommands, exit-code map, logging |
crates/ethernal-core |
SSZ HTR, network params, BLS, BIP-39/HD, deposit generator |
crates/ethernal-keystore |
EIP-2335 v4 + Web3 v3 encrypt/decrypt, directory index, passphrase sources |
crates/ethernal-tx |
deposit() ABI, EIP-1559 builder, JSON-RPC client, URL redaction |
crates/ethernal-signer |
Local secp256k1 + Ledger signers; strict EIP-55 validation |
docs/ |
User Guide, design/plan archive (docs/plan/) |
testdata/ |
Golden fixtures (synthetic keys only) |
scripts/devnet/ |
Docker EL+CL devnet for end-to-end testing |
Unreleased (0.1.0). Formerly the eth-deposit binary in the eth-utils
repository — see CHANGELOG.md for the rename and history.
MIT — see LICENSE.