...
This commit is contained in:
		
							
								
								
									
										327
									
								
								packages/clients/myceliumclient/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								packages/clients/myceliumclient/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,327 @@
 | 
			
		||||
//! SAL Mycelium - Client interface for interacting with Mycelium node's HTTP API
 | 
			
		||||
//!
 | 
			
		||||
//! This crate provides a client interface for interacting with a Mycelium node's HTTP API.
 | 
			
		||||
//! Mycelium is a decentralized networking project, and this SAL module allows Rust applications
 | 
			
		||||
//! and `herodo` Rhai scripts to manage and communicate over a Mycelium network.
 | 
			
		||||
//!
 | 
			
		||||
//! The module enables operations such as:
 | 
			
		||||
//! - Querying node status and information
 | 
			
		||||
//! - Managing peer connections (listing, adding, removing)
 | 
			
		||||
//! - Inspecting routing tables (selected and fallback routes)
 | 
			
		||||
//! - Sending messages to other Mycelium nodes
 | 
			
		||||
//! - Receiving messages from subscribed topics
 | 
			
		||||
//!
 | 
			
		||||
//! All interactions with the Mycelium API are performed asynchronously.
 | 
			
		||||
 | 
			
		||||
use base64::{engine::general_purpose, Engine as _};
 | 
			
		||||
use reqwest::Client;
 | 
			
		||||
use serde_json::Value;
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
 | 
			
		||||
pub mod rhai;
 | 
			
		||||
 | 
			
		||||
/// Get information about the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The node information as a JSON value, or an error message
 | 
			
		||||
pub async fn get_node_info(api_url: &str) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let url = format!("{}/api/v1/admin", api_url);
 | 
			
		||||
 | 
			
		||||
    let response = client
 | 
			
		||||
        .get(&url)
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// List all peers connected to the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The list of peers as a JSON value, or an error message
 | 
			
		||||
pub async fn list_peers(api_url: &str) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let url = format!("{}/api/v1/admin/peers", api_url);
 | 
			
		||||
 | 
			
		||||
    let response = client
 | 
			
		||||
        .get(&url)
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Add a new peer to the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
/// * `peer_address` - The address of the peer to add
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The result of the operation as a JSON value, or an error message
 | 
			
		||||
pub async fn add_peer(api_url: &str, peer_address: &str) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let url = format!("{}/api/v1/admin/peers", api_url);
 | 
			
		||||
 | 
			
		||||
    let response = client
 | 
			
		||||
        .post(&url)
 | 
			
		||||
        .json(&serde_json::json!({
 | 
			
		||||
            "endpoint": peer_address
 | 
			
		||||
        }))
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if status == reqwest::StatusCode::NO_CONTENT {
 | 
			
		||||
        // Successfully added, but no content to parse
 | 
			
		||||
        return Ok(serde_json::json!({"success": true}));
 | 
			
		||||
    }
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // For other success statuses that might have a body
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Remove a peer from the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
/// * `peer_id` - The ID of the peer to remove
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The result of the operation as a JSON value, or an error message
 | 
			
		||||
pub async fn remove_peer(api_url: &str, peer_id: &str) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let peer_id_url_encoded = urlencoding::encode(peer_id);
 | 
			
		||||
    let url = format!("{}/api/v1/admin/peers/{}", api_url, peer_id_url_encoded);
 | 
			
		||||
 | 
			
		||||
    let response = client
 | 
			
		||||
        .delete(&url)
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if status == reqwest::StatusCode::NO_CONTENT {
 | 
			
		||||
        // Successfully removed, but no content to parse
 | 
			
		||||
        return Ok(serde_json::json!({"success": true}));
 | 
			
		||||
    }
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// List all selected routes in the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The list of selected routes as a JSON value, or an error message
 | 
			
		||||
pub async fn list_selected_routes(api_url: &str) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let url = format!("{}/api/v1/admin/routes/selected", api_url);
 | 
			
		||||
 | 
			
		||||
    let response = client
 | 
			
		||||
        .get(&url)
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// List all fallback routes in the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The list of fallback routes as a JSON value, or an error message
 | 
			
		||||
