As we started to define the Waku API and the work for the Chat SDK, we began to see that some “Waku Application SDK” would need to be defined.
We identified that SDS, segmentation and rate limit manager would be good tools for any developers. However, they did not fit in the Waku API: They are application level matters, whereas the Waku API sits in message routing and peer discovery domains.
Moreover, one may want to use those blocks without the opinionated encryption mechanisms of the Chat SDK. Justifying the need for such API.
This Application SDK and layers were previously discussed in:
- Private Chat SDK: Roadmap Skeleton
- API Specification for End-to-end Reliability - #9 by fryorcraken (reliability api)
The explicit definition of an API remains in line with our previous learnings here: Prometheus, REST and FFI: Using APIs as common language - #10 by fryorcraken
Finally, I often used this blog post as a reference for the layered architecture of Waku. This present post supersedes it.
This is the result of many discussions with the Waku app chat team @pablo @kaichao @jazzz, as well as my own experimentations with Reliable Channels (JS) and the Waku API.
Waku’s layered architecture
I propose a new definition of Waku’s architecture:
block-beta
columns 4
sc["Secure Conversations (Chat SDK)"]:4
e["Encryption"]:1
rc["Reliable Channels"]:3
space:1
block:reliablechannels:3
columns 1
sg["Segmentation"]:1
sds["Scalable Data Sync"]:1
enc["Encrypt/Decrypt"]:1
rlm["Rate Limit Manager"]:1
end
e --> enc
P2PReliability["P2P Reliability (Waku API)"]:4
block:wakuapi:4
columns 7
RLNRelay["RLN Relay"]:1
Store["Store"]:1
Lightpush["Lightpush"]:1
Filter["Filter"]:1
Discv5["Waku Discv5"]:1
PeerExchange["Peer Exchange"]:1
PeerManager["Peer Manager"]:1
end
block:libp2p:4
P2PEncryption["Point-to-Point Encryption"]
Multiplexer["Multiplexer"]
Transport["Transport"]
end
block:base:4
UDP["UDP"]
TCP["TCP/IP"]
end
classDef borrowed fill:#e1f5ff,stroke:#0066cc,stroke-width:2px,stroke-dasharray: 5 5
class enc borrowed
- At the top is the secure conversation part of the Chat SDK. I am still unclear on how some parts fit between status-go and the chat SDK, such as identity. Further discussions, explorations and work may be needed here.
- Secure conversations leverage reliable channels and some specific encryption mechanisms. The encryption mechanisms are the core USPs for the Chat SDK, in addition to using Waku.
- Reliable channels is what we have loosely referred to as “Waku Application SDK” in the past. It is an opinionated layer on top of Waku that enables e2e reliability (SDS) with smooth handling of Waku restrictions: message size (segmentation) and RLN Relay (message rate limit manager).
Then, the Waku API remains as defined and enables an easy, foolproof way of using Waku with some p2p reliability mechanisms.
Reliable channels
The existing TypeScript implementation of reliable channel only implements the SDS wrapping part of this new API.
In nim, the various components are ready (sds, segmentation, rate limit manager). The reliable channel API intends to bring them together in a way that is easy to integrate when adding encryption.
Here is a spec draft for reliable channels, as defined in this new layered architecture: introduce reliable channel API by fryorcraken · Pull Request #89 · waku-org/specs · GitHub
And a Frankenstein, non-working implementation in js-waku: feat: Waku API's subscribe by fryorcraken · Pull Request #2683 · waku-org/js-waku · GitHub
(The implementation is blocked, and feedbacks, on the Waku API’s new send and subscribe functions.)
Segmentation
A decision that breaks away from Status’s current approach is the fact that segmentation is to be done within the encryption layer, instead of outside of it. See previous layers.
In Status protocol, messages are encrypted first, and then segmented. This means that segmentation can be seen by external observers.
But it also means more precise segmentation (no encryption overhead to plan, as encryption is already applied).
With the new ordering, we are segmenting a message first, then applying SDS, then encrypting.
The reason for that is to enable SDS to be applied to the message chunks, reducing potential retransmission of all chunks.
It does make the API slightly more complex (we expose the chunks to the API consumer). We could simplify the API by not exposing the chunks.
This proposal stems from the fact that Waku RLN Relay is rate limited, and we would want to avoid retransmission of all chunks when some are already acknowledged.
The downside is that encryption + RLN proof have to be predicted in the segmentation process, as they are done after segmentation (hence a proposal of 100KiB default size for chunks).
Another upside, though I’m not sure it matters, is that segmentation becomes hidden from external observers, preventing any correlation between messages.
Encryption
There may be a better name for this block and I defer to @jazzz to review.
Next steps
Feel free to review any of the pull requests referenced or discuss here.
As we progressed on the Chat SDK deliverables, we may want to do a checkpoint to confirm that the scopes currently defined still make sense.
As part of this review, we can add for 2025 H2, or 2026 H1, a specific deliverable that delivers this API in JS and Nim, to both ensure a strict and tidy boundary within the Chat SDK, and provide said API to all developers.
Finally, as we define the Waku API, we need to ensure it enables reliable channels, with reliable channels being the primary consumer of the Waku API moving forward for both JS and Nim.
Edit: diagram correction: sds wrapper wraps a plain payload, and itself is encrypted