Quick Start

Instructions for installing the Othentic CLI and deploy a demo AVS.

Othentic does not run any network on its own. The Othentic CLI helps you build your own AVS using the Othentic Stack.

This guide references the Simple Price Oracle and demonstrates how to run it on Polygon Amoy Testnet (L2) and Ethereum Holesky Testnet (L1).

Prerequisites

  • Node v22.6.0 ⚠️ (must be exactly v22.6.0; using any other version will cause compatibility issues) and NPM, via NVM

  • Docker and docker-compose (see Docker website for instructions based on your OS)

  • At least 1.56 holETH on Holešky Testnet (Faucet)

  • At least 6 POL on Polygon Amoy Testnet (Faucet)

Steps

1

Install the Othentic CLI

To install the Othentic CLI, run the following command:

npm i -g @othentic/othentic-cli

After installation, verify by running:

othentic-cli -v

You should see an output similar to the below (version may vary based on releases):

othentic-cli version 1.x.y
2

Account requirements

For the purposes of the demo AVS, you'll need the following accounts:

  • Deployer account: These funds cover the gas costs for contract deployment on both L1 and L2, as well as for funding message handlers to process cross-chain messages.

    • Ensure this account has at least 1.5 holETH on Holešky (L1) (Faucet)

    • Ensure this account has at least 5 POL on Amoy (L2) (Faucet)

  • Operator account x 3: Register 3 self-deploy Operator addresses for operator registration in the subsequent steps. You can also use this Script to create and fund these accounts. These funds are used to cover gas fees for operator registration on L1.

    • Ensure each account has at least 0.02 holETH on Holešky.

    • For the demo AVS, operator1 will act as the Performer, Attester, and Aggregator, while operator2 and operator3 will act as Attesters.

    • Since the Aggregator needs funds on L2 to submit tasks on-chain, ensure operator1 is funded on Amoy.

  • ERC-20 token address: the address of the token backing the AVS. For this guide, we'll use WETH.

3

Clone the github repository

Download the Simple Price Oracle Example repository

git clone git@github.com:Othentic-Labs/simple-price-oracle-avs-example.git
cd simple-price-oracle-avs-example
rm -rf .git
cp .env.example .env

From here onward, we assume all commands run from the root of the Simple Price Oracle Example directory.

4

Configure the deployer account’s private key in the .env file:

PRIVATE_KEY_DEPLOYER=

Make sure the Deployer account has at least ~1.5 holETH

To deploy the AVS’s contracts, run the following command:

othentic-cli network deploy \
    --l1-chain holesky \
    --l2-chain amoy \
    --erc20 0x94373a4919B3240D86eA41593D5eBa789FEF3848 \
    --l1-initial-deposit 1000000000000000000 \
    --l2-initial-deposit 2000000000000000000 \
    --name test-avs-name

By default, Othentic CLI deploys your contracts on Ethereum Holešky and Polygon Amoy testnets. To deploy on other chains, you shall specify the appropriate environment variables.

ERC20 is the token used to pay rewards. For detailed information on contract deployment and the available arguments, refer to the Contracts Deployment section.

When prompted, enter the Deployer account's private key to proceed with the deployment:

? Enter your private key:

Once the private key is entered, the deployment will proceed, and transaction hashes for both L1 and L2 will be displayed. It deploys the necessary contracts on L1 (L1AvsTreasury, AvsGovernance, L1MessageHandler) and L2 (AttestationCenter, L2MessageHandler, OBLS, L2AvsTreasury) to run the AVS.

This is how the output will look:

 L1 Deployment TxHash: 0x78d9fc89d19325a82d1f5f70a75763fd20901e96c2083e97ec53d91a59db3226
 L1 Deployment Done
 L2 Deployment TxHash: 0xcb1b32f158d0bb3810e0075ada599583229cf81f94e9c1da0a5959d4906bf63e
 L2 Deployment Done

Othentic AVS deployment summary
Status: Deployment successful!
The following addresses are now available for use:
L1:
  - ERC20: 0x94373a4919B3240D86eA41593D5eBa789FEF3848
  - Vault: 0xDde95FDa7790E8B589DdAD973E71E6043e113F32
  - AvsGovernance: 0xD89584788f7fD117Dc9faaEa1C886e1e08a654a2
  - L1MessageHandler: 0x53dc72F39a55c1bE4C85EbFD8bBCC92493C802B2  (1.0 ETH)
