mirror of
https://github.com/logos-messaging/js-noise.git
synced 2026-01-04 06:33:08 +00:00
feat: example
This commit is contained in:
parent
2cce40a6b3
commit
b4ad35597d
7
example/README.md
Normal file
7
example/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Waku Noise Pairing example app
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
Browse http://localhost:8080 and open the developer tools to see console logs
|
||||||
13
example/index.html
Normal file
13
example/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!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>
|
||||||
|
<canvas id="qrCanvas"></canvas>
|
||||||
|
<script src="./index.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
127
example/index.js
Normal file
127
example/index.js
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
import { createLightNode } from "js-waku/lib/create_waku";
|
||||||
|
import { waitForRemotePeer } from "js-waku/lib/wait_for_remote_peer";
|
||||||
|
import * as noise from "@waku/js-noise";
|
||||||
|
import QRCode from "qrcode";
|
||||||
|
// TODO: Get rid of these
|
||||||
|
import hexToArrayBuffer from "hex-to-array-buffer";
|
||||||
|
import arrayBufferToHex from "array-buffer-to-hex";
|
||||||
|
|
||||||
|
function getPairingInfo() {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmAuthCodeFlow(pairingObj) {
|
||||||
|
const authCode = await pairingObj.getAuthCode();
|
||||||
|
pairingObj.validateAuthCode(confirm("Confirm that authcode is: " + authCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// Starting the node
|
||||||
|
const node = await createLightNode();
|
||||||
|
await node.start();
|
||||||
|
|
||||||
|
// Dialing a node and wait until it's available
|
||||||
|
const ma =
|
||||||
|
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm";
|
||||||
|
await node.dial(ma, ["filter", "lightpush"]);
|
||||||
|
await waitForRemotePeer(node, ["filter", "lightpush"]);
|
||||||
|
|
||||||
|
const sender = {
|
||||||
|
async publish(encoder, msg) {
|
||||||
|
await node.lightPush.push(encoder, msg);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const msgQueue = new Array();
|
||||||
|
const receiver = {
|
||||||
|
async subscribe(decoder) {
|
||||||
|
await node.filter.subscribe([decoder], (wakuMessage) => {
|
||||||
|
msgQueue.push(wakuMessage);
|
||||||
|
// TODO: remove subscription once handshake ends?
|
||||||
|
});
|
||||||
|
},
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const myStaticKey = noise.generateX25519KeyPair();
|
||||||
|
|
||||||
|
const pairingParameters = getPairingInfo();
|
||||||
|
if (pairingParameters) {
|
||||||
|
console.log("Initiator");
|
||||||
|
|
||||||
|
const pairingObj = new noise.WakuPairing(sender, receiver, myStaticKey, pairingParameters);
|
||||||
|
confirmAuthCodeFlow(pairingObj);
|
||||||
|
try {
|
||||||
|
console.log("executing handshake...");
|
||||||
|
const codecs = await pairingObj.execute();
|
||||||
|
alert("Handshake completed!");
|
||||||
|
// TODO: enable a form so users can send messages
|
||||||
|
} catch (err) {
|
||||||
|
alert(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Receiver");
|
||||||
|
|
||||||
|
const pairingObj = new noise.WakuPairing(sender, receiver, myStaticKey, new noise.ReceiverParameters());
|
||||||
|
const pExecute = pairingObj.execute();
|
||||||
|
|
||||||
|
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 qrURL = window.location.href + "?" + encodeURIComponent(qrString);
|
||||||
|
|
||||||
|
console.log("Generating QR...")
|
||||||
|
QRCode.toCanvas(document.getElementById("qrCanvas"), qrURL, (error) => {
|
||||||
|
if (error) console.error(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Auto open page - TODO: remove this
|
||||||
|
window.setTimeout(() => {
|
||||||
|
alert("Automatically opening new page to simulate QR code being scanned");
|
||||||
|
window.open(qrURL);
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log("executing handshake...");
|
||||||
|
const codecs = await pExecute;
|
||||||
|
alert("Handshake completed!");
|
||||||
|
// TODO: enable a form so users can send messages
|
||||||
|
} catch (err) {
|
||||||
|
// TODO: hide QR
|
||||||
|
// TODO: display message indicating pairing is not valid
|
||||||
|
// TODO: handle timeout
|
||||||
|
alert(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
main();
|
||||||
12584
example/package-lock.json
generated
Normal file
12584
example/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
24
example/package.json
Normal file
24
example/package.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "@waku/js-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/js-noise": "file:../",
|
||||||
|
"array-buffer-to-hex": "^1.0.0",
|
||||||
|
"hex-to-array-buffer": "^2.0.0",
|
||||||
|
"js-waku": "^0.29.0-29436ea",
|
||||||
|
"qrcode": "^1.5.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"copy-webpack-plugin": "^11.0.0",
|
||||||
|
"webpack": "^5.74.0",
|
||||||
|
"webpack-cli": "^4.10.0",
|
||||||
|
"webpack-dev-server": "^4.11.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
19
example/webpack.config.js
Normal file
19
example/webpack.config.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
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