Stoffel Rust App SDK
Scope: AI-agent-agnostic playbook for building applications with the Stoffel framework. This is not a maintainer guide for compiler, VM, protocol, or release engineering work. Dependency assumption: use the public 0.1.0 install snippets from these docs. When developing against a local checkout, make that source-based workflow explicit.
Use when
Use this playbook when a Rust application embeds Stoffel compilation, bytecode loading, local execution, client/server builders, typed client IO bindings, or network/off-chain integration.Current source of truth
crates/stoffel-rust-sdk/README.mdcrates/stoffel-rust-sdk/src/lib.rscrates/stoffel-rust-sdk/src/prelude.rscrates/stoffel-rust-sdk/src/runtime.rscrates/stoffel-rust-sdk/src/config.rscrates/stoffel-rust-sdk/src/types.rscrates/stoffel-rust-sdk/examples/*
Dependencies
Preferred public flow after publication:use stoffel::prelude::*; for app code.
Clear local execution
Local MPC execution
Build or install the runner used by local coordinator-backed execution. Source-based 0.1.0 checkout path:STOFFEL_RUN_BIN or .local_runner_path(...) / local-network builder runner paths. Build the runner for the same OS/architecture where it will execute.
Loading and saving bytecode
Builder options to know
Program source:Stoffel::compile(source)Stoffel::compile_file(path)Stoffel::load(bytes)Stoffel::load_file(path)
.parties(n).threshold(t).instance_id(id).honeybadger().avss(Curve::Bls12_381)/.curve(curve).backend(MpcBackend::...).manifest::<ProgramManifest>()when using generated bindings
.optimize(bool).optimization_level(0..=3).print_ir(bool).compiler_options(CompilationOptions { ... })
.with_input("a", 40_i64).with_inputs(&[("a", 40_i64), ("b", 2_i64)]).with_client_input(0, &[40_i64, 2_i64]).with_client_inputs(&[(0, vec![...])]).expected_output_clients(n)
.build().summary()/runtime.summary().to_bytecode()/runtime.to_bytecode().save_bytecode(path)/runtime.save_bytecode(path).execute_clear().execute_local().execute_local_function("entry")/ timeout variants where appropriateruntime.client(),runtime.server(party_id),runtime.offchain_client_config(slot)
SDK value model
Usestoffel::Value at the SDK boundary:
Value::I64,Value::U64,Value::Bool,Value::Float,Value::String,Value::Bytes,Value::List,Value::Object,Value::Unit.- Convenience accessors:
as_i64,as_u64,as_bool,as_f64,as_str,as_bytes,as_list,as_object,is_unit.
- integer shares ->
i64 - unsigned integer shares ->
i64/integer Rust fields at generated boundary depending on manifest mapping - boolean secret integers ->
bool - fixed-point shares ->
f64
Network config builders
For deployment-oriented code, use builders instead of hand-rolled maps:Validation / done criteria
For Rust app setup:Common pitfalls
- Do not use path dependencies as the default after crates.io publication.
- Do not simulate protocol behavior in app code; use SDK/runtime execution paths.
- Do not set an explicit backend that conflicts with bytecode metadata. Prefer generated manifests for ClientStore programs.
- For
ClientStoreapps, validate client input shapes before network submission. - If source is shared between host and container/VM/remote environments, confirm that
stoffel-runwas built for the execution environment. - Using
stoffel-rust-sdkas both an app dependency and a build-dependency can trigger Cargo duplicate-crate/output-collision errors with path or git dependencies. Prefer runtime SDK metadata validation for sample apps, or pre-generate bindings outside the app build.