| Crates.io | tesser-wasm |
| lib.rs | tesser-wasm |
| version | 0.9.3 |
| created_at | 2025-11-29 16:20:06.977853+00 |
| updated_at | 2025-12-04 04:49:01.437805+00 |
| description | WASM plugin SDK for the Tesser execution runtime |
| homepage | |
| repository | https://github.com/tesserspace/tesser |
| max_upload_size | |
| id | 1956920 |
| size | 45,434 |
tesser-wasm is the WebAssembly SDK that lets you author custom execution plugins for the Tesser runtime. It defines the ABI shared between the Rust orchestrator and your plugin, exposes ergonomic data types (PluginSignal, PluginRiskContext, PluginResult, …), and provides a small helper runtime so you can focus exclusively on your execution logic.
| Feature | When to use it | What you get |
|---|---|---|
| default | Any crate that only needs the shared types (host-side orchestration, tests, docs) | All serialization types and helpers. |
guest |
Crates that compile into WASI modules (plugins) | ExecutionPlugin trait, PluginRuntime, export_plugin! macro, and the generated bindings from wit-bindgen. |
Scaffold a crate
cargo new chase-execution --lib
cd chase-execution
Update Cargo.toml
[lib]
crate-type = ["cdylib"]
[dependencies]
rust_decimal = "1"
tesser-wasm = { path = "../../tesser-wasm", features = ["guest"] }
Implement the trait and export it
use rust_decimal::Decimal;
use tesser_wasm::{
export_plugin, ExecutionPlugin, PluginChildOrderAction, PluginInitContext,
PluginOrderRequest, PluginOrderType, PluginResult, PluginSide, PluginTick,
};
#[derive(Default)]
struct ChasePlugin {
symbol: String,
side: PluginSide,
remaining: Decimal,
last_price: Decimal,
}
impl ExecutionPlugin for ChasePlugin {
fn init(&mut self, ctx: PluginInitContext) -> Result<PluginResult, tesser_wasm::PluginError> {
self.symbol = ctx.signal.symbol;
self.side = ctx.signal.side;
self.remaining = ctx.signal.target_quantity;
self.last_price = ctx.risk.last_price;
Ok(PluginResult::new())
}
fn on_tick(&mut self, tick: PluginTick) -> Result<PluginResult, tesser_wasm::PluginError> {
self.last_price = tick.price;
Ok(PluginResult::new())
}
fn on_timer(&mut self) -> Result<PluginResult, tesser_wasm::PluginError> {
if self.remaining <= Decimal::ZERO {
return Ok(PluginResult::new().completed());
}
let slice = self.remaining.min(Decimal::new(1, 1));
self.remaining -= slice;
let request = PluginOrderRequest {
symbol: self.symbol.clone(),
side: self.side,
order_type: PluginOrderType::Limit,
quantity: slice,
price: Some(self.last_price),
trigger_price: None,
time_in_force: None,
client_order_id: None,
take_profit: None,
stop_loss: None,
display_quantity: None,
};
Ok(PluginResult::new().with_order(PluginChildOrderAction::Place(request)))
}
}
export_plugin!(ChasePlugin);
Compile for WASI
rustup target add wasm32-wasi # once per workstation
cargo build --release --target wasm32-wasi
The artifact is emitted at target/wasm32-wasi/release/<crate_name>.wasm.
Configure the orchestrator to search for plugins:
[live]
plugins_dir = "./plugins"
or pass --plugins-dir to tesser live run.
Drop your compiled <crate_name>.wasm into that directory.
Attach an execution hint when emitting a signal:
use serde_json::json;
use tesser_core::{ExecutionHint, Signal, SignalKind};
let signal = Signal::new("BTCUSDT", SignalKind::EnterLong, 0.8).with_hint(
ExecutionHint::Plugin {
name: "chase_execution".into(),
params: json!({ "clip_size": "0.25" }),
},
);
ctx.publish(signal);
The runtime instantiates your module, calls init, then forwards ticks, fills, and timer heartbeats into the plugin. You can persist lightweight JSON snapshots via snapshot / restore, emit structured logs through PluginResult.logs, and return child order actions to delegate to the core orchestration engine. examples/plugin-chase contains a fully working reference implementation.
Crates such as tesser-execution depend on tesser-wasm (without the guest feature) to deserialize plugin responses, mock plugins in tests, and manage persistence. The PluginRuntime<P> helper included in the guest feature can also be reused in host-side integration tests to drive an actual plugin using JSON fixtures.
examples/plugin-chase – minimal end-to-end chase algorithmtesser-execution/src/wasm/engine.rs – host-side loader implementationThe crate inherits the workspace licensing terms (Apache-2.0 OR MIT). Contributions are welcome—follow the repository guidelines before opening a PR.