WAVS Monorepo Template
Template for getting started with developing WAVS applications
A template for developing WebAssembly AVS applications using Rust and Solidity, configured for Windows WSL, Linux, and MacOS. The sample oracle service fetches the current price of a cryptocurrency from CoinMarketCap and saves it on chain via the operators.
Languages
Core (Docker, Compose, Make, JQ, Node v21+, Foundry)
- Linux:
sudo apt update && sudo apt install build-essential
If prompted, remove container with sudo apt remove containerd.io
.
- MacOS:
brew install --cask docker
- Linux:
sudo apt -y install docker.io
- Windows WSL: docker desktop wsl &
sudo chmod 666 /var/run/docker.sock
- Docker Documentation
Note:
sudo
is only used for Docker-related commands in this project. If you prefer not to use sudo with Docker, you can add your user to the Docker group with:sudo groupadd docker && sudo usermod -aG docker $USERAfter adding yourself to the group, log out and back in for changes to take effect.
- MacOS: Already installed with Docker installer
sudo apt remove docker-compose-plugin
may be required if you get adpkg
error
- Linux + Windows WSL:
sudo apt-get install docker-compose-v2
- Compose Documentation
- MacOS:
brew install make
- Linux + Windows WSL:
sudo apt -y install make
- Make Documentation
- MacOS:
brew install jq
- Linux + Windows WSL:
sudo apt -y install jq
- JQ Documentation
- Required Version: v21+
- Installation via NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
nvm install --lts
curl -L https://foundry.paradigm.xyz | bash && $HOME/.foundry/bin/foundryup
Rust v1.85+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup toolchain install stable
rustup target add wasm32-wasip2
# Remove old targets if present
rustup target remove wasm32-wasi || true
rustup target remove wasm32-wasip1 || true
# Update and add required target
rustup update stable
rustup target add wasm32-wasip2
Cargo Components
On Ubuntu LTS, if you later encounter errors like:
wkg: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.38' not found (required by wkg)
wkg: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.39' not found (required by wkg)
If GLIB is out of date. Consider updating your system using:
sudo do-release-upgrade
# Install required cargo components
# https://github.com/bytecodealliance/cargo-component#installation
cargo install cargo-binstall
cargo binstall cargo-component wasm-tools warg-cli wkg --locked --no-confirm --force
# Configure default registry
# Found at: $HOME/.config/wasm-pkg/config.toml
wkg config --default-registry wa.dev
# Allow publishing to a registry
#
# if WSL: `warg config --keyring-backend linux-keyutils`
warg key new
# if foundry is not installed:
# `curl -L https://foundry.paradigm.xyz | bash && $HOME/.foundry/bin/foundryup`
forge init --template Lay3rLabs/wavs-foundry-template my-wavs --branch 0.4
Tip
Run make help
to see all available commands and environment variable overrides.
Install the required packages to build the Solidity contracts. This project supports both submodules and npm packages.
# Install packages (npm & submodules)
make setup
# Build the contracts
forge build
# Run the solidity tests
forge test
Now build the WASI components into the compiled
output directory.
Warning
If you get: error: no registry configured for namespace "wavs"
run, wkg config --default-registry wa.dev
Warning
If you get: failed to find the 'wasm32-wasip1' target and 'rustup' is not available
brew uninstall rust
& install it from https://rustup.rs
# Remove `WASI_BUILD_DIR` to build all components.
WASI_BUILD_DIR=components/evm-price-oracle make wasi-build
How to test the component locally for business logic validation before on-chain deployment. An ID of 1 for the oracle component is Bitcoin.
COIN_MARKET_CAP_ID=1 make wasi-exec
Expected output:
input id: 1
resp_data: PriceFeedData {
symbol: "BTC",
timestamp: "2025-04-01T00:00:00.000Z",
price: 82717.27035239758
}
INFO Fuel used: 653415
Result (hex encoded):
7b2273796d626f6c223a22425443222c2274696d657374616d70223a22323032352d30342d30315430303a34...
Result (utf8):
{"symbol":"BTC","timestamp":"2025-04-01T00:00:00.000Z","price":82717.27035239758}
Note
If you are running on a Mac with an ARM chip, you will need to do the following:
- Set up Rosetta:
softwareupdate --install-rosetta
- Enable Rosetta (Docker Desktop: Settings -> General -> enable "Use Rosetta for x86_64/amd64 emulation on Apple Silicon")
Configure one of the following networking:
- Docker Desktop: Settings -> Resources -> Network -> 'Enable Host Networking'
brew install chipmk/tap/docker-mac-net-connect && sudo brew services start chipmk/tap/docker-mac-net-connect
Start an ethereum node (anvil), the WAVS service, and deploy eigenlayer contracts to the local network.
Set Log Level:
- Open the
.env
file. - Set the
log_level
variable for wavs to debug to ensure detailed logs are captured.
Note
To see details on how to access both traces and metrics, please check out Telemetry Documentation.
# This must remain running in your terminal. Use another terminal to run other commands.
# You can stop the services with `ctrl+c`. Some MacOS terminals require pressing it twice.
cp .env.example .env
# update the .env for either LOCAL or TESTNET
# Starts anvil + IPFS, WARG, Jaeger, and prometheus.
make start-all-local
This script automates the complete WAVS deployment process in a single command:
- Build Check: Rebuilds WebAssembly component if changes detected
- Create Deployer: Sets up and funds deployer account
- Deploy Eigenlayer: Deploys service manager contract
- Deploy Contracts: Creates trigger and submission contracts
- Upload Component: Publishes WebAssembly component to WASI registry
- Build Service: Creates service configuration
- Upload to IPFS: Stores service metadata on IPFS
- Set Service URI: Registers IPFS URI with service manager
- Start Aggregator: Launches result aggregation service
- Start WAVS: Launches operator service with readiness check
- Deploy Service: Configures WAVS to monitor trigger events
- Generate Keys: Creates operator signing keys
- Register Operator: Registers with Eigenlayer AVS (0.001 ETH stake)
- Verify Registration: Confirms operator registration
A fully operational WAVS service that monitors blockchain events, executes WebAssembly components, and submits verified results on-chain.
export RPC_URL=`bash ./script/get-rpc.sh`
export AGGREGATOR_URL=http://127.0.0.1:8001
bash ./script/deploy-script.sh
Anyone can now call the trigger contract which emits the trigger event WAVS is watching for from the previous step. WAVS then calls the service and saves the result on-chain.
# Request BTC from CMC
export COIN_MARKET_CAP_ID=1
# Get the trigger address from previous Deploy forge script
export SERVICE_TRIGGER_ADDR=`make get-trigger-from-deploy`
# Execute on the trigger contract, WAVS will pick this up and submit the result
# on chain via the operators.
# uses FUNDED_KEY as the executor (local: anvil account)
source .env
forge script ./script/Trigger.s.sol ${SERVICE_TRIGGER_ADDR} ${COIN_MARKET_CAP_ID} --sig 'run(string,string)' --rpc-url ${RPC_URL} --broadcast
Query the latest submission contract id from the previous request made.
RPC_URL=${RPC_URL} make get-trigger
TRIGGER_ID=1 RPC_URL=${RPC_URL} make show-result
To spin up a sandboxed instance of Claude Code in a Docker container that only has access to this project's files, run the following command:
npm run claude-code
# or with no restrictions (--dangerously-skip-permissions)
npm run claude-code:unrestricted