mirror of
https://github.com/logos-messaging/lab.waku.org.git
synced 2026-01-04 23:03:08 +00:00
implement new ui
This commit is contained in:
parent
549eb9963a
commit
4256472ac6
@ -1,51 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
||||
<title>Sent Received Message Ratio</title>
|
||||
<title>Waku Dogfooding - Refactored</title>
|
||||
<link rel="apple-touch-icon" href="./favicon.png" />
|
||||
<link rel="manifest" href="./manifest.json" />
|
||||
<link rel="icon" href="./favicon.ico" />
|
||||
<style>
|
||||
#container {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
}
|
||||
#sender,
|
||||
#receiver {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h3>Waku Dogfooding App</h3>
|
||||
<div id="runningScreen" style="display: none">
|
||||
<label for="peerID">Your peer ID:</label>
|
||||
<span id="peerID"></span>
|
||||
<br />
|
||||
<label for="numSent">Messages Sent:</label>
|
||||
<span id="numSent">0</span>
|
||||
<br />
|
||||
<label for="numReceived">Messages Received:</label>
|
||||
<span id="numReceived">0</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="container">
|
||||
<div id="sender">
|
||||
<h3>Sent</h3>
|
||||
<div id="messagesSent"></div>
|
||||
</div>
|
||||
<div id="receiver">
|
||||
<h3>Received</h3>
|
||||
<div id="messagesReceived"></div>
|
||||
</div>
|
||||
<link rel="stylesheet" href="./style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="app-container">
|
||||
<header>
|
||||
<h1>Waku Message Center</h1>
|
||||
<div class="connection-status">
|
||||
<span>Your Peer ID: <span id="peerIdDisplay">Connecting...</span></span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="message-stats">
|
||||
<h2>Message Statistics</h2>
|
||||
<div class="stats-counters">
|
||||
<div>
|
||||
<span class="counter-value" id="sentByMeCount">0</span>
|
||||
<span class="counter-label">Sent by Me</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="counter-value" id="receivedMineCount">0</span>
|
||||
<span class="counter-label">Received (Mine)</span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="counter-value" id="receivedOthersCount">0</span>
|
||||
<span class="counter-label">Received (Others)</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="message-controls">
|
||||
<h2>Controls</h2>
|
||||
<button id="sendMessageButton" class="btn btn-primary">Send New Message Batch</button>
|
||||
<div class="search-container">
|
||||
<input type="text" id="searchInput" placeholder="Search messages by content..." />
|
||||
<button id="searchButton" class="btn">Search</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="message-display">
|
||||
<h2>Message Log</h2>
|
||||
<div id="messageList" class="message-list">
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>Waku Dogfooding App - Modern UI</p>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
172
examples/dogfooding/package-lock.json
generated
172
examples/dogfooding/package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^5.0.5",
|
||||
"@multiformats/multiaddr": "^12.3.1",
|
||||
"@waku/sdk": "0.0.30-0e49a1e.0",
|
||||
"@waku/sdk": "0.0.32-16328a3.0",
|
||||
"libp2p": "^2.1.10",
|
||||
"protobufjs": "^7.3.0",
|
||||
"uint8arrays": "^5.1.0"
|
||||
@ -35,9 +35,9 @@
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@chainsafe/as-sha256": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-1.0.1.tgz",
|
||||
"integrity": "sha512-4Y/kQm0LsJ6QRtGcMq6gOdQP+fZhWDfIV2eIqP6oFJZBWYGmdh3wm8YbrXDPLJO87X2Fu6koRLdUS00O3k14Hw==",
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@chainsafe/as-sha256/-/as-sha256-0.4.2.tgz",
|
||||
"integrity": "sha512-HJ8GZBRjLeWtRsAXf3EbNsNzmTGpzTFjfpSf4yHkLYC+E52DhT6hwz+7qpj6I/EmFzSUm5tYYvT9K8GZokLQCQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@chainsafe/is-ip": {
|
||||
@ -47,20 +47,20 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@chainsafe/libp2p-noise": {
|
||||
"version": "16.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@chainsafe/libp2p-noise/-/libp2p-noise-16.1.0.tgz",
|
||||
"integrity": "sha512-GJA/i5pd6VmetxokvnPlEbVCeL7SfLHkSuUHwbJ4w0u7dZUbse4Hr8SA8RYGwNHbZr2TEKFC9WerhvMWbciIrQ==",
|
||||
"version": "16.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@chainsafe/libp2p-noise/-/libp2p-noise-16.0.0.tgz",
|
||||
"integrity": "sha512-8rqr8V1RD2/lVbfL0Bb//N8iPOFof11cUe8v8z8xJT7fUhCAbtCCSM4jbwI4HCnw0MvHLmcpmAfDCFRwcWzoeA==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"@chainsafe/as-chacha20poly1305": "^0.1.0",
|
||||
"@chainsafe/as-sha256": "^1.0.0",
|
||||
"@chainsafe/as-sha256": "^0.4.1",
|
||||
"@libp2p/crypto": "^5.0.0",
|
||||
"@libp2p/interface": "^2.0.0",
|
||||
"@libp2p/peer-id": "^5.0.0",
|
||||
"@noble/ciphers": "^1.1.3",
|
||||
"@noble/ciphers": "^0.6.0",
|
||||
"@noble/curves": "^1.1.0",
|
||||
"@noble/hashes": "^1.3.1",
|
||||
"it-length-prefixed": "^10.0.1",
|
||||
"it-length-prefixed": "^9.0.1",
|
||||
"it-length-prefixed-stream": "^1.0.0",
|
||||
"it-pair": "^2.0.6",
|
||||
"it-pipe": "^3.0.1",
|
||||
@ -71,6 +71,23 @@
|
||||
"wherearewe": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@chainsafe/libp2p-noise/node_modules/it-length-prefixed": {
|
||||
"version": "9.1.1",
|
||||
"resolved": "https://registry.npmjs.org/it-length-prefixed/-/it-length-prefixed-9.1.1.tgz",
|
||||
"integrity": "sha512-O88nBweT6M9ozsmok68/auKH7ik/slNM4pYbM9lrfy2z5QnpokW5SlrepHZDKtN71llhG2sZvd6uY4SAl+lAQg==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"it-reader": "^6.0.1",
|
||||
"it-stream-types": "^2.0.1",
|
||||
"uint8-varint": "^2.0.1",
|
||||
"uint8arraylist": "^2.0.0",
|
||||
"uint8arrays": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0",
|
||||
"npm": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@chainsafe/netmask": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@chainsafe/netmask/-/netmask-2.0.0.tgz",
|
||||
@ -680,13 +697,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/ciphers": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.2.1.tgz",
|
||||
"integrity": "sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==",
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-0.6.0.tgz",
|
||||
"integrity": "sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^14.21.3 || >=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
@ -719,9 +733,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/secp256k1": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz",
|
||||
"integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==",
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.2.tgz",
|
||||
"integrity": "sha512-/qzwYl5eFLH8OWIecQWM31qld2g1NfjgylK+TNhqtaUKP37Nm+Y+z30Fjhw0Ct8p9yCQEm2N3W/AckdIb3SMcQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@ -1513,16 +1527,16 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@waku/discovery": {
|
||||
"version": "0.0.7-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/discovery/-/discovery-0.0.7-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-dHj/0w11V+Fkfl7T0MqJ9VEINAvuleU8vJ1hLifBbg7lbUWFe8b24qzPNzhqsxV93cLR+okhM7gj0N2yeVpaOQ==",
|
||||
"version": "0.0.9-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/discovery/-/discovery-0.0.9-16328a3.0.tgz",
|
||||
"integrity": "sha512-s3tQpF4t0G/Fa5BCwO+92vf9gPczaz3YIGhrctdU1SYoS5CHhQ0JZ44HKHv/nL+eIzRKwimiGAk3RjLW7Z9pIw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@waku/core": "0.0.34-0e49a1e.0",
|
||||
"@waku/enr": "0.0.28-0e49a1e.0",
|
||||
"@waku/interfaces": "0.0.29-0e49a1e.0",
|
||||
"@waku/proto": "0.0.9-0e49a1e.0",
|
||||
"@waku/utils": "0.0.22-0e49a1e.0",
|
||||
"@waku/core": "0.0.36-16328a3.0",
|
||||
"@waku/enr": "0.0.30-16328a3.0",
|
||||
"@waku/interfaces": "0.0.31-16328a3.0",
|
||||
"@waku/proto": "0.0.11-16328a3.0",
|
||||
"@waku/utils": "0.0.24-16328a3.0",
|
||||
"debug": "^4.3.4",
|
||||
"dns-over-http-resolver": "^3.0.8",
|
||||
"hi-base32": "^0.5.1",
|
||||
@ -1533,16 +1547,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/discovery/node_modules/@waku/core": {
|
||||
"version": "0.0.34-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.34-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-kihMebnMzUnZXAwkAiya34jkcvogkRcszCzaIKO0m4StytKqLBmR1I5MmN9OcsFbygVeGMnax+8K+EHlemSOfg==",
|
||||
"version": "0.0.36-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.36-16328a3.0.tgz",
|
||||
"integrity": "sha512-+5GNNcy3FYnPKaL0RuJ01oo3+wMqkVhHPKdpRc3T0Rodi6IZsFCFdT1ob3A5rpFo5IURXqNjElUVBItIGrtupw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@libp2p/ping": "2.0.1",
|
||||
"@waku/enr": "0.0.28-0e49a1e.0",
|
||||
"@waku/interfaces": "0.0.29-0e49a1e.0",
|
||||
"@waku/proto": "0.0.9-0e49a1e.0",
|
||||
"@waku/utils": "0.0.22-0e49a1e.0",
|
||||
"@waku/enr": "0.0.30-16328a3.0",
|
||||
"@waku/interfaces": "0.0.31-16328a3.0",
|
||||
"@waku/proto": "0.0.11-16328a3.0",
|
||||
"@waku/utils": "0.0.24-16328a3.0",
|
||||
"debug": "^4.3.4",
|
||||
"it-all": "^3.0.4",
|
||||
"it-length-prefixed": "^9.0.4",
|
||||
@ -1633,9 +1647,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/enr": {
|
||||
"version": "0.0.28-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/enr/-/enr-0.0.28-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-K9LcAf3c0pSfmVgx0I17V9wM7idAqu6VdlICrVcxL7ZVnIUPH+Skmk/S15LS9YigDwl283+hmwL8zO8P8inM+g==",
|
||||
"version": "0.0.30-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/enr/-/enr-0.0.30-16328a3.0.tgz",
|
||||
"integrity": "sha512-9D4WVJcuL/ncVsHb7KyeIkkDJia6UVdNK9Kf1u9BhvJBtzioPGgXrmp1O7CsXpIKVu4f8IVCu1Lc6hUVG84Chw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@ethersproject/rlp": "^5.7.0",
|
||||
@ -1643,7 +1657,7 @@
|
||||
"@libp2p/peer-id": "^5.0.1",
|
||||
"@multiformats/multiaddr": "^12.0.0",
|
||||
"@noble/secp256k1": "^1.7.1",
|
||||
"@waku/utils": "0.0.22-0e49a1e.0",
|
||||
"@waku/utils": "0.0.24-16328a3.0",
|
||||
"debug": "^4.3.4",
|
||||
"js-sha3": "^0.9.2"
|
||||
},
|
||||
@ -1660,34 +1674,34 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/interfaces": {
|
||||
"version": "0.0.29-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/interfaces/-/interfaces-0.0.29-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-TaGr2cshZ2qmZsix+QNWwKFjefcOgXnBQk0P1RGE7lGo22KmxLqwwjeEMkmyud3El826Ukg6XprKliVGrceBzA==",
|
||||
"version": "0.0.31-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/interfaces/-/interfaces-0.0.31-16328a3.0.tgz",
|
||||
"integrity": "sha512-2jZCwBSBKd7PX12xJadMmxMpIKGR9SrQTnTqUfDD4aT72GQ9SpaqQDY5h+svMt/qjriZMBSUpITQQF04w0GIaw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@waku/proto": "0.0.9-0e49a1e.0"
|
||||
"@waku/proto": "0.0.11-16328a3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/message-hash": {
|
||||
"version": "0.1.18-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/message-hash/-/message-hash-0.1.18-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-n3S8WOQhp8jj2hLUmRQ2LnJMpJb4E04ZrmknpJ6XIQru0pWq2LV2qqJe3+5RpvrM+JADc6HggmCjxYojW0EkZA==",
|
||||
"version": "0.1.20-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/message-hash/-/message-hash-0.1.20-16328a3.0.tgz",
|
||||
"integrity": "sha512-j1FHSgeJeKnc9Tet3/NcrNjOV1gKa6U3WXNe/uBRZsvn2P30Qg6a1Am2eMfxpmO3ggXz25ywe2WDNA/K4vk/RQ==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/utils": "0.0.22-0e49a1e.0"
|
||||
"@waku/utils": "0.0.24-16328a3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/proto": {
|
||||
"version": "0.0.9-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/proto/-/proto-0.0.9-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-rf82UD5KFobmGrsd/l5AFNACPcP9k0yEfq5eNgoOH5rGo/BFs9N5L7Wi9E+56b5hxPcA8b+2bpu1EGgQuDq2gw==",
|
||||
"version": "0.0.11-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/proto/-/proto-0.0.11-16328a3.0.tgz",
|
||||
"integrity": "sha512-yFGW6UaQC0MrffZV25uVDYC8sUxI6OpnizTfSyebLg84eihYHJyxTed7pD/EyjSl8vL9GFX8nDuksDbkIQ2OQw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"protons-runtime": "^5.4.0"
|
||||
@ -1697,24 +1711,24 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/sdk": {
|
||||
"version": "0.0.30-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/sdk/-/sdk-0.0.30-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-j6L+2idHmx0f5HUHtLW6uqc4F1/JSQKVsqL3Mqyh1OrwaYqKAfDqvOyJq8hb9auWRCOTHZs0Bs5g7iA99kti2Q==",
|
||||
"version": "0.0.32-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/sdk/-/sdk-0.0.32-16328a3.0.tgz",
|
||||
"integrity": "sha512-tHS2+lf7NMQekuxfrZOGsMWya35W8saxjMjPnIRE6FOq0Mlv1ADwso05W7iy9ExNJoFD3+4XVemDvc5RfIM75w==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chainsafe/libp2p-noise": "^16.0.0",
|
||||
"@chainsafe/libp2p-noise": "16.0.0",
|
||||
"@libp2p/bootstrap": "^11.0.1",
|
||||
"@libp2p/identify": "^3.0.1",
|
||||
"@libp2p/mplex": "^11.0.1",
|
||||
"@libp2p/ping": "2.0.1",
|
||||
"@libp2p/websockets": "^9.0.1",
|
||||
"@noble/hashes": "^1.3.3",
|
||||
"@waku/core": "0.0.34-0e49a1e.0",
|
||||
"@waku/discovery": "0.0.7-0e49a1e.0",
|
||||
"@waku/interfaces": "0.0.29-0e49a1e.0",
|
||||
"@waku/message-hash": "0.1.18-0e49a1e.0",
|
||||
"@waku/proto": "0.0.9-0e49a1e.0",
|
||||
"@waku/utils": "0.0.22-0e49a1e.0",
|
||||
"@waku/core": "0.0.36-16328a3.0",
|
||||
"@waku/discovery": "0.0.9-16328a3.0",
|
||||
"@waku/interfaces": "0.0.31-16328a3.0",
|
||||
"@waku/message-hash": "0.1.20-16328a3.0",
|
||||
"@waku/proto": "0.0.11-16328a3.0",
|
||||
"@waku/utils": "0.0.24-16328a3.0",
|
||||
"libp2p": "2.1.8"
|
||||
},
|
||||
"engines": {
|
||||
@ -1722,16 +1736,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/sdk/node_modules/@waku/core": {
|
||||
"version": "0.0.34-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.34-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-kihMebnMzUnZXAwkAiya34jkcvogkRcszCzaIKO0m4StytKqLBmR1I5MmN9OcsFbygVeGMnax+8K+EHlemSOfg==",
|
||||
"version": "0.0.36-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/core/-/core-0.0.36-16328a3.0.tgz",
|
||||
"integrity": "sha512-+5GNNcy3FYnPKaL0RuJ01oo3+wMqkVhHPKdpRc3T0Rodi6IZsFCFdT1ob3A5rpFo5IURXqNjElUVBItIGrtupw==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@libp2p/ping": "2.0.1",
|
||||
"@waku/enr": "0.0.28-0e49a1e.0",
|
||||
"@waku/interfaces": "0.0.29-0e49a1e.0",
|
||||
"@waku/proto": "0.0.9-0e49a1e.0",
|
||||
"@waku/utils": "0.0.22-0e49a1e.0",
|
||||
"@waku/enr": "0.0.30-16328a3.0",
|
||||
"@waku/interfaces": "0.0.31-16328a3.0",
|
||||
"@waku/proto": "0.0.11-16328a3.0",
|
||||
"@waku/utils": "0.0.24-16328a3.0",
|
||||
"debug": "^4.3.4",
|
||||
"it-all": "^3.0.4",
|
||||
"it-length-prefixed": "^9.0.4",
|
||||
@ -1820,13 +1834,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@waku/utils": {
|
||||
"version": "0.0.22-0e49a1e.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/utils/-/utils-0.0.22-0e49a1e.0.tgz",
|
||||
"integrity": "sha512-4aHZK5w4kGN1GgJMQOTwplwPIwiRefsDn2/bfcP87+EPGPw3toaDSWfOhWLvh2ZG1Zsk6k5eZmN4WF/oHx9NdA==",
|
||||
"version": "0.0.24-16328a3.0",
|
||||
"resolved": "https://registry.npmjs.org/@waku/utils/-/utils-0.0.24-16328a3.0.tgz",
|
||||
"integrity": "sha512-zYNeWtRAYGJLVvE/8xnKmO5ctxuPD6/k9NAS/g3ES0o++kBrXNRFy3d1V1nKlnerwJuwYmB0RhfwFmz7ehtwWA==",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/interfaces": "0.0.29-0e49a1e.0",
|
||||
"@waku/interfaces": "0.0.31-16328a3.0",
|
||||
"chai": "^4.3.10",
|
||||
"debug": "^4.3.4",
|
||||
"uint8arrays": "^5.0.1"
|
||||
@ -3283,9 +3297,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/dns-over-http-resolver": {
|
||||
"version": "3.0.10",
|
||||
"resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-3.0.10.tgz",
|
||||
"integrity": "sha512-l2kMOLxK6f9ll+5sf2Ndl8WS/2eXhOf9ZSXZMPnTVyHsv1ktN1WX3FwcyYklMq3ORv2N1nhf0TsGKWBjhgn0ug==",
|
||||
"version": "3.0.15",
|
||||
"resolved": "https://registry.npmjs.org/dns-over-http-resolver/-/dns-over-http-resolver-3.0.15.tgz",
|
||||
"integrity": "sha512-h2Ldu6b8LjW725Q5zjjv7T5s1K3dPjlU3DWvcEFqB3Ksb3QmqC4dHhPKlGlBS/1P47D4T5arZMiE4dD4OIfO6A==",
|
||||
"license": "Apache-2.0 OR MIT",
|
||||
"dependencies": {
|
||||
"quick-lru": "^7.0.0",
|
||||
@ -5727,9 +5741,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/it-first": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/it-first/-/it-first-3.0.7.tgz",
|
||||
"integrity": "sha512-e2dVSlOP+pAxPYPVJBF4fX7au8cvGfvLhIrGCMc5aWDnCvwgOo94xHbi3Da6eXQ2jPL5FGEM8sJMn5uE8Seu+g==",
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/it-first/-/it-first-3.0.8.tgz",
|
||||
"integrity": "sha512-neaRRwOMCmMKkXJVZ4bvUDVlde+Xh0aTWr7hFaOZeDXzbctGVV/WHmPVqBqy3RjlsP7eRM0vcqNtlM8hivcmGw==",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
},
|
||||
"node_modules/it-foreach": {
|
||||
@ -7185,9 +7199,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/quick-lru": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.0.0.tgz",
|
||||
"integrity": "sha512-MX8gB7cVYTrYcFfAnfLlhRd0+Toyl8yX8uBx1MrX7K0jegiz9TumwOK27ldXrgDlHRdVi+MqU9Ssw6dr4BNreg==",
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-7.0.1.tgz",
|
||||
"integrity": "sha512-kLjThirJMkWKutUKbZ8ViqFc09tDQhlbQo2MNuVeLWbRauqYP96Sm6nzlQ24F0HFjUNZ4i9+AgldJ9H6DZXi7g==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
"dependencies": {
|
||||
"@libp2p/crypto": "^5.0.5",
|
||||
"@multiformats/multiaddr": "^12.3.1",
|
||||
"@waku/sdk": "0.0.30-0e49a1e.0",
|
||||
"@waku/sdk": "0.0.32-16328a3.0",
|
||||
"libp2p": "^2.1.10",
|
||||
"protobufjs": "^7.3.0",
|
||||
"uint8arrays": "^5.1.0"
|
||||
|
||||
187
examples/dogfooding/public/style.css
Normal file
187
examples/dogfooding/public/style.css
Normal file
@ -0,0 +1,187 @@
|
||||
/* General Styles */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
margin: 0;
|
||||
background-color: #f4f7f9;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.app-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: #2c3e50;
|
||||
color: #ecf0f1;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 0;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
.connection-status span {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
main {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
section {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
color: #3498db;
|
||||
border-bottom: 2px solid #ecf0f1;
|
||||
padding-bottom: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* Message Statistics */
|
||||
.stats-counters {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.counter-value {
|
||||
display: block;
|
||||
font-size: 2em;
|
||||
font-weight: bold;
|
||||
color: #2980b9;
|
||||
}
|
||||
|
||||
.counter-label {
|
||||
font-size: 0.9em;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
/* Message Controls */
|
||||
.btn {
|
||||
padding: 10px 15px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
font-size: 1em;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #3498db;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
#searchInput {
|
||||
flex-grow: 1;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/* Message Display */
|
||||
.message-list {
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
border: 1px solid #ecf0f1;
|
||||
border-radius: 5px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.message-item {
|
||||
padding: 10px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 4px;
|
||||
background-color: #ecf0f1;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.message-item.sent {
|
||||
background-color: #eafaf1; /* Light green for sent */
|
||||
}
|
||||
|
||||
.message-item.received-mine {
|
||||
background-color: #e8f6fd; /* Light blue for received (mine) */
|
||||
}
|
||||
|
||||
.message-item.received-other {
|
||||
background-color: #fdf3e8; /* Light orange for received (other) */
|
||||
}
|
||||
|
||||
.message-item p {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.message-item .timestamp {
|
||||
font-size: 0.8em;
|
||||
color: #7f8c8d;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.message-item .content {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.message-item .sender-info {
|
||||
font-size: 0.8em;
|
||||
color: #34495e;
|
||||
}
|
||||
|
||||
/* Added style for Message ID */
|
||||
.message-item .message-id {
|
||||
font-size: 0.75em;
|
||||
color: #888;
|
||||
margin-bottom: 3px;
|
||||
word-break: break-all; /* Ensure long IDs don't break layout */
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #ecf0f1;
|
||||
font-size: 0.9em;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (min-width: 768px) {
|
||||
main {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.message-stats, .message-controls {
|
||||
grid-column: span 1;
|
||||
}
|
||||
|
||||
.message-display {
|
||||
grid-column: span 2;
|
||||
}
|
||||
}
|
||||
@ -1,176 +1,139 @@
|
||||
import {
|
||||
createLightNode,
|
||||
createEncoder,
|
||||
createDecoder,
|
||||
DecodedMessage,
|
||||
LightNode,
|
||||
utils,
|
||||
} from "@waku/sdk";
|
||||
import { generateKeyPairFromSeed } from "@libp2p/crypto/keys";
|
||||
import { fromString } from "uint8arrays";
|
||||
|
||||
import { Type, Field } from "protobufjs";
|
||||
getWakuNode,
|
||||
createWakuEncoder,
|
||||
createWakuDecoder,
|
||||
getPeerId
|
||||
} from "./waku-service";
|
||||
import { DecodedMessage } from "@waku/sdk";
|
||||
import {
|
||||
generateRandomNumber,
|
||||
sha256,
|
||||
} from "./util";
|
||||
encodeMessage,
|
||||
decodeMessage,
|
||||
ChatMessage,
|
||||
ProtoChatMessage,
|
||||
} from "./message-service";
|
||||
import {
|
||||
updatePeerIdDisplay,
|
||||
incrementSentByMe,
|
||||
incrementReceivedMine,
|
||||
incrementReceivedOthers,
|
||||
addMessageToLog,
|
||||
renderMessages,
|
||||
getSearchTerm,
|
||||
} from "./ui-manager";
|
||||
|
||||
const DEFAULT_CONTENT_TOPIC = "/js-waku-examples/1/message-ratio/utf8";
|
||||
const NUM_MESSAGES_PER_BATCH = 5;
|
||||
let batchCounter = 0;
|
||||
|
||||
const ProtoSequencedMessage = new Type("SequencedMessage")
|
||||
.add(new Field("hash", 1, "string"))
|
||||
.add(new Field("total", 2, "uint64"))
|
||||
.add(new Field("index", 3, "uint64"))
|
||||
.add(new Field("sender", 4, "string"));
|
||||
async function initializeApp() {
|
||||
try {
|
||||
console.log("Initializing Waku node...");
|
||||
const node = await getWakuNode();
|
||||
const currentPeerId = getPeerId();
|
||||
console.log("Waku node initialized. Peer ID:", currentPeerId);
|
||||
|
||||
const sequenceCompletedEvent = new CustomEvent("sequenceCompleted");
|
||||
|
||||
async function wakuNode(): Promise<LightNode> {
|
||||
let seed = localStorage.getItem("seed");
|
||||
|
||||
if (!seed) {
|
||||
seed = (await sha256(generateRandomNumber())).slice(0, 32);
|
||||
localStorage.setItem("seed", seed);
|
||||
}
|
||||
|
||||
const privateKey = await generateKeyPairFromSeed("Ed25519", fromString(seed));
|
||||
|
||||
const node = await createLightNode({
|
||||
defaultBootstrap: false,
|
||||
networkConfig: {
|
||||
clusterId: 42,
|
||||
shards: [0]
|
||||
},
|
||||
numPeersToUse: 2,
|
||||
libp2p: {
|
||||
privateKey,
|
||||
},
|
||||
});
|
||||
|
||||
(window as any).waku = node;
|
||||
|
||||
await Promise.allSettled([
|
||||
node.dial("/dns4/waku-test.bloxy.one/tcp/8095/wss/p2p/16Uiu2HAmSZbDB7CusdRhgkD81VssRjQV5ZH13FbzCGcdnbbh6VwZ"),
|
||||
node.dial("/dns4/vps-aaa00d52.vps.ovh.ca/tcp/8000/wss/p2p/16Uiu2HAm9PftGgHZwWE3wzdMde4m3kT2eYJFXLZfGoSED3gysofk")
|
||||
]);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export async function app() {
|
||||
const node = await wakuNode();
|
||||
|
||||
console.log("DEBUG: your peer ID is:", node.libp2p.peerId.toString());
|
||||
|
||||
await node.start();
|
||||
await node.waitForPeers();
|
||||
|
||||
const peerId = node.libp2p.peerId.toString();
|
||||
const encoder = createEncoder({
|
||||
contentTopic: DEFAULT_CONTENT_TOPIC,
|
||||
pubsubTopicShardInfo: {
|
||||
clusterId: 42,
|
||||
shard: 0,
|
||||
if (currentPeerId) {
|
||||
updatePeerIdDisplay(currentPeerId);
|
||||
}
|
||||
});
|
||||
|
||||
const startLightPushSequence = async (
|
||||
numMessages: number,
|
||||
period: number = 3000
|
||||
) => {
|
||||
const sequenceHash = await sha256(generateRandomNumber());
|
||||
const sequenceTotal = numMessages;
|
||||
let sequenceIndex = 0;
|
||||
const sendMessageBatch = async () => {
|
||||
const encoder = createWakuEncoder();
|
||||
batchCounter++;
|
||||
console.log(`Sending batch C${batchCounter} of ${NUM_MESSAGES_PER_BATCH} messages...`);
|
||||
for (let i = 0; i < NUM_MESSAGES_PER_BATCH; i++) {
|
||||
const messageContent = `Batch ${batchCounter} - Msg ${i + 1} @ ${new Date().toLocaleTimeString()}`;
|
||||
const payload = encodeMessage(messageContent);
|
||||
|
||||
const sendMessage = async () => {
|
||||
try {
|
||||
const messageHash = await sha256(
|
||||
`${sequenceHash}-${sequenceIndex}-${sequenceTotal}`
|
||||
);
|
||||
const tempDecodedMessage = ProtoChatMessage.decode(payload);
|
||||
const messageId = (tempDecodedMessage as any).id || `temp-id-${Date.now()}`;
|
||||
|
||||
const message = ProtoSequencedMessage.create({
|
||||
hash: messageHash,
|
||||
total: sequenceTotal,
|
||||
index: sequenceIndex,
|
||||
sender: peerId,
|
||||
});
|
||||
const payload = ProtoSequencedMessage.encode(message).finish();
|
||||
const chatMessage: ChatMessage = {
|
||||
id: messageId,
|
||||
timestamp: Date.now(),
|
||||
senderPeerId: currentPeerId || "unknown",
|
||||
content: messageContent
|
||||
};
|
||||
|
||||
const result = await node.lightPush.send(
|
||||
encoder,
|
||||
{
|
||||
try {
|
||||
const result = await node.lightPush.send(encoder, {
|
||||
payload,
|
||||
timestamp: new Date(),
|
||||
},
|
||||
{ autoRetry: true }
|
||||
);
|
||||
timestamp: new Date(chatMessage.timestamp),
|
||||
}, { autoRetry: true });
|
||||
|
||||
console.log("DEBUG: light push successes: ", result.successes.length);
|
||||
console.log(
|
||||
"DEBUG: light push failures: ",
|
||||
result.failures.length
|
||||
);
|
||||
if (result.successes.length > 0) {
|
||||
console.log(`Message ${i + 1} (ID: ${chatMessage.id}) sent successfully.`);
|
||||
incrementSentByMe();
|
||||
addMessageToLog(chatMessage, 'sent');
|
||||
} else {
|
||||
console.warn(`Failed to send message ${i + 1} (ID: ${chatMessage.id}):`, result.failures);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error sending message ${i + 1} (ID: ${chatMessage.id}):`, error);
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
console.log("Message batch sending complete.");
|
||||
};
|
||||
|
||||
// Increment sequence
|
||||
sequenceIndex++;
|
||||
const subscribeToMessages = async () => {
|
||||
const decoder = createWakuDecoder();
|
||||
console.log("Subscribing to messages...");
|
||||
await node.filter.subscribe(decoder, (wakuMessage: DecodedMessage) => {
|
||||
console.log("Raw Waku message received, payload length:", wakuMessage.payload.length);
|
||||
const chatMessage = decodeMessage(wakuMessage.payload);
|
||||
|
||||
if (sequenceIndex < sequenceTotal) {
|
||||
setTimeout(sendMessage, period); // Schedule the next send
|
||||
if (chatMessage) {
|
||||
console.log("Decoded chat message:", chatMessage);
|
||||
if (chatMessage.senderPeerId === currentPeerId) {
|
||||
incrementReceivedMine();
|
||||
console.log("Received own message (loopback):", chatMessage.id);
|
||||
} else {
|
||||
incrementReceivedOthers();
|
||||
addMessageToLog(chatMessage, 'received-other');
|
||||
console.log("Received message from other peer:", chatMessage.id);
|
||||
}
|
||||
} else {
|
||||
document.dispatchEvent(sequenceCompletedEvent);
|
||||
console.warn("Could not decode received Waku message. Payload might be malformed or not a ChatMessage.");
|
||||
}
|
||||
|
||||
if ( result.successes.length > 0) {
|
||||
const messageElement = document.createElement("div");
|
||||
messageElement.textContent = messageHash;
|
||||
|
||||
document.getElementById("messagesSent")?.appendChild(messageElement);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("DEBUG: Error sending message", error);
|
||||
}
|
||||
});
|
||||
console.log("Subscription active.");
|
||||
};
|
||||
|
||||
sendMessage(); // Start the recursive sending
|
||||
};
|
||||
const sendMessageButton = document.getElementById("sendMessageButton");
|
||||
if (sendMessageButton) {
|
||||
sendMessageButton.addEventListener("click", () => {
|
||||
console.log("Send Message Button clicked");
|
||||
sendMessageBatch();
|
||||
});
|
||||
}
|
||||
|
||||
const startFilterSubscription = async () => {
|
||||
const decoder = createDecoder(DEFAULT_CONTENT_TOPIC, { clusterId: 42, shard: 0 });
|
||||
const searchButton = document.getElementById("searchButton");
|
||||
if (searchButton) {
|
||||
searchButton.addEventListener("click", () => {
|
||||
console.log("Search button clicked");
|
||||
renderMessages(getSearchTerm());
|
||||
});
|
||||
}
|
||||
|
||||
const searchInput = document.getElementById("searchInput");
|
||||
if(searchInput) {
|
||||
searchInput.addEventListener("input", () => {
|
||||
console.log("Search input changed");
|
||||
renderMessages(getSearchTerm());
|
||||
});
|
||||
}
|
||||
|
||||
const subscriptionCallback = async (message: DecodedMessage) => {
|
||||
const decodedMessage: any = ProtoSequencedMessage.decode(
|
||||
message.payload
|
||||
);
|
||||
await subscribeToMessages();
|
||||
|
||||
console.log("Application setup complete. Click 'Send New Message Batch' to send messages.");
|
||||
|
||||
if (decodedMessage.sender === peerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const messageElement = document.createElement("div");
|
||||
messageElement.textContent = decodedMessage.hash;
|
||||
|
||||
document.getElementById("messagesReceived")?.appendChild(messageElement);
|
||||
};
|
||||
|
||||
await node.nextFilter.subscribe(decoder, subscriptionCallback);
|
||||
await node.nextFilter.subscribe(decoder, subscriptionCallback);
|
||||
};
|
||||
|
||||
return {
|
||||
node,
|
||||
startLightPushSequence,
|
||||
startFilterSubscription,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Critical error during app initialization:", error);
|
||||
const peerIdDisplayEl = document.getElementById("peerIdDisplay");
|
||||
if(peerIdDisplayEl) peerIdDisplayEl.textContent = "Error connecting to Waku Network.";
|
||||
}
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const { startLightPushSequence, startFilterSubscription } = await app();
|
||||
|
||||
startFilterSubscription();
|
||||
|
||||
document.addEventListener(sequenceCompletedEvent.type, () =>
|
||||
startLightPushSequence(10, 3000)
|
||||
);
|
||||
|
||||
startLightPushSequence(10, 3000);
|
||||
})();
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
console.log("DOM fully loaded and parsed. Starting app initialization.");
|
||||
initializeApp();
|
||||
});
|
||||
|
||||
42
examples/dogfooding/src/message-service.ts
Normal file
42
examples/dogfooding/src/message-service.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { Type, Field } from "protobufjs";
|
||||
import { getPeerId } from "./waku-service";
|
||||
|
||||
// New message structure with a unique ID and content for searchability
|
||||
export const ProtoChatMessage = new Type("ChatMessage")
|
||||
.add(new Field("id", 1, "string")) // Unique message ID (e.g., UUID or timestamp-based)
|
||||
.add(new Field("timestamp", 2, "uint64"))
|
||||
.add(new Field("senderPeerId", 3, "string"))
|
||||
.add(new Field("content", 4, "string")); // Actual message content
|
||||
|
||||
export interface ChatMessage {
|
||||
id: string;
|
||||
timestamp: number;
|
||||
senderPeerId: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export function encodeMessage(content: string): Uint8Array {
|
||||
const id = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
||||
const message = ProtoChatMessage.create({
|
||||
id,
|
||||
timestamp: Date.now(),
|
||||
senderPeerId: getPeerId() || "unknown",
|
||||
content,
|
||||
});
|
||||
return ProtoChatMessage.encode(message).finish();
|
||||
}
|
||||
|
||||
export function decodeMessage(payload: Uint8Array): ChatMessage | null {
|
||||
try {
|
||||
const decoded = ProtoChatMessage.decode(payload) as any;
|
||||
return {
|
||||
id: decoded.id,
|
||||
timestamp: Number(decoded.timestamp),
|
||||
senderPeerId: decoded.senderPeerId,
|
||||
content: decoded.content,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Failed to decode message:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
105
examples/dogfooding/src/ui-manager.ts
Normal file
105
examples/dogfooding/src/ui-manager.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import { ChatMessage } from "./message-service";
|
||||
|
||||
const sentByMeCountEl = document.getElementById("sentByMeCount") as HTMLSpanElement;
|
||||
const receivedMineCountEl = document.getElementById("receivedMineCount") as HTMLSpanElement;
|
||||
const receivedOthersCountEl = document.getElementById("receivedOthersCount") as HTMLSpanElement;
|
||||
const peerIdDisplayEl = document.getElementById("peerIdDisplay") as HTMLSpanElement;
|
||||
const messageListEl = document.getElementById("messageList") as HTMLDivElement;
|
||||
const searchInputEl = document.getElementById("searchInput") as HTMLInputElement;
|
||||
|
||||
let sentByMe = 0;
|
||||
let receivedMine = 0;
|
||||
let receivedOthers = 0;
|
||||
|
||||
let currentMessages: ChatMessage[] = [];
|
||||
let currentPeerId: string | undefined;
|
||||
|
||||
export function updatePeerIdDisplay(peerId: string) {
|
||||
currentPeerId = peerId;
|
||||
if (peerIdDisplayEl) {
|
||||
peerIdDisplayEl.textContent = peerId;
|
||||
}
|
||||
}
|
||||
|
||||
export function incrementSentByMe() {
|
||||
sentByMe++;
|
||||
if (sentByMeCountEl) sentByMeCountEl.textContent = sentByMe.toString();
|
||||
}
|
||||
|
||||
export function incrementReceivedMine() {
|
||||
receivedMine++;
|
||||
if (receivedMineCountEl) receivedMineCountEl.textContent = receivedMine.toString();
|
||||
}
|
||||
|
||||
export function incrementReceivedOthers() {
|
||||
receivedOthers++;
|
||||
if (receivedOthersCountEl) receivedOthersCountEl.textContent = receivedOthers.toString();
|
||||
}
|
||||
|
||||
export function addMessageToLog(message: ChatMessage, type: 'sent' | 'received-mine' | 'received-other') {
|
||||
currentMessages.push(message);
|
||||
renderMessages();
|
||||
}
|
||||
|
||||
export function renderMessages(filterText?: string) {
|
||||
if (!messageListEl) return;
|
||||
|
||||
messageListEl.innerHTML = "";
|
||||
|
||||
const messagesToRender = filterText
|
||||
? currentMessages.filter(msg => {
|
||||
const searchTerm = filterText.toLowerCase();
|
||||
return (
|
||||
msg.content.toLowerCase().includes(searchTerm) ||
|
||||
msg.id.toLowerCase().includes(searchTerm) ||
|
||||
msg.senderPeerId.toLowerCase().includes(searchTerm)
|
||||
);
|
||||
})
|
||||
: currentMessages;
|
||||
|
||||
messagesToRender.sort((a, b) => a.timestamp - b.timestamp);
|
||||
|
||||
messagesToRender.forEach(message => {
|
||||
const item = document.createElement("div");
|
||||
item.classList.add("message-item");
|
||||
|
||||
let typeClass = '';
|
||||
let senderPrefix = '';
|
||||
|
||||
if (message.senderPeerId === currentPeerId) {
|
||||
typeClass = 'sent';
|
||||
senderPrefix = 'Me';
|
||||
} else {
|
||||
typeClass = 'received-other';
|
||||
senderPrefix = `Other (${message.senderPeerId.substring(0, 6)}...)`;
|
||||
}
|
||||
|
||||
item.classList.add(typeClass);
|
||||
|
||||
const idText = document.createElement("p");
|
||||
idText.classList.add("message-id");
|
||||
idText.textContent = `ID: ${message.id}`;
|
||||
|
||||
const contentP = document.createElement("p");
|
||||
contentP.classList.add("content");
|
||||
contentP.textContent = message.content;
|
||||
|
||||
const senderInfoP = document.createElement("p");
|
||||
senderInfoP.classList.add("sender-info");
|
||||
senderInfoP.textContent = `From: ${senderPrefix}`;
|
||||
|
||||
const timestampP = document.createElement("p");
|
||||
timestampP.classList.add("timestamp");
|
||||
timestampP.textContent = new Date(message.timestamp).toLocaleTimeString();
|
||||
|
||||
item.appendChild(idText);
|
||||
item.appendChild(senderInfoP);
|
||||
item.appendChild(contentP);
|
||||
item.appendChild(timestampP);
|
||||
messageListEl.appendChild(item);
|
||||
});
|
||||
}
|
||||
|
||||
export function getSearchTerm(): string {
|
||||
return searchInputEl ? searchInputEl.value : "";
|
||||
}
|
||||
12
examples/dogfooding/src/utils.ts
Normal file
12
examples/dogfooding/src/utils.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export async function sha256(text: string): Promise<string> {
|
||||
const encoder = new TextEncoder();
|
||||
const data = encoder.encode(text);
|
||||
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
||||
return hashHex;
|
||||
}
|
||||
|
||||
export function generateRandomNumber(): string {
|
||||
return Math.random().toString();
|
||||
}
|
||||
64
examples/dogfooding/src/waku-service.ts
Normal file
64
examples/dogfooding/src/waku-service.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { LightNode, createLightNode, createEncoder, createDecoder } from "@waku/sdk";
|
||||
import { generateKeyPairFromSeed } from "@libp2p/crypto/keys";
|
||||
import { fromString } from "uint8arrays";
|
||||
import { sha256, generateRandomNumber } from "./utils";
|
||||
|
||||
export const DEFAULT_CONTENT_TOPIC = "/js-waku-examples/1/message-ratio/utf8";
|
||||
|
||||
let wakuNodeInstance: LightNode | null = null;
|
||||
|
||||
export async function getWakuNode(): Promise<LightNode> {
|
||||
if (wakuNodeInstance) {
|
||||
return wakuNodeInstance;
|
||||
}
|
||||
|
||||
let seed = localStorage.getItem("seed");
|
||||
if (!seed) {
|
||||
seed = (await sha256(generateRandomNumber())).slice(0, 32);
|
||||
localStorage.setItem("seed", seed);
|
||||
}
|
||||
|
||||
const privateKey = await generateKeyPairFromSeed("Ed25519", fromString(seed));
|
||||
|
||||
const node = await createLightNode({
|
||||
defaultBootstrap: false,
|
||||
networkConfig: {
|
||||
clusterId: 42,
|
||||
shards: [0]
|
||||
},
|
||||
numPeersToUse: 2,
|
||||
libp2p: {
|
||||
privateKey,
|
||||
},
|
||||
});
|
||||
|
||||
await Promise.allSettled([
|
||||
node.dial("/dns4/waku-test.bloxy.one/tcp/8095/wss/p2p/16Uiu2HAmSZbDB7CusdRhgkD81VssRjQV5ZH13FbzCGcdnbbh6VwZ"),
|
||||
node.dial("/dns4/vps-aaa00d52.vps.ovh.ca/tcp/8000/wss/p2p/16Uiu2HAm9PftGgHZwWE3wzdMde4m3kT2eYJFXLZfGoSED3gysofk")
|
||||
]);
|
||||
|
||||
await node.start();
|
||||
await node.waitForPeers();
|
||||
|
||||
wakuNodeInstance = node;
|
||||
(window as any).waku = node;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function getPeerId(): string | undefined {
|
||||
return wakuNodeInstance?.libp2p.peerId.toString();
|
||||
}
|
||||
|
||||
export function createWakuEncoder() {
|
||||
return createEncoder({
|
||||
contentTopic: DEFAULT_CONTENT_TOPIC,
|
||||
pubsubTopicShardInfo: {
|
||||
clusterId: 42,
|
||||
shard: 0,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function createWakuDecoder() {
|
||||
return createDecoder(DEFAULT_CONTENT_TOPIC, { clusterId: 42, shard: 0 });
|
||||
}
|
||||
@ -2,7 +2,7 @@ const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
const path = require("path");
|
||||
|
||||
module.exports = {
|
||||
entry: "./src/index.ts", // Changed from index.js to index.ts
|
||||
entry: "./src/index.ts",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "build"),
|
||||
filename: "index.js",
|
||||
@ -11,12 +11,12 @@ module.exports = {
|
||||
asyncWebAssembly: true,
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.ts', '.js'], // Add .ts to the extensions
|
||||
extensions: ['.ts', '.js'],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.ts$/, // Add a rule for TypeScript files
|
||||
test: /\.ts$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
@ -29,7 +29,13 @@ module.exports = {
|
||||
},
|
||||
plugins: [
|
||||
new CopyWebpackPlugin({
|
||||
patterns: ["index.html", "favicon.ico", "favicon.png", "manifest.json"],
|
||||
patterns: [
|
||||
{ from: "index.html", to: "index.html" },
|
||||
{ from: "public/style.css", to: "style.css" },
|
||||
{ from: "manifest.json", to: "manifest.json" },
|
||||
{ from: "favicon.ico", to: "favicon.ico" },
|
||||
{ from: "favicon.png", to: "favicon.png" },
|
||||
],
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user