cotyledon 0.1.0

Framework for writing sprouts — sandboxed, event-driven on-chain trading bots.
Documentation

cotyledon

The framework for writing sprouts — sandboxed, event-driven trading automations for Solana protocols.

A sprout is ordinary Rust that compiles to WebAssembly. It declares its triggers and wallet in a sprout.toml, and implements one handler per trigger inside a #[sprout::program] module. Every privileged operation — prices, balances, signing, submitting, persistent state — goes through the [Ctx] handle, which the Sprouts engine executes on the sprout's behalf. The sprout itself has no keys, no network, and no ambient access; the sandbox is the security boundary.

Install

[dependencies]
cotyledon = "0.1"

Or scaffold a new project with the CLI:

cargo install sprouts
sprouts init my-bot

Example

use cotyledon::prelude::*;

#[sprout::program]
pub mod my_bot {
    use super::*;

    pub async fn tick(ctx: Ctx) -> Result<()> {
        let price = ctx.price("SOL").await?;
        ctx.log(format!("SOL is {price}"));
        Ok(())
    }
}

Each pub async fn(ctx: Ctx) -> Result<()> in the module is a handler that a trigger in sprout.toml can target (a schedule, a webhook, or a manual run).

What Ctx gives you

  • Market datactx.price(...).
  • Wallet — address and balances via ctx.wallet().
  • Signing & submission — sign and send transactions; the engine holds the keys and enforces the sprout's guardrails.
  • State — durable key/value storage scoped to the sprout.
  • Observabilityctx.log(...), ctx.metric(...), and trade events.

Building

Sprouts target wasm32-wasip1:

rustup target add wasm32-wasip1
cargo build --target wasm32-wasip1 --release

sprouts deploy does this for you and uploads the artifact.

A sprout may only .await on Ctx calls — it must not start its own async runtime. The sandbox enforces this.

Feature flags

Optional, opt-in protocol plugins:

  • jupiter
  • meteora

License

MIT OR Apache-2.0