6. Run your service
Local: Start Anvil, WAVS, and deploy Eigenlayer
- Create a
.env
file for your project by copying over the example with the following command:
cp .env.example .env
- Use the following command to start an Anvil test chain, IPFS, Registry, and some optional telemetry. This only runs with
LOCAL
being set in the.env
(default).
make start-all-local
The command must remain running in your terminal. Open another terminal to run other commands.
You can stop the services with ctrl+c
. Some MacOS terminals require pressing this twice.
You can skip all the setup steps below and just run a single command to deploy and run the entire service setup
export RPC_URL=`bash ./script/get-rpc.sh`export AGGREGATOR_URL=http://127.0.0.1:8001bash ./script/deploy-script.sh
This performs all the below steps (with the exception of actually triggering the contract).
With the chain running, you can deploy and run your service.
Create Deployer
An account is required to upload the contracts and to be the original admin of them. The create-deployer.sh
script creates a new wallet then sets a balance if using a local deployment, or waits until it has testnet funds before returning.
You can skip this step by setting FUNDED_KEY=
in .env
to a private key of your choice that has network funds.
bash ./script/create-deployer.sh
Deploy EigenLayer Middleware
Local deployments use the real testnet contracts via a forked anvil instance. This middleware will setup all the required contracts and configurations for the base of your AVS.
COMMAND=deploy make wavs-middleware
Deploy solidity contracts
The deploy-contracts.sh
script is used to deploy the trigger and submission solidity contracts to the chain.
source script/deploy-contracts.sh
Deploy Service
Deploy the compiled component with the contract information from the previous steps.
export COMPONENT_FILENAME=evm_price_oracle.wasmexport PKG_NAME="evmrustoracle"export PKG_VERSION="0.1.0"# ** Testnet Setup: https://wa.dev/account/credentials/new -> warg loginsource script/upload-to-wasi-registry.sh || true# Testnet: set values (default: local if not set)# export TRIGGER_CHAIN=holesky# export SUBMIT_CHAIN=holesky# Package not found with wa.dev? -- make sure it is publicexport AGGREGATOR_URL=http://127.0.0.1:8001REGISTRY=${REGISTRY} source ./script/build-service.sh
The build-service.sh script is used to create a service manifest (service.json) with the configuration for the service, including a workflow with the trigger event, component, aggregator, submission logic, and more. Visit the Service handbook for more information on service configuration.
Upload to IPFS
The ipfs-upload.sh
script is used to upload the service manifest to IPFS where it can be referenced by its URI.
# Upload service.json to IPFSSERVICE_FILE=.docker/service.json source ./script/ipfs-upload.sh
Aggregator
Start the aggregator and register the service with the aggregator. The aggregator is used to collect and validate responses from multiple operators before submitting them to the blockchain.
bash ./script/create-aggregator.sh 1IPFS_GATEWAY=${IPFS_GATEWAY} bash ./infra/aggregator-1/start.shwget -q --header="Content-Type: application/json" --post-data="{\"uri\": \"${IPFS_URI}\"}" ${AGGREGATOR_URL}/register-service -O -
Start WAVS
Create an operator and start WAVS. The create-operator.sh script configures the operator's environment and starts running WAVS.
bash ./script/create-operator.sh 1IPFS_GATEWAY=${IPFS_GATEWAY} bash ./infra/wavs-1/start.sh# Deploy the service JSON to WAVS so it now watches and submits.# 'opt in' for WAVS to watch (this is before we register to Eigenlayer)WAVS_ENDPOINT=http://127.0.0.1:8000 SERVICE_URL=${IPFS_URI} IPFS_GATEWAY=${IPFS_GATEWAY} make deploy-service
Register service specific operator
Each service gets its own key path (hd_path). The first service starts at 1 and increments from there. The following commands are used to register the operator with the service manager contract.
SERVICE_INDEX=0 source ./script/avs-signing-key.sh# Local:export WAVS_SERVICE_MANAGER_ADDRESS=$(jq -r .addresses.WavsServiceManager ./.nodes/avs_deploy.json)# TESTNET: set WAVS_SERVICE_MANAGER_ADDRESSCOMMAND="register ${OPERATOR_PRIVATE_KEY} ${AVS_SIGNING_ADDRESS} 0.001ether" make wavs-middleware# Verify registrationCOMMAND="list_operators" PAST_BLOCKS=500 make wavs-middleware
Trigger the service
Next, use your deployed trigger contract to trigger the oracle to be run. In the following command, you'll specify the INPUT_DATA
as abi encoded 1
, which corresponds to the ID of Bitcoin.
Running this command will execute /script/Trigger.s.sol
and pass the ID to the trigger contract, starting the following chain of events:
- The trigger contract will emit an event with the specified ID as its data.
- Operators listening for the event will receive the data and run it in the oracle component off-chain.
- The oracle component will use the ID to query the price of Bitcoin from the CoinMarketCap API.
- The returned data will be signed by operators and passed to the aggregator and then the submission contract, which will verify the operator's signature and submit the price of Bitcoin on-chain 🎉
# Request BTC from CMCexport INPUT_DATA=`cast abi-encode "addTrigger(string)" "1"`# Get the trigger address from previous Deploy forge scriptexport SERVICE_TRIGGER_ADDR=`make get-trigger-from-deploy`# uses FUNDED_KEY as the executor (local: anvil account)source .envforge script ./script/Trigger.s.sol ${SERVICE_TRIGGER_ADDR} ${INPUT_DATA} --sig 'run(string,string)' --rpc-url ${RPC_URL} --broadcast
Show the result
Run the following to view the result of your service in your terminal:
# Get the latest TriggerId and show the result via `script/ShowResult.s.sol`TRIGGER_ID=1 RPC_URL=${RPC_URL} make show-result
Congratulations, you've just made a simple Bitcoin price oracle service using WAVS!
Proceed to the Prediction Market demo to learn how a similar oracle service can be used in a prediction market.
Check out the Service handbook to learn more about services and creating components.