diff --git a/.gitignore b/.gitignore
index ab1dd7e..222982f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
/target
/Cargo.lock
-/.idea
\ No newline at end of file
+/.idea
+/.fleet
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index fe953e9..e424c95 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
[workspace]
members = [
- "waku",
+ "waku-bindings",
"waku-sys",
"examples/toy-chat"
]
\ No newline at end of file
diff --git a/README.md b/README.md
index 5605839..b816b31 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,35 @@
-# Waku Rust binding
+# Waku Rust bindings
-Rust layer on top of `go-waku` c ffi bindings.
\ No newline at end of file
+Rust layer on top of [`go-waku`](https://github.com/status-im/go-waku) [c ffi bindings](https://github.com/status-im/go-waku/blob/v0.2.2/library/README.md).
+
+
+## About [Waku](https://waku.org/)
+
+Waku is the communication layer for Web3. Decentralized communication that scales.
+
+Private. Secure. Runs anywhere.
+
+### What is Waku?
+
+Waku is a suite of privacy-preserving, peer-to-peer messaging protocols.
+
+Waku removes centralized third parties from messaging, enabling private, secure, censorship-free communication with no single point of failure.
+
+Waku provides privacy-preserving capabilities, such as sender anonymity,metadata protection and unlinkability to personally identifiable information.
+
+Waku is designed for generalized messaging, enabling human-to-human, machine-to-machine or hybrid communication.
+
+Waku runs everywhere: desktop, server, including resource-restricted devices, such as mobile devices and browsers.
+How does it work?
+
+The first version of Waku had its origins in the Whisper protocol, with optimizations for scalability and usability. Waku v2 is a complete rewrite. Its relay protocol implements pub/sub over libp2p, and also introduces additional capabilities:
+
+1. Retrieving historical messages for mostly-offline devices.
+2. Adaptive nodes, allowing for heterogeneous nodes to contribute.
+3. Bandwidth preservation for light nodes.
+
+This makes it ideal for running a p2p protocol on mobile, or in other similarly resource-restricted environments.
+
+
+
+Read the [Waku docs](https://docs.wakuconnect.dev/)
\ No newline at end of file
diff --git a/examples/toy-chat/Cargo.toml b/examples/toy-chat/Cargo.toml
index dbf4d95..acbbc68 100644
--- a/examples/toy-chat/Cargo.toml
+++ b/examples/toy-chat/Cargo.toml
@@ -8,7 +8,7 @@ authors = [
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-waku = { path = "../../waku" }
+waku = { path = "../../waku-bindings" }
tui = "0.19"
crossterm = "0.25"
unicode-width = "0.1"
diff --git a/waku-bindings/.cargo/config.toml b/waku-bindings/.cargo/config.toml
new file mode 100644
index 0000000..5bc05eb
--- /dev/null
+++ b/waku-bindings/.cargo/config.toml
@@ -0,0 +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"]
\ No newline at end of file
diff --git a/waku/Cargo.toml b/waku-bindings/Cargo.toml
similarity index 100%
rename from waku/Cargo.toml
rename to waku-bindings/Cargo.toml
diff --git a/waku-bindings/README.md b/waku-bindings/README.md
new file mode 100644
index 0000000..d5352c1
--- /dev/null
+++ b/waku-bindings/README.md
@@ -0,0 +1,50 @@
+# Waku Rust bindings
+
+[
](https://github.com/waku-org/waku-rust-bindings)
+[
](https://crates.io/crates/waku-rust-bindings)
+[
](https://docs.rs/waku-rust-bindings)
+[
](https://github.com/waku-org/waku-rust-bindings/actions?query=branch%3Amaster)
+
+Rust api on top of [`waku-sys`](https://crates.io/crates/waku-sys) bindgen bindings to [c ffi bindings](https://github.com/status-im/go-waku/blob/v0.2.2/library/README.md).
+
+
+## Usage
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+waku-bindings = "0.1.0"
+```
+
+
+## About [Waku](https://waku.org/)
+
+Waku is the communication layer for Web3. Decentralized communication that scales.
+
+Private. Secure. Runs anywhere.
+
+### What is Waku?
+
+Waku is a suite of privacy-preserving, peer-to-peer messaging protocols.
+
+Waku removes centralized third parties from messaging, enabling private, secure, censorship-free communication with no single point of failure.
+
+Waku provides privacy-preserving capabilities, such as sender anonymity,metadata protection and unlinkability to personally identifiable information.
+
+Waku is designed for generalized messaging, enabling human-to-human, machine-to-machine or hybrid communication.
+
+Waku runs everywhere: desktop, server, including resource-restricted devices, such as mobile devices and browsers.
+How does it work?
+
+The first version of Waku had its origins in the Whisper protocol, with optimizations for scalability and usability. Waku v2 is a complete rewrite. Its relay protocol implements pub/sub over libp2p, and also introduces additional capabilities:
+
+1. Retrieving historical messages for mostly-offline devices.
+2. Adaptive nodes, allowing for heterogeneous nodes to contribute.
+3. Bandwidth preservation for light nodes.
+
+This makes it ideal for running a p2p protocol on mobile, or in other similarly resource-restricted environments.
+
+
+
+Read the [Waku docs](https://docs.wakuconnect.dev/)
\ No newline at end of file
diff --git a/waku/src/decrypt.rs b/waku-bindings/src/decrypt.rs
similarity index 94%
rename from waku/src/decrypt.rs
rename to waku-bindings/src/decrypt.rs
index acf443c..466cc85 100644
--- a/waku/src/decrypt.rs
+++ b/waku-bindings/src/decrypt.rs
@@ -38,7 +38,7 @@ pub fn waku_decode_symmetric(
/// Decrypt a message using a symmetric key
///
-/// As per the [specification](extern char* waku_decode_asymmetric(char* messageJson, char* privateKey))
+/// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_decode_asymmetricchar-messagejson-char-privatekey)
pub fn waku_decode_asymmetric(
message: &WakuMessage,
asymmetric_key: &SecretKey,
diff --git a/waku/src/events/mod.rs b/waku-bindings/src/events/mod.rs
similarity index 100%
rename from waku/src/events/mod.rs
rename to waku-bindings/src/events/mod.rs
diff --git a/waku/src/general/mod.rs b/waku-bindings/src/general/mod.rs
similarity index 98%
rename from waku/src/general/mod.rs
rename to waku-bindings/src/general/mod.rs
index a152520..88cd56c 100644
--- a/waku/src/general/mod.rs
+++ b/waku-bindings/src/general/mod.rs
@@ -58,9 +58,9 @@ pub(crate) enum JsonResponse {
}
/// Waku response, just a `Result` with an `String` error.
-/// Convenient we can transform a [`JsonResponse`] into a [`std::result::Result`]
pub type Result = std::result::Result;
+/// Convenient we can transform a [`JsonResponse`] into a [`std::result::Result`]
impl From> for Result {
fn from(response: JsonResponse) -> Self {
match response {
@@ -127,14 +127,14 @@ impl WakuMessage {
/// Try decode the message with an expected symmetric key
///
- /// wrapper around [`crate::decrypt::waku_decode_symmetric`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_decode_symmetricchar-messagejson-char-symmetrickey)
pub fn try_decode_symmetric(&self, symmetric_key: &Key) -> Result {
waku_decode_symmetric(self, symmetric_key)
}
/// Try decode the message with an expected asymmetric key
///
- /// wrapper around [`crate::decrypt::waku_decode_asymmetric`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_decode_asymmetricchar-messagejson-char-privatekey)
pub fn try_decode_asymmetric(&self, asymmetric_key: &SecretKey) -> Result {
waku_decode_asymmetric(self, asymmetric_key)
}
diff --git a/waku/src/lib.rs b/waku-bindings/src/lib.rs
similarity index 100%
rename from waku/src/lib.rs
rename to waku-bindings/src/lib.rs
diff --git a/waku/src/node/config.rs b/waku-bindings/src/node/config.rs
similarity index 100%
rename from waku/src/node/config.rs
rename to waku-bindings/src/node/config.rs
diff --git a/waku/src/node/discovery.rs b/waku-bindings/src/node/discovery.rs
similarity index 100%
rename from waku/src/node/discovery.rs
rename to waku-bindings/src/node/discovery.rs
diff --git a/waku/src/node/filter.rs b/waku-bindings/src/node/filter.rs
similarity index 100%
rename from waku/src/node/filter.rs
rename to waku-bindings/src/node/filter.rs
diff --git a/waku/src/node/lightpush.rs b/waku-bindings/src/node/lightpush.rs
similarity index 100%
rename from waku/src/node/lightpush.rs
rename to waku-bindings/src/node/lightpush.rs
diff --git a/waku/src/node/management.rs b/waku-bindings/src/node/management.rs
similarity index 100%
rename from waku/src/node/management.rs
rename to waku-bindings/src/node/management.rs
diff --git a/waku/src/node/mod.rs b/waku-bindings/src/node/mod.rs
similarity index 73%
rename from waku/src/node/mod.rs
rename to waku-bindings/src/node/mod.rs
index 191c67b..4f247df 100644
--- a/waku/src/node/mod.rs
+++ b/waku-bindings/src/node/mod.rs
@@ -61,22 +61,19 @@ unsafe impl Sync for WakuNodeHandle {}
impl WakuNodeHandle {
/// If the execution is successful, the result is the peer ID as a string (base58 encoded)
- ///
- /// wrapper around [`management::waku_peer_id`]
+ /// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_stop)
pub fn peer_id(&self) -> Result {
management::waku_peer_id()
}
/// Get the multiaddresses the Waku node is listening to
- ///
- /// wrapper around [`management::waku_listen_addresses`]
+ /// as per [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_listen_addresses)
pub fn listen_addresses(&self) -> Result> {
management::waku_listen_addresses()
}
- /// Add a node multiaddress and protocol to the waku node’s peerstore
- ///
- /// wrapper around [`peers::waku_add_peers`]
+ /// 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 add_peer(&self, address: &Multiaddr, protocol_id: ProtocolId) -> Result {
peers::waku_add_peers(address, protocol_id)
}
@@ -91,16 +88,14 @@ fn stop_node() -> Result<()> {
}
impl WakuNodeHandle {
- /// Start a Waku node mounting all the protocols that were enabled during the Waku node instantiation
- ///
- /// wrapper around [`management::waku_start`]
+ /// 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 start(self) -> Result> {
management::waku_start().map(|_| WakuNodeHandle(Default::default()))
}
/// Stops a Waku node
- ///
- /// internally uses [`management::waku_stop`]
+ /// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_stop)
pub fn stop(self) -> Result<()> {
stop_node()
}
@@ -108,8 +103,7 @@ impl WakuNodeHandle {
impl WakuNodeHandle {
/// Stops a Waku node
- ///
- /// internally uses [`management::waku_stop`]
+ /// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_stop)
pub fn stop(self) -> Result<()> {
stop_node()
}
@@ -118,8 +112,7 @@ impl WakuNodeHandle {
/// If `timeout` as milliseconds doesn't fit into a `i32` it is clamped to [`i32::MAX`]
/// If the function execution takes longer than `timeout` value, the execution will be canceled and an error returned.
/// Use 0 for no timeout
- ///
- /// wrapper around [`peers::waku_connect_peer_with_address`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_connect_peerchar-address-int-timeoutms)
pub fn connect_peer_with_address(
&self,
address: &Multiaddr,
@@ -128,37 +121,35 @@ impl WakuNodeHandle {
peers::waku_connect_peer_with_address(address, timeout)
}
- /// Dial peer using its peer ID
- ///
- /// wrapper around [`peers::waku_connect_peer_with_id`]
+ /// Dial peer using a peer id
+ /// If `timeout` as milliseconds doesn't fit into a `i32` it is clamped to [`i32::MAX`]
+ /// 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) -> Result<()> {
peers::waku_connect_peer_with_id(peer_id, timeout)
}
- /// Disconnect a peer using its peerID
- ///
- /// wrapper around [`peers::waku_disconnect_peer_with_id`]
+ /// 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 disconnect_peer_with_id(&self, peer_id: &PeerId) -> Result<()> {
peers::waku_disconnect_peer_with_id(peer_id)
}
/// Get number of connected peers
- ///
- /// wrapper around [`peers::waku_peer_count`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_peer_count)
pub fn peer_count(&self) -> Result {
peers::waku_peer_count()
}
/// Retrieve the list of peers known by the Waku node
- ///
- /// wrapper around [`peers::waku_peers`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_peers)
pub fn peers(&self) -> Result {
peers::waku_peers()
}
/// Publish a message using Waku Relay
- ///
- /// wrapper around [`relay::waku_relay_publish_message`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_relay_publishchar-messagejson-char-pubsubtopic-int-timeoutms)
pub fn relay_publish_message(
&self,
message: &WakuMessage,
@@ -169,8 +160,7 @@ impl WakuNodeHandle {
}
/// Optionally sign, encrypt using asymmetric encryption and publish a message using Waku Relay
- ///
- /// wrapper around [`relay::waku_relay_publish_encrypt_asymmetric`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_relay_publish_enc_asymmetricchar-messagejson-char-pubsubtopic-char-publickey-char-optionalsigningkey-int-timeoutms)
pub fn relay_publish_encrypt_asymmetric(
&self,
message: &WakuMessage,
@@ -189,8 +179,7 @@ impl WakuNodeHandle {
}
/// Optionally sign, encrypt using symmetric encryption and publish a message using Waku Relay
- ///
- /// wrapper around [`relay::waku_relay_publish_encrypt_symmetric`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_relay_publish_enc_symmetricchar-messagejson-char-pubsubtopic-char-symmetrickey-char-optionalsigningkey-int-timeoutms)
pub fn relay_publish_encrypt_symmetric(
&self,
message: &WakuMessage,
@@ -209,29 +198,24 @@ impl WakuNodeHandle {
}
/// Determine if there are enough peers to publish a message on a given pubsub topic
- ///
- /// wrapper around [`relay::waku_enough_peers`]
pub fn relay_enough_peers(&self, pubsub_topic: Option) -> Result {
relay::waku_enough_peers(pubsub_topic)
}
/// Subscribe to a Waku Relay pubsub topic to receive messages
- ///
- /// wrapper around [`relay::waku_relay_subscribe`]
pub fn relay_subscribe(&self, pubsub_topic: Option) -> Result<()> {
relay::waku_relay_subscribe(pubsub_topic)
}
/// Closes the pubsub subscription to a pubsub topic. No more messages will be received from this pubsub topic
- ///
- /// wrapper around [`relay::waku_relay_unsubscribe`]
pub fn relay_unsubscribe(&self, pubsub_topic: Option) -> Result<()> {
relay::waku_relay_unsubscribe(pubsub_topic)
}
- /// Retrieves historical messages on specific content topics
- ///
- /// wrapper around [`store::waku_store_query`]
+ /// 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`),
+ /// the node must return messages on a per-page basis and include [`PagingOptions`](`crate::general::PagingOptions`) in the response.
+ /// These [`PagingOptions`](`crate::general::PagingOptions`) must contain a cursor pointing to the Index from which a new page can be requested
pub fn store_query(
&self,
query: &StoreQuery,
@@ -242,8 +226,7 @@ impl WakuNodeHandle {
}
/// Publish a message using Waku Lightpush
- ///
- /// wrapper around [`lightpush::waku_lightpush_publish`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_lightpush_publishchar-messagejson-char-topic-char-peerid-int-timeoutms)
pub fn lightpush_publish(
&self,
message: &WakuMessage,
@@ -255,8 +238,7 @@ impl WakuNodeHandle {
}
/// Optionally sign, encrypt using asymmetric encryption and publish a message using Waku Lightpush
- ///
- /// wrapper around [`lightpush::waku_lightpush_publish_encrypt_asymmetric`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_lightpush_publish_enc_asymmetricchar-messagejson-char-pubsubtopic-char-peerid-char-publickey-char-optionalsigningkey-int-timeoutms)
pub fn lightpush_publish_encrypt_asymmetric(
&self,
message: &WakuMessage,
@@ -277,8 +259,7 @@ impl WakuNodeHandle {
}
/// Optionally sign, encrypt using symmetric encryption and publish a message using Waku Lightpush
- ///
- /// wrapper around [`lightpush::waku_lightpush_publish_encrypt_symmetric`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_lightpush_publish_enc_symmetricchar-messagejson-char-pubsubtopic-char-peerid-char-symmetrickey-char-optionalsigningkey-int-timeoutms)
pub fn lightpush_publish_encrypt_symmetric(
&self,
message: &WakuMessage,
@@ -299,8 +280,7 @@ impl WakuNodeHandle {
}
/// Creates a subscription in a lightnode for messages that matches a content filter and optionally a [`WakuPubSubTopic`](`crate::general::WakuPubSubTopic`)
- ///
- /// wrapper around [`filter::waku_filter_subscribe`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_filter_subscribechar-filterjson-char-peerid-int-timeoutms)
pub fn filter_subscribe(
&self,
filter_subscription: &FilterSubscription,
@@ -311,8 +291,7 @@ impl WakuNodeHandle {
}
/// Removes subscriptions in a light node matching a content filter and, optionally, a [`WakuPubSubTopic`](`crate::general::WakuPubSubTopic`)
- ///
- /// wrapper around [`filter::waku_filter_unsubscribe`]
+ /// As per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_filter_unsubscribechar-filterjson-int-timeoutms)
pub fn filter_unsubscribe(
&self,
filter_subscription: &FilterSubscription,
@@ -331,8 +310,8 @@ impl WakuNodeHandle {
}
}
-/// Spawn a new Waku node with the givent configuration (default configuration if `None` provided)
-/// Internally uses [`management::waku_new`]
+/// Spawn a new Waku node with the given configuration (default configuration if `None` provided)
+/// as per the [specification](https://rfc.vac.dev/spec/36/#extern-char-waku_newchar-jsonconfig)
pub fn waku_new(config: Option) -> Result> {
let mut node_initialized = WAKU_NODE_INITIALIZED
.lock()
diff --git a/waku/src/node/peers.rs b/waku-bindings/src/node/peers.rs
similarity index 98%
rename from waku/src/node/peers.rs
rename to waku-bindings/src/node/peers.rs
index dcd7abb..2879cc8 100644
--- a/waku/src/node/peers.rs
+++ b/waku-bindings/src/node/peers.rs
@@ -158,7 +158,7 @@ impl WakuPeerData {
}
}
-/// List of [`WakuPeerData`], return value from [`waku_peers`] funtion
+/// List of [`WakuPeerData`]
pub type WakuPeers = Vec;
/// Retrieve the list of peers known by the Waku node
diff --git a/waku/src/node/relay.rs b/waku-bindings/src/node/relay.rs
similarity index 99%
rename from waku/src/node/relay.rs
rename to waku-bindings/src/node/relay.rs
index d6888ae..fc18092 100644
--- a/waku/src/node/relay.rs
+++ b/waku-bindings/src/node/relay.rs
@@ -28,7 +28,7 @@ pub fn waku_create_content_topic(
.try_into()
.expect("Version should fit within an u32"),
CString::new(content_topic_name)
- .expect("Conmtent topic should always transform to CString")
+ .expect("Content topic should always transform to CString")
.into_raw(),
CString::new(encoding.to_string())
.expect("Encoding should always transform to CString")
diff --git a/waku/src/node/store.rs b/waku-bindings/src/node/store.rs
similarity index 100%
rename from waku/src/node/store.rs
rename to waku-bindings/src/node/store.rs
diff --git a/waku/tests/node.rs b/waku-bindings/tests/node.rs
similarity index 100%
rename from waku/tests/node.rs
rename to waku-bindings/tests/node.rs
diff --git a/waku-sys/README.md b/waku-sys/README.md
new file mode 100644
index 0000000..941efbc
--- /dev/null
+++ b/waku-sys/README.md
@@ -0,0 +1,51 @@
+# Waku rust bindgen bindings
+
+[
](https://github.com/waku-org/waku-rust-bindings)
+[
](https://crates.io/crates/waku-rust-bindings)
+[
](https://docs.rs/waku-rust-bindings)
+[
](https://github.com/waku-org/waku-rust-bindings/actions?query=branch%3Amaster)
+
+Rust layer on top of [`go-waku`](https://github.com/status-im/go-waku) [c ffi bindings](https://github.com/status-im/go-waku/blob/v0.2.2/library/README.md).
+
+## Usage
+
+This are autogenerated, if you are looking for a proper Rust API version check on [`waku-bindings`](https://crates.io/crates/waku-bindings)
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies]
+waku-sys = "0.1.0"
+```
+
+
+## About [Waku](https://waku.org/)
+
+Waku is the communication layer for Web3. Decentralized communication that scales.
+
+Private. Secure. Runs anywhere.
+
+### What is Waku?
+
+Waku is a suite of privacy-preserving, peer-to-peer messaging protocols.
+
+Waku removes centralized third parties from messaging, enabling private, secure, censorship-free communication with no single point of failure.
+
+Waku provides privacy-preserving capabilities, such as sender anonymity,metadata protection and unlinkability to personally identifiable information.
+
+Waku is designed for generalized messaging, enabling human-to-human, machine-to-machine or hybrid communication.
+
+Waku runs everywhere: desktop, server, including resource-restricted devices, such as mobile devices and browsers.
+How does it work?
+
+The first version of Waku had its origins in the Whisper protocol, with optimizations for scalability and usability. Waku v2 is a complete rewrite. Its relay protocol implements pub/sub over libp2p, and also introduces additional capabilities:
+
+1. Retrieving historical messages for mostly-offline devices.
+2. Adaptive nodes, allowing for heterogeneous nodes to contribute.
+3. Bandwidth preservation for light nodes.
+
+This makes it ideal for running a p2p protocol on mobile, or in other similarly resource-restricted environments.
+
+
+
+Read the [Waku docs](https://docs.wakuconnect.dev/)
\ No newline at end of file