127 lines
6.1 KiB
Markdown
127 lines
6.1 KiB
Markdown
# SAL Mycelium Module (`sal::mycelium`)
|
|
|
|
## Overview
|
|
|
|
The `sal::mycelium` module provides a client interface for interacting with a [Mycelium](https://mycelium.com/) 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.
|
|
|
|
## Key Design Points
|
|
|
|
- **Async HTTP Client**: Leverages `reqwest` for asynchronous HTTP requests to the Mycelium node's API, ensuring non-blocking operations suitable for concurrent applications.
|
|
- **JSON Interaction**: Expects and processes JSON-formatted data from the Mycelium API, using `serde_json::Value` for flexible data handling.
|
|
- **Base64 Encoding**: Message payloads and topics are Base64 encoded/decoded when communicating with the Mycelium API, as per its expected format.
|
|
- **Rhai Scriptability**: All core functionalities are exposed to Rhai scripts via `herodo` through the `sal::rhai::mycelium` bridge. This allows for easy automation of Mycelium network tasks.
|
|
- **Error Handling**: Provides clear error messages, converting HTTP and parsing errors into `String` results in Rust, which are then translated to `EvalAltResult` for Rhai.
|
|
- **Tokio Runtime Management**: For Rhai script execution, a Tokio runtime is managed internally by the wrapper functions to bridge Rhai's synchronous world with the asynchronous Rust client.
|
|
|
|
## Rhai Scripting with `herodo`
|
|
|
|
The `sal::mycelium` module can be scripted using `herodo`. The following functions are available in Rhai, typically prefixed with `mycelium_`:
|
|
|
|
All functions take `api_url` (String) as their first argument, which is the base URL of the Mycelium node's HTTP API (e.g., `"http://localhost:7777"`).
|
|
|
|
- `mycelium_get_node_info(api_url: String) -> Dynamic`
|
|
- Retrieves general information about the Mycelium node.
|
|
- Returns a dynamic object (map) representing the JSON response.
|
|
|
|
- `mycelium_list_peers(api_url: String) -> Dynamic`
|
|
- Lists all peers currently connected to the node.
|
|
- Returns a dynamic array of peer information objects.
|
|
|
|
- `mycelium_add_peer(api_url: String, peer_address: String) -> Dynamic`
|
|
- Adds a new peer to the node.
|
|
- `peer_address`: The endpoint address of the peer to add (e.g., `"tcp://192.168.1.10:7778"`).
|
|
- Returns a success status or an error.
|
|
|
|
- `mycelium_remove_peer(api_url: String, peer_id: String) -> Dynamic`
|
|
- Removes a peer from the node.
|
|
- `peer_id`: The ID of the peer to remove.
|
|
- Returns a success status or an error.
|
|
|
|
- `mycelium_list_selected_routes(api_url: String) -> Dynamic`
|
|
- Lists the currently selected (active) routes in the node's routing table.
|
|
- Returns a dynamic array of route objects.
|
|
|
|
- `mycelium_list_fallback_routes(api_url: String) -> Dynamic`
|
|
- Lists the fallback routes in the node's routing table.
|
|
- Returns a dynamic array of route objects.
|
|
|
|
- `mycelium_send_message(api_url: String, destination: String, topic: String, message: String, reply_deadline_secs: Int) -> Dynamic`
|
|
- Sends a message to a specific destination over the Mycelium network.
|
|
- `destination`: The Mycelium address of the recipient node.
|
|
- `topic`: The topic for the message (will be Base64 encoded).
|
|
- `message`: The content of the message (will be Base64 encoded).
|
|
- `reply_deadline_secs`: An integer specifying the timeout in seconds to wait for a reply. If negative, no reply is waited for.
|
|
- Returns a response from the Mycelium API, potentially including a reply if waited for.
|
|
|
|
- `mycelium_receive_messages(api_url: String, topic: String, wait_deadline_secs: Int) -> Dynamic`
|
|
- Subscribes to a topic and waits for messages.
|
|
- `topic`: The topic to subscribe to (will be Base64 encoded).
|
|
- `wait_deadline_secs`: An integer specifying the maximum time in seconds to wait for a message. If negative, waits indefinitely (or until the API's default timeout).
|
|
- Returns an array of received messages, or an empty array if the deadline is met before messages arrive.
|
|
|
|
### Rhai Example
|
|
|
|
```rhai
|
|
// Assuming a Mycelium node is running and accessible at http://localhost:7777
|
|
let api_url = "http://localhost:7777";
|
|
|
|
// Get Node Info
|
|
print("Fetching node info...");
|
|
let node_info = mycelium_get_node_info(api_url);
|
|
if node_info.is_ok() {
|
|
print(`Node Info: ${node_info}`);
|
|
} else {
|
|
print(`Error fetching node info: ${node_info}`);
|
|
}
|
|
|
|
// List Peers
|
|
print("\nListing peers...");
|
|
let peers = mycelium_list_peers(api_url);
|
|
if peers.is_ok() {
|
|
print(`Peers: ${peers}`);
|
|
} else {
|
|
print(`Error listing peers: ${peers}`);
|
|
}
|
|
|
|
// Example: Send a message (destination and topic are illustrative)
|
|
let dest_addr = "some_mycelium_destination_address"; // Replace with actual address
|
|
let msg_topic = "sal/test_topic";
|
|
let msg_content = "Hello from SAL Mycelium via Rhai!";
|
|
|
|
print(`\nSending message to '${dest_addr}' on topic '${msg_topic}'...`);
|
|
// No reply wait (deadline = -1)
|
|
let send_result = mycelium_send_message(api_url, dest_addr, msg_topic, msg_content, -1);
|
|
if send_result.is_ok() {
|
|
print(`Send Result: ${send_result}`);
|
|
} else {
|
|
print(`Error sending message: ${send_result}`);
|
|
}
|
|
|
|
// Example: Receive messages (topic is illustrative)
|
|
// This will block for up to 10 seconds, or until a message arrives.
|
|
print(`\nAttempting to receive messages on topic '${msg_topic}' for 10 seconds...`);
|
|
let received = mycelium_receive_messages(api_url, msg_topic, 10);
|
|
if received.is_ok() {
|
|
if received.len() > 0 {
|
|
print(`Received Messages: ${received}`);
|
|
} else {
|
|
print("No messages received within the deadline.");
|
|
}
|
|
} else {
|
|
print(`Error receiving messages: ${received}`);
|
|
}
|
|
|
|
print("\nMycelium Rhai script finished.");
|
|
```
|
|
|
|
This module facilitates integration with Mycelium networks, enabling automation of peer management, message exchange, and network monitoring through `herodo` scripts or direct Rust integration.
|