### Rust example: get_routing_recommendation usage Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Shows how to call get_routing_recommendation on a SlipstreamClient instance and print the best region and confidence. The example is marked no_run and includes hidden setup lines for configuration and client connection. ```rust # use allenhark_slipstream::{Config, SlipstreamClient}; # async fn example() -> Result<(), Box> { # let config = Config::builder().api_key("test").build()?; # let client = SlipstreamClient::connect(config).await?; let recommendation = client.get_routing_recommendation().await?; println!("Best region: {} (confidence: {}%)", recommendation.best_region, recommendation.confidence); # Ok(()) # } ``` -------------------------------- ### expect examples Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Examples showing expect panic behavior and recommended message style. ```rust let x: Result = Err("emergency failure"); x.expect("Testing expect"); // panics with `Testing expect: emergency failure` ``` ```rust let path = std::env::var("IMPORTANT_PATH") .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`"); ``` -------------------------------- ### iter example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Example of using iter to access the Ok value as an iterator. ```rust let x: Result = Ok(7); assert_eq!(x.iter().next(), Some(&7)); let x: Result = Err("nothing!"); assert_eq!(x.iter().next(), None); ``` -------------------------------- ### Using TransactionBuilder Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/types/struct.TransactionBuilder.html Example showing how to initialize a TransactionBuilder, configure tip and fee parameters, and retrieve the resulting information for transaction construction. ```rust use allenhark_slipstream::TransactionBuilder; let builder = TransactionBuilder::new() .tip_wallet("7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU") .tip_lamports(50_000) .compute_unit_price(10_000) .compute_unit_limit(200_000); // Get the instructions to add to your transaction let tip_info = builder.tip_info(); let fee_info = builder.fee_info(); ``` -------------------------------- ### Example for Result::is_ok_and Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates checking if a Result is Ok and the value matches a predicate. ```rust let x: Result = Ok(2); assert_eq!(x.is_ok_and(|x| x > 1), true); let x: Result = Ok(0); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Err("hey"); assert_eq!(x.is_ok_and(|x| x > 1), false); let x: Result = Ok("ownership".to_string()); assert_eq!(x.as_ref().is_ok_and(|x| x.len() > 1), true); println!("still alive {:?}", x); ``` -------------------------------- ### HealthMonitor::start Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/connection/health/struct.HealthMonitor.html Starts the monitoring loop in the background. ```APIDOC ## HealthMonitor::start ### Description Starts the monitoring loop in the background. ### Method start ### Signature pub fn start(self) ### Parameters - **self** (HealthMonitor) - Required - The health monitor instance. ### Returns - **()** - No return value. ``` -------------------------------- ### Example for Result::is_ok Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates checking if a Result is Ok. ```rust let x: Result = Ok(-3); assert_eq!(x.is_ok(), true); let x: Result = Err("Some error message"); assert_eq!(x.is_ok(), false); ``` -------------------------------- ### inspect example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Example of using inspect to print a value if Ok, continuing to map and expect in a chained call. ```rust let x: u8 = "4" .parse::() .inspect(|x| println!("original: {x}")) .map(|x| x.pow(3)) .expect("failed to parse number"); ``` -------------------------------- ### Post-Connection Setup and Keepalive Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Initializes the health monitor, HTTP client, time synchronization, and optional keepalive background task after a successful connection. ```rust 286 async fn finish_connect( 287 config: Config, 288 transport: Box, 289 connection_info: ConnectionInfo, 290 ) -> Result { 291 let transport = Arc::new(RwLock::new(transport)); 292 293 // Start health monitor to handle auto-reconnection with subscription tracking 294 let subscription_tracker = Arc::new(crate::connection::health::SubscriptionTracker::new()); 295 let monitor = crate::connection::health::HealthMonitor::new( 296 config.clone(), 297 transport.clone(), 298 Arc::clone(&subscription_tracker), 299 ); 300 monitor.start(); 301 302 let http_client = reqwest::Client::builder() 303 .timeout(std::time::Duration::from_secs(10)) 304 .build() 305 .map_err(|e| SdkError::connection(format!("Failed to create HTTP client: {}", e)))?; 306 307 let time_sync = Arc::new(TimeSyncState::new(10)); 308 let keepalive_handle = if config.keepalive { 309 let transport_clone = Arc::clone(&transport); 310 let sync_clone = Arc::clone(&time_sync); 311 let interval = config.keepalive_interval; 312 Some(tokio::spawn(async move { 313 let mut ticker = tokio::time::interval(interval); 314 loop { 315 ticker.tick().await; 316 let transport = transport_clone.read().await; 317 if !transport.is_connected() { 318 break; 319 } 320 match transport.ping().await { 321 Ok(result) => { 322 debug!(rtt_ms = result.rtt_ms, offset_ms = result.clock_offset_ms, "Keepalive ping"); 323 sync_clone.record(result); 324 } 325 Err(_) => { 326 // Transport may not support ping -- that's OK 327 break; 328 } 329 } 330 } 331 })) 332 } else { 333 None 334 }; 335 336 let client = Self { 337 config, 338 transport, 339 connection_info, 340 http_client, 341 latest_tip: Arc::new(RwLock::new(None)), 342 metrics: Arc::new(ClientMetrics { 343 transactions_submitted: AtomicU64::new(0), 344 transactions_confirmed: AtomicU64::new(0), 345 total_latency_ms: AtomicU64::new(0), 346 last_latency_ms: AtomicU64::new(0), 347 }), 348 time_sync, 349 keepalive_handle: tokio::sync::Mutex::new(keepalive_handle), 350 dedup_cache: Arc::new(DedupCache::new()), 351 subscription_tracker, 352 }; 353 354 // Auto-register webhook and fetch initial tip concurrently 355 let webhook_fut = async { 356 if client.config.webhook_url.is_some() { 357 let url = client.config.webhook_url.clone().unwrap(); 358 let events = client.config.webhook_events.clone(); 359 let level = client.config.webhook_notification_level.clone(); 360 match client 361 .register_webhook(&url, Some(events), Some(level)) 362 .await 363 { 364 Ok(_) => info!("Webhook auto-registered at {}", url), 365 Err(e) => debug!("Failed to auto-register webhook: {}", e), 366 } ``` -------------------------------- ### as_deref_mut example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Example of using as_deref_mut to get mutable references with DerefMut. ```rust let mut s = "HELLO".to_string(); let mut x: Result = Ok("hello".to_string()); let y: Result<&mut str, &mut u32> = Ok(&mut s); assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); let mut i = 42; let mut x: Result = Err(42); let y: Result<&mut str, &mut u32> = Err(&mut i); assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); ``` -------------------------------- ### Get routing recommendation example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/client/struct.SlipstreamClient.html Example usage of get_routing_recommendation to retrieve the best region for the current leader validator along with confidence score. The method returns a RoutingRecommendation with best_region and confidence fields, useful for dynamically routing transactions based on validator proximity. ```rust let recommendation = client.get_routing_recommendation().await?; println!("Best region: {} (confidence: {}%)", recommendation.best_region, recommendation.confidence); ``` -------------------------------- ### as_deref example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Example of using as_deref to coerce Ok and Err variants via Deref. ```rust let x: Result = Ok("hello".to_string()); let y: Result<&str, &u32> = Ok("hello"); assert_eq!(x.as_deref(), y); let x: Result = Err(42); let y: Result<&str, &u32> = Err(&42); assert_eq!(x.as_deref(), y); ``` -------------------------------- ### Example for Result::flatten Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates flattening a Result, E> into Result. ```rust let x: Result, u32> = Ok(Ok("hello")); assert_eq!(Ok("hello"), x.flatten()); let x: Result, u32> = Ok(Err(6)); assert_eq!(Err(6), x.flatten()); let x: Result, u32> = Err(6); assert_eq!(Err(6), x.flatten()); ``` -------------------------------- ### Example for Result::transpose Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates transposing a Result of an Option into an Option of a Result. ```rust #[derive(Debug, Eq, PartialEq)] struct SomeErr; let x: Result, SomeErr> = Ok(Some(5)); let y: Option> = Some(Ok(5)); assert_eq!(x.transpose(), y); ``` -------------------------------- ### Result usage example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates basic usage of Result with an iterator map and sum operation. ```rust let res: Result = v.iter().map(f).sum(); assert_eq!(res, Err("Negative element found")); ``` -------------------------------- ### MultiRegionClient example: leader-aware transaction routing Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/multi_region/index.html Shows how to construct a MultiRegionClient with a Config, a list of WorkerEndpoints, and a default MultiRegionConfig, then subscribe to routing updates and submit a transaction. Requires the tokio runtime and a valid API key. The transaction bytes are expected to be signed before submission. ```rust use allenhark_slipstream::{Config, MultiRegionClient, MultiRegionConfig, WorkerEndpoint}; #[tokio::main] async fn main() -> Result<(), Box> { let config = Config::builder() .api_key("sk_test_12345678") .build()?; let workers = vec![ WorkerEndpoint::new("w1", "us-west", "203.0.113.10"), WorkerEndpoint::new("w2", "eu-central", "203.0.113.20"), WorkerEndpoint::new("w3", "asia-east", "203.0.113.30"), ]; let multi_config = MultiRegionConfig::default(); let client = MultiRegionClient::new(config, workers, multi_config).await?; // Subscribe to routing updates let mut routing_rx = client.subscribe_routing_updates(); // Submit transaction - automatically routed to best region let tx_bytes = vec![/* signed transaction bytes */]; let result = client.submit_transaction(&tx_bytes).await?; Ok(()) } ``` -------------------------------- ### Fetch deposit address (get_deposit_address) Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Sends a GET request to the /v1/deposit-address endpoint with the API key as a Bearer token. Returns a TopUpInfo object on success; on failure returns an SdkError::Internal with the response body text. ```rust let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!("Failed to fetch deposit address: {}", error_text))); } let info: TopUpInfo = response.json().await?; Ok(info) } ``` -------------------------------- ### Multi-region client initialization Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/multi_region.rs.html Initializes the multi-region client by validating workers, creating a worker selector, measuring latencies, connecting to the best region, and optionally starting a leader hint listener if auto-follow is enabled. ```rust ) -> Result { if workers.is_empty() { return Err(SdkError::config("No workers provided for multi-region client")); } let worker_selector = Arc::new(WorkerSelector::new(workers)); let (routing_tx, _) = broadcast::channel(16); let client = Self { config, multi_config, worker_selector, region_clients: Arc::new(RwLock::new(HashMap::new())), current_routing: Arc::new(RwLock::new(None)), last_switch: Arc::new(RwLock::new(None)), routing_tx, leader_hint_tx: Arc::new(RwLock::new(None)), }; // Measure latencies to all workers client.worker_selector.measure_all().await; // Connect to the best region initially let best_worker = client.worker_selector.select_best().await?; client.ensure_region_connected(&best_worker.region).await?; // Start leader hint subscription if auto-follow is enabled if client.multi_config.auto_follow_leader { client.start_leader_hint_listener().await?; } info!( initial_region = %best_worker.region, worker_count = client.worker_selector.worker_count(), "Multi-region client initialized" ); Ok(client) } ``` -------------------------------- ### Example for Result::copied on &mut T Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates using the copied method to map a Result<&mut T, E> to Result by copying the Ok value. ```rust let mut val = 12; let x: Result<&mut i32, i32> = Ok(&mut val); assert_eq!(x, Ok(&mut 12)); let copied = x.copied(); assert_eq!(copied, Ok(12)); ``` -------------------------------- ### Example for Result::cloned on &T Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates using the cloned method to map a Result<&T, E> to Result by cloning the Ok value. ```rust let val = 12; let x: Result<&i32, i32> = Ok(&val); assert_eq!(x, Ok(&12)); let cloned = x.cloned(); assert_eq!(cloned, Ok(12)); ``` -------------------------------- ### Example for Result::cloned on &mut T Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates using the cloned method to map a Result<&mut T, E> to Result by cloning the Ok value. ```rust let mut val = 12; let x: Result<&mut i32, i32> = Ok(&mut val); assert_eq!(x, Ok(&mut 12)); let cloned = x.cloned(); assert_eq!(cloned, Ok(12)); ``` -------------------------------- ### Example for Result::copied on &T Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Demonstrates using the copied method to map a Result<&T, E> to Result by copying the Ok value. ```rust let val = 12; let x: Result<&i32, i32> = Ok(&val); assert_eq!(x, Ok(&12)); let copied = x.copied(); assert_eq!(copied, Ok(12)); ``` -------------------------------- ### Poll tip instructions and priority fees with lastId and Authorization Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/connection/http.rs.html Polling loops for tip instructions and priority fees. Both use the same pattern: build a GET request with a timeout query, optionally add lastId and Authorization headers, send it, parse a PollResponse, forward data through an mpsc channel, and sleep POLL_INTERVAL_MS. On failure they log a warning and continue polling. ```rust let url = format!("{}/v1/stream/tip-instructions", base_url); let mut req = client .get(&url) .query(&[("timeout", "30")]); if let Some(ref id) = last_id { req = req.query(&[("lastId", id.as_str())]); } if let Some(ref auth) = auth { req = req.header("Authorization", auth.clone()); } match req.send().await { Ok(response) if response.status().is_success() => { if let Ok(poll_response) = response.json::>().await { if let Some(data) = poll_response.data { last_id = Some(poll_response.message_id); if tx.send(data).await.is_err() { break; } } } } Ok(response) => { warn!(status = %response.status(), "Tip instructions poll failed"); } Err(e) => { warn!(error = %e, "Tip instructions poll error"); } } tokio::time::sleep(Duration::from_millis(POLL_INTERVAL_MS)).await; ``` ```rust let url = format!("{}/v1/stream/priority-fees", base_url); let mut req = client .get(&url) .query(&[("timeout", "30")]); if let Some(ref id) = last_id { req = req.query(&[("lastId", id.as_str())]); } if let Some(ref auth) = auth { req = req.header("Authorization", auth.clone()); } match req.send().await { Ok(response) if response.status().is_success() => { if let Ok(poll_response) = response.json::>().await { if let Some(data) = poll_response.data { last_id = Some(poll_response.message_id); if tx.send(data).await.is_err() { break; } } } } Ok(response) => { warn!(status = %response.status(), "Priority fees poll failed"); } Err(e) => { warn!(error = %e, "Priority fees poll error"); } } tokio::time::sleep(Duration::from_millis(POLL_INTERVAL_MS)).await; ``` -------------------------------- ### Get deposit history (get_deposit_history) Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Fetches SOL deposit history from /v1/deposit-history with optional limit and offset query parameters. Returns a Vec; on unauthorized returns SdkError::auth, on other errors returns SdkError::Internal. ```rust pub async fn get_deposit_history( &self, options: crate::types::DepositHistoryOptions, ) -> Result> { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let mut url = format!("{}/v1/deposit-history", base_url); let mut params = Vec::new(); if let Some(limit) = options.limit { params.push(format!("limit={}", limit)); } if let Some(offset) = options.offset { params.push(format!("offset={}", offset)); } if !params.is_empty() { url = format!("{}?{}", url, params.join("&")); } debug!(url = %url, "Fetching deposit history"); let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!( "Failed to fetch deposit history: {}", error_text ))); } let body: serde_json::Value = response.json().await?; let entries: Vec = serde_json::from_value( body["deposits"].clone(), ) .unwrap_or_default(); Ok(entries) } ``` -------------------------------- ### Get the latest cached tip instruction Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Returns the most recent tip instruction received from the server. Useful for building transactions with the recommended tip. ```rust pub async fn get_latest_tip(&self) -> Option { self.latest_tip.read().await.clone() } ``` -------------------------------- ### Get Minimum Deposit USD Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Returns the minimum USD equivalent of SOL that must be deposited before tokens are credited. Currently $10 USD. ```rust pub fn get_minimum_deposit_usd(&self) -> f64 { 10.0 } ``` -------------------------------- ### Get deposit address with get_deposit_address Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Fetches the Solana wallet deposit address and minimum top-up amount from the /v1/deposit-address endpoint. Returns a TopUpInfo struct with the address and minimum top-up value. ```rust pub async fn get_deposit_address(&self) -> Result { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let url = format!("{}/v1/deposit-address", base_url); debug!(url = %url, "Fetching deposit address"); let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!("Failed to fetch deposit address: {}", error_text))); } let body: serde_json::Value = response.json().await?; Ok(TopUpInfo { address: body["address"].as_str().unwrap_or_default().to_string(), minimum_top_up: body["minimum_top_up"].as_i64().unwrap_or(0), }) } ``` -------------------------------- ### Get pending deposit (get_pending_deposit) Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Fetches pending deposit information from /v1/deposit-pending. Returns a PendingDeposit object; on unauthorized returns SdkError::auth, on other errors returns SdkError::Internal. ```rust pub async fn get_pending_deposit(&self) -> Result { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let url = format!("{}/v1/deposit-pending", base_url); debug!(url = %url, "Fetching pending deposit info"); let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!( "Failed to fetch pending deposits: {}", error_text ))); } let body: serde_json::Value = response.json().await?; let pending: crate::types::PendingDeposit = serde_json::from_value(body).unwrap_or_default(); Ok(pending) } ``` -------------------------------- ### Get Webhook Configuration Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Retrieves the current webhook configuration for the API key. Returns None if no webhook is configured (HTTP 404). Handles 401 and other error responses. ```rust pub async fn get_webhook(&self) -> Result> { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let url = format!("{}/v1/webhooks", base_url); let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if response.status() == reqwest::StatusCode::NOT_FOUND { return Ok(None); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!( "Failed to get webhook: {}", error_text ))); } let config: Option = response.json().await?; Ok(config) } ``` -------------------------------- ### Get usage history (get_usage_history) Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Fetches paginated token usage history from /v1/usage-history. Accepts optional limit and offset query parameters. Returns a Vec; on unauthorized returns SdkError::auth, on other errors returns SdkError::Internal. ```rust pub async fn get_usage_history(&self, options: UsageHistoryOptions) -> Result> { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let mut url = format!("{}/v1/usage-history", base_url); let mut params = Vec::new(); if let Some(limit) = options.limit { params.push(format!("limit={}", limit)); } if let Some(offset) = options.offset { params.push(format!("offset={}", offset)); } if !params.is_empty() { url = format!("{}?{}", url, params.join("&")); } debug!(url = %url, "Fetching usage history"); let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!("Failed to fetch usage history: {}", error_text))); } let body: serde_json::Value = response.json().await?; let entries: Vec = serde_json::from_value( body["entries"].clone(), ) .unwrap_or_default(); Ok(entries) } ``` -------------------------------- ### Get Performance Metrics Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Reads atomic counters for submitted/confirmed transactions and total latency, then computes average latency and success rate. Returns PerformanceMetrics. ```rust pub fn metrics(&self) -> PerformanceMetrics { let submitted = self.metrics.transactions_submitted.load(Ordering::Relaxed); let confirmed = self.metrics.transactions_confirmed.load(Ordering::Relaxed); let total_latency = self.metrics.total_latency_ms.load(Ordering::Relaxed); PerformanceMetrics { transactions_submitted: submitted, transactions_confirmed: confirmed, average_latency_ms: if submitted > 0 { total_latency as f64 / submitted as f64 } else { 0.0 }, success_rate: if submitted > 0 { confirmed as f64 / submitted as f64 } else { 0.0 }, } } ``` -------------------------------- ### Fetch Free Tier Usage Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Sends an HTTP GET request to /v1/free-tier-usage with Bearer token authorization. Returns FreeTierUsage or errors on unauthorized or non-success responses. ```rust pub async fn get_free_tier_usage(&self) -> Result { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let url = format!("{}/v1/free-tier-usage", base_url); debug!(url = %url, "Fetching free tier usage"); let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!( "Failed to fetch free tier usage: {}", error_text ))); } let usage: crate::types::FreeTierUsage = response.json().await?; Ok(usage) } ``` -------------------------------- ### Get token balance with get_balance Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Retrieves the token balance for the authenticated API key from the /v1/balance endpoint. Returns the current balance in SOL, tokens, and lamports, along with tier and free-tier usage. Uses a fixed cost of 50,000 lamports per query and a 1M lamports grace limit. ```rust pub async fn get_balance(&self) -> Result { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let url = format!("{}/v1/balance", base_url); debug!(url = %url, "Fetching token balance"); let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!("Failed to fetch balance: {}", error_text))); } let body: serde_json::Value = response.json().await?; let balance_lamports = body["balance_lamports"].as_i64().unwrap_or(0); let cost_per_query = 50_000i64; // 50,000 lamports per query let grace_limit = 1_000_000i64; // 1M lamports grace let tier = body["tier"].as_str().map(|s| s.to_string()); let free_tier_usage = serde_json::from_value(body["free_tier_usage"].clone()).ok(); Ok(Balance { balance_sol: balance_lamports as f64 / 1_000_000_000.0, balance_tokens: balance_lamports / cost_per_query, balance_lamports, grace_remaining_tokens: (balance_lamports + grace_limit) / cost_per_query, tier, free_tier_usage, }) } ``` -------------------------------- ### get_landing_rates: Fetch landing rate statistics Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Retrieves landing rate statistics for the API key, including overall, per-sender, and per-region breakdowns. Accepts optional start and end time parameters; defaults to the last 24 hours if not specified. ```rust /// Get transaction landing rate statistics for this API key. /// /// Returns overall landing rate plus per-sender and per-region breakdowns. /// Defaults to the last 24 hours if no time range is specified. pub async fn get_landing_rates( &self, options: Option, ) -> Result { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let mut url = format!("{}/v1/metrics/landing-rates", base_url); if let Some(opts) = &options { let mut params = Vec::new(); if let Some(start) = &opts.start { params.push(format!("start={}", start)); } if let Some(end) = &opts.end { params.push(format!("end={}", end)); } if !params.is_empty() { url.push('?'); url.push_str(¶ms.join("&")); } } let response = self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await?; if response.status() == reqwest::StatusCode::UNAUTHORIZED { return Err(SdkError::auth("Invalid API key")); } if !response.status().is_success() { let error_text = response.text().await.unwrap_or_default(); return Err(SdkError::Internal(format!( "Failed to get landing rates: {}", error_text ))); } let stats: LandingRateStats = response.json().await?; Ok(stats) } ``` -------------------------------- ### Subscribe to Tip Instructions Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/connection/grpc.rs.html Initiates a gRPC subscription for tip instructions and sets up a background loop to process incoming stream messages. ```rust async fn subscribe_tip_instructions(&self) -> Result> { if !self.is_connected() { return Err(SdkError::NotConnected); } let client = self.client.as_ref().ok_or(SdkError::NotConnected)?; let mut client = client.clone(); let config = self.config.as_ref().ok_or(SdkError::NotConnected)?; let (tx, rx) = mpsc::channel(32); let request = tonic::Request::new(proto::SubscriptionRequest { api_key: config.api_key.clone(), region: config.region.clone().unwrap_or_default(), }); let response = client .subscribe_tip_instructions(request) .await .map_err(|e| SdkError::connection(format!("Failed to subscribe to tip instructions: {}", e)))?; let mut stream = response.into_inner(); tokio::spawn(async move { loop { match stream.message().await { Ok(Some(tip)) => { ``` -------------------------------- ### Connect and subscribe to leader hints with SlipstreamClient Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/client/index.html Demonstrates initializing a SlipstreamClient with a configuration and subscribing to leader hints. Requires the tokio runtime. ```rust use allenhark_slipstream::{Config, SlipstreamClient}; #[tokio::main] async fn main() -> Result<(), Box> { let config = Config::builder() .api_key("sk_test_12345678") .region("us-west") .build()?; let client = SlipstreamClient::connect(config).await?; // Subscribe to leader hints let mut hints = client.subscribe_leader_hints().await?; while let Some(hint) = hints.recv().await { println!("Leader hint: {}", hint.preferred_region); } Ok(()) } ``` -------------------------------- ### iter_mut example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Example of using iter_mut to modify the value inside a Result::Ok. ```rust let mut x: Result = Ok(7); match x.iter_mut().next() { Some(v) => *v = 40, None => {}, } assert_eq!(x, Ok(40)); let mut x: Result = Err("nothing!"); assert_eq!(x.iter_mut().next(), None); ``` -------------------------------- ### Eagerly fetch initial tip instructions Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/client.rs.html Fetches tip instructions from the HTTP endpoint so get_latest_tip() is populated immediately after connect(). Uses a RawTip struct to map snake_case fields to the SDK's TipInstruction. ```rust async fn fetch_initial_tip(&self) { let base_url = self.config.get_endpoint(crate::types::Protocol::Http); let url = format!("{}/v1/tip-instructions", base_url); let response = match self .http_client .get(&url) .header("Authorization", format!("Bearer {}", self.config.api_key)) .send() .await { Ok(r) if r.status().is_success() => r, _ => return, }; // Worker returns snake_case fields, map to SDK's TipInstruction #[derive(serde::Deserialize)] struct RawTip { sender_id: Option, tip_wallet: Option, #[serde(default)] tip_amount_lamports: u64, tier: Option, #[serde(default)] expected_latency_ms: u32, #[serde(default)] confidence: u32, #[serde(default)] valid_until_slot: u64, #[serde(default)] timestamp: u64, } if let Ok(tips) = response.json::>().await { if let Some(raw) = tips.last() { let tip = TipInstruction { timestamp: if raw.timestamp > 0 { raw.timestamp } else { std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap_or_default() .as_millis() as u64 }, sender: raw.sender_id.clone().unwrap_or_default(), sender_name: raw.sender_id.clone().unwrap_or_default(), tip_wallet_address: raw.tip_wallet.clone().unwrap_or_default(), tip_amount_sol: raw.tip_amount_lamports as f64 / 1_000_000_000.0, tip_tier: raw.tier.clone().unwrap_or_else(|| "standard".to_string()), expected_latency_ms: raw.expected_latency_ms, confidence: raw.confidence, valid_until_slot: raw.valid_until_slot, alternative_senders: vec![], }; self.set_latest_tip(tip).await; } } } ``` -------------------------------- ### inspect_err example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Example of using inspect_err to print error details in a function that might fail to read a file. ```rust use std::{fs, io}; fn read() -> io::Result { fs::read_to_string("address.txt") .inspect_err(|e| eprintln!("failed to read file: {e}")) } ``` -------------------------------- ### Subscribe to Leader Hints Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/connection/grpc.rs.html Establishes a gRPC subscription for leader hints and spawns a background task to stream updates into an mpsc channel. ```rust async fn subscribe_leader_hints(&self) -> Result> { if !self.is_connected() { return Err(SdkError::NotConnected); } let client = self.client.as_ref().ok_or(SdkError::NotConnected)?; let mut client = client.clone(); let config = self.config.as_ref().ok_or(SdkError::NotConnected)?; let (tx, rx) = mpsc::channel(32); let request = tonic::Request::new(proto::SubscriptionRequest { api_key: config.api_key.clone(), region: config.region.clone().unwrap_or_default(), }); let response = client .subscribe_leader_hints(request) .await .map_err(|e| SdkError::connection(format!("Failed to subscribe to leader hints: {}", e)))?; let mut stream = response.into_inner(); tokio::spawn(async move { loop { match stream.message().await { Ok(Some(hint)) => { let sdk_hint = Self::convert_leader_hint(hint); if tx.send(sdk_hint).await.is_err() { debug!("Receiver dropped, stopping leader hints subscription"); break; } } Ok(None) => { debug!("Leader hints stream ended"); break; } Err(e) => { warn!(error = %e, "Error reading leader hints"); break; } } } }); Ok(rx) } ``` -------------------------------- ### map_err example Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/error/type.Result.html Example of using map_err to apply a stringifying function to an Err value, leaving Ok values untouched. ```rust fn stringify(x: u32) -> String { format!("error code: {x}") } let x: Result = Ok(2); assert_eq!(x.map_err(stringify), Ok(2)); let x: Result = Err(13); assert_eq!(x.map_err(stringify), Err("error code: 13".to_string())); ``` -------------------------------- ### Submit a transaction with SlipstreamClient Source: https://docs.rs/allenhark-slipstream Demonstrates how to initialize the Slipstream client with a configuration and submit a transaction. ```rust use allenhark_slipstream::{Config, SlipstreamClient}; #[tokio::main] async fn main() -> Result<(), Box> { // Create configuration let config = Config::builder() .api_key("sk_test_12345678") .region("us-west") .build()?; // Connect to Slipstream let client = SlipstreamClient::connect(config).await?; // Submit a transaction let tx_bytes = vec![/* signed transaction bytes */]; let result = client.submit_transaction(&tx_bytes).await?; println!("Transaction signature: {:?}", result.signature); Ok(()) } ``` -------------------------------- ### Subscribe to leader hints Source: https://docs.rs/allenhark-slipstream Shows how to enable leader hints in the configuration and subscribe to real-time updates from the client. ```rust use allenhark_slipstream::{Config, SlipstreamClient}; #[tokio::main] async fn main() -> Result<(), Box> { let config = Config::builder() .api_key("sk_test_12345678") .leader_hints(true) .build()?; let client = SlipstreamClient::connect(config).await?; // Subscribe to leader hints let mut hints = client.subscribe_leader_hints().await?; while let Some(hint) = hints.recv().await { println!("Preferred region: {} (confidence: {})", hint.preferred_region, hint.confidence); } Ok(()) } ``` -------------------------------- ### subscribe_tip_instructions method Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/connection/websocket.rs.html Subscribes to tip instruction updates. It ensures the client is connected before sending the subscription request and processing incoming messages via a background task. ```rust async fn subscribe_tip_instructions(&self) -> Result> { if !self.is_connected() { return Err(SdkError::NotConnected); } self.send_message(ClientMessage::Subscribe { stream: "tip_instructions".to_string(), }) .await?; let (tx, rx) = mpsc::channel(32); let message_rx = Arc::clone(&self.message_rx); tokio::spawn(async move { loop { let msg = { let mut rx_guard = message_rx.write().await; match rx_guard.as_mut() { Some(r) => r.recv().await, None => break, } }; match msg { Some(ServerMessage::TipInstruction(tip)) => { let sdk_tip = Self::convert_tip_instruction(tip); if tx.send(sdk_tip).await.is_err() { break; } } None => break, _ => {} } } }); Ok(rx) } ``` -------------------------------- ### WorkerSelector::get_all_latencies Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/connection/selector/struct.WorkerSelector.html Gets all cached latency measurements. ```APIDOC ## WorkerSelector::get_all_latencies ### Description Gets all cached latency measurements. ### Method `pub async fn get_all_latencies(&self) -> HashMap` ### Returns - **HashMap** - A map of worker IDs to their latency measurements. ``` -------------------------------- ### QuicTransport::protocol Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/connection/quic/struct.QuicTransport.html Gets the protocol type of the transport. ```APIDOC ## QuicTransport::protocol ### Description Gets the protocol type of the transport. ### Method protocol ### Signature pub fn protocol(&self) -> Protocol ### Parameters None ### Returns Protocol - The protocol type. ``` -------------------------------- ### subscribe_tip_instructions Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/opt/rustwide/target/x86_64-unknown-linux-gnu/debug/build/allenhark-slipstream-62a1facf0d3ee3b3/out/slipstream.rs.html Subscribes to tip instructions emitted on change or every ~1s. Returns a server-streaming response of TipInstruction messages. ```APIDOC ## subscribe_tip_instructions ### Description Subscribes to tip instructions emitted on change or every ~1s. ### Method Server streaming RPC ### Endpoint /slipstream.SlipstreamService/SubscribeTipInstructions ### Parameters #### Request Body - **request** (SubscriptionRequest) - Required - The subscription request containing the desired parameters. ### Response #### Success Response - **TipInstruction** (stream) - A stream of tip instruction messages. ### Response Example Stream ``` -------------------------------- ### FallbackChain::timeout_for Source: https://docs.rs/allenhark-slipstream/latest/allenhark_slipstream/connection/struct.FallbackChain.html Gets the timeout for a specific protocol. ```APIDOC ## FallbackChain::timeout_for ### Description Gets the timeout for a specific protocol. ### Method Getter ### Signature ```rust pub fn timeout_for(&self, protocol: Protocol) -> Duration ``` ### Parameters - **protocol** (Protocol) - Required - The protocol to get the timeout for. ### Returns - **Duration** - The timeout duration for the given protocol. ``` -------------------------------- ### Config builder build method Source: https://docs.rs/allenhark-slipstream/latest/src/allenhark_slipstream/config.rs.html Builds the Config, applying defaults for discovery_url, connection_timeout, max_retries, leader_hints, stream flags, protocol_timeouts, priority_fee, retry_backoff, min_confidence (70), tier ("pro"), keepalive (true), keepalive_interval (5s), webhook_events (["transaction.confirmed"]), and webhook_notification_level ("final"). Requires api_key, otherwise returns SdkError::config("api_key is required"). Validates the config before returning. ```rust /// Build the configuration pub fn build(self) -> Result { let config = Config { api_key: self.api_key.ok_or_else(|| SdkError::config("api_key is required"))?, region: self.region, endpoint: self.endpoint, discovery_url: self.discovery_url.unwrap_or_else(|| { crate::discovery::DEFAULT_DISCOVERY_URL.to_string() }), connection_timeout: self .connection_timeout .unwrap_or_else(|| Duration::from_millis(DEFAULT_CONNECTION_TIMEOUT_MS)), max_retries: self.max_retries.unwrap_or(DEFAULT_MAX_RETRIES), leader_hints: self.leader_hints.unwrap_or(true), stream_tip_instructions: self.stream_tip_instructions.unwrap_or(false), stream_priority_fees: self.stream_priority_fees.unwrap_or(false), stream_latest_blockhash: self.stream_latest_blockhash.unwrap_or(false), stream_latest_slot: self.stream_latest_slot.unwrap_or(false), protocol_timeouts: self.protocol_timeouts.unwrap_or_default(), preferred_protocol: self.preferred_protocol, selected_worker: self.selected_worker, priority_fee: self.priority_fee.unwrap_or_default(), retry_backoff: self.retry_backoff.unwrap_or_default(), min_confidence: self.min_confidence.unwrap_or(70), idle_timeout: self.idle_timeout, tier: self.tier.unwrap_or_else(|| "pro".to_string()), keepalive: self.keepalive.unwrap_or(true), keepalive_interval: self.keepalive_interval.unwrap_or(Duration::from_secs(5)), webhook_url: self.webhook_url, webhook_events: self.webhook_events.unwrap_or_else(|| { vec!["transaction.confirmed".to_string()] }), webhook_notification_level: self .webhook_notification_level .unwrap_or_else(|| "final".to_string()), }; config.validate()?; Ok(config) } ```