Documentation
A sprout is sandboxed, event-driven trading logic. You write it in Rust, it compiles to WebAssembly, and the engine runs it on your behalf — with no keys, network, or ambient access of its own. Go from zero to a deployed automation in four commands.
Getting started
Install the CLI
The sprouts CLI is a Rust crate. You'll need a Rust toolchain and the wasm32-wasip1 target (rustup target add wasm32-wasip1).
Sign in
Authenticate in the browser and save a session to ~/.sprouts/config.json.
Scaffold a sprout
Generate a standalone crate with a handler, a sprout.toml manifest, and the cotyledon dependency.
Deploy it
Build to WebAssembly, upload, and register triggers. Every deploy is a new immutable version you can roll back to.
Anatomy of a sprout
Each pub async fn(ctx: Ctx) -> Result<()> inside a #[sprout::program]module is a handler. An optional second argument is the trigger's deserialized JSON payload.
use cotyledon::prelude::*;
use serde::Deserialize;
#[derive(Deserialize)]
pub struct GreetRequest {
name: String,
}
#[sprout::program]
pub mod hello_world {
use super::*;
// Bound to the `greet` trigger in sprout.toml.
pub async fn greet(ctx: Ctx, req: GreetRequest) -> Result<()> {
// Durable, per-sprout state — empty on the first call.
let mut names: Vec<String> =
ctx.state().get("names").await?.unwrap_or_default();
names.push(req.name.clone());
ctx.state().set("names", &names).await?;
ctx.log().info(&format!("Hello, {}!", req.name));
Ok(())
}
}The manifest — sprout.toml
Declares the sprout's name, whether it gets a wallet, and its triggers. The engine reads it at deploy to register everything.
name = "hello-world"
wallet = false
# POST { "name": "Ada" } to this trigger's URL to run `greet`.
[triggers.greet]
on = "webhook"
handler = "greet"
# A scheduled trigger runs a handler on a cron cadence.
[triggers.daily]
on = "schedule"
cron = "0 13 * * *" # daily at 13:00 UTC
handler = "rebalance"Triggers
Webhook
Each webhook trigger gets a unique, unguessable URL. POST a JSON body to it to invoke the handler with that payload.
Schedule
Run a handler on a cron cadence. cron = "0 13 * * *" fires every day at 13:00 UTC.
Manual
Invoke any handler on demand from the CLI with sprouts run --handler <name>, with an optional input payload.
What a handler can do
Market data
ctx.price("SOL") and other quotes, brokered by the engine.
Wallet & signing
Read balances, sign and submit transactions. The engine holds the keys and enforces the sprout's guardrails — the sandbox never sees them.
Durable state
ctx.state().get / set — a key/value store scoped to the sprout that persists across runs.
Logs & metrics
ctx.log() and ctx.metric() capture per-execution output you can read back with sprouts logs.
CLI reference
sprouts login / logout / whoamiManage your saved session.sprouts init <name>Scaffold a new sprout in the current directory.sprouts deployBuild to wasm, upload, and register triggers.sprouts run --handler <h>Manually run a handler, with an optional payload.sprouts logs [--exec <id>]List executions, or show one run's captured output.sprouts rollbackRoll a sprout back to a previous version.Resources
SDK API reference
The cotyledon crate — Ctx, types, and macros.
CLI on crates.io
cargo install sprouts
Build with AI
Give this URL to an AI assistant (Claude, ChatGPT, Cursor…) so it can write and deploy sprouts for you.