127 lines
4.6 KiB
HTML
127 lines
4.6 KiB
HTML
<!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>
|
|
</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.7/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>
|