Starter template for building WAVS components for CosmWasm chains.
It ships a working pair:
contract/— a minimal CosmWasm contract (event-trigger-contract) that pushes messages via anAddMessageexecute and emits anew-messageevent keyed by an auto-incrementing trigger id.component/— a Rust WASI component (component-example) that listens for that event, echoes the payload back as a bincode-encodedMessageWithId { trigger_id, message }, and demonstrates the host bridge (config-var,log).
Fork it, rename the crates, and replace the body of inner() in component/src/lib.rs with your service logic.
Versions are pinned to match cw-middleware v0.3.0:
| Version | |
|---|---|
cosmwasm-std |
=3.0.2 (cosmwasm_1_2) |
cw-storage-plus / cw2 |
3.0.1 / 3.0.0 |
wavs-types |
=2.0.0-rc.8 (cosmwasm feature) |
wit-bindgen / wit-bindgen-rt |
0.47.0 / 0.44.0 |
wstd / wasip2 |
0.5.3 / 1.0.1 |
bincode |
2.0.1 (serde feature) |
The WIT world is vendored at wit/ from Lay3rLabs/wavs-wasi's wavs:operator@2.4.0 world. Refresh with task wit:fetch.
This template builds against the canonical cw-wavs-trigger-simple event shape but ships its own bespoke trigger contract so you can mutate the storage / event keys / execute API freely. If you want to consume the audited cw-middleware trigger contract directly instead of forking it, depend on cw-wavs-trigger-api from cw-middleware and parse PushMessageEvent instead of NewMessageEvent.
.
├── Cargo.toml # workspace root; pins versions used by both crates
├── Taskfile.yml # build / check / fmt / lint / wit:fetch entry points
├── component/ # WAVS WASI component (cdylib, target wasm32-wasip2)
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs # wit_bindgen::generate! + Guest impl
├── contract/ # CosmWasm contract (cdylib + rlib, target wasm32-unknown-unknown)
│ ├── Cargo.toml
│ └── src/
│ ├── contract.rs # entry_point instantiate/execute/query/migrate
│ ├── event.rs # NewMessageEvent + parser (shared with component)
│ ├── msg.rs # InstantiateMsg / ExecuteMsg / QueryMsg / MigrateMsg
│ └── state.rs # MESSAGES Map<u64, Message>
└── wit/ # vendored WAVS operator world (wavs:operator@2.4.0)
├── operator.wit
└── deps/ # wasi-* + wavs-types dependency wits
- Rust toolchain ≥ 1.88 with the
wasm32-wasip2andwasm32-unknown-unknowntargetsrustup target add wasm32-wasip2 wasm32-unknown-unknown
Task(optional but the recipes assume it)
task build # contract + component
task build:contract # contract only (artifacts/event_trigger_contract.wasm)
task build:component # component only (artifacts/component_example.wasm)Both artifacts land under artifacts/.
task check # cargo check --workspace
task fmt # cargo fmt --all
task lint # fmt check + clippy -D warnings
task test # cargo test --workspace- Deploy
event_trigger_contract.wasmto your target Cosmos chain. - Upload
component_example.wasmto your WAVS node (e.g.wavs-cli component upload). - Configure a service workflow whose trigger is a
cosmos-contract-eventmatching thenew-messageevent type emitted by the contract, and whose component is the uploaded artifact. - To exercise it: call
AddMessage { data }on the contract; the WAVS node will fireGuest::run, the component echoes back, and the response flows into the configured submission handler (typically one of the ECDSA / BLS / Mirror service-handler contracts fromcw-middleware).
The bincode envelope produced by the component (MessageWithId { trigger_id, message }) is byte-compatible with cw-middleware's reference echo-with-id component, so any submission plumbing wired for that flow will decode this template's responses unchanged.
- Vendored WIT (rather than a submodule or git dep) keeps the template buildable in environments without network access during compile. Refresh with
task wit:fetch. - Bespoke contract is shipped for ergonomics — the goal of this template is "fork and customize," not "consume an audited primitive." For the audited path, see
cw-middleware'scw-wavs-trigger-simple. - No SDK dep on
cw-wavs-sdk— the component decodes its own event locally viaevent_trigger_contract::event::NewMessageEvent, keeping the dep graph minimal and avoiding a tight coupling to cw-middleware's release cycle.