pub async fn list_fallback_routes(api_url: &str) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let url = format!("{}/api/v1/admin/routes/fallback", api_url);
 | 
			
		||||
 | 
			
		||||
    let response = client
 | 
			
		||||
        .get(&url)
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Send a message to a destination via the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
/// * `destination` - The destination address
 | 
			
		||||
/// * `topic` - The message topic
 | 
			
		||||
/// * `message` - The message content
 | 
			
		||||
/// * `reply_deadline` - The deadline in seconds; pass `-1` to indicate we do not want to wait on a reply
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The result of the operation as a JSON value, or an error message
 | 
			
		||||
pub async fn send_message(
 | 
			
		||||
    api_url: &str,
 | 
			
		||||
    destination: &str,
 | 
			
		||||
    topic: &str,
 | 
			
		||||
    message: &str,
 | 
			
		||||
    reply_deadline: Option<Duration>, // This is passed in URL query
 | 
			
		||||
) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let url = format!("{}/api/v1/messages", api_url);
 | 
			
		||||
 | 
			
		||||
    let mut request = client.post(&url);
 | 
			
		||||
    if let Some(deadline) = reply_deadline {
 | 
			
		||||
        request = request.query(&[("reply_timeout", deadline.as_secs())]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let response = request
 | 
			
		||||
        .json(&serde_json::json!({
 | 
			
		||||
                "dst": { "ip": destination },
 | 
			
		||||
                "topic": general_purpose::STANDARD.encode(topic),
 | 
			
		||||
                "payload": general_purpose::STANDARD.encode(message)
 | 
			
		||||
        }))
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Receive messages from a topic via the Mycelium node
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `api_url` - The URL of the Mycelium API
 | 
			
		||||
/// * `topic` - The message topic
 | 
			
		||||
/// * `wait_deadline` - Time we wait for receiving a message
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<Value, String>` - The received messages as a JSON value, or an error message
 | 
			
		||||
pub async fn receive_messages(
 | 
			
		||||
    api_url: &str,
 | 
			
		||||
    topic: &str,
 | 
			
		||||
    wait_deadline: Option<Duration>,
 | 
			
		||||
) -> Result<Value, String> {
 | 
			
		||||
    let client = Client::new();
 | 
			
		||||
    let url = format!("{}/api/v1/messages", api_url);
 | 
			
		||||
 | 
			
		||||
    let mut request = client.get(&url);
 | 
			
		||||
 | 
			
		||||
    if let Some(deadline) = wait_deadline {
 | 
			
		||||
        request = request.query(&[
 | 
			
		||||
            ("topic", general_purpose::STANDARD.encode(topic)),
 | 
			
		||||
            ("timeout", deadline.as_secs().to_string()),
 | 
			
		||||
        ])
 | 
			
		||||
    } else {
 | 
			
		||||
        request = request.query(&[("topic", general_purpose::STANDARD.encode(topic))])
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let response = request
 | 
			
		||||
        .send()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to send request: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    let status = response.status();
 | 
			
		||||
    if !status.is_success() {
 | 
			
		||||
        return Err(format!("Request failed with status: {}", status));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let result: Value = response
 | 
			
		||||
        .json()
 | 
			
		||||
        .await
 | 
			
		||||
        .map_err(|e| format!("Failed to parse response: {}", e))?;
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										254
									
								
								packages/clients/myceliumclient/src/rhai.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								packages/clients/myceliumclient/src/rhai.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,254 @@
 | 
			
		||||
//! Rhai wrappers for Mycelium client module functions
 | 
			
		||||
//!
 | 
			
		||||
//! This module provides Rhai wrappers for the functions in the Mycelium client module.
 | 
			
		||||
 | 
			
		||||
use std::time::Duration;
 | 
			
		||||
 | 
			
		||||
use crate as client;
 | 
			
		||||
use rhai::Position;
 | 
			
		||||
use rhai::{Array, Dynamic, Engine, EvalAltResult, Map};
 | 
			
		||||
use serde_json::Value;
 | 
			
		||||
use tokio::runtime::Runtime;
 | 
			
		||||
 | 
			
		||||
/// Register Mycelium module functions with the Rhai engine
 | 
			
		||||
///
 | 
			
		||||
/// # Arguments
 | 
			
		||||
///
 | 
			
		||||
/// * `engine` - The Rhai engine to register the functions with
 | 
			
		||||
///
 | 
			
		||||
/// # Returns
 | 
			
		||||
///
 | 
			
		||||
/// * `Result<(), Box<EvalAltResult>>` - Ok if registration was successful, Err otherwise
 | 
			
		||||
pub fn register_mycelium_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
 | 
			
		||||
    // Register Mycelium client functions
 | 
			
		||||
    engine.register_fn("mycelium_get_node_info", mycelium_get_node_info);
 | 
			
		||||
    engine.register_fn("mycelium_list_peers", mycelium_list_peers);
 | 
			
		||||
    engine.register_fn("mycelium_add_peer", mycelium_add_peer);
 | 
			
		||||
    engine.register_fn("mycelium_remove_peer", mycelium_remove_peer);
 | 
			
		||||
    engine.register_fn(
 | 
			
		||||
        "mycelium_list_selected_routes",
 | 
			
		||||
        mycelium_list_selected_routes,
 | 
			
		||||
    );
 | 
			
		||||
    engine.register_fn(
 | 
			
		||||
        "mycelium_list_fallback_routes",
 | 
			
		||||
        mycelium_list_fallback_routes,
 | 
			
		||||
    );
 | 
			
		||||
    engine.register_fn("mycelium_send_message", mycelium_send_message);
 | 
			
		||||
    engine.register_fn("mycelium_receive_messages", mycelium_receive_messages);
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper function to get a runtime
 | 
			
		||||
fn get_runtime() -> Result<Runtime, Box<EvalAltResult>> {
 | 
			
		||||
    tokio::runtime::Runtime::new().map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Failed to create Tokio runtime: {}", e).into(),
 | 
			
		||||
            rhai::Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper function to convert serde_json::Value to rhai::Dynamic
 | 
			
		||||
fn value_to_dynamic(value: Value) -> Dynamic {
 | 
			
		||||
    match value {
 | 
			
		||||
        Value::Null => Dynamic::UNIT,
 | 
			
		||||
        Value::Bool(b) => Dynamic::from(b),
 | 
			
		||||
        Value::Number(n) => {
 | 
			
		||||
            if let Some(i) = n.as_i64() {
 | 
			
		||||
                Dynamic::from(i)
 | 
			
		||||
            } else if let Some(f) = n.as_f64() {
 | 
			
		||||
                Dynamic::from(f)
 | 
			
		||||
            } else {
 | 
			
		||||
                Dynamic::from(n.to_string())
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Value::String(s) => Dynamic::from(s),
 | 
			
		||||
        Value::Array(arr) => {
 | 
			
		||||
            let mut rhai_arr = Array::new();
 | 
			
		||||
            for item in arr {
 | 
			
		||||
                rhai_arr.push(value_to_dynamic(item));
 | 
			
		||||
            }
 | 
			
		||||
            Dynamic::from(rhai_arr)
 | 
			
		||||
        }
 | 
			
		||||
        Value::Object(map) => {
 | 
			
		||||
            let mut rhai_map = Map::new();
 | 
			
		||||
            for (k, v) in map {
 | 
			
		||||
                rhai_map.insert(k.into(), value_to_dynamic(v));
 | 
			
		||||
            }
 | 
			
		||||
            Dynamic::from_map(rhai_map)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Mycelium Client Function Wrappers
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::get_node_info
 | 
			
		||||
///
 | 
			
		||||
/// Gets information about the Mycelium node.
 | 
			
		||||
pub fn mycelium_get_node_info(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async { client::get_node_info(api_url).await });
 | 
			
		||||
 | 
			
		||||
    let node_info = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(node_info))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::list_peers
 | 
			
		||||
///
 | 
			
		||||
/// Lists all peers connected to the Mycelium node.
 | 
			
		||||
pub fn mycelium_list_peers(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async { client::list_peers(api_url).await });
 | 
			
		||||
 | 
			
		||||
    let peers = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(peers))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::add_peer
 | 
			
		||||
///
 | 
			
		||||
/// Adds a new peer to the Mycelium node.
 | 
			
		||||
pub fn mycelium_add_peer(api_url: &str, peer_address: &str) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async { client::add_peer(api_url, peer_address).await });
 | 
			
		||||
 | 
			
		||||
    let response = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(response))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::remove_peer
 | 
			
		||||
///
 | 
			
		||||
/// Removes a peer from the Mycelium node.
 | 
			
		||||
pub fn mycelium_remove_peer(api_url: &str, peer_id: &str) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async { client::remove_peer(api_url, peer_id).await });
 | 
			
		||||
 | 
			
		||||
    let response = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(response))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::list_selected_routes
 | 
			
		||||
///
 | 
			
		||||
/// Lists all selected routes in the Mycelium node.
 | 
			
		||||
pub fn mycelium_list_selected_routes(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async { client::list_selected_routes(api_url).await });
 | 
			
		||||
 | 
			
		||||
    let routes = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(routes))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::list_fallback_routes
 | 
			
		||||
///
 | 
			
		||||
/// Lists all fallback routes in the Mycelium node.
 | 
			
		||||
pub fn mycelium_list_fallback_routes(api_url: &str) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async { client::list_fallback_routes(api_url).await });
 | 
			
		||||
 | 
			
		||||
    let routes = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(routes))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::send_message
 | 
			
		||||
///
 | 
			
		||||
/// Sends a message to a destination via the Mycelium node.
 | 
			
		||||
pub fn mycelium_send_message(
 | 
			
		||||
    api_url: &str,
 | 
			
		||||
    destination: &str,
 | 
			
		||||
    topic: &str,
 | 
			
		||||
    message: &str,
 | 
			
		||||
    reply_deadline_secs: i64,
 | 
			
		||||
) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let deadline = if reply_deadline_secs < 0 {
 | 
			
		||||
        None
 | 
			
		||||
    } else {
 | 
			
		||||
        Some(Duration::from_secs(reply_deadline_secs as u64))
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async {
 | 
			
		||||
        client::send_message(api_url, destination, topic, message, deadline).await
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let response = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(response))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Wrapper for mycelium::receive_messages
 | 
			
		||||
///
 | 
			
		||||
/// Receives messages from a topic via the Mycelium node.
 | 
			
		||||
pub fn mycelium_receive_messages(
 | 
			
		||||
    api_url: &str,
 | 
			
		||||
    topic: &str,
 | 
			
		||||
    wait_deadline_secs: i64,
 | 
			
		||||
) -> Result<Dynamic, Box<EvalAltResult>> {
 | 
			
		||||
    let rt = get_runtime()?;
 | 
			
		||||
 | 
			
		||||
    let deadline = if wait_deadline_secs < 0 {
 | 
			
		||||
        None
 | 
			
		||||
    } else {
 | 
			
		||||
        Some(Duration::from_secs(wait_deadline_secs as u64))
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let result = rt.block_on(async { client::receive_messages(api_url, topic, deadline).await });
 | 
			
		||||
 | 
			
		||||
    let messages = result.map_err(|e| {
 | 
			
		||||
        Box::new(EvalAltResult::ErrorRuntime(
 | 
			
		||||
            format!("Mycelium error: {}", e).into(),
 | 
			
		||||
            Position::NONE,
 | 
			
		||||
        ))
 | 
			
		||||
    })?;
 | 
			
		||||
 | 
			
		||||
    Ok(value_to_dynamic(messages))
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user