Let's say Alice the User wants to mint a NFT with an image generated from an off-chain process. Meanwhile, Bob the Operator is ready with his beefy GPU to do the work (and earn some rewards for doing so)... how does the work get done? In other words, Alice and Bob don't know eachother, how do they communicate and agree on the work order and delivery?
Lay3r to the rescue! The process looks like this:
- Alice submits a task to a special contract with the required work information (image size, AI prompt, etc.).
- Bob is scanning the chain, looking for on-chain events that encapsulate the work order.
- Bob goes off and does the work with his beefy machine (or crayons, no limits!), ultimately writing some metadata such as the IPFS hash back onto the chain.
- Alice notices that the on-chain status has changed to completed work, and she can now go download her image at that IPFS hash.
There's more details of course - Bob isn't actually staring at a monitor reading blockchain events, and how does Alice know he really ran the "awesome image generation" code she requested? The short answer is Bob is running an AVS and everything is secured by the underlying consensus algorithms, but, as a developer getting started, we're more interested in what pieces need to be built in order to facilitate the flow of data here.
Lay3r is built on three parts:
- The blockchain
- Special contracts deployed on that blockchain
- Actively Validated Services
Each of these work together to create the complete system. Each part can be developed independently, in fact they are in separate repos, but they only shine when fully connected. Let's walk through getting the whole thing up and running up on a local computer.
Keep in mind that it's early days, and while there may eventually be things like public Docker images or fully tested cross-platform scripts, it's a bit of the wild west right now. If you see something, please say something :)
Clone the repo: https://github.com/Lay3rLabs/layer-sdk
The SDK contains the blockchain software and a few additional tools for interacting with it. First, let's get the node up and running:
more localnode documentation here
- Build the Docker image:
scripts/build_docker.sh - Reset the Volumes:
localnode/reset_volumes.sh - Start the node:
localnode/run.sh - Health checks
- Check RPC status:
curl http://localhost:26657/status | jq - Check gRPC status:
grpcurl -plaintext localhost:9090 list - Run JS tests
- cd
js npm installnpm run test
- cd
- Check RPC status:
Now that it's all working, let's stop the blockchain:
localnode/stop.sh
And start it again:
localnode/run.sh
We're going to need a wallet with some funds. We can go ahead and use the provided faucet seed phrase for everything:
economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone
However, it's probably better to use our own wallet. We provide a few tools to make this easy:
- cd to
layer-sdk/js(same place we ran JS tests above)- If running for the first time you might need to call first:
# Install ts-node $ npm install -g ts-node # Install Node.js type definitions $ npm install @types/node --save-dev
- Generate a new mnemonic and address:
npm run generate-mnemonic- Alternatively, get the address for an existing mnemonic:
npm run show-mnemonic -- "{MNEMONIC HERE}"
- Alternatively, get the address for an existing mnemonic:
- Tap the faucet
npm run tap-faucet -- {ADDRESS} {amount}- The amount is optional, if not set then a default of 1000000uslay will be sent
Clone the repo: https://github.com/Lay3rLabs/lay3r-contracts
These contracts serve as the pipeline for tasks, sort-of a communication channel between users and operators.
The exact implementation of how the queue is prioritized, who can write state changes, and other details are subject to change. For now, let's deploy the core contracts needed to enable this functionality.
- Build the contracts:
scripts/collect_wasm.sh cd deploy- add a
.envfile with the following:
TEST_MNEMONIC = "YOUR-TESTNET-MNEMONIC"
LOCAL_MNEMONIC = "YOUR-LOCAL-DOCKER-MNEMONIC"
CW_ORCH_MIN_BLOCK_SPEED = "1"
RUST_LOG = "info"
- Deploy the contracts:
cargo run --bin avs -- --local deploy {OPERATOR_ADDR}- For testing purposes, the operator here can by any valid address
- View the latest-and-greatest deploy:
cargo run --bin avs -- --local view
You'll see output like this:
Task Code ID: {SOME CODE ID}
Task Contract Address: {SOME ADDR}
Verifier Contract Address: {SOME ADDR}
Write down the Task Contract Address - this is going to be important for the next step!
Clone the repo: https://github.com/Lay3rLabs/lay3r-avs-runners
This name is going to come up a lot, so for now on, we'll just use the industry jargon: "AVS"
Our AVS's are executed on Spin, a WASM-based runtime that can run locally and/or on a cloud platform (with a generous free tier). This isn't a hard requirement, we may move to a different host in the future. But for now, it's a prerequisite, so let's get Spin setup:
- Get Spin installed: https://developer.fermyon.com/spin/v2/quickstart
- Install the Task Queue Spin plugin
cd runners/task-queue- `spin plugin install pluginify
- `RUSTFLAGS='-C link-arg=-s' cargo build --releaseA
spin pluginify --install
more details in the plugin documentation
Now that we have spin setup, we can get an example AVS up and running. Let's try out the "demo square" app:
cd apps-lavs-demo-squarespin build- edit
spin.toml- in the
application.trigger.lay3r-task-queuesection:- change
chain_kindtoLocal - change
grpc_urltohttp://localhost:9090 - comment out
faucet_url
- change
- in the
trigger.lay3r-task-queuesection:- comment out
verifier_addr(if it's there - probably delete this soon) - set
task_queue_addrto theTask Contract Addresswe got above when deploying the core contracts
- comment out
- in the
- add a
.envwith the following
TEST_MNEMONIC = "YOUR-TESTNET-MNEMONIC"
LOCAL_MNEMONIC = "YOUR-LOCAL-DOCKER-MNEMONIC"```
spin up --test
If all went well you'll see a result like:
--> Testing Component: square
8^2 = 64
That's it! now you're all setup with a local dev environment.
- Change to Testnet
- Develop your own product with a custom AVS and contracts