/ docs / build / javascript / reliable-channels.md
reliable-channels.md
  1  ---
  2  title: Send and Receive Messages in a Reliable Channel
  3  hide_table_of_contents: true
  4  displayed_sidebar: build
  5  ---
  6  
  7  Learn how to send and receive messages with a convenient SDK that provide various reliable functionalities out-of-the-box.
  8  
  9  :::warning
 10  This is an experimental feature and has a number of [limitations](https://github.com/waku-org/js-waku/pull/2526).
 11  :::
 12  
 13  ## Import Waku SDK
 14  
 15  ```shell
 16  npm install @waku/sdk@latest
 17  ```
 18  
 19  Or using a CDN, note this is an ESM package so `type="module"` is needed.
 20  
 21  ```html
 22  <script type="module">
 23    import {
 24      createLightNode,
 25      ReliableChannel
 26    } from 'https://unpkg.com/@waku/sdk@latest/bundle/index.js';
 27  
 28    // Your code here
 29    
 30  </script>
 31  ```
 32  
 33  ## Create a Waku node
 34  
 35  Use the `createLightNode()` function to create a [Light Node](/learn/glossary#light-node) and interact with the Waku Network:
 36  
 37  ```js
 38  import { createLightNode } from "@waku/sdk";
 39  
 40  // Create a Light Node
 41  const node = await createLightNode({ defaultBootstrap: true });
 42  ```
 43  
 44  :::info
 45  When the `defaultBootstrap` parameter is set to `true`, your node will be bootstrapped using the [default bootstrap method](/build/javascript/configure-discovery#default-bootstrap-method). Have a look at the [Bootstrap Nodes and Discover Peers](/build/javascript/configure-discovery) guide to learn more methods to bootstrap nodes.
 46  :::
 47  
 48  ## Create encoders and decoders
 49  
 50  Choose a [content topic](/learn/concepts/content-topics) for your application and create a message `encoder` and `decoder`:
 51  
 52  ```js
 53  import { createEncoder, createDecoder } from "@waku/sdk";
 54  
 55  // Choose a content topic
 56  const ct = "/my-app/1/messages/proto";
 57  
 58  // Create a message encoder and decoder
 59  const encoder = node.createEncoder({ contentTopic: ct });
 60  const decoder = node.createDecoder({ contentTopic: ct });
 61  ```
 62  
 63  You can also use [`@waku/message-encryption`](/build/javascript/message-encryption) to encrypt and decrypt messages using Waku libraries.
 64  
 65  :::info
 66  In this example, users send and receive messages on a shared content topic. However, real applications may have users broadcasting messages while others listen or only have 1:1 exchanges. Waku supports all these use cases.
 67  :::
 68  
 69  ## Listen for connection status
 70  
 71  The Waku node will emit `health` events to help you know whether the node is connected to the network.
 72  This can be useful to give feedback to the user, or stop some action (e.g. sending messages) when offline:
 73  
 74  ```js
 75  import { HealthStatus } from "@waku/sdk";
 76  
 77  node.events.addEventListener("waku:health", (event) => {
 78      const health = event.detail;
 79      
 80      if (health === HealthStatus.SufficientlyHealthy) {
 81          // Show to the user they are connected
 82      } else if (status === HealthStatus.MinimallyHealthy) {
 83          // Maybe put some clue to the user that while we are connected,
 84          // there may be issues sending or receiving messages
 85      } else {
 86          // Show to the user they are disconnected from the network
 87      }
 88  });
 89  ```
 90  
 91  ## Create a reliable channel
 92  
 93  You need to choose a channel name: it acts as an identifier to the conversation, participants will try to ensure they all have the same
 94  messages within a given channel.
 95  
 96  ```js
 97  const channelName = "channel-number-15"
 98  ```
 99  
100  Finally, each participant need to identify themselves for reliability purposes, so they can confirm _others_ have received their messages.
101  
102  It is up to you how to generate an id. Every participant **must** have a different id.
103  
104  ```js
105  const senderId = generateRandomStringId();
106  ```
107  
108  You can now create a reliable channel:
109  
110  ```js
111  import { ReliableChannel } from "@waku/sdk";
112  
113  const reliableChannel = await ReliableChannel.create(node, channelName, senderId, encoder, decoder)
114  ```
115  
116  The channel will automatically start the Waku node and fetch messages.
117  
118  ## Create a message structure
119  
120  Create your application's message structure using [Protobufjs](https://github.com/protobufjs/protobuf.js#usage):
121  
122  ```js
123  import protobuf from "protobufjs";
124  
125  // Create a message structure using Protobuf
126  const DataPacket = new protobuf.Type("DataPacket")
127    .add(new protobuf.Field("timestamp", 1, "uint64"))
128    .add(new protobuf.Field("sender", 2, "string"))
129    .add(new protobuf.Field("message", 3, "string"));
130  ```
131  
132  :::info
133  Have a look at the [Protobuf installation](/build/javascript/#message-structure) guide for adding the `protobufjs` package to your project.
134  :::
135  
136  ## Listen to incoming messages
137  
138  The reliable channel will emit incoming messages. To process them, simply add a listener:
139  
140  ```js
141  reliableChannel.addEventListener("message-received", (event) => {
142    const wakuMessage = event.detail;
143    
144    // decode your payload using the protobuf object previously created
145    const { timestamp, sender, message } = DataPacket.decode(wakuMessage.payload);
146    
147    // ... process the message as you wish
148  })
149  ```
150  
151  ## Send messages
152  
153  To send messages in the reliable channel, encode the message in a payload.
154  
155  ```js
156  // Create a new message object
157  const protoMessage = DataPacket.create({
158    timestamp: Date.now(),
159    sender: "Alice",
160    message: "Hello, World!",
161  });
162  
163  // Serialise the message using Protobuf
164  const serialisedMessage = DataPacket.encode(protoMessage).finish();
165  ```
166  
167  Then, send the message and setup listeners so you can know when the message:
168  - has been sent
169  - has been acknowledged by other participants in the channel
170  - has encountered an error
171  
172  ```js
173  // Send the message, and get the id to track events
174  const messageId = reliableChannel.send(payload);
175          
176  reliableChannel.addEventListener("sending-message-irrecoverable-error", (event) => {
177      if (messageId === event.detail.messageId) {
178        console.error('Failed to send message:', event.detail.error);
179        // Show an error to the user
180      }
181  })
182  
183  reliableChannel.addEventListener("message-sent", (event) => {
184      if (messageId === event.detail) {
185          // Message sent, show '✔' to the user, etc
186      }
187  })
188  
189  reliableChannel.addEventListener("message-acknowledged", (event) => {
190    if (messageId === event.detail) {
191      // Message acknowledged by other participants, show '✔✔' to the user, etc
192    }
193  })
194  ```
195  
196  :::tip Congratulations!
197  You have successfully sent and received messages over the Waku Network using our reliable protocols such as Scalable Data Sync (SDS) and P2P Reliability.
198  :::