Building the images
Production uses the published multi-arch images. Operators who build their own do so from pinned upstream source via from-source/build.sh — beacond (from beacon-kit) and bera-reth, each with the Krypton patches applied. See the RUNBOOK for the full build → genesis → launch procedure.
Pinned versions (source of truth)
| Client | Ref | Commit | Notes |
|---|---|---|---|
| beacon-kit (→ beacond) | v1.3.9 | 66dec0c20f864e2093bed79c2028adc450c17add | Go 1.26 (go.mod requires go 1.26.2). |
| bera-reth | v1.3.3 | 26762fbc31f69c6746b58f862dddd99000cb9592 | Embeds reth v1.11.3; chain-agnostic. |
Build tooling: Docker buildx (QEMU registered for cross-arch), Rust via upstream cargo-chef image, Kurtosis 1.18.3.
Build
Requires a Docker host with buildx and QEMU registered (docker run --privileged --rm tonistiigi/binfmt --install all).
cd l1/from-source
# Multi-arch build + push (required for arm64 / Raspberry Pi edge nodes):
PUSH=1 ./build.sh # MAINNET 47337 (default)
PUSH=1 KRYPTON_CHAIN_ID=473374 ./build.sh # public testnet
# Quick host-arch-only local build (no push, no manifest list):
./build.sh # --load, single arch
# Build just one client:
PUSH=1 ./build.sh beacond
PUSH=1 ./build.sh bera-rethImage tags
| Layer | Tag | Chain-id |
|---|---|---|
| CL (beacond) | ghcr.io/foreseerco/krypton-beacond:v1.3.9-${KRYPTON_CHAIN_ID} | per-network — …-47337 (mainnet) / …-473374 (testnet) |
| EL (bera-reth) | ghcr.io/foreseerco/krypton-bera-reth:v1.3.3 | chain-agnostic — one tag for both (the EL chain-id comes from genesis) |
KRYPTON_CHAIN_ID (default 47337) threads through the tag, the baked CL spec, and the genesis. The beacond build fails loudly if the upstream DevnetEth1ChainID uint64 = 80087 literal isn't found (guards against an upstream refactor silently skipping the chain-id patch). Confirm the bake afterward:
docker run --rm --entrypoint beacond \
ghcr.io/foreseerco/krypton-beacond:v1.3.9-47337 version
# version string ends in "-krypton-47337"The patches applied
The from-source images carry the two consensus-critical reward patches (kept as .patch files under from-source/patches/):
| Patch | Client | What it does |
|---|---|---|
epoch-mint (beacon-kit-epoch-mint.patch) | beacond | Re-parametrizes the live per-block EVMInflationWithdrawal mint into a state-carried, curve-derived value credited to INFLATION_SINK — the launch security budget. |
fee-router (bera-reth-fee-router.patch) | bera-reth | Forces block.coinbase to the FEE_SINK predeploy in-protocol and redirects the base fee (normally burned) + tips to it, minus a governance baseFeeBurnBps (genesis 0). The growing real-yield source. |
Both patches are determinism-proven
They finalized in lockstep with byte-identical state across a 4-validator Kurtosis net; 4→5 join and EIP-7002 exit also proven live. Determinism (integer-only math, value conservation, no off-chain inputs) is the load-bearing requirement — a non-deterministic amount forks the chain. See Architecture.
The license gate (W1)
Do not bypass the license check on a release build
build.sh runs scripts/check-license.sh and refuses to build release images from a pin set whose license isn't permissive (e.g. a beacon-kit ref still inside its BUSL change-date window). beacon-kit's Change Date (2026-01-31) has passed → MIT; bera-reth and the CometBFT fork are Apache-2.0, so the pinned releases are permissively licensed for mainnet. Do not set SKIP_LICENSE_CHECK=1 for any pushed/release build.
What's validated vs. needs a real host
- Validated here:
bash -n build.sh, both Dockerfiles' arg/stage structure, and that the chain-idsedtarget literal exists in v1.3.9chain/chain_ids.go. - Needs a real host: the actual
docker buildxcompile/link — intentionally not run in CI (bera-reth from source is a heavy Rust build, tens of minutes).
See also
- Networks & chain IDs — how
KRYPTON_CHAIN_IDselects tags. - Genesis & the network bundle — produce genesis with the built image.
- Pin by digest — mutable tags are a consensus/supply-chain risk.