-> Get started
This guide will get you set up with everything you need to start building with Layer. Follow this guide in its entirety to learn how to set up your environment and deploy a custom service. To learn more about how Layer works, visit the Layer AVS page.
Install the Layer AVS CLI
This section of the 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
Clone the AVS repo
Use the following command to clone the Layer AVS toolkit repository: https://github.com/Lay3rLabs/avs-toolkit
git clone --branch v0.2.1 --depth 1 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 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
- In the root of the repo, 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\"" > .envcat .env
This will create a .env
file that contains your 24-word recovery phrase for your new wallet.
Wherever you use the CLI, it will load variables like the mnemonic from your environment. The exact way you set it will depend on your project, your operating system, and maybe even your specific terminal.
For example, taking the TEST_MNEMONIC
environment variable, you might set it in your .bashrc
or .bash_profile
:
export TEST_MNEMONIC="your mnemonic here"
In this guide, you have just created an .env
file has been created in the root of the avs-toolkit
repo. You may need to copy this file to other locations to use CLI commands in different directories.
Example .env
file:
TEST_MNEMONIC="your mnemonic here"
- Use the following command to view your wallet:
avs-toolkit-cli wallet show
You'll need this address to get funds from the faucet.
Hit the Faucet
Right now you don't have any funds in your wallet. You can get some from the faucet by following the steps below.
You'll need to install Telegram in order to get faucet funds for the hacknet. Visit https://telegram.org/ and follow installation instructions for your device.
- After installing Telegram, Visit https://t.me/LayerUp_bot to open the LayerUp Telegram app.
- Click Start and then Start adventure.
- After following the prompts in the app, you'll be able to open the menu in the left corner of the screen. Click the illuminated drop-shaped button.
- Scroll down and input your wallet address. You can use the following command in the CLI to view your address:
avs-toolkit-cli wallet show
- Click Claim Tokens after entering your wallet address. The faucet tokens will be sent to your wallet.
If you run the following in the CLI, you should see some funds in your wallet.
avs-toolkit-cli wallet show
Build Your Contracts
Before proceeding, make sure that Docker is installed and running:
- Install Docker desktop.
- Run Docker in your desktop.
If you are following this guide in sequence, you should already have the avs-toolkit repo on your machine from installing.
Make sure you have Docker running. Then, run the following command in the root of the avs-toolkit
repo 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.
Remember, 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: layer1qx7239qjwgm9dj8e0hunu3f89zw45fehaduvzu7ql9mq3rast93q37saghINFO Verifier Simple: layer19l2kyvvzf4cq9wlkn0r6phn5va0gh08f7dns6ud39vl6qpnesg0s2wjmglINFO Task Queue: layer1qwtnzhgvzwrvdt598lmu093thd8juw6z6uj8ggkv508s695psqzsc33r6aINFO export LOCAL_TASK_QUEUE_ADDRESS=layer1qwtnzhgvzwrvdt598lmu093thd8juw6z6uj8ggkv508s695psqzsc33r6aINFO export TEST_TASK_QUEUE_ADDRESS=layer1qwtnzhgvzwrvdt598lmu093thd8juw6z6uj8ggkv508s695psqzsc33r6a
- Run the last line of the output from your terminal to export the task queue address environment variable.
For example, the command should look like the following:
export TEST_TASK_QUEUE_ADDRESS=<your_layer_task_queue_address>
Make sure to keep your TEST_TASK_QUEUE_ADDRESS
on-hand, as it may be needed later.
- 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 section 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.
- If you haven't yet, add the WASI Preview 1 target:
rustup target add wasm32-wasip1
- Install
cargo-component
andwkg
CLIs:
cargo install cargo-component wkg
- 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
-
Before starting, navigate to the directory where you would like to create your project.
-
To create a new Wasm Component, use
cargo component
to scaffold a new project with a task queue trigger. This project will be calledmy-task
.
cargo component new --lib --target lay3r:avs/task-queue my-task && cd my-task
- Open the directory in your code editor (the following command assumes you are using VS Code).
code .
- 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 yourlib.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
).
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;
- 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
- Let's do the first build to generate the
src/bindings.rs
file. Afterward, you can do the familiarcargo
commands such ascargo test
andcargo clippy
. It may be helpful to inspectsrc/bindings.rs
during development to see the type information for producing the Wasm component.
cargo component build --release
You may need to create a .env
file in your project. Use the following command to copy the .env
file you made earlier (assuming your project is in the same directory as AVS-toolkit
):
cp ../avs-toolkit/.env .
- 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>
in the code below 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
If you get the following error, error: a value is required for '--task <TASK_TRIGGER>' but none was supplied
, you may need to set the $TEST_TASK_QUEUE_ADDRESS
environment variable again. You can also replace $TEST_TASK_QUEUE_ADDRESS
with your task queue contract address from earlier.
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.
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.
- 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
- 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>
in the code below to the name of your task from the previous section.
avs-toolkit-cli wasmatic test --name <task-name> --input '{"x": 15}'
Operators will retrieve your input from the task queue, run the service, and provide the output. Then, the verifier contract will verify that there is consensus on the result from all three operators. The output will then be written onchain.
After waiting a few second, you should be able to view the output. In this case, you'll see all three operators that were runnning your task have output the same value (225).
Test executed successfully!Output for operator `https://op3.hack.layer.xyz`: {"output":{"y":225}}Test executed successfully!Output for operator `https://op1.hack.layer.xyz`: {"output":{"y":225}}Test executed successfully!Output for operator `https://op2.hack.layer.xyz`: {"output":{"y":225}}
Congratulations 🎉 You've just run a fully-decentralized service using Layer!
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.
Visit the testing guide to learn how to run tests on your custom service, or visit the Verifier contract guide to learn how to make a custom verifier contract.
Connect a frontend to your contracts
Follow the frontend connection guide to learn how to connect the frontend to your contract. Make sure you have your task queue address on hand, as you'll need to add this address to the front end code. You can view an example of the squaring frontend at https://example.hack.layer.xyz/. Create a Keplr wallet and check it out!