mirror of
https://github.com/waku-org/waku-rust-bindings.git
synced 2025-01-11 15:14:09 +00:00
Free strings (#46)
* Free strings on discovery * Free strings on filter * Free strings on lightpush * Added missing linking flags * Free strings on management * Fix management inner calls * Free strings on peers * Free strings on relay * Free strings on store * Free strings on decrypt * Fix toychat example * Fix tests * Added decode_response method * Use decode response * Rename decode response util * Use decode response in decrypt
This commit is contained in:
parent
48300c15a2
commit
d1a467edcc
@ -1,4 +1,4 @@
|
||||
[target.'cfg(target_os = "macos")']
|
||||
# when using osx, we need to link against some golang libraries, it did just work with this missing flags
|
||||
# from: https://github.com/golang/go/issues/42459
|
||||
rustflags = ["-C", "link-args=-framework CoreFoundation -framework Security"]
|
||||
rustflags = ["-C", "link-args=-framework CoreFoundation -framework Security -framework CoreServices"]
|
@ -107,7 +107,7 @@ fn setup_node_handle() -> std::result::Result<WakuNodeHandle<Running>, Box<dyn E
|
||||
let node_handle = node_handle.start()?;
|
||||
for address in NODES.iter().map(|a| Multiaddr::from_str(a).unwrap()) {
|
||||
let peerid = node_handle.add_peer(&address, ProtocolId::Relay)?;
|
||||
node_handle.connect_peer_with_id(peerid, None)?;
|
||||
node_handle.connect_peer_with_id(&peerid, None)?;
|
||||
}
|
||||
node_handle.relay_subscribe(None)?;
|
||||
Ok(node_handle)
|
||||
|
@ -1,12 +1,13 @@
|
||||
//! Symmetric and asymmetric waku messages [decrypting](https://rfc.vac.dev/spec/36/#decrypting-messages) methods
|
||||
|
||||
// std
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ffi::CString;
|
||||
// crates
|
||||
use aes_gcm::{Aes256Gcm, Key};
|
||||
use secp256k1::SecretKey;
|
||||
// internal
|
||||
use crate::general::{DecodedPayload, JsonResponse, Result, WakuMessage};
|
||||
use crate::general::{DecodedPayload, Result, WakuMessage};
|
||||
use crate::utils::decode_and_free_response;
|
||||
|
||||
/// Decrypt a message using a symmetric key
|
||||
///
|
||||
@ -16,24 +17,25 @@ pub fn waku_decode_symmetric(
|
||||
symmetric_key: &Key<Aes256Gcm>,
|
||||
) -> Result<DecodedPayload> {
|
||||
let symk = hex::encode(symmetric_key.as_slice());
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_decode_symmetric(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(symk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
let response: JsonResponse<DecodedPayload> =
|
||||
serde_json::from_str(result).map_err(|e| format!("{e}"))?;
|
||||
response.into()
|
||||
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let symk_ptr = CString::new(symk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_decode_symmetric(message_ptr, symk_ptr);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(symk_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
||||
/// Decrypt a message using a symmetric key
|
||||
@ -44,22 +46,23 @@ pub fn waku_decode_asymmetric(
|
||||
asymmetric_key: &SecretKey,
|
||||
) -> Result<DecodedPayload> {
|
||||
let sk = hex::encode(asymmetric_key.secret_bytes());
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_decode_asymmetric(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
let response: JsonResponse<DecodedPayload> =
|
||||
serde_json::from_str(result).map_err(|e| format!("{e}"))?;
|
||||
response.into()
|
||||
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let sk_ptr = CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_decode_asymmetric(message_ptr, sk_ptr);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(sk_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ mod decrypt;
|
||||
mod events;
|
||||
mod general;
|
||||
mod node;
|
||||
mod utils;
|
||||
|
||||
pub use node::{
|
||||
waku_create_content_topic, waku_create_pubsub_topic, waku_dafault_pubsub_topic, waku_new,
|
||||
|
@ -1,11 +1,11 @@
|
||||
// std
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ffi::CString;
|
||||
use std::time::Duration;
|
||||
// crates
|
||||
use multiaddr::Multiaddr;
|
||||
use url::{Host, Url};
|
||||
// internal
|
||||
use crate::general::JsonResponse;
|
||||
use crate::utils::decode_and_free_response;
|
||||
use crate::Result;
|
||||
|
||||
/// RetrieveNodes returns a list of multiaddress given a url to a DNS discoverable ENR tree.
|
||||
@ -15,18 +15,20 @@ pub fn waku_dns_discovery(
|
||||
server: Option<&Host>,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<Vec<Multiaddr>> {
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_dns_discovery(
|
||||
CString::new(url.to_string())
|
||||
.expect("CString should build properly from a valid Url")
|
||||
.into_raw(),
|
||||
CString::new(
|
||||
server
|
||||
.map(|host| host.to_string())
|
||||
.unwrap_or_else(|| "".to_string()),
|
||||
)
|
||||
.expect("CString should build properly from a String nameserver")
|
||||
.into_raw(),
|
||||
let url = CString::new(url.to_string())
|
||||
.expect("CString should build properly from a valid Url")
|
||||
.into_raw();
|
||||
let server = CString::new(
|
||||
server
|
||||
.map(|host| host.to_string())
|
||||
.unwrap_or_else(|| "".to_string()),
|
||||
)
|
||||
.expect("CString should build properly from a String nameserver")
|
||||
.into_raw();
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_dns_discovery(
|
||||
url,
|
||||
server,
|
||||
timeout
|
||||
.map(|timeout| {
|
||||
timeout
|
||||
@ -35,13 +37,12 @@ pub fn waku_dns_discovery(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
);
|
||||
// Recover strings and drop them
|
||||
drop(CString::from_raw(url));
|
||||
drop(CString::from_raw(server));
|
||||
res
|
||||
};
|
||||
|
||||
let response: JsonResponse<Vec<Multiaddr>> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
response.into()
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
@ -1,13 +1,14 @@
|
||||
//! Waku [filter](https://rfc.vac.dev/spec/36/#waku-filter) protocol related methods
|
||||
|
||||
// std
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ffi::CString;
|
||||
use std::time::Duration;
|
||||
// crates
|
||||
|
||||
// internal
|
||||
use crate::general::Result;
|
||||
use crate::general::{FilterSubscription, JsonResponse, PeerId};
|
||||
use crate::general::{FilterSubscription, PeerId};
|
||||
use crate::utils::decode_and_free_response;
|
||||
|
||||
/// Creates a subscription in a lightnode for messages that matches a content filter and optionally a [`WakuPubSubTopic`](`crate::general::WakuPubSubTopic`)
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_filter_subscribechar-filterjson-char-peerid-int-timeoutms)
|
||||
@ -16,30 +17,30 @@ pub fn waku_filter_subscribe(
|
||||
peer_id: PeerId,
|
||||
timeout: Duration,
|
||||
) -> Result<()> {
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_filter_subscribe(
|
||||
CString::new(
|
||||
serde_json::to_string(filter_subscription)
|
||||
.expect("FilterSubscription should always be able to be serialized"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized filter subscription")
|
||||
.into_raw(),
|
||||
CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw(),
|
||||
let filter_subscription_ptr = CString::new(
|
||||
serde_json::to_string(filter_subscription)
|
||||
.expect("FilterSubscription should always succeed to serialize"),
|
||||
)
|
||||
.expect("FilterSubscription should always be able to be serialized")
|
||||
.into_raw();
|
||||
let peer_id_ptr = CString::new(peer_id)
|
||||
.expect("PeerId should always be able to be serialized")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let result_ptr = waku_sys::waku_filter_subscribe(
|
||||
filter_subscription_ptr,
|
||||
peer_id_ptr,
|
||||
timeout
|
||||
.as_millis()
|
||||
.try_into()
|
||||
.expect("Duration as milliseconds should fit in a i32"),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let response: JsonResponse<bool> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
Result::from(response).map(|_| ())
|
||||
);
|
||||
drop(CString::from_raw(filter_subscription_ptr));
|
||||
drop(CString::from_raw(peer_id_ptr));
|
||||
result_ptr
|
||||
};
|
||||
decode_and_free_response::<bool>(result_ptr).map(|_| ())
|
||||
}
|
||||
|
||||
/// Removes subscriptions in a light node matching a content filter and, optionally, a [`WakuPubSubTopic`](`crate::general::WakuPubSubTopic`)
|
||||
@ -48,25 +49,23 @@ pub fn waku_filter_unsubscribe(
|
||||
filter_subscription: &FilterSubscription,
|
||||
timeout: Duration,
|
||||
) -> Result<()> {
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_filter_unsubscribe(
|
||||
CString::new(
|
||||
serde_json::to_string(filter_subscription)
|
||||
.expect("FilterSubscription should always be able to be serialized"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized filter subscription")
|
||||
.into_raw(),
|
||||
let filter_subscription_ptr = CString::new(
|
||||
serde_json::to_string(filter_subscription)
|
||||
.expect("FilterSubscription should always succeed to serialize"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized filter subscription")
|
||||
.into_raw();
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_filter_unsubscribe(
|
||||
filter_subscription_ptr,
|
||||
timeout
|
||||
.as_millis()
|
||||
.try_into()
|
||||
.expect("Duration as milliseconds should fit in a i32"),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
);
|
||||
drop(CString::from_raw(filter_subscription_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let response: JsonResponse<bool> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
Result::from(response).map(|_| ())
|
||||
decode_and_free_response::<bool>(result_ptr).map(|_| ())
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
//! Waku [lightpush](https://rfc.vac.dev/spec/36/#waku-lightpush) protocol related methods
|
||||
|
||||
// std
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ffi::CString;
|
||||
use std::time::Duration;
|
||||
// crates
|
||||
use aes_gcm::{Aes256Gcm, Key};
|
||||
use secp256k1::{PublicKey, SecretKey};
|
||||
// internal
|
||||
use crate::general::{JsonResponse, MessageId, PeerId, Result, WakuMessage, WakuPubSubTopic};
|
||||
use crate::general::{MessageId, PeerId, Result, WakuMessage, WakuPubSubTopic};
|
||||
use crate::node::waku_dafault_pubsub_topic;
|
||||
use crate::utils::decode_and_free_response;
|
||||
|
||||
/// Publish a message using Waku Lightpush
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_lightpush_publishchar-messagejson-char-topic-char-peerid-int-timeoutms)
|
||||
@ -21,20 +22,23 @@ pub fn waku_lightpush_publish(
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_lightpush_publish(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw(),
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
let peer_id_ptr = CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw();
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_lightpush_publish(
|
||||
message_ptr,
|
||||
topic_ptr,
|
||||
peer_id_ptr,
|
||||
timeout
|
||||
.map(|timeout| {
|
||||
timeout
|
||||
@ -43,15 +47,14 @@ pub fn waku_lightpush_publish(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(topic_ptr));
|
||||
drop(CString::from_raw(peer_id_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let response: JsonResponse<MessageId> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
response.into()
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
||||
/// Optionally sign, encrypt using asymmetric encryption and publish a message using Waku Lightpush
|
||||
@ -71,26 +74,32 @@ pub fn waku_lightpush_publish_encrypt_asymmetric(
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_lightpush_publish_enc_asymmetric(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw(),
|
||||
CString::new(pk)
|
||||
.expect("CString should build properly from hex encoded public key")
|
||||
.into_raw(),
|
||||
CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw(),
|
||||
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
let peer_id_ptr = CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw();
|
||||
let pk_ptr = CString::new(pk)
|
||||
.expect("CString should build properly from hex encoded public key")
|
||||
.into_raw();
|
||||
let sk_ptr = CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw();
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_lightpush_publish_enc_asymmetric(
|
||||
message_ptr,
|
||||
pubsub_topic_ptr,
|
||||
peer_id_ptr,
|
||||
pk_ptr,
|
||||
sk_ptr,
|
||||
timeout
|
||||
.map(|timeout| {
|
||||
timeout
|
||||
@ -99,13 +108,16 @@ pub fn waku_lightpush_publish_encrypt_asymmetric(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str")
|
||||
);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
drop(CString::from_raw(peer_id_ptr));
|
||||
drop(CString::from_raw(pk_ptr));
|
||||
drop(CString::from_raw(sk_ptr));
|
||||
res
|
||||
};
|
||||
let message_id: JsonResponse<MessageId> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
message_id.into()
|
||||
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
||||
/// Optionally sign, encrypt using symmetric encryption and publish a message using Waku Lightpush
|
||||
@ -125,26 +137,31 @@ pub fn waku_lightpush_publish_encrypt_symmetric(
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_lightpush_publish_enc_symmetric(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw(),
|
||||
CString::new(symk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw(),
|
||||
CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw(),
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
let peer_id_ptr = CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw();
|
||||
let symk_ptr = CString::new(symk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw();
|
||||
let sk_ptr = CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw();
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_lightpush_publish_enc_symmetric(
|
||||
message_ptr,
|
||||
pubsub_topic_ptr,
|
||||
peer_id_ptr,
|
||||
symk_ptr,
|
||||
sk_ptr,
|
||||
timeout
|
||||
.map(|timeout| {
|
||||
timeout
|
||||
@ -153,11 +170,14 @@ pub fn waku_lightpush_publish_encrypt_symmetric(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str")
|
||||
);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
drop(CString::from_raw(peer_id_ptr));
|
||||
drop(CString::from_raw(symk_ptr));
|
||||
drop(CString::from_raw(sk_ptr));
|
||||
res
|
||||
};
|
||||
let message_id: JsonResponse<MessageId> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
message_id.into()
|
||||
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
@ -7,75 +7,99 @@ use std::ffi::{CStr, CString};
|
||||
// internal
|
||||
use super::config::WakuNodeConfig;
|
||||
use crate::general::{JsonResponse, PeerId, Result};
|
||||
use crate::utils::decode_and_free_response;
|
||||
|
||||
/// Instantiates a Waku node
|
||||
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_newchar-jsonconfig)
|
||||
pub fn waku_new(config: Option<WakuNodeConfig>) -> Result<bool> {
|
||||
let config = config.unwrap_or_default();
|
||||
let s_config = serde_json::to_string(&config)
|
||||
.expect("Serialization from properly built NodeConfig should never fail");
|
||||
let result: &str = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_new(
|
||||
CString::new(s_config)
|
||||
.expect("CString should build properly from the serialized node config")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let config_ptr = CString::new(
|
||||
serde_json::to_string(&config)
|
||||
.expect("Serialization from properly built NodeConfig should never fail"),
|
||||
)
|
||||
.expect("CString should build properly from the config")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_new(config_ptr);
|
||||
drop(CString::from_raw(config_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let result = unsafe { CStr::from_ptr(result_ptr) }
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let json_response: JsonResponse<bool> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(result_ptr);
|
||||
}
|
||||
|
||||
json_response.into()
|
||||
}
|
||||
|
||||
/// Start a Waku node mounting all the protocols that were enabled during the Waku node instantiation.
|
||||
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_start)
|
||||
pub fn waku_start() -> Result<bool> {
|
||||
let response = unsafe { CStr::from_ptr(waku_sys::waku_start()) }
|
||||
let response_ptr = unsafe { waku_sys::waku_start() };
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let json_response: JsonResponse<bool> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
json_response.into()
|
||||
}
|
||||
|
||||
/// Stops a Waku node
|
||||
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_stop)
|
||||
pub fn waku_stop() -> Result<bool> {
|
||||
let response = unsafe { CStr::from_ptr(waku_sys::waku_stop()) }
|
||||
let response_ptr = unsafe { waku_sys::waku_stop() };
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let json_response: JsonResponse<bool> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
json_response.into()
|
||||
}
|
||||
|
||||
/// If the execution is successful, the result is the peer ID as a string (base58 encoded)
|
||||
/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_stop)
|
||||
pub fn waku_peer_id() -> Result<PeerId> {
|
||||
let response = unsafe { CStr::from_ptr(waku_sys::waku_peerid()) }
|
||||
let response_ptr = unsafe { waku_sys::waku_peerid() };
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let json_response: JsonResponse<String> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
json_response.into()
|
||||
}
|
||||
|
||||
/// Get the multiaddresses the Waku node is listening to
|
||||
/// as per [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_listen_addresses)
|
||||
pub fn waku_listen_addresses() -> Result<Vec<Multiaddr>> {
|
||||
let response = unsafe { CStr::from_ptr(waku_sys::waku_listen_addresses()) }
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let json_response: JsonResponse<Vec<Multiaddr>> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
json_response.into()
|
||||
let response_ptr = unsafe { waku_sys::waku_listen_addresses() };
|
||||
decode_and_free_response(response_ptr)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -126,7 +126,7 @@ impl WakuNodeHandle<Running> {
|
||||
/// The peer must be already known.
|
||||
/// It must have been added before with [`WakuNodeHandle::add_peer`] or previously dialed with [`WakuNodeHandle::connect_peer_with_address`]
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_connect_peeridchar-peerid-int-timeoutms)
|
||||
pub fn connect_peer_with_id(&self, peer_id: PeerId, timeout: Option<Duration>) -> Result<()> {
|
||||
pub fn connect_peer_with_id(&self, peer_id: &PeerId, timeout: Option<Duration>) -> Result<()> {
|
||||
peers::waku_connect_peer_with_id(peer_id, timeout)
|
||||
}
|
||||
|
||||
|
@ -8,26 +8,36 @@ use multiaddr::Multiaddr;
|
||||
use serde::Deserialize;
|
||||
// internal
|
||||
use crate::general::{JsonResponse, PeerId, ProtocolId, Result};
|
||||
use crate::utils::decode_and_free_response;
|
||||
|
||||
/// Add a node multiaddress and protocol to the waku node’s peerstore.
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_add_peerchar-address-char-protocolid)
|
||||
pub fn waku_add_peers(address: &Multiaddr, protocol_id: ProtocolId) -> Result<PeerId> {
|
||||
let response = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_add_peer(
|
||||
CString::new(address.to_string())
|
||||
.expect("CString should build properly from the address")
|
||||
.into_raw(),
|
||||
CString::new(protocol_id.to_string())
|
||||
.expect("CString should build properly from the protocol id")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
let address_ptr = CString::new(address.to_string())
|
||||
.expect("CString should build properly from the address")
|
||||
.into_raw();
|
||||
let protocol_id_ptr = CString::new(protocol_id.to_string())
|
||||
.expect("CString should build properly from the protocol id")
|
||||
.into_raw();
|
||||
|
||||
let response_ptr = unsafe {
|
||||
let res = waku_sys::waku_add_peer(address_ptr, protocol_id_ptr);
|
||||
drop(CString::from_raw(address_ptr));
|
||||
drop(CString::from_raw(protocol_id_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
|
||||
let result: JsonResponse<PeerId> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
result.into()
|
||||
}
|
||||
|
||||
@ -40,22 +50,31 @@ pub fn waku_connect_peer_with_address(
|
||||
address: &Multiaddr,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<()> {
|
||||
let response = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_connect(
|
||||
CString::new(address.to_string())
|
||||
.expect("CString should build properly from multiaddress")
|
||||
.into_raw(),
|
||||
let address_ptr = CString::new(address.to_string())
|
||||
.expect("CString should build properly from multiaddress")
|
||||
.into_raw();
|
||||
let response_ptr = unsafe {
|
||||
let res = waku_sys::waku_connect(
|
||||
address_ptr,
|
||||
timeout
|
||||
.map(|duration| duration.as_millis().try_into().unwrap_or(i32::MAX))
|
||||
.unwrap_or(0),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
);
|
||||
drop(CString::from_raw(address_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
|
||||
let result: JsonResponse<bool> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
Result::from(result).map(|_| ())
|
||||
}
|
||||
|
||||
@ -64,55 +83,77 @@ pub fn waku_connect_peer_with_address(
|
||||
/// The peer must be already known.
|
||||
/// It must have been added before with [`waku_add_peers`] or previously dialed with [`waku_connect_peer_with_address`]
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_connect_peeridchar-peerid-int-timeoutms)
|
||||
pub fn waku_connect_peer_with_id(peer_id: PeerId, timeout: Option<Duration>) -> Result<()> {
|
||||
let response = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_connect_peerid(
|
||||
CString::new(peer_id)
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw(),
|
||||
pub fn waku_connect_peer_with_id(peer_id: &PeerId, timeout: Option<Duration>) -> Result<()> {
|
||||
let peer_id_ptr = CString::new(peer_id.as_bytes())
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw();
|
||||
let response_ptr = unsafe {
|
||||
let res = waku_sys::waku_connect_peerid(
|
||||
peer_id_ptr,
|
||||
timeout
|
||||
.map(|duration| duration.as_millis().try_into().unwrap_or(i32::MAX))
|
||||
.unwrap_or(0),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
);
|
||||
drop(CString::from_raw(peer_id_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
|
||||
let result: JsonResponse<bool> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
Result::from(result).map(|_| ())
|
||||
}
|
||||
|
||||
/// Disconnect a peer using its peer id
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_disconnect_peerchar-peerid)
|
||||
pub fn waku_disconnect_peer_with_id(peer_id: &PeerId) -> Result<()> {
|
||||
let response = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_disconnect(
|
||||
CString::new(peer_id.as_bytes())
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
let peer_id_ptr = CString::new(peer_id.as_bytes())
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw();
|
||||
|
||||
let response_ptr = unsafe {
|
||||
let res = waku_sys::waku_disconnect(peer_id_ptr);
|
||||
drop(CString::from_raw(peer_id_ptr));
|
||||
res
|
||||
};
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
|
||||
let result: JsonResponse<bool> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
Result::from(result).map(|_| ())
|
||||
}
|
||||
|
||||
/// Get number of connected peers
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_peer_count)
|
||||
pub fn waku_peer_count() -> Result<usize> {
|
||||
let response = unsafe { CStr::from_ptr(waku_sys::waku_peer_cnt()) }
|
||||
let response_ptr = unsafe { waku_sys::waku_peer_cnt() };
|
||||
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
|
||||
let result: JsonResponse<usize> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
result.into()
|
||||
}
|
||||
|
||||
@ -164,14 +205,8 @@ pub type WakuPeers = Vec<WakuPeerData>;
|
||||
/// Retrieve the list of peers known by the Waku node
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_peers)
|
||||
pub fn waku_peers() -> Result<WakuPeers> {
|
||||
let response = unsafe { CStr::from_ptr(waku_sys::waku_peers()) }
|
||||
.to_str()
|
||||
.expect("&str should build properly from the returning response");
|
||||
|
||||
let result: JsonResponse<WakuPeers> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
result.into()
|
||||
let response_ptr = unsafe { waku_sys::waku_peers() };
|
||||
decode_and_free_response(response_ptr)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -10,6 +10,7 @@ use secp256k1::{PublicKey, SecretKey};
|
||||
use crate::general::{
|
||||
Encoding, JsonResponse, MessageId, Result, WakuContentTopic, WakuMessage, WakuPubSubTopic,
|
||||
};
|
||||
use crate::utils::decode_and_free_response;
|
||||
|
||||
/// Create a content topic according to [RFC 23](https://rfc.vac.dev/spec/23/)
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_content_topicchar-applicationname-unsigned-int-applicationversion-char-contenttopicname-char-encoding)
|
||||
@ -19,54 +20,83 @@ pub fn waku_create_content_topic(
|
||||
content_topic_name: &str,
|
||||
encoding: Encoding,
|
||||
) -> WakuContentTopic {
|
||||
unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_content_topic(
|
||||
CString::new(application_name)
|
||||
.expect("Application name should always transform to CString")
|
||||
.into_raw(),
|
||||
application_version
|
||||
.try_into()
|
||||
.expect("Version should fit within an u32"),
|
||||
CString::new(content_topic_name)
|
||||
.expect("Content topic should always transform to CString")
|
||||
.into_raw(),
|
||||
CString::new(encoding.to_string())
|
||||
.expect("Encoding should always transform to CString")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("&str from result should always be extracted")
|
||||
.parse()
|
||||
.expect("Content topic data should be always parseable")
|
||||
let application_name_ptr = CString::new(application_name)
|
||||
.expect("Application name should always transform to CString")
|
||||
.into_raw();
|
||||
let application_version = application_version
|
||||
.try_into()
|
||||
.expect("Version should fit within an u32");
|
||||
let content_topic_name_ptr = CString::new(content_topic_name)
|
||||
.expect("Content topic should always transform to CString")
|
||||
.into_raw();
|
||||
let encoding_ptr = CString::new(encoding.to_string())
|
||||
.expect("Encoding should always transform to CString")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_content_topic(
|
||||
application_name_ptr,
|
||||
application_version,
|
||||
content_topic_name_ptr,
|
||||
encoding_ptr,
|
||||
);
|
||||
drop(CString::from_raw(application_name_ptr));
|
||||
drop(CString::from_raw(content_topic_name_ptr));
|
||||
drop(CString::from_raw(encoding_ptr));
|
||||
res
|
||||
};
|
||||
let result = unsafe { CStr::from_ptr(result_ptr) }
|
||||
.to_str()
|
||||
.expect("&str from result should always be extracted")
|
||||
.parse()
|
||||
.expect("Content topic data should be always parseable");
|
||||
|
||||
unsafe { waku_sys::waku_utils_free(result_ptr) };
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Create a pubsub topic according to [RFC 23](https://rfc.vac.dev/spec/23/)
|
||||
/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_pubsub_topicchar-name-char-encoding)
|
||||
pub fn waku_create_pubsub_topic(topic_name: &str, encoding: Encoding) -> WakuPubSubTopic {
|
||||
unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_pubsub_topic(
|
||||
CString::new(topic_name)
|
||||
.expect("Topic name should always transform to CString")
|
||||
.into_raw(),
|
||||
CString::new(encoding.to_string())
|
||||
.expect("Encoding should always transform to CString")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("&str from result should always be extracted")
|
||||
.parse()
|
||||
.expect("Pubsub topic data should be always parseable")
|
||||
let topic_name_ptr = CString::new(topic_name)
|
||||
.expect("Topic name should always transform to CString")
|
||||
.into_raw();
|
||||
let encoding_ptr = CString::new(encoding.to_string())
|
||||
.expect("Encoding should always transform to CString")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_pubsub_topic(topic_name_ptr, encoding_ptr);
|
||||
drop(CString::from_raw(topic_name_ptr));
|
||||
drop(CString::from_raw(encoding_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let result = unsafe { CString::from_raw(result_ptr) }
|
||||
.to_str()
|
||||
.expect("&str from result should always be extracted")
|
||||
.parse()
|
||||
.expect("Pubsub topic data should be always parseable");
|
||||
|
||||
unsafe { waku_sys::waku_utils_free(result_ptr) };
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Default pubsub topic used for exchanging waku messages defined in [RFC 10](https://rfc.vac.dev/spec/10/)
|
||||
pub fn waku_dafault_pubsub_topic() -> WakuPubSubTopic {
|
||||
unsafe { CStr::from_ptr(waku_sys::waku_default_pubsub_topic()) }
|
||||
let result_ptr = unsafe { waku_sys::waku_default_pubsub_topic() };
|
||||
|
||||
let result = unsafe { CString::from_raw(result_ptr) }
|
||||
.to_str()
|
||||
.expect("&str from result should always be extracted")
|
||||
.parse()
|
||||
.expect("Default pubsub topic should always be parseable")
|
||||
.expect("Default pubsub topic should always be parseable");
|
||||
|
||||
unsafe { waku_sys::waku_utils_free(result_ptr) };
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Publish a message using Waku Relay
|
||||
@ -79,17 +109,21 @@ pub fn waku_relay_publish_message(
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_relay_publish(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_relay_publish(
|
||||
message_ptr,
|
||||
pubsub_topic_ptr,
|
||||
timeout
|
||||
.map(|duration| {
|
||||
duration
|
||||
@ -98,13 +132,13 @@ pub fn waku_relay_publish_message(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("&str from result should always be extracted");
|
||||
let message_id: JsonResponse<MessageId> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
message_id.into()
|
||||
);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
||||
/// Optionally sign, encrypt using asymmetric encryption and publish a message using Waku Relay
|
||||
@ -123,23 +157,29 @@ pub fn waku_relay_publish_encrypt_asymmetric(
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_relay_publish_enc_asymmetric(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
CString::new(pk)
|
||||
.expect("CString should build properly from hex encoded public key")
|
||||
.into_raw(),
|
||||
CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw(),
|
||||
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
let pk_ptr = CString::new(pk)
|
||||
.expect("CString should build properly from hex encoded public key")
|
||||
.into_raw();
|
||||
let sk_ptr = CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_relay_publish_enc_asymmetric(
|
||||
message_ptr,
|
||||
pubsub_topic_ptr,
|
||||
pk_ptr,
|
||||
sk_ptr,
|
||||
timeout
|
||||
.map(|timeout| {
|
||||
timeout
|
||||
@ -148,13 +188,15 @@ pub fn waku_relay_publish_encrypt_asymmetric(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str")
|
||||
);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
drop(CString::from_raw(pk_ptr));
|
||||
drop(CString::from_raw(sk_ptr));
|
||||
res
|
||||
};
|
||||
let message_id: JsonResponse<MessageId> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
message_id.into()
|
||||
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
||||
/// Optionally sign, encrypt using symmetric encryption and publish a message using Waku Relay
|
||||
@ -173,23 +215,29 @@ pub fn waku_relay_publish_encrypt_symmetric(
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_relay_publish_enc_symmetric(
|
||||
CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw(),
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
CString::new(symk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw(),
|
||||
CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw(),
|
||||
|
||||
let message_ptr = CString::new(
|
||||
serde_json::to_string(&message)
|
||||
.expect("WakuMessages should always be able to success serializing"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized waku message")
|
||||
.into_raw();
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
let symk_ptr = CString::new(symk)
|
||||
.expect("CString should build properly from hex encoded symmetric key")
|
||||
.into_raw();
|
||||
let sk_ptr = CString::new(sk)
|
||||
.expect("CString should build properly from hex encoded signing key")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_relay_publish_enc_symmetric(
|
||||
message_ptr,
|
||||
pubsub_topic_ptr,
|
||||
symk_ptr,
|
||||
sk_ptr,
|
||||
timeout
|
||||
.map(|timeout| {
|
||||
timeout
|
||||
@ -198,30 +246,41 @@ pub fn waku_relay_publish_encrypt_symmetric(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str")
|
||||
);
|
||||
drop(CString::from_raw(message_ptr));
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
drop(CString::from_raw(symk_ptr));
|
||||
drop(CString::from_raw(sk_ptr));
|
||||
res
|
||||
};
|
||||
let message_id: JsonResponse<MessageId> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
message_id.into()
|
||||
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
||||
pub fn waku_enough_peers(pubsub_topic: Option<WakuPubSubTopic>) -> Result<bool> {
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_relay_enough_peers(
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_relay_enough_peers(pubsub_topic_ptr);
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let result = unsafe { CStr::from_ptr(result_ptr) }
|
||||
.to_str()
|
||||
.expect("&str from result should always be extracted");
|
||||
|
||||
let enough_peers: JsonResponse<bool> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe { waku_sys::waku_utils_free(result_ptr) };
|
||||
|
||||
enough_peers.into()
|
||||
}
|
||||
|
||||
@ -229,34 +288,34 @@ pub fn waku_relay_subscribe(pubsub_topic: Option<WakuPubSubTopic>) -> Result<()>
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_relay_subscribe(
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
let enough_peers: JsonResponse<bool> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
Result::from(enough_peers).map(|_| ())
|
||||
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_relay_subscribe(pubsub_topic_ptr);
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
decode_and_free_response::<bool>(result_ptr).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn waku_relay_unsubscribe(pubsub_topic: Option<WakuPubSubTopic>) -> Result<()> {
|
||||
let pubsub_topic = pubsub_topic
|
||||
.unwrap_or_else(waku_dafault_pubsub_topic)
|
||||
.to_string();
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_relay_unsubscribe(
|
||||
CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw(),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
let enough_peers: JsonResponse<bool> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
Result::from(enough_peers).map(|_| ())
|
||||
|
||||
let pubsub_topic_ptr = CString::new(pubsub_topic)
|
||||
.expect("CString should build properly from pubsub topic")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_relay_unsubscribe(pubsub_topic_ptr);
|
||||
drop(CString::from_raw(pubsub_topic_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
decode_and_free_response::<bool>(result_ptr).map(|_| ())
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
//! Waku [store](https://rfc.vac.dev/spec/36/#waku-store) handling methods
|
||||
|
||||
// std
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::ffi::CString;
|
||||
use std::time::Duration;
|
||||
// crates
|
||||
// internal
|
||||
use crate::general::{JsonResponse, PeerId, Result, StoreQuery, StoreResponse};
|
||||
use crate::general::{PeerId, Result, StoreQuery, StoreResponse};
|
||||
use crate::utils::decode_and_free_response;
|
||||
|
||||
/// Retrieves historical messages on specific content topics. This method may be called with [`PagingOptions`](`crate::general::PagingOptions`),
|
||||
/// to retrieve historical messages on a per-page basis. If the request included [`PagingOptions`](`crate::general::PagingOptions`),
|
||||
@ -16,17 +17,19 @@ pub fn waku_store_query(
|
||||
peer_id: &PeerId,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<StoreResponse> {
|
||||
let result = unsafe {
|
||||
CStr::from_ptr(waku_sys::waku_store_query(
|
||||
CString::new(
|
||||
serde_json::to_string(query)
|
||||
.expect("StoreQuery should always be able to be serialized"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized filter subscription")
|
||||
.into_raw(),
|
||||
CString::new(peer_id.clone())
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw(),
|
||||
let query_ptr = CString::new(
|
||||
serde_json::to_string(query).expect("StoreQuery should always be able to be serialized"),
|
||||
)
|
||||
.expect("CString should build properly from the serialized filter subscription")
|
||||
.into_raw();
|
||||
let peer_id_ptr = CString::new(peer_id.clone())
|
||||
.expect("CString should build properly from peer id")
|
||||
.into_raw();
|
||||
|
||||
let result_ptr = unsafe {
|
||||
let res = waku_sys::waku_store_query(
|
||||
query_ptr,
|
||||
peer_id_ptr,
|
||||
timeout
|
||||
.map(|timeout| {
|
||||
timeout
|
||||
@ -35,12 +38,11 @@ pub fn waku_store_query(
|
||||
.expect("Duration as milliseconds should fit in a i32")
|
||||
})
|
||||
.unwrap_or(0),
|
||||
))
|
||||
}
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
);
|
||||
drop(CString::from_raw(query_ptr));
|
||||
drop(CString::from_raw(peer_id_ptr));
|
||||
res
|
||||
};
|
||||
|
||||
let response: JsonResponse<StoreResponse> =
|
||||
serde_json::from_str(result).expect("JsonResponse should always succeed to deserialize");
|
||||
response.into()
|
||||
decode_and_free_response(result_ptr)
|
||||
}
|
||||
|
20
waku-bindings/src/utils.rs
Normal file
20
waku-bindings/src/utils.rs
Normal file
@ -0,0 +1,20 @@
|
||||
use crate::general::{JsonResponse, Result};
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::ffi::{c_char, CStr};
|
||||
|
||||
/// Safety: The caller is responsible for ensuring that the pointer is valid for the duration of the call.
|
||||
/// This takes a pointer to a C string coming from the waku lib, that data is consumed and then freed using [`waku_sys::waku_utils_free`].
|
||||
pub fn decode_and_free_response<T: DeserializeOwned>(response_ptr: *mut c_char) -> Result<T> {
|
||||
let response = unsafe { CStr::from_ptr(response_ptr) }
|
||||
.to_str()
|
||||
.expect("Response should always succeed to load to a &str");
|
||||
|
||||
let response: JsonResponse<T> =
|
||||
serde_json::from_str(response).expect("JsonResponse should always succeed to deserialize");
|
||||
|
||||
unsafe {
|
||||
waku_sys::waku_utils_free(response_ptr);
|
||||
}
|
||||
|
||||
response.into()
|
||||
}
|
@ -162,7 +162,7 @@ async fn discv5_echo() -> Result<(), String> {
|
||||
for node_address in NODES {
|
||||
let address: Multiaddr = node_address.parse().unwrap();
|
||||
let peer_id = node.add_peer(&address, ProtocolId::Relay)?;
|
||||
node.connect_peer_with_id(peer_id, None)?;
|
||||
node.connect_peer_with_id(&peer_id, None)?;
|
||||
}
|
||||
|
||||
assert!(node.peers()?.len() >= NODES.len());
|
||||
@ -213,7 +213,7 @@ async fn default_echo() -> Result<(), String> {
|
||||
for node_address in NODES {
|
||||
let address: Multiaddr = node_address.parse().unwrap();
|
||||
let peer_id = node.add_peer(&address, ProtocolId::Relay)?;
|
||||
node.connect_peer_with_id(peer_id, None)?;
|
||||
node.connect_peer_with_id(&peer_id, None)?;
|
||||
}
|
||||
|
||||
assert!(node.peers()?.len() >= NODES.len());
|
||||
|
Loading…
x
Reference in New Issue
Block a user