<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta content="width=device-width, initial-scale=1.0" name="viewport" /> <title>JS-Waku Chat</title> <link rel="apple-touch-icon" href="./favicon.png" /> <link rel="manifest" href="./manifest.json" /> <link rel="icon" href="./favicon.ico" /> </head> <body> <div><h1>Waku Node Status</h1></div> <div id="status"></div> <label for="textInput">Message text</label> <input disabled id="textInput" placeholder="Type your message here" type="text" /> <button disabled id="sendButton" type="button"> Send Message using Relay </button> <div><h1>Messages</h1></div> <div id="messages"></div> <script type="module"> /** * Demonstrate usage of js-waku in the browser. Use relay, gossip sub protocol to send and receive messages. * Recommended payload is protobuf. Using simple utf-8 string for demo purposes only. */ import { bytesToUtf8, utf8ToBytes, } from "https://unpkg.com/@waku/byte-utils@0.0.2/bundle/index.js"; import { createRelayNode } from "https://unpkg.com/@waku/create@0.0.5/bundle/index.js"; import { waitForRemotePeer, createDecoder, createEncoder, } from "https://unpkg.com/@waku/core@0.0.10/bundle/index.js"; const statusDiv = document.getElementById("status"); const messagesDiv = document.getElementById("messages"); const textInput = document.getElementById("textInput"); const sendButton = document.getElementById("sendButton"); // Every Waku Message has a content topic that categorizes it. // It is always encoded in clear text. // Recommendation: `/dapp-name/version/functionality/codec` // We recommend to use protobuf as codec (`proto`), this demo uses utf-8 // for simplicity's sake. const contentTopic = "/js-waku-examples/1/chat/utf8"; // Prepare encoder and decoder, `V0` for clear text messages. const encoder = createEncoder(contentTopic); const decoder = createDecoder(contentTopic); try { statusDiv.innerHTML = "<p>Starting</p>"; // Create and starts a Waku node. // `default: true` bootstraps by connecting to pre-defined/hardcoded Waku nodes. // We are currently working on migrating this method to DNS Discovery. // // https://js.waku.org/functions/lib_create_waku.createPrivacyNode.html const waku = await createRelayNode({ defaultBootstrap: true }); await waku.start(); // Add a hook to process all incoming messages on a specified content topic. // // https://js.waku.org/classes/index.waku_relay.WakuRelay.html#addObserver waku.relay.addObserver( decoder, (message) => { // Checks there is a payload on the message. // Waku Message is encoded in protobuf, in proto v3 fields are always optional. // // https://js.waku.org/interfaces/index.proto_message.WakuMessage-1.html#payload if (!message.payload) return; // Helper method to decode the payload to utf-8. A production dApp should // use `wakuMessage.payload` (Uint8Array) which enables encoding a data // structure of their choice. // // https://js.waku.org/functions/index.utils.bytesToUtf8.html const text = bytesToUtf8(message.payload); messagesDiv.innerHTML = `<p>${text}</p><br />` + messagesDiv.innerHTML; }, [contentTopic] ); statusDiv.innerHTML = "<p>Connecting to a peer</p>"; // Best effort method that waits for the Waku node to be connected to remote // waku nodes (peers) and for appropriate handshakes to be done. // // https://js.waku.org/functions/lib_wait_for_remote_peer.waitForRemotePeer.html await waitForRemotePeer(waku); // We are now connected to a remote peer, let's define the `sendMessage` // function that sends the text input over Waku Relay, the gossipsub // protocol. sendButton.onclick = async () => { const payload = utf8ToBytes(textInput.value); await waku.relay.send(encoder, { payload }); console.log("Message sent!"); // Reset the text input. textInput.value = null; }; // Ready to send & receive messages, enable text input. textInput.disabled = false; sendButton.disabled = false; statusDiv.innerHTML = "<p>Ready!</p>"; } catch (e) { statusDiv.innerHTML = "Failed to start application"; console.log(e); } </script> </body> </html>