working example for mycelium
Some checks failed
Rhai Tests / Run Rhai Tests (pull_request) Has been cancelled

This commit is contained in:
Maxime Van Hees 2025-05-13 11:52:31 +02:00
parent 2e90e6fa39
commit 330ab23930
3 changed files with 106 additions and 82 deletions

View File

@ -48,6 +48,7 @@ tokio-test = "0.4.4"
uuid = { version = "1.16.0", features = ["v4"] } uuid = { version = "1.16.0", features = ["v4"] }
zinit-client = { git = "https://github.com/threefoldtech/zinit", branch = "json_rpc", package = "zinit-client" } zinit-client = { git = "https://github.com/threefoldtech/zinit", branch = "json_rpc", package = "zinit-client" }
reqwest = { version = "0.12.15", features = ["json"] } reqwest = { version = "0.12.15", features = ["json"] }
urlencoding = "2.1.3"
# Optional features for specific OS functionality # Optional features for specific OS functionality
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]

View File

@ -22,9 +22,9 @@ try {
print("No peers connected."); print("No peers connected.");
} else { } else {
for peer in peers { for peer in peers {
print(`Peer ID: ${peer.id}`); print(`Peer Endpoint: ${peer.endpoint.proto}://${peer.endpoint.socketAddr}`);
print(` Address: ${peer.address}`); print(` Type: ${peer.type}`);
print(` Connected: ${peer.connected}`); print(` Connection State: ${peer.connectionState}`);
print(` Bytes sent: ${peer.txBytes}`); print(` Bytes sent: ${peer.txBytes}`);
print(` Bytes received: ${peer.rxBytes}`); print(` Bytes received: ${peer.rxBytes}`);
} }
@ -35,7 +35,7 @@ try {
// Add a new peer // Add a new peer
print("\nAdding a new peer:"); print("\nAdding a new peer:");
let new_peer_address = "tcp://185.69.166.8:9651"; let new_peer_address = "tcp://65.21.231.58:9651";
try { try {
let result = mycelium_add_peer(api_url, new_peer_address); let result = mycelium_add_peer(api_url, new_peer_address);
print(`Peer added: ${result.success}`); print(`Peer added: ${result.success}`);
@ -80,47 +80,51 @@ try {
} }
// Send a message // Send a message
print("\nSending a message:"); // TO SEND A MESSAGE FILL IN THE DESTINATION IP ADDRESS
let destination = "400:1234:5678:9abc:def0:1234:5678:9abc"; // -----------------------------------------------------//
let topic = "test"; // print("\nSending a message:");
let message = "Hello from Rhai!"; // let destination = < FILL IN CORRECT DEST IP >
let deadline_secs = 60; // let topic = "test";
// let message = "Hello from Rhai!";
// let deadline_secs = 60;
try { // try {
let result = mycelium_send_message(api_url, destination, topic, message, deadline_secs); // let result = mycelium_send_message(api_url, destination, topic, message, deadline_secs);
print(`Message sent: ${result.success}`); // print(`Message sent: ${result.success}`);
if result.id { // if result.id {
print(`Message ID: ${result.id}`); // print(`Message ID: ${result.id}`);
} // }
} catch(err) { // } catch(err) {
print(`Error sending message: ${err}`); // print(`Error sending message: ${err}`);
} // }
// Receive messages // Receive messages
print("\nReceiving messages:"); // RECEIVING MESSAGES SHOULD BE DONE ON THE DESTINATION NODE FROM THE CALL ABOVE
let receive_topic = "test"; // -----------------------------------------------------------------------------//
let count = 5; // print("\nReceiving messages:");
// let receive_topic = "test";
// let count = 5;
try { // try {
let messages = mycelium_receive_messages(api_url, receive_topic, count); // let messages = mycelium_receive_messages(api_url, receive_topic, count);
if messages.is_empty() { // if messages.is_empty() {
print("No messages received."); // print("No messages received.");
} else { // } else {
for msg in messages { // for msg in messages {
print(`Message from: ${msg.source}`); // print(`Message from: ${msg.source}`);
print(` Topic: ${msg.topic}`); // print(` Topic: ${msg.topic}`);
print(` Content: ${msg.content}`); // print(` Content: ${msg.content}`);
print(` Timestamp: ${msg.timestamp}`); // print(` Timestamp: ${msg.timestamp}`);
} // }
} // }
} catch(err) { // } catch(err) {
print(`Error receiving messages: ${err}`); // print(`Error receiving messages: ${err}`);
} // }
// Remove a peer // Remove a peer
print("\nRemoving a peer:"); print("\nRemoving a peer:");
let peer_id = "some-peer-id"; // Replace with an actual peer ID let peer_id = "tcp://65.21.231.58:9651"; // This is the peer we added earlier
try { try {
let result = mycelium_remove_peer(api_url, peer_id); let result = mycelium_remove_peer(api_url, peer_id);
print(`Peer removed: ${result.success}`); print(`Peer removed: ${result.success}`);

View File

@ -1,7 +1,11 @@
use std::time::Duration; use base64::{
use serde_json::Value; alphabet,
engine::{self, general_purpose},
Engine as _,
};
use reqwest::Client; use reqwest::Client;
use base64::encode; use serde_json::Value;
use std::time::Duration;
/// Get information about the Mycelium node /// Get information about the Mycelium node
/// ///
@ -84,17 +88,22 @@ pub async fn add_peer(api_url: &str, peer_address: &str) -> Result<Value, String
let response = client let response = client
.post(&url) .post(&url)
.json(&serde_json::json!({ .json(&serde_json::json!({
"address": peer_address "endpoint": peer_address
})) }))
.send() .send()
.await .await
.map_err(|e| format!("Failed to send request: {}", e))?; .map_err(|e| format!("Failed to send request: {}", e))?;
let status = response.status(); 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() { if !status.is_success() {
return Err(format!("Request failed with status: {}", status)); return Err(format!("Request failed with status: {}", status));
} }
// For other success statuses that might have a body
let result: Value = response let result: Value = response
.json() .json()
.await .await
@ -115,7 +124,8 @@ pub async fn add_peer(api_url: &str, peer_address: &str) -> Result<Value, String
/// * `Result<Value, String>` - The result of the operation as a JSON value, or an error message /// * `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> { pub async fn remove_peer(api_url: &str, peer_id: &str) -> Result<Value, String> {
let client = Client::new(); let client = Client::new();
let url = format!("{}/api/v1/admin/peers/{}", api_url, peer_id); 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 let response = client
.delete(&url) .delete(&url)
@ -124,6 +134,10 @@ pub async fn remove_peer(api_url: &str, peer_id: &str) -> Result<Value, String>
.map_err(|e| format!("Failed to send request: {}", e))?; .map_err(|e| format!("Failed to send request: {}", e))?;
let status = response.status(); 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() { if !status.is_success() {
return Err(format!("Request failed with status: {}", status)); return Err(format!("Request failed with status: {}", status));
} }
@ -213,7 +227,13 @@ pub async fn list_fallback_routes(api_url: &str) -> Result<Value, String> {
/// # Returns /// # Returns
/// ///
/// * `Result<Value, String>` - The result of the operation as a JSON value, or an error message /// * `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, deadline_secs: u64) -> Result<Value, String> { pub async fn send_message(
api_url: &str,
destination: &str,
topic: &str,
message: &str,
deadline_secs: u64,
) -> Result<Value, String> {
let client = Client::new(); let client = Client::new();
let url = format!("{}/api/v1/messages", api_url); let url = format!("{}/api/v1/messages", api_url);
@ -223,10 +243,9 @@ pub async fn send_message(api_url: &str, destination: &str, topic: &str, message
let response = client let response = client
.post(&url) .post(&url)
.json(&serde_json::json!({ .json(&serde_json::json!({
"destination": destination, "dst": { "ip": destination },
"topic": topic, "topic": general_purpose::STANDARD.encode(topic),
"content": message, "payload": general_purpose::STANDARD.encode(message)
"deadline": deadline
})) }))
.send() .send()
.await .await
@ -262,7 +281,7 @@ pub async fn receive_messages(api_url: &str, topic: &str, count: u32) -> Result<
let response = client let response = client
.get(&url) .get(&url)
.query(&[("topic", encode(topic)), ("count", count.to_string())]) .query(&[("topic", general_purpose::STANDARD.encode(topic))])
.send() .send()
.await .await
.map_err(|e| format!("Failed to send request: {}", e))?; .map_err(|e| format!("Failed to send request: {}", e))?;