1use base64::{engine::general_purpose, Engine as _};
17use reqwest::Client;
18use serde_json::Value;
19use std::time::Duration;
20
21pub mod rhai;
22
23pub async fn get_node_info(api_url: &str) -> Result<Value, String> {
33 let client = Client::new();
34 let url = format!("{}/api/v1/admin", api_url);
35
36 let response = client
37 .get(&url)
38 .send()
39 .await
40 .map_err(|e| format!("Failed to send request: {}", e))?;
41
42 let status = response.status();
43 if !status.is_success() {
44 return Err(format!("Request failed with status: {}", status));
45 }
46
47 let result: Value = response
48 .json()
49 .await
50 .map_err(|e| format!("Failed to parse response: {}", e))?;
51
52 Ok(result)
53}
54
55pub async fn list_peers(api_url: &str) -> Result<Value, String> {
65 let client = Client::new();
66 let url = format!("{}/api/v1/admin/peers", api_url);
67
68 let response = client
69 .get(&url)
70 .send()
71 .await
72 .map_err(|e| format!("Failed to send request: {}", e))?;
73
74 let status = response.status();
75 if !status.is_success() {
76 return Err(format!("Request failed with status: {}", status));
77 }
78
79 let result: Value = response
80 .json()
81 .await
82 .map_err(|e| format!("Failed to parse response: {}", e))?;
83
84 Ok(result)
85}
86
87pub async fn add_peer(api_url: &str, peer_address: &str) -> Result<Value, String> {
98 let client = Client::new();
99 let url = format!("{}/api/v1/admin/peers", api_url);
100
101 let response = client
102 .post(&url)
103 .json(&serde_json::json!({
104 "endpoint": peer_address
105 }))
106 .send()
107 .await
108 .map_err(|e| format!("Failed to send request: {}", e))?;
109
110 let status = response.status();
111 if status == reqwest::StatusCode::NO_CONTENT {
112 return Ok(serde_json::json!({"success": true}));
114 }
115 if !status.is_success() {
116 return Err(format!("Request failed with status: {}", status));
117 }
118
119 let result: Value = response
121 .json()
122 .await
123 .map_err(|e| format!("Failed to parse response: {}", e))?;
124
125 Ok(result)
126}
127
128pub async fn remove_peer(api_url: &str, peer_id: &str) -> Result<Value, String> {
139 let client = Client::new();
140 let peer_id_url_encoded = urlencoding::encode(peer_id);
141 let url = format!("{}/api/v1/admin/peers/{}", api_url, peer_id_url_encoded);
142
143 let response = client
144 .delete(&url)
145 .send()
146 .await
147 .map_err(|e| format!("Failed to send request: {}", e))?;
148
149 let status = response.status();
150 if status == reqwest::StatusCode::NO_CONTENT {
151 return Ok(serde_json::json!({"success": true}));
153 }
154 if !status.is_success() {
155 return Err(format!("Request failed with status: {}", status));
156 }
157
158 let result: Value = response
159 .json()
160 .await
161 .map_err(|e| format!("Failed to parse response: {}", e))?;
162
163 Ok(result)
164}
165
166pub async fn list_selected_routes(api_url: &str) -> Result<Value, String> {
176 let client = Client::new();
177 let url = format!("{}/api/v1/admin/routes/selected", api_url);
178
179 let response = client
180 .get(&url)
181 .send()
182 .await
183 .map_err(|e| format!("Failed to send request: {}", e))?;
184
185 let status = response.status();
186 if !status.is_success() {
187 return Err(format!("Request failed with status: {}", status));
188 }
189
190 let result: Value = response
191 .json()
192 .await
193 .map_err(|e| format!("Failed to parse response: {}", e))?;
194
195 Ok(result)
196}
197
198pub async fn list_fallback_routes(api_url: &str) -> Result<Value, String> {
208 let client = Client::new();
209 let url = format!("{}/api/v1/admin/routes/fallback", api_url);
210
211 let response = client
212 .get(&url)
213 .send()
214 .await
215 .map_err(|e| format!("Failed to send request: {}", e))?;
216
217 let status = response.status();
218 if !status.is_success() {
219 return Err(format!("Request failed with status: {}", status));
220 }
221
222 let result: Value = response
223 .json()
224 .await
225 .map_err(|e| format!("Failed to parse response: {}", e))?;
226
227 Ok(result)
228}
229
230pub async fn send_message(
244 api_url: &str,
245 destination: &str,
246 topic: &str,
247 message: &str,
248 reply_deadline: Option<Duration>, ) -> Result<Value, String> {
250 let client = Client::new();
251 let url = format!("{}/api/v1/messages", api_url);
252
253 let mut request = client.post(&url);
254 if let Some(deadline) = reply_deadline {
255 request = request.query(&[("reply_timeout", deadline.as_secs())]);
256 }
257
258 let response = request
259 .json(&serde_json::json!({
260 "dst": { "ip": destination },
261 "topic": general_purpose::STANDARD.encode(topic),
262 "payload": general_purpose::STANDARD.encode(message)
263 }))
264 .send()
265 .await
266 .map_err(|e| format!("Failed to send request: {}", e))?;
267
268 let status = response.status();
269 if !status.is_success() {
270 return Err(format!("Request failed with status: {}", status));
271 }
272
273 let result: Value = response
274 .json()
275 .await
276 .map_err(|e| format!("Failed to parse response: {}", e))?;
277
278 Ok(result)
279}
280
281pub async fn receive_messages(
293 api_url: &str,
294 topic: &str,
295 wait_deadline: Option<Duration>,
296) -> Result<Value, String> {
297 let client = Client::new();
298 let url = format!("{}/api/v1/messages", api_url);
299
300 let mut request = client.get(&url);
301
302 if let Some(deadline) = wait_deadline {
303 request = request.query(&[
304 ("topic", general_purpose::STANDARD.encode(topic)),
305 ("timeout", deadline.as_secs().to_string()),
306 ])
307 } else {
308 request = request.query(&[("topic", general_purpose::STANDARD.encode(topic))])
309 };
310
311 let response = request
312 .send()
313 .await
314 .map_err(|e| format!("Failed to send request: {}", e))?;
315
316 let status = response.status();
317 if !status.is_success() {
318 return Err(format!("Request failed with status: {}", status));
319 }
320
321 let result: Value = response
322 .json()
323 .await
324 .map_err(|e| format!("Failed to parse response: {}", e))?;
325
326 Ok(result)
327}