Skip to content

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.shbeacond (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)

ClientRefCommitNotes
beacon-kit (→ beacond)v1.3.966dec0c20f864e2093bed79c2028adc450c17addGo 1.26 (go.mod requires go 1.26.2).
bera-rethv1.3.326762fbc31f69c6746b58f862dddd99000cb9592Embeds 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).

sh
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-reth

Image tags

LayerTagChain-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.3chain-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:

sh
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/):

PatchClientWhat it does
epoch-mint (beacon-kit-epoch-mint.patch)beacondRe-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-rethForces 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-id sed target literal exists in v1.3.9 chain/chain_ids.go.
  • Needs a real host: the actual docker buildx compile/link — intentionally not run in CI (bera-reth from source is a heavy Rust build, tens of minutes).

See also

Operator docs. Testnet chain-id 473374; mainnet 47337 (gated on external audit). Not financial advice.