Layer LogoLayer AVS Docs

-> Get started

This guide will walk you through the process of installing the Layer AVS CLI, setting up your environment, and deploying example contracts to create a service.

Prerequisites

The only thing you'll need to start is a Rust compiler. The exact way to install will depend on your operating system, but in general you can use the rustup tool:

bash curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Check out the official Rust installation site for more information: https://www.rust-lang.org/tools/install

You could also skip to the next step and run:

scripts/setup_wasi.sh

to install the necessary dependencies.

Clone the AVS repo

Use the following command to clone the Layer AVS toolkit repository: https://github.com/Lay3rLabs/avs-toolkit

git clone https://github.com/Lay3rLabs/avs-toolkit.git

This command will create a new directory called avs-toolkit in your current directory.

Install the CLI

From within the [avs-toolkit](https://github.com/Lay3rLabs/avs-toolkit) directory, navigate to tools/cli:

cd avs-toolkit/tools/cli

And then install the CLI using Cargo:

cargo install --path .

It will take some time to finish.

When completed, navigate to the root of the directory

cd ...

Set up Your Wallet

Run the following commands to create a wallet and a local mnemonic. This will print the mnemonic to standard out for you to see, as well as add it to your .env locally.

M=$(avs-toolkit-cli wallet create | tail -1 | cut -c16-)
echo "TEST_MNEMONIC=\"$M\"" > .env
cat .env

This should have a nice 24-word phrase.

Once you have a wallet, you can add funds from the faucet:

avs-toolkit-cli faucet tap

You can view your funds with the following commands:

avs-toolkit-cli wallet show

Build Your Contracts

Install and Run Docker

Before proceeding, make sure that Docker is installed and running:

  1. Install Docker desktop.
  2. Run Docker in your desktop.

If you are following this quide in sequence, you should already have the avs-toolkit repo on your machine from installing.

Run the following to build your contracts:

./scripts/optimizer.sh

After running this, you should see several .wasm files that correspond to your contracts in your artifacts folder Note: you'll need to rebuild and redeploy your contracts whenever you make any changes to them.

Deploy the example verifier, operator, and task queue contracts

The following steps will deploy a simple verifier, task queue, and operator contracts for your AVS.

Run the following to deploy the contracts:

avs-toolkit-cli deploy --mode verifier-simple contracts --artifacts-path ./artifacts --operators wasmatic

The output of the deployment should look like the following:

INFO ---- All contracts instantiated successfully ----
INFO Mock Operators: layer1qx7239qjwgm9dj8e0hunu3f89zw45fehaduvzu7ql9mq3rast93q37sagh
INFO Verifier Simple: layer19l2kyvvzf4cq9wlkn0r6phn5va0gh08f7dns6ud39vl6qpnesg0s2wjmgl
INFO Task Queue: layer1qwtnzhgvzwrvdt598lmu093thd8juw6z6uj8ggkv508s695psqzsc33r6a
INFO export LOCAL_TASK_QUEUE_ADDRESS=layer1qwtnzhgvzwrvdt598lmu093thd8juw6z6uj8ggkv508s695psqzsc33r6a
INFO export TEST_TASK_QUEUE_ADDRESS=layer1qwtnzhgvzwrvdt598lmu093thd8juw6z6uj8ggkv508s695psqzsc33r6a

Run the last line of the output from your terminal to export the task queue address for the contract.

For example, the command should look like the following:

export export TEST_TASK_QUEUE_ADDRESS=<your_layer_task_queue_address>

To view the deployed verifier contracts after this point, run the following commands.

avs-toolkit-cli task-queue view-queue

It's important to be able to find the Task Contract Address and the Verifier Contract Address by using these commands, so that you can use them when developing WASM components in the next section of this tutorial.

Create your WASM Component

This guide will walk you through developing a WASM component, which is the core logic of a service. In this example, you'll be building the Squaring Service, which takes a number as an input, and multiplies it by itself as an output. You can read more in-depth about this example in the Squaring Service Example Guide.

Setup

Even though we will be building a Wasm component that targets WASI Preview 2, the Rust wasm32-wasip2 build target is not quite ready yet. So we will use cargo-component to compile the wasm32-wasip1 binaries and package to use WASI Preview 2.

  1. If you haven't yet, add the WASI Preview 1 target:
rustup target add wasm32-wasip1
  1. Install cargo-component and wkg CLIs:
cargo install cargo-component wkg
  1. Set the default registry configuration, where the lay3r:avs WIT package is published:
wkg config --default-registry wa.dev

For more information about configuration, visit the wkg docs.

Create your project

  1. Before starting, navigate to the directory where you would like to create your project.

  2. To create a new Wasm Component, use cargo component to scaffold a new project with a task queue trigger. Feel free to choose a different project name other than "my-task".

cargo component new --lib --target lay3r:avs/task-queue my-task && cd my-task
  1. Open the directory in your code editor.
code .
  1. In your code editor, open /src/lib.rs. This file will contain all of the logic for your WASM service. You can delete the existing code in the file. Then, copy and paste the example below into your lib.rs file to create a service that squares a given number.
#[allow(warnings)]
mod bindings;
use anyhow::anyhow;
use bindings::{Guest, Output, TaskQueueInput};
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug)]
pub struct TaskRequestData {
pub x: u64,
}
#[derive(Serialize, Debug)]
pub struct TaskResponseData {
pub y: u64,
}
struct Component;
impl Guest for Component {
fn run_task(request: TaskQueueInput) -> Output {
let TaskRequestData { x } = serde_json::from_slice(&request.request)
.map_err(|e| anyhow!("Could not deserialize input request from JSON: {}", e))
.unwrap();
let y = x * x;
println!("{}^2 = {}", x, y);
Ok(serde_json::to_vec(&TaskResponseData { y })
.map_err(|e| anyhow!("Could not serialize output data into JSON: {}", e))
.unwrap())
}
}
bindings::export!(Component with_types_in bindings);

