After writing a small PoC extracting some functionality from Status (https://github.com/plopezlpz/chatsdk), we can plan some work to write private chat specifications, implement those and integrate that in Status. We want to build on top of the current Status specifications and implementation, improving it and making it reusable by other projects.

The scope for now is only for private chats (one-to-one and private groups), leaving aside communities.

Status and Private Messages

Waku provides a suite of protocols for peer discovery and message delivery. However, features such as end-to-end encryption (E2EE), reliability, and offline message recovery are left to the applications built on top of Waku. Many applications will benefit from a well-specified SDK that handles reliability and encryption, sparing developers from re-implementing these features from scratch.

In Status, a message’s payload is wrapped in multiple layers to support these features. We propose extracting part of this functionality into a separate repo. This repo would include clear specifications and offer SDKs first for Status and later for other projects, as depicted in the following diagram:

status connection-arnold(1).svg

The wrapping is how the current implementation works in status, the right hand side is the proposal of the new protocol API.

Considerations

While the diagram looks straightforward, it is important to note that the proposed API would require the SDK to manage some local storage and send auxiliary messages not directly triggered by the application. For instance, the DataSync feature will resend messages, and the E2EE module will automatically broadcast the node’s cryptographic bundle or request a peer’s bundle from a store node. These behaviors should be explicitly specified in the API documentation.

API Specification

Send

When the Application wants to send a message, it can provide several parameters: the payload bytes, the application type, a message ID, recipient information, and the desired content and pubsub topics. This design gives the application full control over the destination of the message—for example,

“I want to send hello to bob in shard /waku/1/my-content-topic/32.

Since the encryption layer may also send messages, it will determine the shards to be used for such transmissions. This can be configured separately. Currently, the application layer is responsible for signing messages before encryption; however, this responsibility could also be migrated to the SDK.

In summary, the SDK’s send function would accept a structure similar to the following:

// MessageToSend represents a message to be sent to a counterparty
message MessageToSend {
  // Content contains the message payload and metadata
  message Content {
    bytes payload = 1;
    int32 type = 2;
    string message_id = 3;
    repeated string waku_envelope_hashes = 4;
  }

  // CounterParty represents the recipient of the message
  message CounterParty {
    string chat_id = 1;
    bytes public_key = 2;
  }

  // SendConfig contains delivery and feature settings
  message SendConfig {
    string content_topic = 1;
    string pubsub_topic = 2;
    bool use_status_signature = 3;
    bool use_waku_message_v1 = 4;
    bool use_mvds = 5;
    bool use_e2ee = 6;
    bool use_segmentation = 7;
  }

  Content content = 1;
  CounterParty to = 2;
  SendConfig config = 3;
}

OnReceive and GetMessages

The application layer should be notified when new messages arrive after encryption. The following structure illustrates a possible implementation: