Skip to content

Boundless Rust SDK

The Boundless Market SDK offers high-level Rust APIs for interacting with the Boundless Market smart contracts, preparing and submitting ZK proofs, and handling relevant offchain data such as images and inputs.

Crate Documentation

Installation

cargo add boundless-market

or add manually to your Cargo.toml:

[dependencies]
boundless-market = "X.X.X"

where X.X.X is the latest release specified on the Boundless GitHub Release page.

SDK Workflow Overview

Below is an example of the Boundless end-to-end programmatic workflow:

1. Initialize Client

use boundless_market::client::ClientBuilder;
use alloy::signers::local::LocalSigner;
# use alloy::primitives::Address;
# use url::Url;
# async fn init_client(rpc_url: Url, market_address: Address, set_verifier_address: Address) -> anyhow::Result<()> {
let client = ClientBuilder::new()
    .with_rpc_url(rpc_url)
    .with_boundless_market_address(market_address)
    .with_set_verifier_address(set_verifier_address)
    .with_wallet(LocalSigner::random().into())
    .build()
    .await?;
# Ok(())
# }

2. Upload ELF and Input













let elf_url = client.upload_image(&std::fs::read("guest.elf")?).await?;
let input_url = client.upload_input(&[0x41, 0x42, 0x43]).await?;

3. Submit Proof Request











let (request_id, expires_at) = client.submit_request(&request).await?;

4. Await Fulfillment













let (journal, seal) = client
    .wait_for_request_fulfillment(request_id, Duration::from_secs(10), expires_at)
    .await?;

5. Fetch Proof Results











// If not using wait_for_request_fulfillment:
let (journal, seal) = client.boundless_market.get_request_fulfillment(request_id).await?;
 
// Advanced: Set-Inclusion Receipt
let (journal, receipt) = client.fetch_set_inclusion_receipt(request_id, [0u8; 32].into()).await?;

SDK Modules

client

  • Client: Core struct for transactions, storage, and offchain interaction.
  • ClientBuilder: Configure and build the client.

contracts

  • BoundlessMarketService: Onchain interactions (requests, fulfillments, deposits).
  • SetVerifierService: Manages aggregated proof verifications.
  • Structures: ProofRequest, Offer, Fulfillment.

input

  • InputBuilder: Prepare inputs for RISC Zero guests.

order_stream_client

  • OrderStreamClient: Submit/fetch orders offchain via WebSocket.

storage

  • Providers: S3, Pinata, and TempFile for uploading ELF/input data.

selector

  • Utilities for tracking/verifying proof types.

Example: Full Proof Submission

use boundless_market::{
  client::ClientBuilder,
  contracts::{ProofRequest, RequestId, Requirements, Predicate, Offer},
  input::InputBuilder,
  storage::StorageProvider,
  };
use alloy::signers::local::LocalSigner;
use alloy::signers::local::PrivateKeySigner;
use alloy::primitives::{Address, U256};
use std::time::Duration;
use url::Url;
 
async fn proof_submission(signer: &PrivateKeySigner, rpc_url: Url, market_address: Address, set_verifier_address: Address) -> anyhow::Result<()> {
    let client = ClientBuilder::new()
        .with_rpc_url(rpc_url)
        .with_boundless_market_address(market_address)
        .with_set_verifier_address(set_verifier_address)
        .with_wallet(signer.clone().into())
        .build()
        .await?;
 
    let elf_url = client.upload_image(&std::fs::read("guest.elf")?).await?;
    let input_url = client.upload_input(&InputBuilder::new().write(&42u32)?.build_vec()?).await?;
 
    let request = ProofRequest::new(
        RequestId::new(signer.address(), 0),
        Requirements::new([0u8; 32], Predicate::prefix_match([])),
        elf_url,
        input_url,
        Offer {
            minPrice: U256::from(1_000),
            maxPrice: U256::from(2_000),
            biddingStart: 0,
            rampUpPeriod: 60,
            timeout: 3600,
            lockTimeout: 1800,
            lockStake: U256::from(500),
        }
    );
 
    let (request_id, expires_at) = client.submit_request(&request).await?;
 
    let (journal, seal) = client
        .wait_for_request_fulfillment(request_id, Duration::from_secs(10), expires_at)
        .await?;
 
    println!("Journal: {:?}, Seal: {:?}", journal, seal);
 
    Ok(())
}