Skip to content

Rust SDK

The Hyperstack Rust SDK is a high-performance, asynchronous client for consuming real-time data from Hyperstack streaming servers. It is designed for backend services, trading bots, and CLI tools that require type-safe access to Solana state projections.

Add hyperstack-sdk to your Cargo.toml. The SDK is currently available via GitHub:

[dependencies]
hyperstack-sdk = { git = "https://github.com/HyperTekOrg/hyperstack.git" }
tokio = { version = "1.0", features = ["full"] }
futures-util = "0.3"

The SDK supports both rustls (default) and native-tls:

# Use native-tls instead of rustls
hyperstack-sdk = { git = "...", default-features = false, features = ["native-tls"] }

The SDK requires the Tokio runtime. Ensure you have it enabled in your project (specifically the rt-multi-thread, macros, and time features).


The following example shows how to connect to a Hyperstack server and watch for updates on a specific entity type.

use hyperstack_sdk::{HyperStack, Update};
use futures_util::StreamExt;
// These types are typically imported from your generated SDK crate
// use my_stack_sdk::{TokenEntity, Token};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. Connect to the Hyperstack server
let hs = HyperStack::connect("wss://mainnet.hyperstack.xyz").await?;
// 2. Start watching an entity
let mut stream = hs.watch::<TokenEntity>().await;
println!("Watching for token updates...");
// 3. Process real-time updates
while let Some(update) = stream.next().await {
match update {
Update::Upsert { key, data } => {
println!("Entity {} updated: {:?}", key, data);
}
Update::Delete { key } => {
println!("Entity {} deleted", key);
}
_ => {}
}
}
Ok(())
}

Simple connection with default settings.

let hs = HyperStack::connect("wss://api.hyperstack.xyz").await?;

Configure the client with custom reconnection logic and intervals.

use std::time::Duration;
let hs = HyperStack::builder()
.url("wss://api.hyperstack.xyz")
.auto_reconnect(true)
.max_reconnect_attempts(10)
.reconnect_intervals(vec![
Duration::from_secs(1),
Duration::from_secs(2),
Duration::from_secs(5),
])
.ping_interval(Duration::from_secs(30))
.connect()
.await?;

The SDK provides several ways to interact with entity data, depending on your use case.

Fetch a single entity by its primary key. If the client is not yet subscribed to the entity’s state view, it will automatically subscribe.

if let Some(token) = hs.get::<TokenEntity>("mint_address").await {
println!("Found token: {:?}", token);
}

Fetch all entities of type E currently tracked by the server.

let all_tokens = hs.list::<TokenEntity>().await;
println!("Total tokens: {}", all_tokens.len());

Subscribe to a stream of all updates for entity type E.

let mut stream = hs.watch::<TokenEntity>().await;
while let Some(update) = stream.next().await {
// Handle Update<E::Data>
}

Subscribe to updates for a specific entity instance by its key.

let mut stream = hs.watch_key::<TokenEntity>("mint_address").await;

Type safety is achieved through the Entity trait. While you can implement this manually, it is designed to be implemented by code generated by the Hyperstack CLI.

pub trait Entity: Sized + Send + Sync + 'static {
/// The data struct for this entity
type Data: Serialize + DeserializeOwned + Clone + Send + Sync + 'static;
/// Unique name of the entity
const NAME: &'static str;
/// Server paths for different view modes
fn state_view() -> &'static str;
fn list_view() -> &'static str;
fn kv_view() -> &'static str;
}

The Update enum represents changes to an entity:

pub enum Update<T> {
/// Full entity data or partial update that resulted in a new state
Upsert { key: String, data: T },
/// Partial update (merged into current state)
Patch { key: String, data: T },
/// Entity was removed
Delete { key: String },
}

Monitor the health of your connection:

let state = hs.connection_state().await;
match state {
ConnectionState::Connected => { println!("Online"); },
ConnectionState::Connecting => { println!("Connecting..."); },
ConnectionState::Reconnecting { attempt } => { println!("Retrying attempt {}", attempt); },
ConnectionState::Disconnected => { println!("Offline"); },
ConnectionState::Failed { error } => { println!("Error: {}", error); },
}

Most users will interact with the Rust SDK using a generated crate. This ensures that all entities and their fields are fully typed.

Use the Hyperstack CLI to generate a Rust crate from your spec:

Terminal window
hs sdk create rust my-stream-name --output ./my-sdk

Add the generated crate to your dependencies:

[dependencies]
hyperstack-sdk = { git = "https://github.com/HyperTekOrg/hyperstack.git" }
my-stream-sdk = { path = "./my-sdk" }

Import the generated entities and use them with the HyperStack client:

use my_stream_sdk::{PoolEntity, Pool};
let hs = HyperStack::connect("wss://example.com").await?;
let pool = hs.get::<PoolEntity>("pool_address").await;

For real-world usage patterns, check the examples/ directory in the Hyperstack repository:

  • Flip Demo: Tracking game state for a coin flip program.
  • Pump New Launches: Monitoring new token launches on Pumpfun.
  • Pump Trades: Real-time trade monitoring for specific tokens.