Utilities and crates
wavs-wasi-utils crate
The wavs-wasi-utils crate provides a set of helpful functions for making HTTP requests and interacting with the blockchain. It also provides a macro for decoding trigger data for use in the component.
Learn more in the crate documentation.
The decode_event_log_data macro is a utility for decoding Ethereum event logs from triggers into typed Rust events. It takes raw log data (topics and data) from the WAVS worker bindings and converts it into a Rust type that implements SolEvent.
Sol! macro
The sol! macro from alloy-sol-macro allows you to generate Rust types from Solidity interface files.
You can write Solidity definitions (interfaces, structs, enums, custom errors, events, and function signatures) directly inside the sol! macro invocation in your Rust code.
At compile time, the sol! macro parses that Solidity syntax and automatically generates the equivalent Rust types, structs, enums, and associated functions (like abi_encode() for calls or abi_decode() for return data/events) needed to interact with smart contracts based on those definitions.
Required Dependencies:
[dependencies]alloy-sol-macro = { workspace = true } # For Solidity type generationalloy-sol-types = { workspace = true } # For ABI handling
Basic Pattern:
mod solidity {use alloy_sol_macro::sol;// Generate types from Solidity filesol!("../../src/interfaces/ITypes.sol");// Or define types inlinesol! {struct TriggerInfo {uint64 triggerId;bytes data;}event NewTrigger(TriggerInfo _triggerInfo);}}
In the template, the sol! macro is used in the trigger.rs component file to generate Rust types from the ITypes.sol file.
mod solidity {use alloy_sol_macro::sol;pub use ITypes::*;// The objects here will be generated automatically into Rust types.// If you update the .sol file, you must re-run `cargo build` to see the changes.sol!("../../src/interfaces/ITypes.sol");}
The macro reads a Solidity interface file and generates corresponding Rust types and encoding/decoding functions. In the example above, it reads ITypes.sol which defines:
NewTriggereventTriggerInfostructDataWithIdstruct
More documentation on the sol! macro can be found at: https://docs.rs/alloy-sol-macro/latest/alloy_sol_macro/macro.sol.html
alloy-contract crate
The alloy-contract crate provides a high-level interface for interacting with Ethereum smart contracts. It offers a type-safe way to call contract functions and handle events, with features like automatic ABI encoding/decoding, gas estimation, and transaction management.
The crate works with the sol! macro. You can use the #[sol(rpc)] attribute in components to generate contract bindings that work with WASI:
use alloy_primitives::{Address, U256};use alloy_sol_types::sol;use alloy_provider::RootProvider;use alloy_network::Ethereum;use wavs_wasi_utils::evm::new_evm_provider;use crate::bindings::host::get_evm_chain_config;// Define your contract interface with RPC bindingssol! {#[sol(rpc)]contract ERC721 {function balanceOf(address owner) external view returns (uint256);function totalSupply() external view returns (uint256);function ownerOfTokenByIndex(uint256 index) external view returns (address);}}// Get chain config and create providerlet chain_config = get_evm_chain_config("local")?;let provider: RootProvider<Ethereum> = new_evm_provider::<Ethereum>(chain_config.http_endpoint.unwrap())?;// Create contract instance with the providerlet contract = ERC721::new(contract_address, &provider);// Call contract functions directlylet balance = contract.balanceOf(owner).call().await?;let total_supply = contract.totalSupply().call().await?;let owner = contract.ownerOfTokenByIndex(index).call().await?;
Alloy Ecosystem Crates
The Alloy ecosystem provides a comprehensive set of crates for Ethereum development:
alloy-primitives: Core Ethereum types (Address,U256,Bytes, etc.)alloy-provider: Ethereum node interaction (RPC, WebSocket, batching)alloy-network: Network types and chain-specific functionalityalloy-sol-types: ABI handling and type generation
Utility Crates
Essential utility crates for WAVS components:
wstd: WASI standard library withblock_onfor async operationsserde/serde_json: Data serialization and JSON handlinganyhow: Error handling and propagation
