wip internal-dev
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
build:
|
||||
wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/credentials
|
||||
wasm-opt -Oz -o ../../dist/wasm/credentials/nym_node_tester_wasm_bg.wasm ../../dist/wasm/credentials/nym_node_tester_wasm_bg.wasm
|
||||
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
dist
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// A dependency graph that contains any wasm must all be imported
|
||||
// asynchronously. This `bootstrap.js` file does the single async import, so
|
||||
// that no one else needs to worry about it again.
|
||||
import('./index.js')
|
||||
.catch(e => console.error('Error importing `index.js`:', e));
|
||||
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Nym Credentials WebAssembly Demo</title>
|
||||
<script src="bootstrap.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
Create here the demo
|
||||
</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,173 @@
|
||||
// Copyright 2020-2023 Nym Technologies SA
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
class WebWorkerClient {
|
||||
worker = null;
|
||||
|
||||
constructor() {
|
||||
this.worker = new Worker('./worker.js');
|
||||
|
||||
this.worker.onmessage = (ev) => {
|
||||
if (ev.data && ev.data.kind) {
|
||||
switch (ev.data.kind) {
|
||||
case 'Ready':
|
||||
const {selfAddress} = ev.data.args;
|
||||
displaySenderAddress(selfAddress);
|
||||
break;
|
||||
case 'ReceiveMessage':
|
||||
const {message, senderTag, isTestPacket } = ev.data.args;
|
||||
displayReceived(message, senderTag, isTestPacket);
|
||||
break;
|
||||
case 'DisplayString':
|
||||
const { rawString } = ev.data.args;
|
||||
displayReceivedRawString(rawString)
|
||||
break;
|
||||
case 'DisableMagicTestButton':
|
||||
const magicButton = document.querySelector('#magic-button');
|
||||
magicButton.setAttribute('disabled', "true")
|
||||
break;
|
||||
case 'DisplayTesterResults':
|
||||
const {score, sentPackets, receivedPackets, receivedAcks, duplicatePackets, duplicateAcks} = ev.data.args;
|
||||
const resultText = `Test score: ${score}. Sent ${sentPackets} packets. Received ${receivedPackets} packets and ${receivedAcks} acks back. We also got ${duplicatePackets} duplicate packets and ${duplicateAcks} duplicate acks.`
|
||||
displayReceivedRawString(resultText)
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
sendMessage = (message, recipient) => {
|
||||
if (!this.worker) {
|
||||
console.error('Could not send message because worker does not exist');
|
||||
return;
|
||||
}
|
||||
|
||||
this.worker.postMessage({
|
||||
kind: 'SendMessage',
|
||||
args: {
|
||||
message, recipient,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
sendMagicPayload = (mixnodeIdentity) => {
|
||||
if (!this.worker) {
|
||||
console.error('Could not send message because worker does not exist');
|
||||
return;
|
||||
}
|
||||
|
||||
this.worker.postMessage({
|
||||
kind: 'MagicPayload',
|
||||
args: {
|
||||
mixnodeIdentity,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let client = null;
|
||||
|
||||
async function main() {
|
||||
client = new WebWorkerClient();
|
||||
|
||||
const sendButton = document.querySelector('#send-button');
|
||||
sendButton.onclick = function () {
|
||||
sendMessageTo();
|
||||
};
|
||||
|
||||
const magicButton = document.querySelector('#magic-button');
|
||||
magicButton.onclick = function () {
|
||||
sendMagicPayload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Sphinx packet and send it to the mixnet through the gateway node.
|
||||
*
|
||||
* Message and recipient are taken from the values in the user interface.
|
||||
*
|
||||
*/
|
||||
async function sendMessageTo() {
|
||||
const message = document.getElementById('message').value;
|
||||
const recipient = document.getElementById('recipient').value;
|
||||
|
||||
await client.sendMessage(message, recipient);
|
||||
displaySend(message);
|
||||
}
|
||||
|
||||
async function sendMagicPayload() {
|
||||
const payload = document.getElementById('magic_payload').value;
|
||||
await client.sendMagicPayload(payload)
|
||||
|
||||
displaySend(`clicked the button and the payload is: ${payload}...`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display messages that have been sent up the websocket. Colours them blue.
|
||||
*
|
||||
* @param {string} message
|
||||
*/
|
||||
function displaySend(message) {
|
||||
let timestamp = new Date().toISOString().substr(11, 12);
|
||||
|
||||
let sendDiv = document.createElement('div');
|
||||
let paragraph = document.createElement('p');
|
||||
paragraph.setAttribute('style', 'color: blue');
|
||||
let paragraphContent = document.createTextNode(timestamp + ' sent >>> ' + message);
|
||||
paragraph.appendChild(paragraphContent);
|
||||
|
||||
sendDiv.appendChild(paragraph);
|
||||
document.getElementById('output').appendChild(sendDiv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display received text messages in the browser. Colour them green.
|
||||
*
|
||||
* @param {Uint8Array} raw
|
||||
*/
|
||||
function displayReceived(raw, sender_tag, isTestPacket) {
|
||||
let content = new TextDecoder().decode(raw);
|
||||
if (sender_tag !== undefined) {
|
||||
console.log("this message also contained some surbs from", sender_tag)
|
||||
}
|
||||
|
||||
if (isTestPacket) {
|
||||
const decoded = JSON.parse(content)
|
||||
content = `Received packet ${decoded.msg_id} / ${decoded.total_msgs} for node ${decoded.encoded_node_identity} (test: ${decoded.test_id})`
|
||||
}
|
||||
|
||||
displayReceivedRawString(content)
|
||||
}
|
||||
|
||||
function displayReceivedRawString(raw) {
|
||||
let timestamp = new Date().toISOString().substr(11, 12);
|
||||
let receivedDiv = document.createElement('div');
|
||||
let paragraph = document.createElement('p');
|
||||
paragraph.setAttribute('style', 'color: green');
|
||||
let paragraphContent = document.createTextNode(timestamp + ' received >>> ' + raw);
|
||||
paragraph.appendChild(paragraphContent);
|
||||
receivedDiv.appendChild(paragraph);
|
||||
document.getElementById('output').appendChild(receivedDiv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the nymClient's sender address in the user interface
|
||||
*
|
||||
* @param {String} address
|
||||
*/
|
||||
function displaySenderAddress(address) {
|
||||
document.getElementById('sender').value = address;
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "create-wasm-app",
|
||||
"version": "0.1.0",
|
||||
"description": "create an app to consume rust-generated wasm packages",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
"create-wasm-app": ".bin/create-wasm-app.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"build:wasm": "cd ../ && make wasm-build",
|
||||
"start": "webpack-dev-server --port 8001"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/rustwasm/create-wasm-app.git"
|
||||
},
|
||||
"keywords": [
|
||||
"webassembly",
|
||||
"wasm",
|
||||
"rust",
|
||||
"webpack"
|
||||
],
|
||||
"author": "Gala Calero <https://github.com/gala1234>",
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nymtech/nym/issues"
|
||||
},
|
||||
"homepage": "https://nymtech.net/docs",
|
||||
"devDependencies": {
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"hello-wasm-pack": "^0.1.0",
|
||||
"webpack": "^5.70.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@nymproject/nym_node_tester_wasm": "file:../../../dist/wasm/credentials"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
performance: {
|
||||
hints: false,
|
||||
maxEntrypointSize: 512000,
|
||||
maxAssetSize: 512000
|
||||
},
|
||||
entry: {
|
||||
bootstrap: './bootstrap.js',
|
||||
worker: './worker.js',
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: '[name].js',
|
||||
},
|
||||
mode: 'development',
|
||||
// mode: 'production',
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
'index.html',
|
||||
{
|
||||
from: '../../../dist/wasm/credentials/*.(js|wasm)',
|
||||
to: '[name][ext]',
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
],
|
||||
experiments: { syncWebAssembly: true },
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
// Copyright 2020-2023 Nym Technologies SA
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
const RUST_WASM_URL = "nym_credentials_wasm_bg.wasm"
|
||||
|
||||
importScripts('nym_credentials_wasm_bg.js');
|
||||
|
||||
console.log('Initializing worker');
|
||||
|
||||
// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts`
|
||||
const {
|
||||
default_debug,
|
||||
no_cover_debug,
|
||||
NymNodeTester,
|
||||
set_panic_hook,
|
||||
currentNetworkTopology,
|
||||
} = wasm_bindgen;
|
||||
|
||||
let client = null;
|
||||
|
||||
function dummyTopology() {
|
||||
const l1Mixnode = {
|
||||
mixId: 1,
|
||||
owner: 'n1lftjhnl35cjsfd533zhgrwrspx6qmumd8vjgp9',
|
||||
host: '80.85.86.75',
|
||||
mixPort: 1789,
|
||||
identityKey: '91mNjhJSBkJ9Lb6f1iuYMDQPLiX3kAv6paSUCWjGRwQz',
|
||||
sphinxKey: 'DmfN1mL1T95nPXvLK44AQKCpW1pStHNQCi6Fgpz5dxDV',
|
||||
layer: 1,
|
||||
version: '1.1.20',
|
||||
};
|
||||
const l2Mixnode = {
|
||||
mixId: 2,
|
||||
owner: 'n18ztkyh20gwzrel0e5m4sahd358fq9p4skwa7d3',
|
||||
host: '139.162.199.75',
|
||||
mixPort: 1789,
|
||||
identityKey: 'BkLhuKQNyPS19sHZ3HHKCTKwK7hCU6XiFLndyZZHiB7s',
|
||||
sphinxKey: '7KGC97tJRhJZKhDqFcsp4Vu715VVxizuD7BktnzuSmZC',
|
||||
layer: 2,
|
||||
version: '1.1.20',
|
||||
};
|
||||
const l3Mixnode = {
|
||||
mixId: 3,
|
||||
owner: 'n1njq8h4nndp7ngays5el2rdp22hq67lwqcaq3ph',
|
||||
host: '139.162.244.139',
|
||||
identityKey: 'EPja9Kv8JtPHsFbzPdBQierMu5GmQy5roE5njyD6dmND',
|
||||
sphinxKey: 'HWpsZChDrtEH8XNscW3qJMRzdCfUD8N8DmMcKqFv7tcf',
|
||||
layer: 3,
|
||||
};
|
||||
|
||||
const gateway = {
|
||||
owner: 'n1d9lclqnfddgg57xe5p0fw4ng54m9f95hal5tlq',
|
||||
host: '85.159.211.99',
|
||||
mixPort: 1789,
|
||||
clientsPort: 9000,
|
||||
identityKey: '6pXQcG1Jt9hxBzMgTbQL5Y58z6mu4KXVRbA1idmibwsw',
|
||||
sphinxKey: 'GSdqV7GFSwHWQrVV13pNLMeafTLDVFKBKVPxuhdGrpR3',
|
||||
version: '1.1.19',
|
||||
};
|
||||
|
||||
const mixnodes = new Map();
|
||||
mixnodes.set(1, [l1Mixnode]);
|
||||
mixnodes.set(2, [l2Mixnode]);
|
||||
mixnodes.set(3, [l3Mixnode]);
|
||||
|
||||
const gateways = [gateway];
|
||||
|
||||
return {
|
||||
mixnodes, gateways
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function printAndDisplayTestResult(result) {
|
||||
result.log_details();
|
||||
|
||||
self.postMessage({
|
||||
kind: 'DisplayTesterResults',
|
||||
args: {
|
||||
score: result.score(),
|
||||
sentPackets: result.sent_packets,
|
||||
receivedPackets: result.received_packets,
|
||||
receivedAcks: result.received_acks,
|
||||
duplicatePackets: result.duplicate_packets,
|
||||
duplicateAcks: result.duplicate_acks,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function testWithNymCredentials() {
|
||||
const preferredGateway = "6pXQcG1Jt9hxBzMgTbQL5Y58z6mu4KXVRbA1idmibwsw";
|
||||
const nymApi = 'https://qa-nym-api.qa.nymte.ch/api';
|
||||
|
||||
// A) construct with hardcoded topology
|
||||
const topology = dummyTopology()
|
||||
|
||||
// optional arguments: id, gateway
|
||||
// mandatory (one of) arguments: topology, nymApi
|
||||
const nodeTester = await new NymNodeTester({ id: "foomp", topology: topology });
|
||||
|
||||
// B) first get topology directly from nym-api
|
||||
// const topology = await currentNetworkTopology(nymApi)
|
||||
// const nodeTester = await new NymNodeTester({topology});
|
||||
|
||||
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
||||
// const validator = 'https://qa-nym-api.qa.nymte.ch/api';
|
||||
// const nodeTester = await new NymNodeTester({nymApi});
|
||||
|
||||
self.onmessage = async event => {
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case 'MagicPayload': {
|
||||
const {mixnodeIdentity} = event.data.args;
|
||||
console.log("starting node test...");
|
||||
|
||||
let result = await nodeTester.test_node(mixnodeIdentity);
|
||||
printAndDisplayTestResult(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN START");
|
||||
|
||||
// load rust WASM package
|
||||
await wasm_bindgen(RUST_WASM_URL);
|
||||
console.log('Loaded RUST WASM');
|
||||
|
||||
// sets up better stack traces in case of in-rust panics
|
||||
set_panic_hook();
|
||||
//
|
||||
// run test on simplified and dedicated tester:
|
||||
await testWithTester();
|
||||
//
|
||||
console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN END")
|
||||
}
|
||||
|
||||
// Let's get started!
|
||||
main();
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user