- Docker and Docker Compose
- Foundry (Forge and Cast) for local development and testing
To run the test suite, make sure you have Foundry installed. Then run:
# Run all tests
cd contracts
forge test -C ./eigenlayer -vvv
# Run a specific test function
forge test -C ./eigenlayer --match-test test_pause -vvv
First, ensure you have all submodules:
git submodule update --init --recursive
Then, build the image:
docker build -t wavs-middleware .
Prepare the env file:
cp docker/env.example docker/.env
# edit the RPC_URL for a paid testnet rpc endpoint, add funded key, and TESTNET_RPC_URL
Start anvil in one terminal:
source docker/.env
anvil --fork-url $RPC_URL --host 0.0.0.0 --port 8545
Run all the following scripts in the docker/
directory.
cd docker/
Deploy:
docker run --rm --network host --env-file .env -v ./.nodes:/root/.nodes wavs-middleware deploy
Set Service URI:
SERVICE_URI="https://ipfs.url/for-custom-service.json"
docker run --rm --network host --env-file .env -v ./.nodes:/root/.nodes wavs-middleware set_service_uri "$SERVICE_URI"
Register:
# Generate a new private key for the operator (needs ETH for transactions)
OPERATOR_KEY=$(cast wallet new --json | jq -r '.[0].private_key')
OPERATOR_ADDRESS=$(cast wallet addr --private-key "$OPERATOR_KEY")
echo "Operator address: $OPERATOR_ADDRESS"
export WAVS_SERVICE_MANAGER_ADDRESS=$(jq -r '.addresses.WavsServiceManager' .nodes/avs_deploy.json)
# Generate or use an existing AVS signing key address
# Option 1: Generate a new AVS signing key
AVS_KEY=$(cast wallet new --json | jq -r '.[0].private_key')
AVS_SIGNING_ADDRESS=$(cast wallet addr --private-key "$AVS_KEY")
echo "AVS signing address: $AVS_SIGNING_ADDRESS"
# Option 2: Use an existing AVS signing address from your AVS node
# AVS_SIGNING_ADDRESS="0x..." # Address of the key that will sign for the AVS
# Register the operator using the operator key and AVS signing address
docker run --rm --network host --env-file .env \
-e WAVS_SERVICE_MANAGER_ADDRESS=${WAVS_SERVICE_MANAGER_ADDRESS} \
wavs-middleware register "$OPERATOR_KEY" "$AVS_SIGNING_ADDRESS" "0.01ether"
List Operators:
# View stake registry status, including registered operators and their weights
docker run --rm --network host --env-file .env \
-e WAVS_SERVICE_MANAGER_ADDRESS=${WAVS_SERVICE_MANAGER_ADDRESS} \
-e PAST_BLOCKS=1000 \
wavs-middleware list_operator
Pause Registration:
docker run --rm --network host --env-file .env -v ./.nodes:/root/.nodes wavs-middleware pause
Unpause Registration:
docker run --rm --network host --env-file .env -v ./.nodes:/root/.nodes wavs-middleware unpause
Same as the local deploy, but add TESTNET_RPC_URL
to the .env and change DEPLOY_ENV
to "TESTNET"
and make sure the FUNDED_KEY
is actually funded on testnet
sequenceDiagram
autonumber
participant Env as Environment
participant Deploy as Deploy Script
participant Service as Service U
participant Register as Register Operator
participant Contracts as Contracts
Env->>Env: Load Environment Variables
Env->>Env: Set LOCAL_ETHEREUM_RPC_URL
Env->>Env: Check Required Variables
Deploy->>Contracts: Deploy Middleware Contracts
Deploy->>Deploy: Read Contract Addresses
Deploy->>Contracts: Update Quorum Config
Deploy->>Contracts: Update Minimum Weight
Deploy->>Contracts: Update AVS Registrar
Deploy->>Contracts: Update Metadata URL
Deploy->>Contracts: Create Operator Sets
Service->>Service: Read Deployer Key
Service->>Service: Get Service Manager Address
Service->>Service: Get Owner Address
Service->>Contracts: Impersonate Owner
Service->>Contracts: Set Service URI
Service->>Contracts: Stop Impersonating
Register->>Register: Read Operator Key and AVS Signing Address
Register->>Register: Setup Operator
Register->>Register: Fund Operator Account
Register->>Contracts: Mint LST Tokens
Register->>Contracts: Approve LST Tokens
Register->>Contracts: Deposit into Strategy
Register->>Contracts: Register as Operator
Register->>Contracts: Register for Operator Sets
Register->>Contracts: Get Stake Registry Address
Register->>Contracts: Get Service Manager Address
Register->>Contracts: Get AVS Directory Address
Register->>Register: Generate Random Salt
Register->>Register: Calculate Expiry
Register->>Register: Calculate Digest Hash
Register->>Register: Sign Digest Hash with Operator Key
Register->>Contracts: Register with Signature using AVS Signing Address
- Load environment variables from
.env
file - Set
LOCAL_ETHEREUM_RPC_URL
based on environment (TESTNET or LOCAL) - Check for required environment variables
- Deploy middleware contracts using Forge script
- Read contract addresses from deployment JSON
- Update quorum config with strategy weights
- Set minimum weight for operators
- Configure AVS registrar
- Update metadata URL for EigenLayer frontend
- Create operator sets for meta-AVS functionality
- Read deployer private key from file
- Get service manager address from deployment JSON
- Get owner address from service manager contract
- Impersonate owner account (LOCAL only)
- Set service URI on service manager contract
- Stop impersonating owner account
- Read operator private key and AVS signing address from command line
- Setup operator with initial configuration
- Fund operator account with ETH
- Mint LST tokens for operator
- Approve LST tokens for strategy manager
- Deposit LST tokens into strategy
- Register as operator with delegation manager
- Register for operator sets with allocation manager
- Register with AVS using signature:
- Get stake registry address
- Get service manager address
- Get AVS directory address
- Generate random salt
- Calculate expiry time
- Calculate digest hash
- Sign digest hash with operator's private key
- Register with signature on stake registry, using the AVS signing address as the signing key
-
wait_for_ethereum
: Check if Ethereum node is ready -
impersonate_account
: Impersonate an account (LOCAL only) -
execute_transaction
: Run a transaction and handle errors -
stop_impersonating
: Stop impersonating an account (LOCAL only)
To get Holesky ETH for running on testnet:
-
PoW Mining Faucet:
- Go to https://holesky-faucet.pk910.de/
- Connect your wallet
- Mine blocks in your browser to earn ETH
- Rewards based on mining time/hashrate
- No external requirements
-
Alchemy Faucet (Alternative):
- Visit https://www.alchemy.com/faucets/holesky
- Requires mainnet ETH balance to use
- Connect wallet and verify ownership
- Request funds (limits apply)