--- title: ADR-004 id: adr-004 displayed_sidebar: resourcesSidebar --- - **Author(s):** [Prad Nukala](https://github.com/prnk28) - **Last Updated:** June 21, 2022 - **Status:** Draft - **Deployment:** `integrate/adr-004` # ADR-004: Realtime Data Channels [![hackmd-github-sync-badge](https://hackmd.io/iomfscGXR1ycI_67NrLvMw/badge)](https://hackmd.io/iomfscGXR1ycI_67NrLvMw) ## Abstract The fundamental communication component across all Sonr nodes is the `channel`. By utilizing data and transport agnostic realtime streams between nodes, we effectively have realtime structured data transmission at any point in the world. ## Primer The Sonr channel implementation requires prior knowledge of the following definitions before implementation. ### `multiaddr` Multiaddr's are self describing addresses that operate on any network protocol. They provide human-readable and efficient machine-readable representations. [The multiaddr spec](https://github.com/multiformats/multiaddr) by protocol labs provides further details about the mechanism. ### `pub-sub` The Sonr implementation follows the standard publish/subscribe model present with the modern web, with the caveat that it operates on a peer-to-peer node. In particular, Sonr utilizes the [gossip-sub implementation specification](https://docs.libp2p.io/concepts/publish-subscribe/) to manage sending messages between peers on the network. ### `Service endpoint` A `Service endpoint` describes a `url` which is associated to the did. ### `Topic` A `Topic` is a series of contexts which are denoted by '/' these contexts are heigharical and facilitate routing of data. ### `Temporary Channel` A temporary channel is a channel that exists between two `Peers` on the Sonr network. This channel exists for as long as the application which defines it keeps the channel active. Once the channel is `deactivated` it is destroyed. Messages passed between the two `Peers` are not persistent in this mode. Temporary Channels communicate on specified topics and utilize the `Exchange` model within Sonr. ### `Persistent Channel` A persistent channel is a channel which mirrors the implementation of a `Temporary Channel` but has more functionality. - A `Schema` is defined for the data sent between two `Peers` - On creation, a new `Bucket` is created for the channel - Data `published` on the channel is also stored in the `Channel`'s bucket ## Objective - An Open transport agnostic communication mechanism - Accessibility for users to listen to channels based on application - A mechanism for developers to create channels for their individual development needs - Structured Object reperesentation as the payload body between messages, as specified in [ADR-002](http://docs.sonr.io/articles/reference/adr-002) ## Addressing & Identifiying Topics In Sonr, the name of a channel follows the `multiaddr` specification for individual protocols that operate for a specific application. When resolving a `DIDDocument` of a particular application, developers are also provided a list of channels present for the application under its `Service endpoint` property. ### Topics Topics in the Sonr channel mechanism are defined as Developer created persistent stream endpoints where users can join and are always ensured to return pre-defined structured data, as per [ADR-002](http://docs.sonr.io/articles/reference/adr-002). **Topic Name Representation** `/sonr/channels/[applicationName]/[version]/[topicName]` **Example Topic Identifier** `/sonr/channels/beam/v1/SonrGroupChat` ### Protocols Protocols in the Sonr channel mechanism are defined as having pre-packaged spec-compliant functionality, accessible to both users to interact and developers to leverage. For example one of the provided core protocols by the Sonr Team is our [Libp2p Matrix Integration](https://archive.fosdem.org/2020/schedule/event/dip_p2p_matrix/). ## Client Side Interaction (Ephemeral Channels) ## Description The `Client side`, or `Motor` implementation of `Channels` utilizes the `Sonr` exchange protocol. Exchange protocol is in charge of routing messages between `Peers`. The methods defined in the below section wrap the `Exchange protcol` in order to implement described functionality. ## Relationship between Channel instance and Topics Each channel Object created is for a single `topic` each topic is then associated with that channel for both `publishing` and `listening` on `topics`. ## Methods The following methods are provided by Sonr's client-side Motor package, to be leveraged by frontends powered by the Sonr ecosystem. ### `Listen()` `topicName` : string When a channel has succesfully been routed and verified, the client is returned a `Channel` definition this facilitates communication on the specified topic when other `Peers` that are also `Listening` on the given `Topic` ### `Publish()` `topicName` : string `body` : buffer Calling a post method to the endpoint results in the client posting a message to the underlying `PubSub` topic. The message will successfully publish to the channel if the provided body message correctly maps to the `DID` and object reference involved with the channel. ## Channels on chain (Persistent Channel Definitions) ### Description `Persistent` channels have the same behavior of `Ephemeral` changes. When said channel is created the following record is stored on chain. ### Models #### who is model ``` go= HowIs { // Did is the DID of the channel Did: string // Document is the DID Document of the registered name and account encoded as JSON Creator: string // ChannelDoc is the structure of the channel encoded as JSON Channel: ChannelDoc // Timestamp is the time of the last update of the DID Document Timestamp int64 // Is Active is the status of the DID Document IsActive bool } ``` ``` go // options is a collection of options for the beam. options { ttl: time.Duration capacity: int } ``` #### Channel X modle interface definition Definition ```go= // Channel is a pubsub based Key-Value store for Libp2p nodes. Channel { // Did returns the DID of the channel. Did() string // Read returns a list of all peers subscribed to the channel topic. Read() []peer.ID // Publish publishes the given message to the channel topic. Publish(obj *ot.ObjectDoc) error // Listen subscribes to the beam topic and returns a channel that will // receive events. Listen(opChan chan *ChannelMessage) // Close closes the channel. Close() error } ``` ### Document Schema and applications A `Schema` is defined when the `Persistant` channel is created. Creation of said channel will create a `Transaction` on chain. **only** persistant channels use this mechanism. ### `CreateChannel` #### Parameters `Creator` : string `Label` : string `Description` : string `RegisteredObject` : ObjectDoc Creates a new Channel definition for an application. The method requires the DID of the application or user, a label for human-readable representation, description for the functionality of the channel, and a registered object for defining what structured data is returned by the channel. > When the `channel` is created, the created object is set to `Listening` as side effect. **Response** ```json= { type : "tx/MsgCreateChannel", body: { "code": 200, "did": "did:snr:abc123", "channel": { "label": "test", "description": "A example channel", "registeredObject": [...] // See ADR-002 } } } ``` ### `UpdateChannel` #### Parameters `Creator` : string `Label` : string (optional) `Description` : string (optional) `RegisteredObject` : sonrio.sonr.object.ObjectDoc (optional) Updates a Channel's information, all data is optional for update. However, the entire `object document` must be updated as that is considered a single property in this model. **Response** ```json= { type : "tx/MsgUpdateChannel", body: { "code": 200, "did": "did:snr:abc123", "channel": { "label": "test", "description": "A example channel", "registeredObject": [...] // See ADR-002 } } } ``` ### `DeactivateChannel` `creator`: : DID of the creator of the channel. `label` : A human readable label to assign to the channel. Utilized by developers to effectively eliminate any existing structured channel representation for a given application. A record will be created on change flagging the `isActive` property to false. Denoting the channel is no longer active. **Response** ```json= { type : "tx/MsgDeleteChannel", body: { "code": 200, "did": "did:snr:abc123", } } ``` ## Sequence Diagrams --- ### References - [Libp2p Pubsub](https://docs.libp2p.io/concepts/publish-subscribe/) - [MultiAddr Specification](https://github.com/multiformats/multiaddr) - [Sonr ADR-003](http://localhost:3000/articles/reference/adr-003)