Merge pull request #111 from waku-org/js-waku-0.29.0
chore: bump js-waku to 0.29.0
This commit is contained in:
commit
9872f1082d
|
@ -3,6 +3,7 @@
|
|||
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/master/cspell.schema.json",
|
||||
"language": "en",
|
||||
"words": [
|
||||
"asym",
|
||||
"backoff",
|
||||
"backoffs",
|
||||
"bitjson",
|
||||
|
|
|
@ -18,15 +18,13 @@ only knowing their Ethereum Address.
|
|||
This protocol has been created to demonstrated how encryption and signature could be added to message
|
||||
sent over the Waku v2 network.
|
||||
|
||||
The `master` branch's HEAD is deployed at https://js-waku.wakuconnect.dev/examples/eth-pm/.
|
||||
The `master` branch's HEAD is deployed at https://examples.waku.org/eth-pm/.
|
||||
|
||||
To run a development version locally, do:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/status-im/js-waku/ ; cd js-waku
|
||||
npm install # Install dependencies for js-waku
|
||||
npm run build # Build js-waku
|
||||
cd examples/eth-pm
|
||||
npm install # Install dependencies for the web app
|
||||
npm run start # Start development server to serve the web app on http://localhost:3000/js-waku/eth-pm
|
||||
git clone https://github.com/waku-org/js-waku-examples
|
||||
cd eth-pm
|
||||
npm install
|
||||
npm run start
|
||||
```
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
"@material-ui/icons": "^4.11.2",
|
||||
"ethers": "5.7.1",
|
||||
"fontsource-roboto": "^4.0.0",
|
||||
"js-waku": "0.28.1",
|
||||
"js-waku": "0.29.0",
|
||||
"protobufjs": "^7.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
|
|
@ -14,7 +14,7 @@ specifiers:
|
|||
eslint: ^8.9.0
|
||||
ethers: 5.7.1
|
||||
fontsource-roboto: ^4.0.0
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
npm-run-all: ^4.1.5
|
||||
prettier: ^2.5.1
|
||||
protobufjs: ^7.1.0
|
||||
|
@ -27,14 +27,14 @@ specifiers:
|
|||
dependencies:
|
||||
'@ethersproject/abstract-signer': 5.7.0
|
||||
'@ethersproject/providers': 5.7.0
|
||||
'@material-ui/core': 4.12.4_x6vcehmdzjj6pm7ndhhuigqb3i
|
||||
'@material-ui/icons': 4.11.3_3v7i52wmmfi3wwfybpvt6ex6wq
|
||||
'@material-ui/core': 4.12.4_zxljzmqdrxwnuenbkrz77w74uy
|
||||
'@material-ui/icons': 4.11.3_upnjamd3tbaukgopcqqdlc7jbm
|
||||
ethers: 5.7.1
|
||||
fontsource-roboto: 4.0.0
|
||||
js-waku: 0.28.1_undici@5.10.0
|
||||
js-waku: 0.29.0_undici@5.10.0
|
||||
protobufjs: 7.1.0
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
uint8arrays: 3.1.0
|
||||
|
||||
devDependencies:
|
||||
|
@ -47,7 +47,7 @@ devDependencies:
|
|||
eslint: 8.21.0
|
||||
npm-run-all: 4.1.5
|
||||
prettier: 2.7.1
|
||||
react-scripts: 5.0.1_eqoi5id72ccwlxlz5mj7wjr7gu
|
||||
react-scripts: 5.0.1_zqc2lflk57y5fs7vjdkkfoejyi
|
||||
typescript: 4.8.2
|
||||
|
||||
packages:
|
||||
|
@ -3284,7 +3284,7 @@ packages:
|
|||
- utf-8-validate
|
||||
dev: false
|
||||
|
||||
/@material-ui/core/4.12.4_x6vcehmdzjj6pm7ndhhuigqb3i:
|
||||
/@material-ui/core/4.12.4_zxljzmqdrxwnuenbkrz77w74uy:
|
||||
resolution: {integrity: sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
|
@ -3296,23 +3296,23 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.18.9
|
||||
'@material-ui/styles': 4.11.5_x6vcehmdzjj6pm7ndhhuigqb3i
|
||||
'@material-ui/system': 4.12.2_x6vcehmdzjj6pm7ndhhuigqb3i
|
||||
'@material-ui/styles': 4.11.5_zxljzmqdrxwnuenbkrz77w74uy
|
||||
'@material-ui/system': 4.12.2_zxljzmqdrxwnuenbkrz77w74uy
|
||||
'@material-ui/types': 5.1.0_@types+react@18.0.17
|
||||
'@material-ui/utils': 4.11.3_sfoxds7t5ydpegc3knd667wn6m
|
||||
'@material-ui/utils': 4.11.3_biqbaboplfbrettd7655fr4n2y
|
||||
'@types/react': 18.0.17
|
||||
'@types/react-transition-group': 4.4.5
|
||||
clsx: 1.2.1
|
||||
hoist-non-react-statics: 3.3.2
|
||||
popper.js: 1.16.1-lts
|
||||
prop-types: 15.8.1
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
react-is: 17.0.2
|
||||
react-transition-group: 4.4.5_sfoxds7t5ydpegc3knd667wn6m
|
||||
react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y
|
||||
dev: false
|
||||
|
||||
/@material-ui/icons/4.11.3_3v7i52wmmfi3wwfybpvt6ex6wq:
|
||||
/@material-ui/icons/4.11.3_upnjamd3tbaukgopcqqdlc7jbm:
|
||||
resolution: {integrity: sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
|
@ -3325,13 +3325,13 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.18.9
|
||||
'@material-ui/core': 4.12.4_x6vcehmdzjj6pm7ndhhuigqb3i
|
||||
'@material-ui/core': 4.12.4_zxljzmqdrxwnuenbkrz77w74uy
|
||||
'@types/react': 18.0.17
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@material-ui/styles/4.11.5_x6vcehmdzjj6pm7ndhhuigqb3i:
|
||||
/@material-ui/styles/4.11.5_zxljzmqdrxwnuenbkrz77w74uy:
|
||||
resolution: {integrity: sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
|
@ -3345,7 +3345,7 @@ packages:
|
|||
'@babel/runtime': 7.18.9
|
||||
'@emotion/hash': 0.8.0
|
||||
'@material-ui/types': 5.1.0_@types+react@18.0.17
|
||||
'@material-ui/utils': 4.11.3_sfoxds7t5ydpegc3knd667wn6m
|
||||
'@material-ui/utils': 4.11.3_biqbaboplfbrettd7655fr4n2y
|
||||
'@types/react': 18.0.17
|
||||
clsx: 1.2.1
|
||||
csstype: 2.6.20
|
||||
|
@ -3359,11 +3359,11 @@ packages:
|
|||
jss-plugin-rule-value-function: 10.9.2
|
||||
jss-plugin-vendor-prefixer: 10.9.2
|
||||
prop-types: 15.8.1
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@material-ui/system/4.12.2_x6vcehmdzjj6pm7ndhhuigqb3i:
|
||||
/@material-ui/system/4.12.2_zxljzmqdrxwnuenbkrz77w74uy:
|
||||
resolution: {integrity: sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
|
@ -3375,12 +3375,12 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.18.9
|
||||
'@material-ui/utils': 4.11.3_sfoxds7t5ydpegc3knd667wn6m
|
||||
'@material-ui/utils': 4.11.3_biqbaboplfbrettd7655fr4n2y
|
||||
'@types/react': 18.0.17
|
||||
csstype: 2.6.20
|
||||
prop-types: 15.8.1
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/@material-ui/types/5.1.0_@types+react@18.0.17:
|
||||
|
@ -3394,7 +3394,7 @@ packages:
|
|||
'@types/react': 18.0.17
|
||||
dev: false
|
||||
|
||||
/@material-ui/utils/4.11.3_sfoxds7t5ydpegc3knd667wn6m:
|
||||
/@material-ui/utils/4.11.3_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
|
@ -3403,8 +3403,8 @@ packages:
|
|||
dependencies:
|
||||
'@babel/runtime': 7.18.9
|
||||
prop-types: 15.8.1
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
react-is: 17.0.2
|
||||
dev: false
|
||||
|
||||
|
@ -8487,8 +8487,8 @@ packages:
|
|||
/js-tokens/4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
/js-waku/0.28.1_undici@5.10.0:
|
||||
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==}
|
||||
/js-waku/0.29.0_undici@5.10.0:
|
||||
resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@chainsafe/libp2p-gossipsub': 4.1.1_undici@5.10.0
|
||||
|
@ -10735,15 +10735,14 @@ packages:
|
|||
- vue-template-compiler
|
||||
dev: true
|
||||
|
||||
/react-dom/17.0.2_react@17.0.2:
|
||||
resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==}
|
||||
/react-dom/18.2.0_react@18.2.0:
|
||||
resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
|
||||
peerDependencies:
|
||||
react: 17.0.2
|
||||
react: ^18.2.0
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
react: 17.0.2
|
||||
scheduler: 0.20.2
|
||||
react: 18.2.0
|
||||
scheduler: 0.23.0
|
||||
dev: false
|
||||
|
||||
/react-error-overlay/6.0.11:
|
||||
|
@ -10765,7 +10764,7 @@ packages:
|
|||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/react-scripts/5.0.1_eqoi5id72ccwlxlz5mj7wjr7gu:
|
||||
/react-scripts/5.0.1_zqc2lflk57y5fs7vjdkkfoejyi:
|
||||
resolution: {integrity: sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
@ -10809,7 +10808,7 @@ packages:
|
|||
postcss-normalize: 10.0.1_mu2kzpkteq3ketk6piffleamkq
|
||||
postcss-preset-env: 7.7.2_postcss@8.4.16
|
||||
prompts: 2.4.2
|
||||
react: 17.0.2
|
||||
react: 18.2.0
|
||||
react-app-polyfill: 3.0.0
|
||||
react-dev-utils: 12.0.1_6powqha3uet7brcqpdvamgrsxu
|
||||
react-refresh: 0.11.0
|
||||
|
@ -10862,7 +10861,7 @@ packages:
|
|||
- webpack-plugin-serve
|
||||
dev: true
|
||||
|
||||
/react-transition-group/4.4.5_sfoxds7t5ydpegc3knd667wn6m:
|
||||
/react-transition-group/4.4.5_biqbaboplfbrettd7655fr4n2y:
|
||||
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
|
||||
peerDependencies:
|
||||
react: '>=16.6.0'
|
||||
|
@ -10872,16 +10871,15 @@ packages:
|
|||
dom-helpers: 5.2.1
|
||||
loose-envify: 1.4.0
|
||||
prop-types: 15.8.1
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
dev: false
|
||||
|
||||
/react/17.0.2:
|
||||
resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
|
||||
/react/18.2.0:
|
||||
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
|
||||
/read-cache/1.0.0:
|
||||
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
|
||||
|
@ -11202,11 +11200,10 @@ packages:
|
|||
xmlchars: 2.2.0
|
||||
dev: true
|
||||
|
||||
/scheduler/0.20.2:
|
||||
resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==}
|
||||
/scheduler/0.23.0:
|
||||
resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
object-assign: 4.1.1
|
||||
dev: false
|
||||
|
||||
/schema-utils/2.7.0:
|
||||
|
|
|
@ -3,6 +3,7 @@ import "@ethersproject/shims";
|
|||
import React, { useEffect, useState } from "react";
|
||||
import "./App.css";
|
||||
import type { WakuLight } from "js-waku/lib/interfaces";
|
||||
import { AsymDecoder, SymDecoder } from "js-waku/lib/waku_message/version_1";
|
||||
import { KeyPair, PublicKeyMessageEncryptionKey } from "./crypto";
|
||||
import { Message } from "./messaging/Messages";
|
||||
import "fontsource-roboto";
|
||||
|
@ -26,7 +27,6 @@ import {
|
|||
} from "./waku";
|
||||
import { Web3Provider } from "@ethersproject/providers/src.ts/web3-provider";
|
||||
import ConnectWallet from "./ConnectWallet";
|
||||
import { waku_message } from "js-waku";
|
||||
|
||||
const theme = createMuiTheme({
|
||||
palette: {
|
||||
|
@ -72,6 +72,8 @@ function App() {
|
|||
const [encryptionKeyPair, setEncryptionKeyPair] = useState<
|
||||
KeyPair | undefined
|
||||
>();
|
||||
const [privateMessageDecoder, setPrivateMessageDecoder] =
|
||||
useState<AsymDecoder>();
|
||||
const [publicKeys, setPublicKeys] = useState<Map<string, Uint8Array>>(
|
||||
new Map()
|
||||
);
|
||||
|
@ -109,14 +111,15 @@ function App() {
|
|||
setPublicKeys
|
||||
);
|
||||
|
||||
const publicKeyMessageDecoder = new SymDecoder(
|
||||
PublicKeyContentTopic,
|
||||
PublicKeyMessageEncryptionKey
|
||||
);
|
||||
|
||||
let unsubscribe: undefined | (() => Promise<void>);
|
||||
|
||||
waku.filter.addDecryptionKey(PublicKeyMessageEncryptionKey, {
|
||||
method: waku_message.DecryptionMethod.Symmetric,
|
||||
contentTopics: [PublicKeyContentTopic],
|
||||
});
|
||||
waku.filter
|
||||
.subscribe(observerPublicKeyMessage, [PublicKeyContentTopic])
|
||||
.subscribe([publicKeyMessageDecoder], observerPublicKeyMessage)
|
||||
.then(
|
||||
(_unsubscribe) => {
|
||||
console.log("subscribed to ", PublicKeyContentTopic);
|
||||
|
@ -128,9 +131,8 @@ function App() {
|
|||
);
|
||||
|
||||
return function cleanUp() {
|
||||
if (!waku) return;
|
||||
waku.filter.deleteDecryptionKey(PublicKeyMessageEncryptionKey);
|
||||
if (typeof unsubscribe === "undefined") return;
|
||||
|
||||
unsubscribe().then(
|
||||
() => {
|
||||
console.log("unsubscribed to ", PublicKeyContentTopic);
|
||||
|
@ -141,25 +143,16 @@ function App() {
|
|||
}, [waku, address]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!waku) return;
|
||||
if (!encryptionKeyPair) return;
|
||||
|
||||
waku.filter.addDecryptionKey(encryptionKeyPair.privateKey, {
|
||||
method: waku_message.DecryptionMethod.Asymmetric,
|
||||
contentTopics: [PrivateMessageContentTopic],
|
||||
});
|
||||
|
||||
return function cleanUp() {
|
||||
if (!waku) return;
|
||||
if (!encryptionKeyPair) return;
|
||||
|
||||
waku.filter.deleteDecryptionKey(encryptionKeyPair.privateKey);
|
||||
};
|
||||
}, [waku, encryptionKeyPair]);
|
||||
setPrivateMessageDecoder(
|
||||
new AsymDecoder(PrivateMessageContentTopic, encryptionKeyPair.privateKey)
|
||||
);
|
||||
}, [encryptionKeyPair]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!waku) return;
|
||||
if (!encryptionKeyPair) return;
|
||||
if (!privateMessageDecoder) return;
|
||||
if (!address) return;
|
||||
|
||||
const observerPrivateMessage = handlePrivateMessage.bind(
|
||||
|
@ -170,23 +163,20 @@ function App() {
|
|||
|
||||
let unsubscribe: undefined | (() => Promise<void>);
|
||||
|
||||
waku.filter
|
||||
.subscribe(observerPrivateMessage, [PrivateMessageContentTopic])
|
||||
.then(
|
||||
(_unsubscribe) => {
|
||||
unsubscribe = _unsubscribe;
|
||||
},
|
||||
(e) => {
|
||||
console.error("Failed to subscribe", e);
|
||||
}
|
||||
);
|
||||
waku.filter.subscribe([privateMessageDecoder], observerPrivateMessage).then(
|
||||
(_unsubscribe) => {
|
||||
unsubscribe = _unsubscribe;
|
||||
},
|
||||
(e) => {
|
||||
console.error("Failed to subscribe", e);
|
||||
}
|
||||
);
|
||||
|
||||
return function cleanUp() {
|
||||
if (!waku) return;
|
||||
if (typeof unsubscribe === "undefined") return;
|
||||
unsubscribe().catch((e) => console.error("Failed to unsubscribe", e));
|
||||
};
|
||||
}, [waku, address, encryptionKeyPair]);
|
||||
}, [waku, address, privateMessageDecoder]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!waku) return;
|
||||
|
@ -252,7 +242,7 @@ function App() {
|
|||
/>
|
||||
<BroadcastPublicKey
|
||||
address={address}
|
||||
EncryptionKeyPair={encryptionKeyPair}
|
||||
encryptionKeyPair={encryptionKeyPair}
|
||||
waku={waku}
|
||||
signer={provider?.getSigner()}
|
||||
/>
|
||||
|
|
|
@ -6,66 +6,53 @@ import {
|
|||
PublicKeyMessageEncryptionKey,
|
||||
} from "./crypto";
|
||||
import { PublicKeyMessage } from "./messaging/wire";
|
||||
import { WakuMessage } from "js-waku";
|
||||
import { WakuLight } from "js-waku/lib/interfaces";
|
||||
import type { WakuLight } from "js-waku/lib/interfaces";
|
||||
import { SymEncoder } from "js-waku/lib/waku_message/version_1";
|
||||
import { PublicKeyContentTopic } from "./waku";
|
||||
import type { TypedDataSigner } from "@ethersproject/abstract-signer";
|
||||
|
||||
interface Props {
|
||||
EncryptionKeyPair: KeyPair | undefined;
|
||||
encryptionKeyPair: KeyPair | undefined;
|
||||
waku: WakuLight | undefined;
|
||||
address: string | undefined;
|
||||
signer: TypedDataSigner | undefined;
|
||||
}
|
||||
|
||||
export default function BroadcastPublicKey({
|
||||
EncryptionKeyPair,
|
||||
encryptionKeyPair,
|
||||
waku,
|
||||
address,
|
||||
signer,
|
||||
}: Props) {
|
||||
const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>();
|
||||
|
||||
const broadcastPublicKey = () => {
|
||||
if (!EncryptionKeyPair) return;
|
||||
const broadcastPublicKey = async () => {
|
||||
if (!encryptionKeyPair) return;
|
||||
if (!address) return;
|
||||
if (!waku) return;
|
||||
if (!signer) return;
|
||||
|
||||
if (publicKeyMsg) {
|
||||
encodePublicKeyWakuMessage(publicKeyMsg)
|
||||
.then((wakuMsg) => {
|
||||
waku.lightPush.push(wakuMsg).catch((e) => {
|
||||
console.error("Failed to send Public Key Message", e);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log("Failed to encode Public Key Message in Waku Message", e);
|
||||
});
|
||||
} else {
|
||||
createPublicKeyMessage(address, EncryptionKeyPair.publicKey, signer)
|
||||
.then((msg) => {
|
||||
setPublicKeyMsg(msg);
|
||||
encodePublicKeyWakuMessage(msg)
|
||||
.then((wakuMsg) => {
|
||||
waku.lightPush
|
||||
.push(wakuMsg)
|
||||
.then((res) => console.log("Public Key Message pushed", res))
|
||||
.catch((e) => {
|
||||
console.error("Failed to send Public Key Message", e);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(
|
||||
"Failed to encode Public Key Message in Waku Message",
|
||||
e
|
||||
);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("Failed to create public key message", e);
|
||||
});
|
||||
}
|
||||
const _publicKeyMessage = await (async () => {
|
||||
if (!publicKeyMsg) {
|
||||
const pkm = await createPublicKeyMessage(
|
||||
address,
|
||||
encryptionKeyPair.publicKey,
|
||||
signer
|
||||
);
|
||||
|
||||
setPublicKeyMsg(pkm);
|
||||
return pkm;
|
||||
}
|
||||
return publicKeyMsg;
|
||||
})();
|
||||
const payload = _publicKeyMessage.encode();
|
||||
|
||||
const publicKeyMessageEncoder = new SymEncoder(
|
||||
PublicKeyContentTopic,
|
||||
PublicKeyMessageEncryptionKey
|
||||
);
|
||||
|
||||
waku.lightPush.push(publicKeyMessageEncoder, { payload });
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -73,18 +60,9 @@ export default function BroadcastPublicKey({
|
|||
variant="contained"
|
||||
color="primary"
|
||||
onClick={broadcastPublicKey}
|
||||
disabled={!EncryptionKeyPair || !waku || !address || !signer}
|
||||
disabled={!encryptionKeyPair || !waku || !address || !signer}
|
||||
>
|
||||
Broadcast Encryption Public Key
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
async function encodePublicKeyWakuMessage(
|
||||
publicKeyMessage: PublicKeyMessage
|
||||
): Promise<WakuMessage> {
|
||||
const payload = publicKeyMessage.encode();
|
||||
return await WakuMessage.fromBytes(payload, PublicKeyContentTopic, {
|
||||
symKey: PublicKeyMessageEncryptionKey,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,9 +41,6 @@ export async function createPublicKeyMessage(
|
|||
signer
|
||||
);
|
||||
|
||||
console.log("Asking wallet to sign Public Key Message");
|
||||
console.log("Public Key Message signed");
|
||||
|
||||
return new PublicKeyMessage({
|
||||
encryptionPublicKey: encryptionPublicKey,
|
||||
ethAddress: utils.hexToBytes(address),
|
||||
|
|
|
@ -7,8 +7,9 @@ import {
|
|||
TextField,
|
||||
} from "@material-ui/core";
|
||||
import React, { ChangeEvent, useState, KeyboardEvent } from "react";
|
||||
import { utils, WakuMessage } from "js-waku";
|
||||
import { utils } from "js-waku";
|
||||
import type { WakuLight } from "js-waku/lib/interfaces";
|
||||
import { AsymEncoder } from "js-waku/lib/waku_message/version_1";
|
||||
import { PrivateMessage } from "./wire";
|
||||
import { PrivateMessageContentTopic } from "../waku";
|
||||
|
||||
|
@ -104,45 +105,26 @@ export default function SendMessage({ waku, recipients }: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
async function encodeEncryptedWakuMessage(
|
||||
message: string,
|
||||
publicKey: Uint8Array,
|
||||
address: string
|
||||
): Promise<WakuMessage> {
|
||||
const privateMessage = new PrivateMessage({
|
||||
toAddress: utils.hexToBytes(address),
|
||||
message: message,
|
||||
});
|
||||
|
||||
const payload = privateMessage.encode();
|
||||
return WakuMessage.fromBytes(payload, PrivateMessageContentTopic, {
|
||||
encPublicKey: publicKey,
|
||||
});
|
||||
}
|
||||
|
||||
function sendMessage(
|
||||
async function sendMessage(
|
||||
waku: WakuLight,
|
||||
recipientAddress: string,
|
||||
recipientPublicKey: Uint8Array,
|
||||
message: string,
|
||||
callback: (res: boolean) => void
|
||||
) {
|
||||
encodeEncryptedWakuMessage(message, recipientPublicKey, recipientAddress)
|
||||
.then((msg) => {
|
||||
console.log("pushing");
|
||||
waku.lightPush
|
||||
.push(msg)
|
||||
.then((res) => {
|
||||
console.log("Message sent", res);
|
||||
callback(res?.isSuccess ?? false);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("Failed to send message", e);
|
||||
callback(false);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("Cannot encode & encrypt message", e);
|
||||
callback(false);
|
||||
});
|
||||
const privateMessage = new PrivateMessage({
|
||||
toAddress: utils.hexToBytes(recipientAddress),
|
||||
message: message,
|
||||
});
|
||||
const payload = privateMessage.encode();
|
||||
|
||||
const encoder = new AsymEncoder(
|
||||
PrivateMessageContentTopic,
|
||||
recipientPublicKey
|
||||
);
|
||||
|
||||
console.log("pushing");
|
||||
const res = await waku.lightPush.push(encoder, { payload });
|
||||
console.log("Message sent", res);
|
||||
callback(Boolean(res.recipients.length));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Dispatch, SetStateAction } from "react";
|
||||
import { Protocols, utils, WakuMessage } from "js-waku";
|
||||
import type { WakuLight } from "js-waku/lib/interfaces";
|
||||
import { Protocols, utils } from "js-waku";
|
||||
import type { WakuLight, Message as WakuMessage } from "js-waku/lib/interfaces";
|
||||
import { PrivateMessage, PublicKeyMessage } from "./messaging/wire";
|
||||
import { validatePublicKeyMessage } from "./crypto";
|
||||
import { Message } from "./messaging/Messages";
|
||||
|
|
|
@ -10,4 +10,4 @@ This example uses Waku Filter to listen to messages and Waku Light Push to send
|
|||
|
||||
To test the example, simply download the `index.html` file from this folder and open it in a browser.
|
||||
|
||||
The `master` branch's HEAD is deployed at https://js.waku.org/light-js/.
|
||||
The `master` branch's HEAD is deployed at https://examples.waku.org/light-js/.
|
||||
|
|
|
@ -36,14 +36,16 @@
|
|||
<script type='module'>
|
||||
import {
|
||||
utils,
|
||||
WakuMessage
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/index.js';
|
||||
} from 'https://unpkg.com/js-waku@0.29.0/bundle/index.js';
|
||||
import {
|
||||
createLightNode
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/lib/create_waku.js'
|
||||
} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/create_waku.js'
|
||||
import {
|
||||
waitForRemotePeer
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/lib/wait_for_remote_peer.js'
|
||||
} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/wait_for_remote_peer.js'
|
||||
import {
|
||||
EncoderV0, DecoderV0
|
||||
} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/waku_message/version_0.js'
|
||||
|
||||
const peerIdDiv = document.getElementById('peer-id');
|
||||
const remotePeerIdDiv = document.getElementById('remote-peer-id');
|
||||
|
@ -57,10 +59,13 @@
|
|||
const sendButton = document.getElementById('sendButton');
|
||||
|
||||
const ContentTopic = "/js-waku-examples/1/chat/utf8";
|
||||
let messages = []
|
||||
const decoder = new DecoderV0(ContentTopic);
|
||||
const encoder = new EncoderV0(ContentTopic);
|
||||
let messages = [];
|
||||
let unsubscribe;
|
||||
|
||||
subscribeButton.disabled = true
|
||||
dialButton.disabled = true;
|
||||
subscribeButton.disabled = true;
|
||||
textInput.disabled = true;
|
||||
sendButton.disabled = true;
|
||||
unsubscribeButton.disabled = true;
|
||||
|
@ -78,6 +83,7 @@
|
|||
await node.start();
|
||||
statusDiv.innerHTML = '<p>Waku node started.</p>';
|
||||
peerIdDiv.innerHTML = '<p>' + node.libp2p.peerId.toString() + '</p>'
|
||||
dialButton.disabled = false;
|
||||
|
||||
dialButton.onclick = async () => {
|
||||
const ma = remoteMultiAddrDiv.value
|
||||
|
@ -104,7 +110,7 @@
|
|||
}
|
||||
|
||||
subscribeButton.onclick = async () => {
|
||||
unsubscribe = await node.filter.subscribe(callback, [ContentTopic])
|
||||
unsubscribe = await node.filter.subscribe([decoder], callback)
|
||||
unsubscribeButton.disabled = false;
|
||||
subscribeButton.disabled = true;
|
||||
}
|
||||
|
@ -119,8 +125,7 @@
|
|||
sendButton.onclick = async () => {
|
||||
const text = textInput.value;
|
||||
|
||||
const wakuMessage = await WakuMessage.fromUtf8String(text, ContentTopic);
|
||||
await node.lightPush.push(wakuMessage);
|
||||
await node.lightPush.push(encoder, {payload: utils.utf8ToBytes(text)});
|
||||
console.log('Message sent!');
|
||||
textInput.value = null;
|
||||
};
|
||||
|
|
|
@ -10,15 +10,15 @@
|
|||
|
||||
A barebones messaging app to illustrate the [Angular Relay guide](https://docs.wakuconnect.dev/docs/guides/10_angular_relay/).
|
||||
|
||||
The `master` branch's HEAD is deployed at https://examples.waku.org/relay-angular-chat/.
|
||||
|
||||
To run a development version locally, do:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/status-im/js-waku/ ; cd js-waku
|
||||
npm install # Install dependencies for js-waku
|
||||
npm run build # Build js-waku
|
||||
cd examples/relay-reactjs-chat
|
||||
yarn # Install dependencies for the web app
|
||||
yarn start # Start development server to serve the web app on http://localhost:4200/
|
||||
git clone https://github.com/waku-org/js-waku-examples
|
||||
cd relay-angular-chat
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
### Known issues
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
"@angular/platform-browser": "~14.2.0",
|
||||
"@angular/platform-browser-dynamic": "~14.2.0",
|
||||
"@angular/router": "~14.2.0",
|
||||
"js-waku": "0.28.1",
|
||||
"js-waku": "0.29.0",
|
||||
"protobufjs": "^7.1.0",
|
||||
"rxjs": "~7.5.0",
|
||||
"tslib": "^2.3.0",
|
||||
|
|
|
@ -16,7 +16,7 @@ specifiers:
|
|||
'@types/node': ^17.0.21
|
||||
is-ci-cli: ^2.2.0
|
||||
jasmine-core: ~4.3.0
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
karma: ~6.4.0
|
||||
karma-chrome-launcher: ~3.1.0
|
||||
karma-coverage: ~2.2.0
|
||||
|
@ -37,7 +37,7 @@ dependencies:
|
|||
'@angular/platform-browser': 14.2.0_afytwol7hs4qio34buyx2grhfa
|
||||
'@angular/platform-browser-dynamic': 14.2.0_owch6soaoexeadly32xw5vendq
|
||||
'@angular/router': 14.2.0_6lk4yxyxfaqzosenawf2bqx6vy
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
protobufjs: 7.1.0
|
||||
rxjs: 7.5.6
|
||||
tslib: 2.4.0
|
||||
|
@ -5440,8 +5440,8 @@ packages:
|
|||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
dev: true
|
||||
|
||||
/js-waku/0.28.1:
|
||||
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==}
|
||||
/js-waku/0.29.0:
|
||||
resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@chainsafe/libp2p-gossipsub': 4.1.1
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { WakuService } from "../waku.service";
|
||||
import { WakuMessage } from "js-waku";
|
||||
import type { WakuPrivacy } from "js-waku/lib/interfaces";
|
||||
import protobuf from "protobufjs";
|
||||
import { DecoderV0, EncoderV0 } from "js-waku/lib/waku_message/version_0";
|
||||
import type { MessageV0 } from "js-waku/lib/waku_message/version_0";
|
||||
|
||||
const ProtoChatMessage = new protobuf.Type("ChatMessage")
|
||||
.add(new protobuf.Field("timestamp", 1, "uint32"))
|
||||
|
@ -20,13 +21,18 @@ interface MessageInterface {
|
|||
})
|
||||
export class MessagesComponent implements OnInit {
|
||||
contentTopic: string = `/js-waku-examples/1/chat/proto`;
|
||||
decoder: DecoderV0;
|
||||
encoder: EncoderV0;
|
||||
messages: MessageInterface[] = [];
|
||||
messageCount: number = 0;
|
||||
waku!: WakuPrivacy;
|
||||
wakuStatus!: string;
|
||||
deleteObserver?: () => void;
|
||||
|
||||
constructor(private wakuService: WakuService) {}
|
||||
constructor(private wakuService: WakuService) {
|
||||
this.decoder = new DecoderV0(this.contentTopic);
|
||||
this.encoder = new EncoderV0(this.contentTopic);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.wakuService.wakuStatus.subscribe((wakuStatus) => {
|
||||
|
@ -36,8 +42,8 @@ export class MessagesComponent implements OnInit {
|
|||
this.wakuService.waku.subscribe((waku) => {
|
||||
this.waku = waku;
|
||||
this.deleteObserver = this.waku.relay.addObserver(
|
||||
this.processIncomingMessages,
|
||||
[this.contentTopic]
|
||||
this.decoder,
|
||||
this.processIncomingMessages
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -57,16 +63,13 @@ export class MessagesComponent implements OnInit {
|
|||
});
|
||||
|
||||
const payload = ProtoChatMessage.encode(protoMsg).finish();
|
||||
|
||||
WakuMessage.fromBytes(payload, this.contentTopic).then((wakuMessage) => {
|
||||
this.waku.relay.send(wakuMessage).then(() => {
|
||||
console.log(`Message #${this.messageCount} sent`);
|
||||
this.messageCount += 1;
|
||||
});
|
||||
this.waku.relay.send(this.encoder, { payload }).then(() => {
|
||||
console.log(`Message #${this.messageCount} sent`);
|
||||
this.messageCount += 1;
|
||||
});
|
||||
}
|
||||
|
||||
processIncomingMessages = (wakuMessage: WakuMessage) => {
|
||||
processIncomingMessages = (wakuMessage: MessageV0) => {
|
||||
if (!wakuMessage.payload) return;
|
||||
|
||||
const { text, timestamp } = ProtoChatMessage.decode(
|
||||
|
|
|
@ -10,4 +10,4 @@ This example uses Waku Relay to send and receive simple text messages.
|
|||
|
||||
To test the example, simply download the `index.html` file from this folder and open it in a browser.
|
||||
|
||||
The `master` branch's HEAD is deployed at https://js-waku.wakuconnect.dev/examples/relay-js/.
|
||||
The `master` branch's HEAD is deployed at https://examples.waku.org/relay-js/.
|
||||
|
|
|
@ -26,15 +26,10 @@
|
|||
* Recommended payload is protobuf. Using simple utf-8 string for demo purposes only.
|
||||
*/
|
||||
|
||||
import {
|
||||
WakuMessage
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/index.js';
|
||||
import {
|
||||
createPrivacyNode
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/lib/create_waku.js'
|
||||
import {
|
||||
waitForRemotePeer
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/lib/wait_for_remote_peer.js'
|
||||
import {utils} from 'https://unpkg.com/js-waku@0.29.0/bundle/index.js';
|
||||
import {createPrivacyNode} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/create_waku.js'
|
||||
import {waitForRemotePeer} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/wait_for_remote_peer.js'
|
||||
import {DecoderV0, EncoderV0} from "https://unpkg.com/js-waku@0.29.0/bundle/lib/waku_message/version_0.js";
|
||||
|
||||
const statusDiv = document.getElementById('status');
|
||||
const messagesDiv = document.getElementById('messages');
|
||||
|
@ -52,6 +47,11 @@
|
|||
// for simplicity's sake.
|
||||
const contentTopic = '/js-waku-examples/1/chat/utf8';
|
||||
|
||||
// Prepare encoder and decoder, `V0` for clear text messages.
|
||||
|
||||
const encoder = new EncoderV0(contentTopic);
|
||||
const decoder = new DecoderV0(contentTopic);
|
||||
|
||||
try {
|
||||
statusDiv.innerHTML = '<p>Starting</p>';
|
||||
|
||||
|
@ -59,20 +59,20 @@
|
|||
// `default: true` bootstraps by connecting to pre-defined/hardcoded Waku nodes.
|
||||
// We are currently working on migrating this method to DNS Discovery.
|
||||
//
|
||||
// https://js-waku.wakuconnect.dev/classes/waku.Waku.html#create
|
||||
// https://js.waku.org/functions/lib_create_waku.createPrivacyNode.html
|
||||
const waku = await createPrivacyNode({defaultBootstrap: true});
|
||||
await waku.start();
|
||||
|
||||
// Had a hook to process all incoming messages on a specified content topic.
|
||||
//
|
||||
// https://js-waku.wakuconnect.dev/classes/waku_relay.WakuRelay.html#addObserver
|
||||
waku.relay.addObserver((wakuMessage) => {
|
||||
waku.relay.addObserver(decoder, (message) => {
|
||||
|
||||
// Checks there is a payload on the message.
|
||||
// Waku Message is encoded in protobuf, in proto v3 fields are always optional.
|
||||
//
|
||||
// https://js-waku.wakuconnect.dev/classes/waku_message.WakuMessage.html#payload
|
||||
if (!wakuMessage.payload)
|
||||
if (!message.payload)
|
||||
return;
|
||||
|
||||
// Helper method to decode the payload to utf-8. A production dApp should
|
||||
|
@ -80,7 +80,7 @@
|
|||
// structure of their choice.
|
||||
//
|
||||
// https://js-waku.wakuconnect.dev/classes/waku_message.WakuMessage.html#payloadAsUtf8
|
||||
const text = wakuMessage.payloadAsUtf8;
|
||||
const text = utils.bytesToUtf8(message.payload);
|
||||
messagesDiv.innerHTML = `<p>${text}</p><br />` + messagesDiv.innerHTML;
|
||||
}, [contentTopic]);
|
||||
|
||||
|
@ -96,22 +96,8 @@
|
|||
// function that sends the text input over Waku Relay, the gossipsub
|
||||
// protocol.
|
||||
sendButton.onclick = async () => {
|
||||
const text = textInput.value;
|
||||
|
||||
// Helper functions are available to create a Waku Message.
|
||||
// These functions also provide native symmetric, asymmetric encryption,
|
||||
// signing and signature verification. Check the `Options` object for details:
|
||||
// https://js-waku.wakuconnect.dev/interfaces/waku_message.Options.html
|
||||
//
|
||||
// `WakuMessage.fromBytes` should be preferred for a production dApp to
|
||||
// serialize a data structure.
|
||||
//
|
||||
// https://js-waku.wakuconnect.dev/classes/waku_message.WakuMessage.html#fromUtf8String
|
||||
const wakuMessage = await WakuMessage.fromUtf8String(text, contentTopic);
|
||||
// Once the message is constructed, send it over Waku Relay.
|
||||
//
|
||||
// https://js-waku.wakuconnect.dev/classes/waku_relay.WakuRelay.html#send
|
||||
await waku.relay.send(wakuMessage);
|
||||
const payload = utils.utf8ToBytes(textInput.value)
|
||||
await waku.relay.send(encoder, {payload});
|
||||
console.log('Message sent!');
|
||||
|
||||
// Reset the text input.
|
||||
|
|
|
@ -10,11 +10,13 @@
|
|||
|
||||
A barebone chat app to illustrate the [ReactJS Relay guide](https://docs.wakuconnect.dev/docs/guides/07_reactjs_relay/).
|
||||
|
||||
The `master` branch's HEAD is deployed at https://examples.waku.org/relay-reactjs-chat/.
|
||||
|
||||
To run a development version locally, do:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/waku-org/js-waku-examples/
|
||||
cd js-waku-examples/relay-reactjs-chat
|
||||
git clone https://github.com/waku-org/js-waku-examples
|
||||
cd relay-reactjs-chat
|
||||
npm install
|
||||
npm run start
|
||||
```
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"js-waku": "0.28.1",
|
||||
"js-waku": "0.29.0",
|
||||
"protobufjs": "^7.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
|
|
@ -6,7 +6,7 @@ specifiers:
|
|||
'@testing-library/react': ^13.3.0
|
||||
'@testing-library/user-event': ^13.5.0
|
||||
eslint: ^8.22.0
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
protobufjs: ^7.0.0
|
||||
react: ^18.2.0
|
||||
react-dom: ^18.2.0
|
||||
|
@ -17,7 +17,7 @@ dependencies:
|
|||
'@testing-library/jest-dom': 5.16.5
|
||||
'@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y
|
||||
'@testing-library/user-event': 13.5.0_wl4iynrlixafokvgqnhzlvigei
|
||||
js-waku: 0.28.1_undici@5.10.0
|
||||
js-waku: 0.29.0_undici@5.10.0
|
||||
protobufjs: 7.0.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
|
@ -7001,8 +7001,8 @@ packages:
|
|||
/js-tokens/4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
/js-waku/0.28.1_undici@5.10.0:
|
||||
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==}
|
||||
/js-waku/0.29.0_undici@5.10.0:
|
||||
resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@chainsafe/libp2p-gossipsub': 4.1.1_undici@5.10.0
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { WakuMessage } from "js-waku";
|
||||
import * as React from "react";
|
||||
import protobuf from "protobufjs";
|
||||
import { createPrivacyNode } from "js-waku/lib/create_waku";
|
||||
import { waitForRemotePeer } from "js-waku/lib/wait_for_remote_peer";
|
||||
import { DecoderV0, EncoderV0 } from "js-waku/lib/waku_message/version_0";
|
||||
|
||||
const ContentTopic = `/js-waku-examples/1/chat/proto`;
|
||||
const Encoder = new EncoderV0(ContentTopic);
|
||||
const Decoder = new DecoderV0(ContentTopic);
|
||||
|
||||
const SimpleChatMessage = new protobuf.Type("SimpleChatMessage")
|
||||
.add(new protobuf.Field("timestamp", 1, "uint32"))
|
||||
|
@ -34,6 +36,7 @@ function App() {
|
|||
}, [waku, wakuStatus]);
|
||||
|
||||
const processIncomingMessage = React.useCallback((wakuMessage) => {
|
||||
console.log("Message received", wakuMessage);
|
||||
if (!wakuMessage.payload) return;
|
||||
|
||||
const { text, timestamp } = SimpleChatMessage.decode(wakuMessage.payload);
|
||||
|
@ -52,9 +55,10 @@ function App() {
|
|||
if (!waku) return;
|
||||
|
||||
// Pass the content topic to only process messages related to your dApp
|
||||
const deleteObserver = waku.relay.addObserver(processIncomingMessage, [
|
||||
ContentTopic,
|
||||
]);
|
||||
const deleteObserver = waku.relay.addObserver(
|
||||
Decoder,
|
||||
processIncomingMessage
|
||||
);
|
||||
|
||||
// Called when the component is unmounted, see ReactJS doc.
|
||||
return deleteObserver;
|
||||
|
@ -105,11 +109,8 @@ function sendMessage(message, waku, timestamp) {
|
|||
});
|
||||
const payload = SimpleChatMessage.encode(protoMsg).finish();
|
||||
|
||||
// Wrap in a Waku Message
|
||||
return WakuMessage.fromBytes(payload, ContentTopic).then((wakuMessage) =>
|
||||
// Send over Waku Relay
|
||||
waku.relay.send(wakuMessage)
|
||||
);
|
||||
// Send over Waku Relay
|
||||
return waku.relay.send(Encoder, { payload });
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
|
@ -10,4 +10,4 @@ This example uses Waku Store to retrieve the latest ping relay message (used for
|
|||
|
||||
To test the example, simply download the `index.html` file from this folder and open it in a browser.
|
||||
|
||||
The `master` branch's HEAD is deployed at https://js-waku.wakuconnect.dev/examples/store-js/.
|
||||
The `master` branch's HEAD is deployed at https://examples.waku.org/store-js/.
|
||||
|
|
|
@ -13,15 +13,10 @@
|
|||
<div id='timestamp'></div>
|
||||
|
||||
<script type='module'>
|
||||
import {
|
||||
Protocols
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/index.js';
|
||||
import {
|
||||
createWaku
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/lib/create_waku.js'
|
||||
import {
|
||||
waitForRemotePeer
|
||||
} from 'https://unpkg.com/js-waku@0.28.1/bundle/lib/wait_for_remote_peer.js'
|
||||
import {Protocols} from 'https://unpkg.com/js-waku@0.29.0/bundle/index.js';
|
||||
import {createWaku} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/create_waku.js'
|
||||
import {waitForRemotePeer} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/wait_for_remote_peer.js'
|
||||
import {DecoderV0} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/waku_message/version_0.js'
|
||||
|
||||
/**
|
||||
* This example demonstrates how to use the js-waku minified bundle
|
||||
|
@ -56,7 +51,7 @@
|
|||
startTime.setTime(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
||||
try {
|
||||
await node.store
|
||||
.queryOrderedCallback([],
|
||||
.queryOrderedCallback([new DecoderV0("/relay-ping/1/ping/null")],
|
||||
callback,
|
||||
{
|
||||
pageDirection: 'backward',
|
||||
|
|
|
@ -9,15 +9,13 @@
|
|||
A simple app that retrieves chat messages using [Waku Store](https://rfc.vac.dev/spec/13/)
|
||||
to illustrate the [Retrieve Messages Using Waku Store With ReactJS guide](https://docs.wakuconnect.dev/docs/guides/08_reactjs_store/).
|
||||
|
||||
The `master` branch's HEAD is deployed at https://js-waku.wakuconnect.dev/examples/store-reactjs-chat/.
|
||||
The `master` branch's HEAD is deployed at https://examples.waku.org/store-reactjs-chat/.
|
||||
|
||||
To run a development version locally, do:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/status-im/js-waku/ ; cd js-waku
|
||||
npm install # Install dependencies for js-waku
|
||||
npm run build # Build js-waku
|
||||
cd examples/store-reactjs-chat
|
||||
npm install # Install dependencies for the web app
|
||||
npm run start # Start development server to serve the web app on http://localhost:3000/
|
||||
git clone https://github.com/waku-org/js-waku-examples
|
||||
cd store-reactjs-chat
|
||||
npm install
|
||||
npm run start
|
||||
```
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react": "^13.2.0",
|
||||
"@testing-library/user-event": "^14.1.1",
|
||||
"js-waku": "0.28.1",
|
||||
"js-waku": "0.29.0",
|
||||
"protobufjs": "^7.1.0",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
|
|
|
@ -5,7 +5,7 @@ specifiers:
|
|||
'@testing-library/jest-dom': ^5.16.4
|
||||
'@testing-library/react': ^13.2.0
|
||||
'@testing-library/user-event': ^14.1.1
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
protobufjs: ^7.1.0
|
||||
react: ^18.1.0
|
||||
react-dom: ^18.1.0
|
||||
|
@ -17,7 +17,7 @@ dependencies:
|
|||
'@testing-library/jest-dom': 5.16.5
|
||||
'@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y
|
||||
'@testing-library/user-event': 14.4.2_znfriv3ismgf3ybh2woqwlpfea
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
protobufjs: 7.1.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0_react@18.2.0
|
||||
|
@ -7375,8 +7375,8 @@ packages:
|
|||
/js-tokens/4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
/js-waku/0.28.1:
|
||||
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==}
|
||||
/js-waku/0.29.0:
|
||||
resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@chainsafe/libp2p-gossipsub': 4.1.1
|
||||
|
|
|
@ -8,8 +8,10 @@ import {
|
|||
} from "js-waku/lib/predefined_bootstrap_nodes";
|
||||
import { PeerDiscoveryStaticPeers } from "js-waku/lib/peer_discovery_static_list";
|
||||
import { waitForRemotePeer } from "js-waku/lib/wait_for_remote_peer";
|
||||
import { DecoderV0 } from "js-waku/lib/waku_message/version_0";
|
||||
|
||||
const ContentTopic = "/toy-chat/2/huilong/proto";
|
||||
const Decoder = new DecoderV0(ContentTopic);
|
||||
|
||||
const ProtoChatMessage = new protobuf.Type("ChatMessage")
|
||||
.add(new protobuf.Field("timestamp", 1, "uint64"))
|
||||
|
@ -65,7 +67,7 @@ function App() {
|
|||
|
||||
try {
|
||||
for await (const messagesPromises of waku.store.queryGenerator(
|
||||
[ContentTopic],
|
||||
[Decoder],
|
||||
{
|
||||
timeFilter: { startTime, endTime: new Date() },
|
||||
pageDirection: "forward",
|
||||
|
|
|
@ -11,17 +11,15 @@
|
|||
|
||||
A ReactJS chat app is provided as a showcase of the library used in the browser.
|
||||
It implements [Waku v2 Toy Chat](https://rfc.vac.dev/spec/22/) protocol.
|
||||
A deployed version is available at https://js-waku.wakuconnect.dev/examples/web-chat/.
|
||||
A deployed version is available at https://examples.waku.org/web-chat/.
|
||||
|
||||
To run a development version locally, do:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/status-im/js-waku/ ; cd js-waku
|
||||
npm install # Install dependencies for js-waku
|
||||
npm run build # Build js-waku
|
||||
cd examples/web-chat
|
||||
npm install # Install dependencies for the web app
|
||||
npm run start # Start development server to serve the web app on http://localhost:3000/js-waku
|
||||
git clone https://github.com/waku-org/js-waku-examples
|
||||
cd web-chat
|
||||
npm install
|
||||
npm run start
|
||||
```
|
||||
|
||||
Use `/help` to see the available commands.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"dependencies": {
|
||||
"@livechat/ui-kit": "^0.5.0-20",
|
||||
"@multiformats/multiaddr": "^10.4.0",
|
||||
"js-waku": "0.28.1",
|
||||
"js-waku": "0.29.0",
|
||||
"process": "^0.11.10",
|
||||
"protons-runtime": "^3.1.0",
|
||||
"react": "^17.0.2",
|
||||
|
|
|
@ -9,7 +9,7 @@ specifiers:
|
|||
'@types/react-dom': ^17.0.11
|
||||
cspell: ^6.0.0
|
||||
gh-pages: ^4.0.0
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
npm-run-all: ^4.1.5
|
||||
prettier: ^2.6.2
|
||||
process: ^0.11.10
|
||||
|
@ -26,7 +26,7 @@ specifiers:
|
|||
dependencies:
|
||||
'@livechat/ui-kit': 0.5.0-20_ibvs32p3vr2bbtbo3dwziny444
|
||||
'@multiformats/multiaddr': 10.4.0
|
||||
js-waku: 0.28.1
|
||||
js-waku: 0.29.0
|
||||
process: 0.11.10
|
||||
protons-runtime: 3.1.0_uint8arraylist@2.3.2
|
||||
react: 17.0.2
|
||||
|
@ -8382,8 +8382,8 @@ packages:
|
|||
/js-tokens/4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
/js-waku/0.28.1:
|
||||
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==}
|
||||
/js-waku/0.29.0:
|
||||
resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
'@chainsafe/libp2p-gossipsub': 4.1.1
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useEffect, useReducer, useState } from "react";
|
||||
import "./App.css";
|
||||
import { PageDirection, Protocols, WakuMessage } from "js-waku";
|
||||
import { PageDirection, Protocols } from "js-waku";
|
||||
import handleCommand from "./command";
|
||||
import Room from "./Room";
|
||||
import { WakuContext } from "./WakuContext";
|
||||
|
@ -16,6 +16,7 @@ import { PeerDiscoveryStaticPeers } from "js-waku/lib/peer_discovery_static_list
|
|||
import type { WakuLight } from "js-waku/lib/interfaces";
|
||||
import process from "process";
|
||||
import { createLightNode } from "js-waku/lib/create_waku";
|
||||
import { DecoderV0, MessageV0 } from "js-waku/lib/waku_message/version_0";
|
||||
|
||||
const themes = {
|
||||
AuthorName: {
|
||||
|
@ -47,6 +48,7 @@ const themes = {
|
|||
};
|
||||
|
||||
export const ChatContentTopic = "/toy-chat/2/huilong/proto";
|
||||
const ChatDecoder = new DecoderV0(ChatContentTopic);
|
||||
|
||||
async function retrieveStoreMessages(
|
||||
waku: WakuLight,
|
||||
|
@ -60,7 +62,7 @@ async function retrieveStoreMessages(
|
|||
|
||||
try {
|
||||
for await (const messagesPromises of waku.store.queryGenerator(
|
||||
[ChatContentTopic],
|
||||
[ChatDecoder],
|
||||
{
|
||||
pageSize: 5,
|
||||
pageDirection: PageDirection.FORWARD,
|
||||
|
@ -70,11 +72,11 @@ async function retrieveStoreMessages(
|
|||
},
|
||||
}
|
||||
)) {
|
||||
const messages: Message[] = [];
|
||||
const wakuMessages = await Promise.all(messagesPromises);
|
||||
|
||||
const messages: Message[] = [];
|
||||
wakuMessages
|
||||
.filter(isWakuMessageDefined)
|
||||
.filter(isMessageDefined)
|
||||
.map((wakuMsg) => Message.fromWakuMessage(wakuMsg))
|
||||
.forEach((message) => {
|
||||
if (message) {
|
||||
|
@ -113,7 +115,7 @@ export default function App() {
|
|||
// Let's retrieve previous messages before listening to new messages
|
||||
if (!historicalMessagesRetrieved) return;
|
||||
|
||||
const handleIncomingMessage = (wakuMsg: WakuMessage) => {
|
||||
const handleIncomingMessage = (wakuMsg: MessageV0) => {
|
||||
console.log("Message received: ", wakuMsg);
|
||||
const msg = Message.fromWakuMessage(wakuMsg);
|
||||
if (msg) {
|
||||
|
@ -122,7 +124,7 @@ export default function App() {
|
|||
};
|
||||
|
||||
let unsubscribe: undefined | (() => Promise<void>);
|
||||
waku.filter.subscribe(handleIncomingMessage, [ChatContentTopic]).then(
|
||||
waku.filter.subscribe([ChatDecoder], handleIncomingMessage).then(
|
||||
(_unsubscribe) => {
|
||||
console.log("subscribed to ", ChatContentTopic);
|
||||
unsubscribe = _unsubscribe;
|
||||
|
@ -229,8 +231,6 @@ function reduceMessages(state: Message[], newMessages: Message[]) {
|
|||
return state.concat(newMessages);
|
||||
}
|
||||
|
||||
const isWakuMessageDefined = (
|
||||
msg: WakuMessage | undefined
|
||||
): msg is WakuMessage => {
|
||||
const isMessageDefined = (msg: MessageV0 | undefined): msg is MessageV0 => {
|
||||
return !!msg;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { WakuMessage } from "js-waku";
|
||||
import { MessageV0 } from "js-waku/lib/waku_message/version_0";
|
||||
import { ChatMessage } from "./chat_message";
|
||||
|
||||
export class Message {
|
||||
|
@ -11,7 +11,7 @@ export class Message {
|
|||
this.sentTimestamp = sentTimestamp;
|
||||
}
|
||||
|
||||
static fromWakuMessage(wakuMsg: WakuMessage): Message | undefined {
|
||||
static fromWakuMessage(wakuMsg: MessageV0): Message | undefined {
|
||||
if (wakuMsg.payload) {
|
||||
try {
|
||||
const chatMsg = ChatMessage.decode(wakuMsg.payload);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { PushResponse, WakuMessage } from "js-waku";
|
||||
import type { Message as WakuMessage } from "js-waku/lib/interfaces";
|
||||
import { ChatContentTopic } from "./App";
|
||||
import ChatList from "./ChatList";
|
||||
import MessageInput from "./MessageInput";
|
||||
|
@ -7,6 +7,7 @@ import { TitleBar } from "@livechat/ui-kit";
|
|||
import { Message } from "./Message";
|
||||
import { ChatMessage } from "./chat_message";
|
||||
import { useEffect, useState } from "react";
|
||||
import { EncoderV0 } from "js-waku/lib/waku_message/version_0";
|
||||
|
||||
interface Props {
|
||||
messages: Message[];
|
||||
|
@ -21,6 +22,8 @@ export default function Room(props: Props) {
|
|||
const [filterPeers, setFilterPeers] = useState(0);
|
||||
const [lightPushPeers, setLightPushPeers] = useState(0);
|
||||
|
||||
const ChatEncoder = new EncoderV0(ChatContentTopic);
|
||||
|
||||
useEffect(() => {
|
||||
if (!waku) return;
|
||||
|
||||
|
@ -57,7 +60,9 @@ export default function Room(props: Props) {
|
|||
messageToSend,
|
||||
props.nick,
|
||||
props.commandHandler,
|
||||
waku.lightPush.push.bind(waku.lightPush)
|
||||
async (msg) => {
|
||||
await waku.lightPush.push(ChatEncoder, msg);
|
||||
}
|
||||
);
|
||||
}
|
||||
: undefined
|
||||
|
@ -71,18 +76,15 @@ async function handleMessage(
|
|||
message: string,
|
||||
nick: string,
|
||||
commandHandler: (cmd: string) => void,
|
||||
messageSender: (msg: WakuMessage) => Promise<PushResponse | null>
|
||||
sender: (wakuMsg: WakuMessage) => Promise<void>
|
||||
) {
|
||||
if (message.startsWith("/")) {
|
||||
commandHandler(message);
|
||||
} else {
|
||||
const timestamp = new Date();
|
||||
const chatMessage = ChatMessage.fromUtf8String(timestamp, nick, message);
|
||||
const wakuMsg = await WakuMessage.fromBytes(
|
||||
chatMessage.encode(),
|
||||
ChatContentTopic,
|
||||
{ timestamp }
|
||||
);
|
||||
await messageSender(wakuMsg);
|
||||
const payload = chatMessage.encode();
|
||||
|
||||
await sender({ payload, timestamp });
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue