STATUS: This repo has been brought into https://github.com/hyperware-ai/kit
Automates the creation of WIT (WebAssembly Interface Type) files and RPC stubs for Hyperware processes.
# Install from the current directory
cargo install --path .Run this tool before building your Hyperware project:
# Navigate to your project rootcd my-hyperware-project
# Run hyper-bindgen
hyper-bindgen
# The tool will:# 1. Find all Rust files with hyperprocess implementations# 2. Generate corresponding WIT files in the api/ directory# 3. Create the caller-utils crate with RPC stubs# Then build as normal
kit b # build
kit s # start (assuming you started a fakenode with `kit f`)Hyper-Bindgen scans your codebase for Hyperware processes (identified by the #[hyperprocess] macro) and performs two steps:
- WIT File Generation: Creates wit files with function signatures and downstream structs used either in the args or return value for all annotated functions
- Caller Utils Generation: Builds a helper crate with RPC stub functions
This allows you to call other process endpoints from a process through auto-generated async functions with proper type checking, rather than manually constructing JSON messages.
When run in a project, Hyper-Bindgen performs two main tasks:
- Scans for Rust projects with
package.metadata.component.package = "hyperware:process"in Cargo.toml - Analyzes each project for
#[hyperprocess]macro implementations - Extracts function signatures from methods annotated with
#[http],#[remote], or#[local] - Generates WIT files in an
/apidirectory with proper type conversions
- Creates a
caller-utilscrate containing RPC stub functions for easy inter-process communication - Updates the workspace Cargo.toml to include the new crate
- Adds the caller-utils dependency to relevant projects
Note: In the future, we should extend the
kit bcommand to automatically execute hyper-bindgen beforehand, eliminating the need for a separate step.
For a Hyperware process with annotated functions:
#[hyperprocess( name = "Async Requester", wit_world = "async-app-template-dot-os-v0")]implAsyncRequesterState{#[remote]#[local]fnincrement_counter(&mutself,value:i32,name:String) -> f32{// Implementation...0.0}}Hyper-Bindgen will:
Generate a WIT file with:
interfaceasync-requester { usestandard.{address}; recordincrement-counter-signature-remote { target:address, value:s32, name:string, returning:f32, } recordincrement-counter-signature-local { target:address, value:s32, name:string, returning:f32, } }
Create a caller-utils crate with stub functions:
pubmod async_requester {usecrate::*;/// Generated stub for `increment-counter` remote RPC callpubasyncfnincrement_counter_remote_rpc(target:&Address,value:i32,name:String) -> SendResult<f32>{let request = json!({"IncrementCounter":(value, name)});send::<f32>(&request, target,30).await}/// Generated stub for `increment-counter` local RPC call pubasyncfnincrement_counter_local_rpc(target:&Address,value:i32,name:String) -> SendResult<f32>{let request = json!({"IncrementCounter":(value, name)});send::<f32>(&request, target,30).await}}
With the generated stubs, you can call another process's endpoint like this:
use caller_utils::async_requester::increment_counter_remote_rpc;use shared::receiver_address;asyncfnmy_function(){let result = increment_counter_remote_rpc(&receiver_address(),42,"test".to_string()).await;match result {SendResult::Success(value) => println!("Got result: {}", value),SendResult::Error(err) => println!("Error: {}", err),}}Instead of manually constructing JSON:
// Without hyper-bindgen (error-prone)let request = json!({"IncrementCounter":(42,"test")});let result = send::<f32>(&request,&receiver_address(),30).await;Under the hood, we still do the regular sending of data through messages. The body of the messages will always follow the RequestEnum/ResponseEnum with the variants being a CamelCase version of each defined function, and the inner value of those variants being the arguments of the functions defined in the hyperware macro functions.