From 0b45ae46e8da59be681ebd65646899c93090db1e Mon Sep 17 00:00:00 2001 From: "fryorcraken.eth" Date: Mon, 27 Mar 2023 09:39:24 +1100 Subject: [PATCH 1/5] add build chat and quick start guides --- docs/browser/build-chat-app.mdx | 280 ++++++++++++++++++ .../{introduction.md => introduction.mdx} | 0 docs/browser/quick-start.mdx | 115 +++++++ sidebars.js | 4 +- 4 files changed, 398 insertions(+), 1 deletion(-) create mode 100644 docs/browser/build-chat-app.mdx rename docs/browser/{introduction.md => introduction.mdx} (100%) create mode 100644 docs/browser/quick-start.mdx diff --git a/docs/browser/build-chat-app.mdx b/docs/browser/build-chat-app.mdx new file mode 100644 index 0000000..a5ec66d --- /dev/null +++ b/docs/browser/build-chat-app.mdx @@ -0,0 +1,280 @@ +--- +title: Build a Chat App +--- + +# Build a Chat App + +In this guide, you will learn how to receive and send messages using Waku by building an app from scratch. +If you want to learn how to add Waku to an existing app, check the [Quick Start](./quick-start) guide. + +## Pre-Requisites + +### 1. Set up Project + +Setup a new npm package: + +```shell +mkdir waku-app +cd waku-app +npm init -y +``` + +### 2. Set up Web Server + +Use the `serve` package as a web server + +```shell +npm i -D serve +``` + +Add a `start` script to the `package.json` file: + +```json +{ + "scripts": { + "start": "serve ." + } +} +``` + +### 3. Create Files + +Finally, create empty files for your project: + +```shell +touch index.html index.js +``` + +## Write Your App + +## 1. Add HTML Elements + +In `index.html`, add a button, text box and `div` for messages to have a basic chat app. +Also, import the `index.js` file. + +```html title=index.html + + + + + + Waku Chat App + + + + + +
+
+ + + +``` + +## 2. Access HTML Elements + +::: note + +From now on, all changes need to be done in the `index.js` file. + +::: + +Initialize variables to easily modify the HTML content: + +```js +const sendButton = document.getElementById("send") +const messagesDiv = document.getElementById("messages") +const textInput = document.getElementById("textInput") +``` + +## 3. Start a Waku Node + +Create and start a Waku Node: + +```js +import {createLightNode} from "https://unpkg.com/@waku/create@0.0.6/bundle/index.js" + +const wakuNode = await createLightNode({defaultBootstrap: true}) +await wakuNode.start() +``` + +:::info + +Setting the `defaultBootstrap` option to true allows your Waku node to connect to a set of pre-defined nodes. + +::: + +## 4. Wait for Connection to be Established + +Your Waku node needs to connect to a remote node in order to access the network. +To wait for this, use the `waitForRemotePeer` function: + +```js +import * as waku from "https://unpkg.com/@waku/core@0.0.10/bundle/index.js" + +await waku.waitForRemotePeer(wakuNode) +``` + +## 5. Define a Content Topic + +The `contentTopic` is a metadata `string` used for categorizing messages on the Waku network. +Depending on your use case, you can create one or more new `contentTopic`(s). +Refer to our [How to Choose a Content Topic](/overview/concepts/content-topics) guide more details. + +For this guide, we'll use `/chat-app-guide/1/message/utf8`. +Note that our payload will be encoded using `utf-8`. +We recommended using Protobuf for production purposes. + +```js +const contentTopic = `/chat-app-guide/1/message/utf8` +``` + +## 6. Render Incoming Messages + +Let's store incoming messages in an array and create a function to render them in the `messages` div: + +```js +const updateMessages = (msgs, div) => { + div.innerHTML = "" +}; + +const messages = [] +``` + +## 7. Create a Decoder + +Waku supports various encryption protocols. +A decoder allows you to specify the content topic to use and how to decrypt messages. +For the chosen content topic, create a plain text decoder (without encryption): + +```js +const decoder = waku.createDecoder(contentTopic) +``` + +## 8. Listen for Incoming Messages + +Messages sent over the network are `Waku Message`s, +as defined in the [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#wire-format) RFC. + +Messages returned by the plain text decoder implement the [`DecodedMessage`](https://js.waku.org/classes/_waku_core.DecodedMessage.html) interface. + +For now, we will just use the `payload` field. +It is a byte array field that can be used to encode any data. +We will store messages as a `utf-8` string. + +Listen to messages using the decoder and add them to the `messages` div upon reception: + +```ts +import * as utils from "https://unpkg.com/@waku/utils@0.0.10/bundle/index.js" + +wakuNode.filter.subscribe([decoder], (message) => { + const str = utils.bytesToUtf8(message.payload) + messages.push(str) + updateMessages(messages, messagesDiv); +}) +``` + +## 9. Send Messages + +Finally, create a plain text encoder and set up the `send` button to send messages. +Users will be able to enter the message using the `textInput` div. + +Once done, we can enable the `send` button. + +```ts +const encoder = waku.createEncoder(contentTopic) + +sendButton.onclick = async () => { + const text = textInput.value; + + await wakuNode.lightPush.push(encoder, { + payload: utils.utf8ToBytes(text), + }); + textInput.value = null; +}; +sendButton.disabled = false +``` + +### 10. Run the App + +You can now start a local web server to run the app: + +```shell +npm start +``` + +Click on the link in the console (http://localhost:3000/) and send a message! +You can open your app in several tabs to see messages being sent around. + +## Conclusion + +Congratulations on building your first Waku chat app. You can find the complete files below: + +```html title=index.html + + + + + + JS-Waku Quick Start App + + + + + +
+
+ + + +``` + +```js title=index.js +import {createLightNode} from "https://unpkg.com/@waku/create@0.0.6/bundle/index.js" +import * as waku from "https://unpkg.com/@waku/core@0.0.10/bundle/index.js" +import * as utils from "https://unpkg.com/@waku/byte-utils@0.0.2/bundle/index.js" + +const sendButton = document.getElementById("send") +const messagesDiv = document.getElementById("messages") +const textInput = document.getElementById("textInput") + +const wakuNode = await createLightNode({defaultBootstrap: true}) +await wakuNode.start() + +await waku.waitForRemotePeer(wakuNode) + +const contentTopic = `/chat-app-guide/1/message/utf8` +const decoder = waku.createDecoder(contentTopic) + +const updateMessages = (msgs, div) => { + div.innerHTML = "" +}; + +const messages = [] + +wakuNode.filter.subscribe([decoder], (message) => { + const str = utils.bytesToUtf8(message.payload) + messages.push(str) + updateMessages(messages, messagesDiv); +}) + +const encoder = waku.createEncoder(contentTopic) + +sendButton.onclick = async () => { + const text = textInput.value; + + await wakuNode.lightPush.push(encoder, { + payload: utils.utf8ToBytes(text), + }); + textInput.value = null; +}; +sendButton.disabled = false +``` diff --git a/docs/browser/introduction.md b/docs/browser/introduction.mdx similarity index 100% rename from docs/browser/introduction.md rename to docs/browser/introduction.mdx diff --git a/docs/browser/quick-start.mdx b/docs/browser/quick-start.mdx new file mode 100644 index 0000000..ad5ddc1 --- /dev/null +++ b/docs/browser/quick-start.mdx @@ -0,0 +1,115 @@ +--- +title: Quick Start +date: 2021-12-09T14:00:00+01:00 +weight: 20 +--- + +# Quick Start + +In this guide, you will learn how to integrate Waku into an **existing** JavaScript project. +If you're looking to build a Waku app from scratch, check out our [Build a Chat App](./build-chat-app.md) guide. + +## 1. Install Waku Libraries + +To begin, install the required Waku libraries with the following command: + +```shell +npm i @waku/core @waku/create @waku/utils +``` + +## 2. Start a Waku Node + +Next, create and start a Waku Node: + +```js +import {createLightNode} from "@waku/create" + +const waku = await createLightNode({defaultBootstrap: true}) +await waku.start() +``` + +:::info + +Setting the `defaultBootstrap` option to true allows your Waku node to connect to a set of pre-defined nodes. + +::: + +## 3. Wait for Connection to be Established + +Your Waku node needs to connect to a remote node in order to access the network. +To wait for this, use the `waitForRemotePeer` function: + +```js +import * as waku from "@waku/core" + +await waku.waitForRemotePeer(wakuNode) +``` + +## 4. Define a Content Topic + +The `contentTopic` is a metadata `string` used for categorizing messages on the Waku network. +Depending on your use case, you can create one or more new `contentTopic`(s). +Refer to our [How to Choose a Content Topic](/overview/concepts/content-topics) guide more details. + +For this guide, we'll use `/quick-start/1/message/utf8`. +Note that our payload will be encoded using `utf-8`. +We recommended using Protobuf for production purposes. + +```js +const contentTopic = `/quick-start/1/message/utf8` +``` + +## 5. Create a Decoder + +Waku supports various encryption protocols. +A decoder allows you to specify the content topic to use and how to decrypt messages. +For the chosen content topic, create a plain text decoder (without encryption): + +```js +const decoder = waku.createDecoder(contentTopic) +``` + +## 6. Listen for Incoming Messages + +Messages sent over the network are `Waku Message`s, +as defined in the [14/WAKU2-MESSAGE](https://rfc.vac.dev/spec/14/#wire-format) RFC. + +Messages returned by the plain text decoder implement the [`DecodedMessage`](https://js.waku.org/classes/_waku_core.DecodedMessage.html) interface. + +For now, we will just use the `payload` field. +It is a byte array field that can be used to encode any data. +We will store messages as a `utf-8` string. + +To listen for messages using the decoder, use the following code: + +```js + +wakuNode.filter.subscribe([decoder], (message) => { + const str = utils.bytesToUtf8(message.payload) + // str is a string, render it in your app as desired +}) +``` + +## 7. Send Messages + +Finally, create a `sendMessage` function that sends messages over Waku: + +```js +import * as utils from "@waku/utils" + +const encoder = waku.createEncoder(contentTopic) + +const sendMessage = async (textMsg) => { + await wakuNode.lightPush.push(encoder, { + payload: utils.utf8ToBytes(textMsg), + }); +}; +``` + +Now, you can use the `sendMessage` function in your app to send messages. + +## Conclusion + +Congratulations! You've successfully added decentralized communication features to your app. + +Continue learning by exploring how to [build a chat app](./build-chat-app) from scratch using Waku. diff --git a/sidebars.js b/sidebars.js index 97c26f9..eb09af8 100644 --- a/sidebars.js +++ b/sidebars.js @@ -30,7 +30,9 @@ const sidebars = { }, ], browser: [ - "browser/introduction" + "browser/introduction", + "browser/quick-start", + "browser/build-chat-app", ] }; From 8137a5129a1a0715baea9a61d191af157bbdf30d Mon Sep 17 00:00:00 2001 From: "fryorcraken.eth" Date: Mon, 27 Mar 2023 13:56:52 +1100 Subject: [PATCH 2/5] update packages versions --- docs/browser/build-chat-app.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/browser/build-chat-app.mdx b/docs/browser/build-chat-app.mdx index a5ec66d..5e3ce1c 100644 --- a/docs/browser/build-chat-app.mdx +++ b/docs/browser/build-chat-app.mdx @@ -94,7 +94,7 @@ const textInput = document.getElementById("textInput") Create and start a Waku Node: ```js -import {createLightNode} from "https://unpkg.com/@waku/create@0.0.6/bundle/index.js" +import {createLightNode} from "https://unpkg.com/@waku/create@0.0.9/bundle/index.js" const wakuNode = await createLightNode({defaultBootstrap: true}) await wakuNode.start() @@ -112,7 +112,7 @@ Your Waku node needs to connect to a remote node in order to access the network. To wait for this, use the `waitForRemotePeer` function: ```js -import * as waku from "https://unpkg.com/@waku/core@0.0.10/bundle/index.js" +import * as waku from "https://unpkg.com/@waku/core@0.0.13/bundle/index.js" await waku.waitForRemotePeer(wakuNode) ``` @@ -169,7 +169,7 @@ We will store messages as a `utf-8` string. Listen to messages using the decoder and add them to the `messages` div upon reception: ```ts -import * as utils from "https://unpkg.com/@waku/utils@0.0.10/bundle/index.js" +import * as utils from "https://unpkg.com/@waku/utils@0.0.3/bundle/index.js" wakuNode.filter.subscribe([decoder], (message) => { const str = utils.bytesToUtf8(message.payload) From 1e5e3dde9348568d4352c5786701545e80106cc7 Mon Sep 17 00:00:00 2001 From: "fryorcraken.eth" Date: Mon, 27 Mar 2023 14:15:17 +1100 Subject: [PATCH 3/5] Add intro for js-waku --- docs/browser/introduction.mdx | 36 ++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/browser/introduction.mdx b/docs/browser/introduction.mdx index 2b15ebb..8d7ea6e 100644 --- a/docs/browser/introduction.mdx +++ b/docs/browser/introduction.mdx @@ -2,4 +2,38 @@ title: Introduction --- -js-waku doc goes here +# JS-Waku Documentation + +[JS-Waku](https://github.com/waku-org/js-waku) is the TypeScript implementation of the Waku protocol, +specifically designed for the browser environment. +This powerful, easy-to-use library enables you to integrate Waku into your web applications seamlessly. + +:::info + +If you wish to use Waku with a NodeJS application, you can either: +- Use [nwaku](https://github.com/status-im/nwaku)'s [JSON RPC API](https://rfc.vac.dev/spec/16/) +- Or, attempt to use go-waku's [c-bindings](https://github.com/waku-org/go-waku/tree/master/examples/c-bindings) in NodeJS + +::: + +To get started, the [Quick Start](./quick-start) guide offers a simple way to integrate Waku into your web app. +For a more comprehensive tutorial, follow the [Build a Chat App](./build-chat-app) guide, +which demonstrates how to create a chat app from scratch. + +Explore the [js-waku-examples repository](https://github.com/waku-org/js-waku-examples) to find various working Proof-of-Concepts that showcase how to use JS-Waku effectively. +You can also interact with these examples live: + +- [web-chat](https://examples.waku.org/web-chat): A simple public chat. +- [eth-pm](https://examples.waku.org/eth-pm): End-to-end encrypted private messages. +- [rln-js](https://examples.waku.org/rln-js): Demonstration of [RLN](https://rfc.vac.dev/spec/32/), +an economic spam protection protocol that rate limit using zero-knowledge for privacy preserving purposes. + +To gain a deeper understanding of Waku, visit the [overview documentation](/). +If you're interested in learning how Waku works under the hood, check out the specs at [rfc.vac.dev](https://rfc.vac.dev/). + +## Bugs, Questions & Support + +If you encounter any bug or would like to propose new features, feel free to [open an issue](https://github.com/waku-org/js-waku/issues/new/). + +For general discussion, get help or latest news, +join **#js-waku** on [Vac Discord](https://discord.gg/Nrac59MfSX) or the [Waku Telegram Group](https://t.me/waku_org). From 6ce93a983f4c157e90b45a678070b99a2e5e237b Mon Sep 17 00:00:00 2001 From: "fryorcraken.eth" Date: Tue, 28 Mar 2023 16:59:13 +1100 Subject: [PATCH 4/5] fix link --- docs/browser/quick-start.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/browser/quick-start.mdx b/docs/browser/quick-start.mdx index ad5ddc1..06ff46f 100644 --- a/docs/browser/quick-start.mdx +++ b/docs/browser/quick-start.mdx @@ -7,7 +7,7 @@ weight: 20 # Quick Start In this guide, you will learn how to integrate Waku into an **existing** JavaScript project. -If you're looking to build a Waku app from scratch, check out our [Build a Chat App](./build-chat-app.md) guide. +If you're looking to build a Waku app from scratch, check out our [Build a Chat App](./build-chat-app) guide. ## 1. Install Waku Libraries From eb7868260826875c15bd9fa887a187d486503e64 Mon Sep 17 00:00:00 2001 From: "fryorcraken.eth" Date: Mon, 17 Apr 2023 16:57:20 +1000 Subject: [PATCH 5/5] update versions --- docs/browser/build-chat-app.mdx | 42 +++++++++++++++++---------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/docs/browser/build-chat-app.mdx b/docs/browser/build-chat-app.mdx index 5e3ce1c..c85977f 100644 --- a/docs/browser/build-chat-app.mdx +++ b/docs/browser/build-chat-app.mdx @@ -94,7 +94,7 @@ const textInput = document.getElementById("textInput") Create and start a Waku Node: ```js -import {createLightNode} from "https://unpkg.com/@waku/create@0.0.9/bundle/index.js" +import {createLightNode} from "https://unpkg.com/@waku/create@0.0.12/bundle/index.js" const wakuNode = await createLightNode({defaultBootstrap: true}) await wakuNode.start() @@ -112,7 +112,7 @@ Your Waku node needs to connect to a remote node in order to access the network. To wait for this, use the `waitForRemotePeer` function: ```js -import * as waku from "https://unpkg.com/@waku/core@0.0.13/bundle/index.js" +import * as waku from "https://unpkg.com/@waku/core@0.0.16/bundle/index.js" await waku.waitForRemotePeer(wakuNode) ``` @@ -140,7 +140,7 @@ const updateMessages = (msgs, div) => { div.innerHTML = "
    " msgs.forEach((msg) => (div.innerHTML += `
  • ${msg}
  • `)) div.innerHTML += "
" -}; +} const messages = [] ``` @@ -169,7 +169,7 @@ We will store messages as a `utf-8` string. Listen to messages using the decoder and add them to the `messages` div upon reception: ```ts -import * as utils from "https://unpkg.com/@waku/utils@0.0.3/bundle/index.js" +import * as utils from "https://unpkg.com/@waku/utils@0.0.4/bundle/bytes.js" wakuNode.filter.subscribe([decoder], (message) => { const str = utils.bytesToUtf8(message.payload) @@ -186,15 +186,15 @@ Users will be able to enter the message using the `textInput` div. Once done, we can enable the `send` button. ```ts -const encoder = waku.createEncoder(contentTopic) +const encoder = waku.createEncoder({contentTopic}) sendButton.onclick = async () => { - const text = textInput.value; + const text = textInput.value - await wakuNode.lightPush.push(encoder, { + await wakuNode.lightPush.send(encoder, { payload: utils.utf8ToBytes(text), }); - textInput.value = null; + textInput.value = null }; sendButton.disabled = false ``` @@ -236,9 +236,9 @@ Congratulations on building your first Waku chat app. You can find the complete ``` ```js title=index.js -import {createLightNode} from "https://unpkg.com/@waku/create@0.0.6/bundle/index.js" -import * as waku from "https://unpkg.com/@waku/core@0.0.10/bundle/index.js" -import * as utils from "https://unpkg.com/@waku/byte-utils@0.0.2/bundle/index.js" +import {createLightNode} from "https://unpkg.com/@waku/create@0.0.12/bundle/index.js" +import * as waku from "https://unpkg.com/@waku/core@0.0.16/bundle/index.js" +import * as utils from "https://unpkg.com/@waku/utils@0.0.4/bundle/bytes.js" const sendButton = document.getElementById("send") const messagesDiv = document.getElementById("messages") @@ -250,31 +250,33 @@ await wakuNode.start() await waku.waitForRemotePeer(wakuNode) const contentTopic = `/chat-app-guide/1/message/utf8` -const decoder = waku.createDecoder(contentTopic) const updateMessages = (msgs, div) => { div.innerHTML = "
    " - msgs.forEach((msg) => (div.innerHTML += "
  • " + msg + "
  • ")) + msgs.forEach((msg) => (div.innerHTML += `
  • ${msg}
  • `)) div.innerHTML += "
" -}; +} const messages = [] +const decoder = waku.createDecoder(contentTopic) + wakuNode.filter.subscribe([decoder], (message) => { + console.log("message received", message) const str = utils.bytesToUtf8(message.payload) messages.push(str) updateMessages(messages, messagesDiv); }) -const encoder = waku.createEncoder(contentTopic) +const encoder = waku.createEncoder({contentTopic}) sendButton.onclick = async () => { - const text = textInput.value; + const text = textInput.value - await wakuNode.lightPush.push(encoder, { + await wakuNode.lightPush.send(encoder, { payload: utils.utf8ToBytes(text), - }); - textInput.value = null; -}; + }) + textInput.value = null +} sendButton.disabled = false ```