You'll notice that this example takes an input from a task queue trigger (x), multiplies the number by itself, and returns the result (y).

Make it your own

Layer makes things simple. You'll notice that the logic for this service is only a few lines of code. You can play around with this example to see for yourself how easy it is to make the logic for a simple AVS. For example, you could try cubing the number by modifying the equation to let y = x * x * x;

  1. Then, run the following in the root of your project to add the dependencies used in the example:
cargo add anyhow serde-json serde --features serde/derive
  1. Let's do the first build to generate the src/bindings.rs file. Afterward, you can do the familiar cargo commands such as cargo test and cargo clippy. It may be helpful to inspect src/bindings.rs during development to see the type information for producing the Wasm component.
cargo component build --release
Create a .env file

You may need to create a .env file in your project. Use the following command to copy the file you made earlier:

cp ../avs-toolkit/.env .
  1. Run the following code to upload the compiled Wasm component to the Wasmatic node using the avs-toolkit-cli CLI tool.

When doing an upload, you'll need to choose a unique name for your app, so that you can identify and test it, or remove your deployment if needed. In this example, replace <task-name> with a unique name for your task.

avs-toolkit-cli wasmatic deploy --name <task-name> \
--wasm-source ./target/wasm32-wasip1/release/my_task.wasm \
--testable \
--task $TEST_TASK_QUEUE_ADDRESS
Name conflict error

If you get an appname conflict error, it means that someone else has submitted the same name. Change the <task-name> in the previous step to something more unique. You can also remove the deployment by following this guide.

cp ../avs-toolkit/.env .

Add a Task

Now that your service is ready, you can add a task to the queue and see your service in action! To create tasks for your contract task queue, you can run the following commands.

  1. You can view the task queue by running the following command. It should be empty before you begin:
avs-toolkit-cli task-queue view-queue
  1. Run the following command to add a task to the queue. In this example, you'll input the number 15. Remember to change <my-task> to the name of your task from the previous section.
avs-toolkit-cli wasmatic test --name <task-name> --input '{"x": 13}'

After waiting a few second, you should be able to view the output. In this case, you'll see all 3 operators that were runnning your task have output the same value (169). Congratulations, you've just run a fully-decentralized offchain service using Layer!

Test executed successfully!
Output for operator `https://op3.layer-p.net`: {"output":{"y":169}}
Test executed successfully!
Output for operator `https://op1.layer-p.net`: {"output":{"y":169}}
Test executed successfully!
Output for operator `https://op2.layer-p.net`: {"output":{"y":169}}

If you want, you can go back to the Create your project section, modify the lib.rs section and run the commands again to create a custom service.

Connect a frontend to your contracts

Follow the frontend connection guide to learn how to connect the frontend to your contract. You'll need to edit the frontend code to add your task queue address.

On this page