L2:
  - AttestationCenter: 0x4169B868ea4CF94B4b3aef93630DD96e1BB797Ff
  - L2MessageHandler: 0x62811f3377DE4BA8C22b8BCCE61953592abc7125  (2.0 ETH)
  - OBLS: 0x8EcfC154DDcbc4Fec11b627dc3770aE3460CB5b9
AVS deployment done!
Run `othentic-cli network contracts` to see the contract addresses you need for node operations
5

Configure Environment Variables

To configure your environment, update the .env file with the following deployed contract addresses and private keys. Retrieve the contract addresses by running:

othentic-cli network contracts

Required Configuration:

  • Governance and Attestation Contract Addresses Add the contract addresses for governance and attestation center.

    .env
    AVS_GOVERNANCE_ADDRESS=<GovernanceContractAddress>
    ATTESTATION_CENTER_ADDRESS=<AttestationCenterContractAddress>
  • Private Keys for Performer, Aggregator and Attester Operators For the demo AVS, you can use the first operator's private key as the values for the performer and aggregator private keys. (As created in step 2)

    .env
    PRIVATE_KEY_PERFORMER=<Operator1PrivateKey>  
    PRIVATE_KEY_AGGREGATOR=<Operator1PrivateKey>
    PRIVATE_KEY_ATTESTER1=<Operator1PrivateKey>  
    PRIVATE_KEY_ATTESTER2=<Operator2PrivateKey>  
    PRIVATE_KEY_ATTESTER3=<Operator3PrivateKey> 
  • Deployer Private Key Add the deployer private key as created in Step 2:

    .env
    PRIVATE_KEY_DEPLOYER=<DeployerPrivateKey> 
  • L1_CHAIN and L2_CHAIN Add the chain Ids. It is recommended to set these variable in the .env file to avoid specifying --l1-chain in every command.

    .env
    L1_CHAIN=17000
    L2_CHAIN=80002

Pre-configured

  • Pinata Configuration for IPFS: Used by the execution service to store the proof of task

    .env
    PINATA_API_KEY=7824585a98fe36414d68  
    PINATA_SECRET_API_KEY=41a53a837879721969e73008d91180df30dbc66097c7f75f08cd5489176b43ea  
    IPFS_HOST=https://othentic.mypinata.cloud/ipfs/
  • Bootstrap Node Configuration: Used to connect peers on the network

    .env
    OTHENTIC_BOOTSTRAP_ID=12D3KooWBNFG1QjuF3UKAKvqhdXcxh9iBmj88cM5eU2EK5Pa91KB
    OTHENTIC_BOOTSTRAP_SEED=97a64de0fb18532d4ce56fb35b730aedec993032b533f783b04c9175d465d9bf
6

In order to run the AVS Operators, it is required to setup their corresponding Ethereum accounts with the necessary metadata and stake on EigenLayer.

To deposit (restake) 0.01 stETH into the EigenLayer stETH staking contract, run the following command for all the three operators listed in your .env file:

othentic-cli operator deposit

Enter operator's private key, select the stEth staking contract and enter the amount 0.012

If you don't have stETH, the command will automatically convert holETH into stETH before depositing.

✅ Your internal Operators are now ready to opt-in to your AVS.

7

For this demo, you’ll need to register 3 internal Operators.

To Register as an operator for both EigenLayer and the AVS, run the following command three times, once for each operator:

othentic-cli operator register

When prompted, enter the Operator's private key. Note: In production, it is recommended to use separate keys for security purposes, as outlined in the Key Separation section.

? Enter your private key:
? Use a different private-key for Consensus?:

Next, enter the governance contract address

? AVS Governance address:

Lastly, the Rewards Receiver address: Ideally, the rewards receiver address should be a smart contract that distributes rewards to all the stakers. You can leave this field empty to pass the Operator address by default.

? Rewards Receiver address (default: msg.sender): 
 Rewards Receiver address configured 

Upon successful registration, the terminal will display the transaction hash on L2. This is how the output will look:

Registered on EigenLayer: true
Registered on AVS: false
┌─────────────────────┬────────────────────────────────────────────┐
 Address:             0xf5715961C550FC497832063a98eA34673ad7C816 
├─────────────────────┼────────────────────────────────────────────┤
 ETH:                 5.98595                                    
├─────────────────────┼────────────────────────────────────────────┤
 Total Voting Power:  0.00992                                    
└─────────────────────┴────────────────────────────────────────────┘
┌───────┬─────────┬──────────────┐
 Token  Balance  Voting Power 
