A widget for participating in Lido CSM based on Lido Frontend Template.
Lido Community Staking Module (CSM) is a permissionless module allowing community stakers to operate Ethereum validators with lower entry costs. Stakers provide stETH bonds, serving as security collateral, and receive rewards in the form of bond rebase and staking rewards (including execution layer rewards), which are socialized across Lido’s staking modules.
More on CSM in the docs.
- Node.js v24 (
>=24.0.0 <25.0.0) - Yarn package manager v1
This project requires an .env file which is distributed via private communication channels. A sample can be found in .env.example
Step 1. Copy the contents of .env.example to .env.local
cp .env.example .env.localStep 2. Fill out the .env.local. You will need to provide RPC provider urls and CL API urls with keys included.
Step 3. Install dependencies
yarn installStep 4. Start the development server
yarn devStep 5. Open http://localhost:3000 with your browser to see the result.
This project uses publicRuntimeConfig in the next.config.mjs and getServerSideProps on the pages (function may be empty, but it forces Next.js to switch to Server-Side Rendering mode). This is necessary to quickly start the docker container without rebuilding the application.
Read more about runtime configuration and automatic static optimization
Note! This repo uses automatic versioning, please follow the commit message conventions.
e.g.
git commit -m "fix: a bug in calculation"
git commit -m "feat: dark theme"yarn build && yarn startBefore running the test suite, create a file named .env.local in the project root and populate it with the following variables:
# Choose one: testnet, prod, staging, preview
STAND_TYPE=testnet
# Wallet environment
WALLET_SECRET_PHRASE=
WALLET_PASSWORD=Replace each value as needed for your environment.
Install browser:
yarn playwright install chromium --with-depsTo execute the tests, run the suite for the module you want:
yarn test:csm:e2e # CSM widget
yarn test:cm:e2e # CM widgetAppend :ui (yarn test:csm:ui / yarn test:cm:ui) to run Playwright in interactive UI mode. This loads your .env.local file and runs the configured test scripts.
Forked tests run against a local anvil fork started by compose.yaml. There is one
profile per network — mainnet, hoodi — so both forks can run side by side:
docker compose --env-file fork.env --profile hoodi up -d --wait # start, waits until the fork answers
docker compose --env-file fork.env run --rm hoodi-url # print the local and public URLs
docker compose --env-file fork.env --profile hoodi logs -f # follow logs
docker compose --env-file fork.env --profile hoodi down # stop and remove
docker compose --env-file fork.env ps # every running forkEvery module of a network (CSM, CSM_02, CM) is already deployed in that network, so one fork serves them all — the module a command or a suite works with only decides which contract addresses the calls go to.
export COMPOSE_ENV_FILES=fork.env once in your shell and the flag can be dropped.
The compose project is named csm-widget-forks and the containers are named
hoodi-fork, mainnet-fork, ipfs (each with its -tunnel), so they read the
same in docker ps and stay the same from any checkout of the repo — a second
worktree talks to the running forks instead of starting its own.
The fork is made from EL_RPC_URLS_1 / EL_RPC_URLS_560048 and funds the
WALLET_SECRET_PHRASE accounts, both taken from .env.local. Every fork also
gets a cloudflared quick tunnel, so it can be reached from outside — the -url
service prints that address.
The tests also need an IPFS node to pin merkle trees to. It has its own profile and can be started once and left running next to any fork:
docker compose --env-file fork.env --profile ipfs up -d --wait
docker compose --env-file fork.env run --rm ipfs-url # gateway URLs, local and publicIt gets a tunnel of its own, so the gateway is reachable from outside. Only the gateway — the API on 5001 is unauthenticated admin access to the node.
The ports live in fork.env — the only place they are written down. The tests and the contract commands read the same file, so nothing has to be switched by hand between forks (in CI they all use the plain 8545):
yarn fork csm hoodi addKeys 12 5 # hits the hoodi fork as CSM; `yarn fork help` lists every command
USE_FORK=true yarn test:cm:e2e # hits the hoodi fork as CM (STAND_TYPE=testnet)A fork is shared state: evm_snapshot / evm_revert cover the whole node, so
two suites running against the same fork at once will roll back each other's
setup. Run them one after another.
To create a new release:
- Merge all changes to the
mainbranch. - After the merge, the
Prepare release draftaction will run automatically. When the action is complete, a release draft is created. - When you need to release, go to Repo → Releases.
- Publish the desired release draft manually by clicking the edit button - this release is now the
Latest Published. - After publication, the action to create a release bump will be triggered automatically.
Learn more about App Release Flow.