mirror of
https://github.com/logos-messaging/js-noise.git
synced 2026-01-02 13:43:08 +00:00
chore: remove noise example
This commit is contained in:
parent
ead21e71b6
commit
83d7370328
16
README.md
16
README.md
@ -17,18 +17,10 @@ yarn add @waku/noise
|
|||||||
Refer to the specs and examples for details on how to use this library
|
Refer to the specs and examples for details on how to use this library
|
||||||
|
|
||||||
|
|
||||||
### Running example app
|
### Usage
|
||||||
|
An example of usage of js-noise library with waku can be seen here: https://examples.waku.org/noise-js/
|
||||||
```
|
The code for this example is available in the [js-waku-examples repository](https://github.com/waku-org/js-waku-examples/tree/master/examples/noise-js) repository
|
||||||
git clone https://github.com/waku-org/js-noise
|
You can also refer to the test units available within this repository (`*.spec.ts`) for more examples on usage.
|
||||||
cd js-noise/example
|
|
||||||
npm install # or yarn
|
|
||||||
npm start
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
Browse http://localhost:8080 to see the webapp where the pairing process can be initiated
|
|
||||||
|
|
||||||
|
|
||||||
## Bugs, Questions & Features
|
## Bugs, Questions & Features
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
# Waku Noise Pairing example app
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
Browse http://localhost:8080 and open the developer tools to see console logs
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
|
||||||
<title>JS-Waku light node example</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>Press F12 to open the console</p>
|
|
||||||
<p><b>Waku Status:</b> <span id="waku-status">connecting...</span></p>
|
|
||||||
<p id="handshake-span"><b>Handshake Status:</b> <span id="handshake-status">-</span></p>
|
|
||||||
<canvas id="qr-canvas"></canvas>
|
|
||||||
<a href="#" id="qr-url" style="display: none" target="_blank">Open QR code link in new window instead of scanning it.</a>
|
|
||||||
|
|
||||||
<div id="chat-area" style="display: none">
|
|
||||||
<label for="nick-input">Your nickname</label>
|
|
||||||
<input id="nick-input" placeholder="Choose a nickname" type="text" />
|
|
||||||
<label for="text-input">Message text</label>
|
|
||||||
<input id="text-input" placeholder="Type your message here" type="text" />
|
|
||||||
<button id="send-btn" type="button" disabled>Send message using Light Push</button>
|
|
||||||
<span id="sending-status"></span>
|
|
||||||
|
|
||||||
<h4 class="mu1">Messages</h4>
|
|
||||||
<div id="messages"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="./index.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
288
example/index.js
288
example/index.js
@ -1,288 +0,0 @@
|
|||||||
import { createLightNode } from "js-waku/lib/create_waku";
|
|
||||||
import { utils } from "js-waku";
|
|
||||||
import { waitForRemotePeer } from "js-waku/lib/wait_for_remote_peer";
|
|
||||||
import { Fleet, getPredefinedBootstrapNodes } from "js-waku/lib/predefined_bootstrap_nodes";
|
|
||||||
import { PeerDiscoveryStaticPeers } from "js-waku/lib/peer_discovery_static_list";
|
|
||||||
import { Protocols } from "js-waku";
|
|
||||||
import * as noise from "@waku/noise";
|
|
||||||
import protobuf from "protobufjs";
|
|
||||||
import QRCode from "qrcode";
|
|
||||||
// TODO: Get rid of these
|
|
||||||
import hexToArrayBuffer from "hex-to-array-buffer";
|
|
||||||
import arrayBufferToHex from "array-buffer-to-hex";
|
|
||||||
|
|
||||||
const messagesDiv = document.getElementById("messages");
|
|
||||||
const nicknameInput = document.getElementById("nick-input");
|
|
||||||
const textInput = document.getElementById("text-input");
|
|
||||||
const sendButton = document.getElementById("send-btn");
|
|
||||||
const sendingStatusSpan = document.getElementById("sending-status");
|
|
||||||
const chatArea = document.getElementById("chat-area");
|
|
||||||
const qrCanvas = document.getElementById("qr-canvas");
|
|
||||||
const qrUrl = document.getElementById("qr-url");
|
|
||||||
const wakuStatusSpan = document.getElementById("waku-status");
|
|
||||||
const handshakeStatusSpan = document.getElementById("handshake-status");
|
|
||||||
|
|
||||||
function getPairingInfofromUrl() {
|
|
||||||
const urlParts = window.location.href.split("?");
|
|
||||||
if (urlParts.length < 2) return undefined;
|
|
||||||
|
|
||||||
const pairingParts = decodeURIComponent(urlParts[1]).split(":");
|
|
||||||
if (pairingParts.length < 6) throw new Error("invalid pairing information format");
|
|
||||||
|
|
||||||
const qrMessageNameTag = new Uint8Array(hexToArrayBuffer(pairingParts.shift()));
|
|
||||||
|
|
||||||
return new noise.InitiatorParameters(pairingParts.join(":"), qrMessageNameTag);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSenderAndResponder(node) {
|
|
||||||
const sender = {
|
|
||||||
async publish(encoder, msg) {
|
|
||||||
await node.lightPush.push(encoder, msg);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const msgQueue = new Array();
|
|
||||||
const subscriptions = new Map();
|
|
||||||
const intervals = new Map();
|
|
||||||
|
|
||||||
const responder = {
|
|
||||||
async subscribe(decoder) {
|
|
||||||
const subscription = await node.filter.subscribe([decoder], (wakuMessage) => {
|
|
||||||
msgQueue.push(wakuMessage);
|
|
||||||
});
|
|
||||||
subscriptions.set(decoder.contentTopic, subscription);
|
|
||||||
},
|
|
||||||
async nextMessage(contentTopic) {
|
|
||||||
if (msgQueue.length != 0) {
|
|
||||||
const oldestMsg = msgQueue.shift();
|
|
||||||
if (oldestMsg.contentTopic === contentTopic) {
|
|
||||||
return oldestMsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
if (msgQueue.length != 0) {
|
|
||||||
clearInterval(interval);
|
|
||||||
const oldestMsg = msgQueue.shift();
|
|
||||||
if (oldestMsg.contentTopic === contentTopic) {
|
|
||||||
resolve(oldestMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
intervals.set(contentTopic, interval);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
async stop(contentTopic) {
|
|
||||||
if (intervals.has(contentTopic)) {
|
|
||||||
clearInterval(intervals.get(contentTopic));
|
|
||||||
intervals.delete(contentTopic);
|
|
||||||
}
|
|
||||||
if (subscriptions.has(contentTopic)) {
|
|
||||||
await subscriptions.get(contentTopic)();
|
|
||||||
subscriptions.delete(contentTopic);
|
|
||||||
} else {
|
|
||||||
console.log("Subscription doesnt exist");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return [sender, responder];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function confirmAuthCodeFlow(pairingObj) {
|
|
||||||
const authCode = await pairingObj.getAuthCode();
|
|
||||||
pairingObj.validateAuthCode(confirm("Confirm that authcode is: " + authCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function hideQR() {
|
|
||||||
qrCanvas.remove();
|
|
||||||
qrUrl.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function disableUI() {
|
|
||||||
hideQR();
|
|
||||||
chatArea.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to update the fields to guide the user by disabling buttons.
|
|
||||||
const updateFields = () => {
|
|
||||||
const readyToSend = nicknameInput.value !== "";
|
|
||||||
textInput.disabled = !readyToSend;
|
|
||||||
sendButton.disabled = !readyToSend;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Protobuf
|
|
||||||
const ProtoChatMessage = new protobuf.Type("ChatMessage")
|
|
||||||
.add(new protobuf.Field("timestamp", 1, "uint64"))
|
|
||||||
.add(new protobuf.Field("nick", 2, "string"))
|
|
||||||
.add(new protobuf.Field("text", 3, "bytes"));
|
|
||||||
|
|
||||||
let messages = [];
|
|
||||||
|
|
||||||
const updateMessages = () => {
|
|
||||||
messagesDiv.innerHTML = "<ul>";
|
|
||||||
messages.forEach((msg) => {
|
|
||||||
messagesDiv.innerHTML += `<li>${msg}</li>`;
|
|
||||||
});
|
|
||||||
messagesDiv.innerHTML += "</ul>";
|
|
||||||
};
|
|
||||||
|
|
||||||
const onMessage = (wakuMessage) => {
|
|
||||||
const { timestamp, nick, text } = ProtoChatMessage.decode(wakuMessage.payload);
|
|
||||||
const time = new Date();
|
|
||||||
time.setTime(Number(timestamp) * 1000);
|
|
||||||
|
|
||||||
messages.push(`(${nick}) <strong>${utils.bytesToUtf8(text)}</strong> <i>[${time.toISOString()}]</i>`);
|
|
||||||
updateMessages();
|
|
||||||
};
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
// Starting the node
|
|
||||||
const node = await createLightNode({
|
|
||||||
libp2p: {
|
|
||||||
peerDiscovery: [new PeerDiscoveryStaticPeers(getPredefinedBootstrapNodes(Fleet.Test))],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
await node.start();
|
|
||||||
|
|
||||||
await waitForRemotePeer(node, [Protocols.Filter, Protocols.LightPush]);
|
|
||||||
|
|
||||||
wakuStatusSpan.innerHTML = "connected";
|
|
||||||
|
|
||||||
const [sender, responder] = getSenderAndResponder(node);
|
|
||||||
|
|
||||||
const myStaticKey = noise.generateX25519KeyPair();
|
|
||||||
|
|
||||||
const pairingParameters = getPairingInfofromUrl();
|
|
||||||
|
|
||||||
const initiator = pairingParameters ? true : false;
|
|
||||||
|
|
||||||
let encoder;
|
|
||||||
let decoder;
|
|
||||||
|
|
||||||
if (initiator) {
|
|
||||||
console.log("Initiator");
|
|
||||||
qrCanvas.remove(); // Initiator does not require a QR code
|
|
||||||
|
|
||||||
const pairingObj = new noise.WakuPairing(sender, responder, myStaticKey, pairingParameters);
|
|
||||||
const pExecute = pairingObj.execute(120000); // timeout after 2m
|
|
||||||
|
|
||||||
confirmAuthCodeFlow(pairingObj);
|
|
||||||
|
|
||||||
try {
|
|
||||||
handshakeStatusSpan.innerHTML = "executing handshake...";
|
|
||||||
|
|
||||||
[encoder, decoder] = await pExecute;
|
|
||||||
|
|
||||||
handshakeStatusSpan.innerHTML = "handshake completed!";
|
|
||||||
} catch (err) {
|
|
||||||
handshakeStatusSpan.innerHTML = err.message;
|
|
||||||
disableUI();
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// The information needs to be backed up to decrypt messages sent with
|
|
||||||
// codecs generated with the handshake. The `handshakeResult` variable
|
|
||||||
// contains private information that needs to be stored safely
|
|
||||||
const contentTopic = pairingObj.contentTopic;
|
|
||||||
const handshakeResult = pairingObj.getHandshakeResult();
|
|
||||||
|
|
||||||
// To restore the codecs for decrypting older messages, or continuing an existing
|
|
||||||
// session, use this:
|
|
||||||
[encoder, decoder] = WakuPairing.getSecureCodec(contentTopic, handshakeResult);
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
console.log("Responder");
|
|
||||||
|
|
||||||
const pairingObj = new noise.WakuPairing(sender, responder, myStaticKey, new noise.ResponderParameters());
|
|
||||||
const pExecute = pairingObj.execute(120000); // timeout after 2m
|
|
||||||
|
|
||||||
confirmAuthCodeFlow(pairingObj);
|
|
||||||
|
|
||||||
const pInfo = pairingObj.getPairingInfo();
|
|
||||||
|
|
||||||
// Data to encode in the QR code. The qrMessageNametag too to the QR string (separated by )
|
|
||||||
const qrString = arrayBufferToHex(pInfo.qrMessageNameTag) + ":" + pInfo.qrCode;
|
|
||||||
const qrURLString = window.location.href + "?" + encodeURIComponent(qrString);
|
|
||||||
|
|
||||||
handshakeStatusSpan.innerHTML = "generating QR code...";
|
|
||||||
|
|
||||||
console.log("Generating QR...");
|
|
||||||
|
|
||||||
QRCode.toCanvas(qrCanvas, qrURLString, (err) => {
|
|
||||||
if (err) {
|
|
||||||
handshakeStatusSpan.innerHTML = err.message;
|
|
||||||
disableUI();
|
|
||||||
console.error(err);
|
|
||||||
} else {
|
|
||||||
handshakeStatusSpan.innerHTML = "waiting for handshake to start";
|
|
||||||
qrUrl.href = qrURLString;
|
|
||||||
qrUrl.style.display = "block";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
handshakeStatusSpan.innerHTML = "executing handshake...";
|
|
||||||
|
|
||||||
[encoder, decoder] = await pExecute;
|
|
||||||
|
|
||||||
handshakeStatusSpan.innerHTML = "handshake completed!";
|
|
||||||
|
|
||||||
hideQR();
|
|
||||||
} catch (err) {
|
|
||||||
handshakeStatusSpan.innerHTML = err.message;
|
|
||||||
disableUI();
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// The information needs to be backed up to decrypt messages sent with
|
|
||||||
// codecs generated with the handshake. The `handshakeResult` variable
|
|
||||||
// contains private information that needs to be stored safely
|
|
||||||
const contentTopic = pairingObj.contentTopic;
|
|
||||||
const handshakeResult = pairingObj.getHandshakeResult();
|
|
||||||
|
|
||||||
// To restore the codecs for decrypting older messages, or continuing an existing
|
|
||||||
// session, use this:
|
|
||||||
[encoder, decoder] = WakuPairing.getSecureCodec(contentTopic, handshakeResult);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
nicknameInput.onchange = updateFields;
|
|
||||||
nicknameInput.onblur = updateFields;
|
|
||||||
|
|
||||||
sendButton.onclick = async () => {
|
|
||||||
const text = utils.utf8ToBytes(textInput.value);
|
|
||||||
const timestamp = new Date();
|
|
||||||
const msg = ProtoChatMessage.create({
|
|
||||||
text,
|
|
||||||
nick: nicknameInput.value,
|
|
||||||
timestamp: Math.floor(timestamp.valueOf() / 1000),
|
|
||||||
});
|
|
||||||
const payload = ProtoChatMessage.encode(msg).finish();
|
|
||||||
sendingStatusSpan.innerText = "sending...";
|
|
||||||
await node.lightPush.push(encoder, { payload, timestamp });
|
|
||||||
sendingStatusSpan.innerText = "sent!";
|
|
||||||
|
|
||||||
onMessage({ payload });
|
|
||||||
|
|
||||||
textInput.value = null;
|
|
||||||
setTimeout(() => {
|
|
||||||
sendingStatusSpan.innerText = "";
|
|
||||||
}, 5000);
|
|
||||||
};
|
|
||||||
|
|
||||||
await node.filter.subscribe([decoder], onMessage);
|
|
||||||
|
|
||||||
chatArea.style.display = "block";
|
|
||||||
} catch (err) {
|
|
||||||
wakuStatusSpan.innerHTML = err.message;
|
|
||||||
disableUI();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
main();
|
|
||||||
12433
example/package-lock.json
generated
12433
example/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@waku/noise-example",
|
|
||||||
"private": true,
|
|
||||||
"version": "0.1.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"build": "webpack --config webpack.config.js",
|
|
||||||
"start": "webpack-dev-server"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@waku/noise": "file:../",
|
|
||||||
"array-buffer-to-hex": "^1.0.0",
|
|
||||||
"hex-to-array-buffer": "^2.0.0",
|
|
||||||
"js-waku": "^0.29.0-29436ea",
|
|
||||||
"protobufjs": "^7.1.2",
|
|
||||||
"qrcode": "^1.5.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
|
||||||
"webpack": "^5.76.0",
|
|
||||||
"webpack-cli": "^4.10.0",
|
|
||||||
"webpack-dev-server": "^4.11.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,19 +0,0 @@
|
|||||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
entry: "./index.js",
|
|
||||||
output: {
|
|
||||||
path: path.resolve(__dirname, "dist"),
|
|
||||||
filename: "index.js",
|
|
||||||
},
|
|
||||||
experiments: {
|
|
||||||
asyncWebAssembly: true,
|
|
||||||
},
|
|
||||||
mode: "development",
|
|
||||||
plugins: [
|
|
||||||
new CopyWebpackPlugin({
|
|
||||||
patterns: ['index.html']
|
|
||||||
})
|
|
||||||
],
|
|
||||||
};
|
|
||||||
Loading…
x
Reference in New Issue
Block a user