Skip to main content

Prerequisites

  1. Rust Toolchain
    • Install Rust via rustup
    • Version: 1.75.0 or later
  2. WASM Targets
# Install the WASI Preview 1 target
rustup target add wasm32-wasip1

# Optionally, install WASI Preview 2 target for future compatibility
rustup target add wasm32-wasip2
  1. Required Tools
# Install cargo-component for building WASM components
cargo install cargo-component

# Install wasm-tools for validation and inspection
cargo install wasm-tools

Project Structure

component/
├── Cargo.toml          # Rust project configuration
├── src/
│   └── lib.rs          # Main Rust implementation
└── wit/
    └── world.wit       # WebAssembly Interface Types definition

Step-by-Step Build Process

Step 1: Define the WIT Interface

Create a WIT file (wit/world.wit) compatible with Newton Protocol:
package newton:provider@0.1.0;

interface http {
    record http-request {
        url: string,
        method: string,
        headers: list<tuple<string, string>>,
        body: option<list<u8>>,
    }

    record http-response {
        status: u16,
        headers: list<tuple<string, string>>,
        body: list<u8>,
    }

    fetch: func(request: http-request) -> result<http-response, string>;
}

world newton-provider {
    import http;
    export run: func(input: string) -> result<string, string>;
}

Step 2: Configure Cargo.toml

Set up your Cargo.toml for WASM component compilation:
[package]
name = "eligibility-checker"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]  # Required for WASM components

[dependencies]
wit-bindgen = "0.36"     # WIT bindings generator
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[package.metadata.component]
package = "newton:provider"

[package.metadata.component.dependencies]
# Add any WIT dependencies here

Step 3: Implement the Rust Code

In src/lib.rs, generate bindings and implement your functionality:
use serde::{Deserialize, Serialize};
use serde_json;

// Generate bindings from the WIT file
wit_bindgen::generate!({
    world: "newton-provider",  // Must match the world name in WIT
    path: "wit",               // Path to WIT files
});

// Export the implementation
export!(YourImplementation);

struct YourImplementation;

impl Guest for YourImplementation {
    fn run(input: String) -> Result<String, String> {
        // Your implementation here
        Ok("result".to_string())
    }
}

Step 4: Build the WASM Component

# Build the component
cargo component build --release

# Output location:
# target/wasm32-wasip1/release/<package_name>.wasm

Option B: Using standard cargo

# Build for WASI Preview 1
cargo build --target wasm32-wasip1 --release

# Output location:
# target/wasm32-wasip1/release/<package_name>.wasm

Step 5: Validate the WASM Component

# Validate the WASM module
wasm-tools validate target/wasm32-wasip1/release/<package_name>.wasm

# Inspect the component's WIT interface
wasm-tools component wit target/wasm32-wasip1/release/<package_name>.wasm

# Check the component's imports and exports
wasm-tools component new target/wasm32-wasip1/release/<package_name>.wasm \
  -o component.wasm --adapt wasi_snapshot_preview1.wasm