feat: example

This commit is contained in:
Richard Ramos 2022-12-06 23:01:56 -04:00
parent 2cce40a6b3
commit b4ad35597d
No known key found for this signature in database
GPG Key ID: BD36D48BC9FFC88C
6 changed files with 12774 additions and 0 deletions

7
example/README.md Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

24
example/package.json Normal file
View 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
View 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']
})
],
};