Skip to main content

Send and Receive Messages Using Light Push and Filter

This guide provides detailed steps to start using the @waku/sdk package by setting up a Light Node to send messages using the Light Push protocol, and receive messages using the Filter protocol. Have a look at the installation guide for steps on adding @waku/sdk to your project.

Create a light node

Use the createLightNode() function to create a Light Node and interact with the Waku Network:

import { createLightNode } from "@waku/sdk";

// Create and start a Light Node
const node = await createLightNode({ defaultBootstrap: true });
await node.start();

// Use the stop() function to stop a running node
// await node.stop();
info

When the defaultBootstrap parameter is set to true, your node will be bootstrapped using the default bootstrap method. Have a look at the Bootstrap Nodes and Discover Peers guide to learn more methods to bootstrap nodes.

A node needs to know how to route messages. By default, it will use The Waku Network configuration ({ clusterId: 1, shards: [0,1,2,3,4,5,6,7] }). For most applications, it's recommended to use autosharding:

// Create node with auto sharding (recommended)
const node = await createLightNode({
defaultBootstrap: true,
networkConfig: {
clusterId: 1,
contentTopics: ["/my-app/1/notifications/proto"],
},
});

Alternative network configuration

If your project requires a specific network configuration, you can use static sharding:

// Create node with static sharding
const node = await createLightNode({
defaultBootstrap: true,
networkConfig: {
clusterId: 1,
shards: [0, 1, 2, 3],
},
});

Connect to remote peers

Use the node.waitForPeers() function to wait for the node to connect with peers on the Waku Network:

// Wait for a successful peer connection
await node.waitForPeers();

The protocols parameter allows you to specify the protocols that the remote peers should have enabled:

import { Protocols } from "@waku/sdk";

// Wait for peer connections with specific protocols
await node.waitForPeers([Protocols.LightPush, Protocols.Filter]);

Choose a content topic

Choose a content topic for your application and create a message encoder and decoder:

import { createEncoder, createDecoder } from "@waku/sdk";

// Choose a content topic
const contentTopic = "/light-guide/1/message/proto";

// Create a message encoder and decoder
const encoder = createEncoder({ contentTopic });
const decoder = createDecoder(contentTopic);

The ephemeral parameter allows you to specify whether messages should NOT be stored by Store peers:

const encoder = createEncoder({
contentTopic: contentTopic, // message content topic
ephemeral: true, // allows messages NOT be stored on the network
});

The pubsubTopicShardInfo parameter allows you to configure a different network configuration for your encoder and decoder:

// Create the network config
const networkConfig = { clusterId: 3, shards: [1, 2] };

// Create encoder and decoder with custom network config
const encoder = createEncoder({
contentTopic: contentTopic,
pubsubTopicShardInfo: networkConfig,
});
const decoder = createDecoder(contentTopic, networkConfig);
info

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.

Create a message structure

Create your application's message structure using Protobuf's valid message fields:

import protobuf from "protobufjs";

// Create a message structure using Protobuf
const DataPacket = new protobuf.Type("DataPacket")
.add(new protobuf.Field("timestamp", 1, "uint64"))
.add(new protobuf.Field("sender", 2, "string"))
.add(new protobuf.Field("message", 3, "string"));
info

Have a look at the Protobuf installation guide for adding the protobufjs package to your project.

Send messages using light push

To send messages over the Waku Network using the Light Push protocol, create a new message object and use the lightPush.send() function:

// Create a new message object
const protoMessage = DataPacket.create({
timestamp: Date.now(),
sender: "Alice",
message: "Hello, World!",
});

// Serialise the message using Protobuf
const serialisedMessage = DataPacket.encode(protoMessage).finish();

// Send the message using Light Push
await node.lightPush.send(encoder, {
payload: serialisedMessage,
});

Receive messages using filter

To receive messages using the Filter protocol, create a callback function for message processing, then use the filter.subscribe() function to subscribe to a content topic:

// Create the callback function
const callback = (wakuMessage) => {
// Check if there is a payload on the message
if (!wakuMessage.payload) return;
// Render the messageObj as desired in your application
const messageObj = DataPacket.decode(wakuMessage.payload);
console.log(messageObj);
};

// Create a Filter subscription
const { error, subscription } = await node.filter.createSubscription({ contentTopics: [contentTopic] });

if (error) {
// handle errors if happens
throw Error(error);
}

// Subscribe to content topics and process new messages
await subscription.subscribe([decoder], callback);

The pubsubTopicShardInfo parameter allows you to configure a different network configuration for your Filter subscription:

// Create the network config
const networkConfig = { clusterId: 3, shards: [1, 2] };

// Create Filter subscription with custom network config
const subscription = await node.filter.createSubscription(networkConfig);

You can use the subscription.unsubscribe() function to stop receiving messages from a content topic:

await subscription.unsubscribe([contentTopic]);
Congratulations!

You have successfully sent and received messages over the Waku Network using the Light Push and Filter protocols. Have a look at the light-js and light-chat examples for working demos.