├───────┼─────────┼──────────────┤
 stETH  0.00201  0.00992      
├───────┼─────────┼──────────────┤
 cbETH  1.00000  0.00000      
└───────┴─────────┴──────────────┘
isAllowlisted: false
Registered on network 0xD89584788f7fD117Dc9faaEa1C886e1e08a654a2
Operator: 0xf5715961C550FC497832063a98eA34673ad7C816
Tx hash: 0x1178a0b385a8a83dac7a8f8555a0be0288e46ec65dedccaf7746c154abfcebec
8

Run the AVS network

To run the demo AVS, navigate to the simple-price-oracle-avs-example directory and execute the following command:

docker-compose up --build

This command will build and start the AVS network, which consists of multiple services defined in the docker-compose.yml file. The services set up are as follows:

  • 3 Attester nodes: These nodes are responsible for validating and attesting task execution.

  • Aggregator node: Subscribes to attestation events from Attesters, aggregates their signatures, and submits an on chain transaction to the AttestationCenter contract.

  • Validation service: Provides task validation functionality for the AVS.

  • Execution service: Provides task execution functionality for the AVS.

If you wish to rebuild existing images, update the Othentic CLI inside the docker images:

docker-compose build --no-cache
9

Execute task

To execute a task, run the following command:

curl -X POST http://localhost:4003/task/execute

The above command will trigger a task execution.

Your demo AVS is completed.

Next,

  • Explore the quickstart repository Modify the various configurations, tailor the task execution logic to your use case, and run the AVS with your updates.

  • Define Task Specifications Create detailed task definitions based on your use case. Ensure that all parameters, including taskDefinitionId, are correctly configured for seamless execution.

  • Find all the CLI commands in the CLI Command Reference page.

Utility script for creating an account [Optional]

Prerequisites: Foundry (see Foundry Book for instructions)

If you don't have existing accounts to use as Operators, you can run this script to create and fund accounts on Holešky:

Script for creating operator accounts
CreateOperator.sh
source .env

RPC=https://rpc.ankr.com/eth_holesky/80921f6657bf5ad15fb4577b369c28c4f84a652625322575f085fceaa7e47653
OPERATOR_ACCOUNT1=$(openssl rand -hex 32)
OPERATOR_ADDRESS1=$(cast wallet address --private-key $OPERATOR_ACCOUNT1)

OPERATOR_ACCOUNT2=$(openssl rand -hex 32)
OPERATOR_ADDRESS2=$(cast wallet address --private-key $OPERATOR_ACCOUNT2)

OPERATOR_ACCOUNT3=$(openssl rand -hex 32)
OPERATOR_ADDRESS3=$(cast wallet address --private-key $OPERATOR_ACCOUNT3)

echo "Transferring 0.02 ETH on Holesky to all accounts..."

cast send \
    --rpc-url $RPC \
    --private-key $PRIVATE_KEY_DEPLOYER \
    --value 0.02ether \
    $OPERATOR_ADDRESS1

cast send \
    --rpc-url $RPC \
    --private-key $PRIVATE_KEY_DEPLOYER \
    --value 0.02ether \
    $OPERATOR_ADDRESS2

cast send \
    --rpc-url $RPC \
    --private-key $PRIVATE_KEY_DEPLOYER \
    --value 0.02ether \
    $OPERATOR_ADDRESS3

echo "Private key For Operator Account 1: $OPERATOR_ACCOUNT1"
echo "Operator 1 Address: $OPERATOR_ADDRESS1"
echo "Operator 1 Balance: $(cast balance --rpc-url $RPC $OPERATOR_ADDRESS1)"

echo "Private key For Operator Account 2: $OPERATOR_ACCOUNT2"
echo "Operator 2 Address: $OPERATOR_ADDRESS2"
echo "Operator 2 Balance: $(cast balance --rpc-url $RPC $OPERATOR_ADDRESS2)"

echo "Private key For Operator Account 3: $OPERATOR_ACCOUNT3"
echo "Operator 3 Address: $OPERATOR_ADDRESS3"
echo "Operator 3 Balance: $(cast balance --rpc-url $RPC $OPERATOR_ADDRESS3)"

You can run the script by using sh <script-path>, or make it executable with chmod a+x <script-path> and then execute it with ./<script-path>.

If you've deployed your contracts on chains other than the defaults, make sure to set the corresponding environment variables.

Last updated