Rust Integration Guide Home > Developers > Rust Integration guide to integrating with Noderr Protocol using Rust with production-ready code examples.
GraphQL Client rust use graphql_client::{GraphQLQuery, Response}; use reqwest::Client; #[derive(GraphQLQuery)] #[graphql( schema_path = "schema.graphql", query_path = "queries/get_vault.graphql", response_derives = "Debug" )] pub struct GetVault; pub struct GraphQLClient { client: Client, endpoint: String, api_key: String, } impl GraphQLClient { pub fn new(endpoint: String, api_key: String) -> Self { Self { client: Client::new(), endpoint, api_key, } } pub async fn fetch_vault(&self, vault_id: &str) -> Result<Vault, Box<dyn std::error::Error>> { let variables = get_vault::Variables { id: vault_id.to_string(), }; let body = GetVault::build_query(variables); let response = self.client.post(&self.endpoint).header("Authorization", format!("Bearer {}", self.api_key)).json(&body).send().await?; let response_body: Response<get_vault::ResponseData> = response.json().await?; match response_body.data { Some(data) => Ok(data.vault), None => Err("No vault data returned".into()), } } } // Query definitions pub const GET_VAULT_QUERY: &str = r#" query GetVault($id: ID!) { vault(id: $id) { id name totalAssets apy strategies { id name allocation } } } "#; pub const GET_USER_VOTES_QUERY: &str = r#" query GetUserVotes($userId: ID!) { user(id: $userId) { id votes { proposalId vote votingPower } } } "#; pub const GET_VAULT_PERFORMANCE_QUERY: &str = r#" query GetVaultPerformance($vaultId: ID!, $period: String!) { vaultPerformance(vaultId: $vaultId, period: $period) { returns volatility sharpeRatio maxDrawdown } } "#; pub const GET_PROPOSALS_QUERY: &str = r#" query GetProposals($status: String!) { proposals(status: $status) { id title description votesFor votesAgainst endTime } } "#;
WebSocket Subscriptions rust use tokio_tungstenite::{connect_async, tungstenite::Message}; use futures::{SinkExt, StreamExt}; use serde_json::json; pub async fn subscribe_to_prices(asset_id: &str) -> Result<(), Box<dyn std::error::Error>> { let (ws_stream, _) = connect_async("wss://api.noderr.xyz/ws").await?; let (mut write, mut read) = ws_stream.split(); let subscribe_msg = json!({ "type": "subscribe", "channel": format!("prices:{}", asset_id) }).to_string(); write.send(Message::Text(subscribe_msg)).await?; while let Some(msg) = read.next().await { match msg? { Message::Text(text) => { println!("Price update: {}", text); } Message::Close(_) => { println!("WebSocket closed"); break; } _ => {} } } Ok(()) } pub async fn subscribe_to_apy_changes(vault_id: &str) -> Result<(), Box<dyn std::error::Error>> { let (ws_stream, _) = connect_async("wss://api.noderr.xyz/ws").await?; let (mut write, mut read) = ws_stream.split(); let subscribe_msg = json!({ "type": "subscribe", "channel": format!("apy:{}", vault_id) }).to_string(); write.send(Message::Text(subscribe_msg)).await?; while let Some(msg) = read.next().await { match msg? { Message::Text(text) => { println!("APY update: {}", text); } _ => {} } } Ok(()) } pub async fn subscribe_to_governance() -> Result<(), Box<dyn std::error::Error>> { let (ws_stream, _) = connect_async("wss://api.noderr.xyz/ws").await?; let (mut write, mut read) = ws_stream.split(); let subscribe_msg = json!({ "type": "subscribe", "channel": "governance" }).to_string(); write.send(Message::Text(subscribe_msg)).await?; while let Some(msg) = read.next().await { match msg? { Message::Text(text) => { println!("Governance event: {}", text); } _ => {} } } Ok(()) }
Smart Contract Interaction rust use ethers::prelude::*; use std::sync::Arc; #[derive(EthContract)] #[ethcontract( name = "Vault", raw_contract_json = "vault_abi.json" )] pub struct Vault; pub async fn get_vault_balance( vault_address: Address, user_address: Address, provider: Arc<Provider<Http>>, ) -> Result<U256, Box<dyn std::error::Error>> { let vault = Vault::new(vault_address, provider); let balance = vault.balance_of(user_address).call().await?; Ok(balance) } pub async fn deposit( vault_address: Address, amount: U256, wallet: LocalWallet, provider: Arc<Provider<Http>>, ) -> Result<TransactionReceipt, Box<dyn std::error::Error>> { let client = SignerMiddleware::new(provider, wallet); let vault = Vault::new(vault_address, Arc::new(client)); let tx = vault.deposit(amount).send().await?; let receipt = tx.await?; Ok(receipt.ok_or("Transaction failed")?) } pub async fn withdraw( vault_address: Address, shares: U256, wallet: LocalWallet, provider: Arc<Provider<Http>>, ) -> Result<TransactionReceipt, Box<dyn std::error::Error>> { let client = SignerMiddleware::new(provider, wallet); let vault = Vault::new(vault_address, Arc::new(client)); let tx = vault.withdraw(shares).send().await?; let receipt = tx.await?; Ok(receipt.ok_or("Transaction failed")?) } pub async fn monitor_transaction( tx_hash: H256, provider: Arc<Provider<Http>>, ) -> Result<TransactionReceipt, Box<dyn std::error::Error>> { let receipt = provider.get_transaction_receipt(tx_hash).await?.ok_or("Transaction not found")?; Ok(receipt) }
Async Runtime rust #[tokio::] async fn () -> Result<(), Box<dyn std::error::Error>> { // Initialize client let client = NoderrClient::new(None); // Fetch vault let vault = client.get_vault("vault-1").await?; println!("Vault: {:?}", vault); // Deposit let deposit_result = client.deposit("vault-1", 100.0).await?; println!("Deposit result: {:?}", deposit_result); // Subscribe to prices tokio::spawn(async { if let Err(e) = subscribe_to_prices("ETH").await { eprintln!("WebSocket error: {}", e); } }); // Keep running tokio::signal::ctrl_c().await?; Ok(()) }