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:
fryorcraken.eth 2022-09-22 20:38:19 +10:00 committed by GitHub
commit 9872f1082d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 251 additions and 316 deletions

View File

@ -3,6 +3,7 @@
"$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/master/cspell.schema.json", "$schema": "https://raw.githubusercontent.com/streetsidesoftware/cspell/master/cspell.schema.json",
"language": "en", "language": "en",
"words": [ "words": [
"asym",
"backoff", "backoff",
"backoffs", "backoffs",
"bitjson", "bitjson",

View File

@ -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 This protocol has been created to demonstrated how encryption and signature could be added to message
sent over the Waku v2 network. 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: To run a development version locally, do:
```shell ```shell
git clone https://github.com/status-im/js-waku/ ; cd js-waku git clone https://github.com/waku-org/js-waku-examples
npm install # Install dependencies for js-waku cd eth-pm
npm run build # Build js-waku npm install
cd examples/eth-pm npm run start
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
``` ```

View File

@ -10,7 +10,7 @@
"@material-ui/icons": "^4.11.2", "@material-ui/icons": "^4.11.2",
"ethers": "5.7.1", "ethers": "5.7.1",
"fontsource-roboto": "^4.0.0", "fontsource-roboto": "^4.0.0",
"js-waku": "0.28.1", "js-waku": "0.29.0",
"protobufjs": "^7.1.0", "protobufjs": "^7.1.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",

93
eth-pm/pnpm-lock.yaml generated
View File

@ -14,7 +14,7 @@ specifiers:
eslint: ^8.9.0 eslint: ^8.9.0
ethers: 5.7.1 ethers: 5.7.1
fontsource-roboto: ^4.0.0 fontsource-roboto: ^4.0.0
js-waku: 0.28.1 js-waku: 0.29.0
npm-run-all: ^4.1.5 npm-run-all: ^4.1.5
prettier: ^2.5.1 prettier: ^2.5.1
protobufjs: ^7.1.0 protobufjs: ^7.1.0
@ -27,14 +27,14 @@ specifiers:
dependencies: dependencies:
'@ethersproject/abstract-signer': 5.7.0 '@ethersproject/abstract-signer': 5.7.0
'@ethersproject/providers': 5.7.0 '@ethersproject/providers': 5.7.0
'@material-ui/core': 4.12.4_x6vcehmdzjj6pm7ndhhuigqb3i '@material-ui/core': 4.12.4_zxljzmqdrxwnuenbkrz77w74uy
'@material-ui/icons': 4.11.3_3v7i52wmmfi3wwfybpvt6ex6wq '@material-ui/icons': 4.11.3_upnjamd3tbaukgopcqqdlc7jbm
ethers: 5.7.1 ethers: 5.7.1
fontsource-roboto: 4.0.0 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 protobufjs: 7.1.0
react: 17.0.2 react: 18.2.0
react-dom: 17.0.2_react@17.0.2 react-dom: 18.2.0_react@18.2.0
uint8arrays: 3.1.0 uint8arrays: 3.1.0
devDependencies: devDependencies:
@ -47,7 +47,7 @@ devDependencies:
eslint: 8.21.0 eslint: 8.21.0
npm-run-all: 4.1.5 npm-run-all: 4.1.5
prettier: 2.7.1 prettier: 2.7.1
react-scripts: 5.0.1_eqoi5id72ccwlxlz5mj7wjr7gu react-scripts: 5.0.1_zqc2lflk57y5fs7vjdkkfoejyi
typescript: 4.8.2 typescript: 4.8.2
packages: packages:
@ -3284,7 +3284,7 @@ packages:
- utf-8-validate - utf-8-validate
dev: false dev: false
/@material-ui/core/4.12.4_x6vcehmdzjj6pm7ndhhuigqb3i: /@material-ui/core/4.12.4_zxljzmqdrxwnuenbkrz77w74uy:
resolution: {integrity: sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==} resolution: {integrity: sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
peerDependencies: peerDependencies:
@ -3296,23 +3296,23 @@ packages:
optional: true optional: true
dependencies: dependencies:
'@babel/runtime': 7.18.9 '@babel/runtime': 7.18.9
'@material-ui/styles': 4.11.5_x6vcehmdzjj6pm7ndhhuigqb3i '@material-ui/styles': 4.11.5_zxljzmqdrxwnuenbkrz77w74uy
'@material-ui/system': 4.12.2_x6vcehmdzjj6pm7ndhhuigqb3i '@material-ui/system': 4.12.2_zxljzmqdrxwnuenbkrz77w74uy
'@material-ui/types': 5.1.0_@types+react@18.0.17 '@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': 18.0.17
'@types/react-transition-group': 4.4.5 '@types/react-transition-group': 4.4.5
clsx: 1.2.1 clsx: 1.2.1
hoist-non-react-statics: 3.3.2 hoist-non-react-statics: 3.3.2
popper.js: 1.16.1-lts popper.js: 1.16.1-lts
prop-types: 15.8.1 prop-types: 15.8.1
react: 17.0.2 react: 18.2.0
react-dom: 17.0.2_react@17.0.2 react-dom: 18.2.0_react@18.2.0
react-is: 17.0.2 react-is: 17.0.2
react-transition-group: 4.4.5_sfoxds7t5ydpegc3knd667wn6m react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y
dev: false dev: false
/@material-ui/icons/4.11.3_3v7i52wmmfi3wwfybpvt6ex6wq: /@material-ui/icons/4.11.3_upnjamd3tbaukgopcqqdlc7jbm:
resolution: {integrity: sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==} resolution: {integrity: sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
peerDependencies: peerDependencies:
@ -3325,13 +3325,13 @@ packages:
optional: true optional: true
dependencies: dependencies:
'@babel/runtime': 7.18.9 '@babel/runtime': 7.18.9
'@material-ui/core': 4.12.4_x6vcehmdzjj6pm7ndhhuigqb3i '@material-ui/core': 4.12.4_zxljzmqdrxwnuenbkrz77w74uy
'@types/react': 18.0.17 '@types/react': 18.0.17
react: 17.0.2 react: 18.2.0
react-dom: 17.0.2_react@17.0.2 react-dom: 18.2.0_react@18.2.0
dev: false 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==} resolution: {integrity: sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
peerDependencies: peerDependencies:
@ -3345,7 +3345,7 @@ packages:
'@babel/runtime': 7.18.9 '@babel/runtime': 7.18.9
'@emotion/hash': 0.8.0 '@emotion/hash': 0.8.0
'@material-ui/types': 5.1.0_@types+react@18.0.17 '@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': 18.0.17
clsx: 1.2.1 clsx: 1.2.1
csstype: 2.6.20 csstype: 2.6.20
@ -3359,11 +3359,11 @@ packages:
jss-plugin-rule-value-function: 10.9.2 jss-plugin-rule-value-function: 10.9.2
jss-plugin-vendor-prefixer: 10.9.2 jss-plugin-vendor-prefixer: 10.9.2
prop-types: 15.8.1 prop-types: 15.8.1
react: 17.0.2 react: 18.2.0
react-dom: 17.0.2_react@17.0.2 react-dom: 18.2.0_react@18.2.0
dev: false dev: false
/@material-ui/system/4.12.2_x6vcehmdzjj6pm7ndhhuigqb3i: /@material-ui/system/4.12.2_zxljzmqdrxwnuenbkrz77w74uy:
resolution: {integrity: sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==} resolution: {integrity: sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
peerDependencies: peerDependencies:
@ -3375,12 +3375,12 @@ packages:
optional: true optional: true
dependencies: dependencies:
'@babel/runtime': 7.18.9 '@babel/runtime': 7.18.9
'@material-ui/utils': 4.11.3_sfoxds7t5ydpegc3knd667wn6m '@material-ui/utils': 4.11.3_biqbaboplfbrettd7655fr4n2y
'@types/react': 18.0.17 '@types/react': 18.0.17
csstype: 2.6.20 csstype: 2.6.20
prop-types: 15.8.1 prop-types: 15.8.1
react: 17.0.2 react: 18.2.0
react-dom: 17.0.2_react@17.0.2 react-dom: 18.2.0_react@18.2.0
dev: false dev: false
/@material-ui/types/5.1.0_@types+react@18.0.17: /@material-ui/types/5.1.0_@types+react@18.0.17:
@ -3394,7 +3394,7 @@ packages:
'@types/react': 18.0.17 '@types/react': 18.0.17
dev: false dev: false
/@material-ui/utils/4.11.3_sfoxds7t5ydpegc3knd667wn6m: /@material-ui/utils/4.11.3_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==} resolution: {integrity: sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==}
engines: {node: '>=8.0.0'} engines: {node: '>=8.0.0'}
peerDependencies: peerDependencies:
@ -3403,8 +3403,8 @@ packages:
dependencies: dependencies:
'@babel/runtime': 7.18.9 '@babel/runtime': 7.18.9
prop-types: 15.8.1 prop-types: 15.8.1
react: 17.0.2 react: 18.2.0
react-dom: 17.0.2_react@17.0.2 react-dom: 18.2.0_react@18.2.0
react-is: 17.0.2 react-is: 17.0.2
dev: false dev: false
@ -8487,8 +8487,8 @@ packages:
/js-tokens/4.0.0: /js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
/js-waku/0.28.1_undici@5.10.0: /js-waku/0.29.0_undici@5.10.0:
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==} resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
engines: {node: '>=16'} engines: {node: '>=16'}
dependencies: dependencies:
'@chainsafe/libp2p-gossipsub': 4.1.1_undici@5.10.0 '@chainsafe/libp2p-gossipsub': 4.1.1_undici@5.10.0
@ -10735,15 +10735,14 @@ packages:
- vue-template-compiler - vue-template-compiler
dev: true dev: true
/react-dom/17.0.2_react@17.0.2: /react-dom/18.2.0_react@18.2.0:
resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
peerDependencies: peerDependencies:
react: 17.0.2 react: ^18.2.0
dependencies: dependencies:
loose-envify: 1.4.0 loose-envify: 1.4.0
object-assign: 4.1.1 react: 18.2.0
react: 17.0.2 scheduler: 0.23.0
scheduler: 0.20.2
dev: false dev: false
/react-error-overlay/6.0.11: /react-error-overlay/6.0.11:
@ -10765,7 +10764,7 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/react-scripts/5.0.1_eqoi5id72ccwlxlz5mj7wjr7gu: /react-scripts/5.0.1_zqc2lflk57y5fs7vjdkkfoejyi:
resolution: {integrity: sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==} resolution: {integrity: sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
@ -10809,7 +10808,7 @@ packages:
postcss-normalize: 10.0.1_mu2kzpkteq3ketk6piffleamkq postcss-normalize: 10.0.1_mu2kzpkteq3ketk6piffleamkq
postcss-preset-env: 7.7.2_postcss@8.4.16 postcss-preset-env: 7.7.2_postcss@8.4.16
prompts: 2.4.2 prompts: 2.4.2
react: 17.0.2 react: 18.2.0
react-app-polyfill: 3.0.0 react-app-polyfill: 3.0.0
react-dev-utils: 12.0.1_6powqha3uet7brcqpdvamgrsxu react-dev-utils: 12.0.1_6powqha3uet7brcqpdvamgrsxu
react-refresh: 0.11.0 react-refresh: 0.11.0
@ -10862,7 +10861,7 @@ packages:
- webpack-plugin-serve - webpack-plugin-serve
dev: true dev: true
/react-transition-group/4.4.5_sfoxds7t5ydpegc3knd667wn6m: /react-transition-group/4.4.5_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
peerDependencies: peerDependencies:
react: '>=16.6.0' react: '>=16.6.0'
@ -10872,16 +10871,15 @@ packages:
dom-helpers: 5.2.1 dom-helpers: 5.2.1
loose-envify: 1.4.0 loose-envify: 1.4.0
prop-types: 15.8.1 prop-types: 15.8.1
react: 17.0.2 react: 18.2.0
react-dom: 17.0.2_react@17.0.2 react-dom: 18.2.0_react@18.2.0
dev: false dev: false
/react/17.0.2: /react/18.2.0:
resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==} resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dependencies: dependencies:
loose-envify: 1.4.0 loose-envify: 1.4.0
object-assign: 4.1.1
/read-cache/1.0.0: /read-cache/1.0.0:
resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
@ -11202,11 +11200,10 @@ packages:
xmlchars: 2.2.0 xmlchars: 2.2.0
dev: true dev: true
/scheduler/0.20.2: /scheduler/0.23.0:
resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==} resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
dependencies: dependencies:
loose-envify: 1.4.0 loose-envify: 1.4.0
object-assign: 4.1.1
dev: false dev: false
/schema-utils/2.7.0: /schema-utils/2.7.0:

View File

@ -3,6 +3,7 @@ import "@ethersproject/shims";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import "./App.css"; import "./App.css";
import type { WakuLight } from "js-waku/lib/interfaces"; 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 { KeyPair, PublicKeyMessageEncryptionKey } from "./crypto";
import { Message } from "./messaging/Messages"; import { Message } from "./messaging/Messages";
import "fontsource-roboto"; import "fontsource-roboto";
@ -26,7 +27,6 @@ import {
} from "./waku"; } from "./waku";
import { Web3Provider } from "@ethersproject/providers/src.ts/web3-provider"; import { Web3Provider } from "@ethersproject/providers/src.ts/web3-provider";
import ConnectWallet from "./ConnectWallet"; import ConnectWallet from "./ConnectWallet";
import { waku_message } from "js-waku";
const theme = createMuiTheme({ const theme = createMuiTheme({
palette: { palette: {
@ -72,6 +72,8 @@ function App() {
const [encryptionKeyPair, setEncryptionKeyPair] = useState< const [encryptionKeyPair, setEncryptionKeyPair] = useState<
KeyPair | undefined KeyPair | undefined
>(); >();
const [privateMessageDecoder, setPrivateMessageDecoder] =
useState<AsymDecoder>();
const [publicKeys, setPublicKeys] = useState<Map<string, Uint8Array>>( const [publicKeys, setPublicKeys] = useState<Map<string, Uint8Array>>(
new Map() new Map()
); );
@ -109,14 +111,15 @@ function App() {
setPublicKeys setPublicKeys
); );
const publicKeyMessageDecoder = new SymDecoder(
PublicKeyContentTopic,
PublicKeyMessageEncryptionKey
);
let unsubscribe: undefined | (() => Promise<void>); let unsubscribe: undefined | (() => Promise<void>);
waku.filter.addDecryptionKey(PublicKeyMessageEncryptionKey, {
method: waku_message.DecryptionMethod.Symmetric,
contentTopics: [PublicKeyContentTopic],
});
waku.filter waku.filter
.subscribe(observerPublicKeyMessage, [PublicKeyContentTopic]) .subscribe([publicKeyMessageDecoder], observerPublicKeyMessage)
.then( .then(
(_unsubscribe) => { (_unsubscribe) => {
console.log("subscribed to ", PublicKeyContentTopic); console.log("subscribed to ", PublicKeyContentTopic);
@ -128,9 +131,8 @@ function App() {
); );
return function cleanUp() { return function cleanUp() {
if (!waku) return;
waku.filter.deleteDecryptionKey(PublicKeyMessageEncryptionKey);
if (typeof unsubscribe === "undefined") return; if (typeof unsubscribe === "undefined") return;
unsubscribe().then( unsubscribe().then(
() => { () => {
console.log("unsubscribed to ", PublicKeyContentTopic); console.log("unsubscribed to ", PublicKeyContentTopic);
@ -141,25 +143,16 @@ function App() {
}, [waku, address]); }, [waku, address]);
useEffect(() => { useEffect(() => {
if (!waku) return;
if (!encryptionKeyPair) return; if (!encryptionKeyPair) return;
waku.filter.addDecryptionKey(encryptionKeyPair.privateKey, { setPrivateMessageDecoder(
method: waku_message.DecryptionMethod.Asymmetric, new AsymDecoder(PrivateMessageContentTopic, encryptionKeyPair.privateKey)
contentTopics: [PrivateMessageContentTopic], );
}); }, [encryptionKeyPair]);
return function cleanUp() {
if (!waku) return;
if (!encryptionKeyPair) return;
waku.filter.deleteDecryptionKey(encryptionKeyPair.privateKey);
};
}, [waku, encryptionKeyPair]);
useEffect(() => { useEffect(() => {
if (!waku) return; if (!waku) return;
if (!encryptionKeyPair) return; if (!privateMessageDecoder) return;
if (!address) return; if (!address) return;
const observerPrivateMessage = handlePrivateMessage.bind( const observerPrivateMessage = handlePrivateMessage.bind(
@ -170,23 +163,20 @@ function App() {
let unsubscribe: undefined | (() => Promise<void>); let unsubscribe: undefined | (() => Promise<void>);
waku.filter waku.filter.subscribe([privateMessageDecoder], observerPrivateMessage).then(
.subscribe(observerPrivateMessage, [PrivateMessageContentTopic]) (_unsubscribe) => {
.then( unsubscribe = _unsubscribe;
(_unsubscribe) => { },
unsubscribe = _unsubscribe; (e) => {
}, console.error("Failed to subscribe", e);
(e) => { }
console.error("Failed to subscribe", e); );
}
);
return function cleanUp() { return function cleanUp() {
if (!waku) return;
if (typeof unsubscribe === "undefined") return; if (typeof unsubscribe === "undefined") return;
unsubscribe().catch((e) => console.error("Failed to unsubscribe", e)); unsubscribe().catch((e) => console.error("Failed to unsubscribe", e));
}; };
}, [waku, address, encryptionKeyPair]); }, [waku, address, privateMessageDecoder]);
useEffect(() => { useEffect(() => {
if (!waku) return; if (!waku) return;
@ -252,7 +242,7 @@ function App() {
/> />
<BroadcastPublicKey <BroadcastPublicKey
address={address} address={address}
EncryptionKeyPair={encryptionKeyPair} encryptionKeyPair={encryptionKeyPair}
waku={waku} waku={waku}
signer={provider?.getSigner()} signer={provider?.getSigner()}
/> />

View File

@ -6,66 +6,53 @@ import {
PublicKeyMessageEncryptionKey, PublicKeyMessageEncryptionKey,
} from "./crypto"; } from "./crypto";
import { PublicKeyMessage } from "./messaging/wire"; import { PublicKeyMessage } from "./messaging/wire";
import { WakuMessage } from "js-waku"; import type { WakuLight } from "js-waku/lib/interfaces";
import { WakuLight } from "js-waku/lib/interfaces"; import { SymEncoder } from "js-waku/lib/waku_message/version_1";
import { PublicKeyContentTopic } from "./waku"; import { PublicKeyContentTopic } from "./waku";
import type { TypedDataSigner } from "@ethersproject/abstract-signer"; import type { TypedDataSigner } from "@ethersproject/abstract-signer";
interface Props { interface Props {
EncryptionKeyPair: KeyPair | undefined; encryptionKeyPair: KeyPair | undefined;
waku: WakuLight | undefined; waku: WakuLight | undefined;
address: string | undefined; address: string | undefined;
signer: TypedDataSigner | undefined; signer: TypedDataSigner | undefined;
} }
export default function BroadcastPublicKey({ export default function BroadcastPublicKey({
EncryptionKeyPair, encryptionKeyPair,
waku, waku,
address, address,
signer, signer,
}: Props) { }: Props) {
const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>(); const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>();
const broadcastPublicKey = () => { const broadcastPublicKey = async () => {
if (!EncryptionKeyPair) return; if (!encryptionKeyPair) return;
if (!address) return; if (!address) return;
if (!waku) return; if (!waku) return;
if (!signer) return; if (!signer) return;
if (publicKeyMsg) { const _publicKeyMessage = await (async () => {
encodePublicKeyWakuMessage(publicKeyMsg) if (!publicKeyMsg) {
.then((wakuMsg) => { const pkm = await createPublicKeyMessage(
waku.lightPush.push(wakuMsg).catch((e) => { address,
console.error("Failed to send Public Key Message", e); encryptionKeyPair.publicKey,
}); signer
}) );
.catch((e) => {
console.log("Failed to encode Public Key Message in Waku Message", e); setPublicKeyMsg(pkm);
}); return pkm;
} else { }
createPublicKeyMessage(address, EncryptionKeyPair.publicKey, signer) return publicKeyMsg;
.then((msg) => { })();
setPublicKeyMsg(msg); const payload = _publicKeyMessage.encode();
encodePublicKeyWakuMessage(msg)
.then((wakuMsg) => { const publicKeyMessageEncoder = new SymEncoder(
waku.lightPush PublicKeyContentTopic,
.push(wakuMsg) PublicKeyMessageEncryptionKey
.then((res) => console.log("Public Key Message pushed", res)) );
.catch((e) => {
console.error("Failed to send Public Key Message", e); waku.lightPush.push(publicKeyMessageEncoder, { payload });
});
})
.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);
});
}
}; };
return ( return (
@ -73,18 +60,9 @@ export default function BroadcastPublicKey({
variant="contained" variant="contained"
color="primary" color="primary"
onClick={broadcastPublicKey} onClick={broadcastPublicKey}
disabled={!EncryptionKeyPair || !waku || !address || !signer} disabled={!encryptionKeyPair || !waku || !address || !signer}
> >
Broadcast Encryption Public Key Broadcast Encryption Public Key
</Button> </Button>
); );
} }
async function encodePublicKeyWakuMessage(
publicKeyMessage: PublicKeyMessage
): Promise<WakuMessage> {
const payload = publicKeyMessage.encode();
return await WakuMessage.fromBytes(payload, PublicKeyContentTopic, {
symKey: PublicKeyMessageEncryptionKey,
});
}

View File

@ -41,9 +41,6 @@ export async function createPublicKeyMessage(
signer signer
); );
console.log("Asking wallet to sign Public Key Message");
console.log("Public Key Message signed");
return new PublicKeyMessage({ return new PublicKeyMessage({
encryptionPublicKey: encryptionPublicKey, encryptionPublicKey: encryptionPublicKey,
ethAddress: utils.hexToBytes(address), ethAddress: utils.hexToBytes(address),

View File

@ -7,8 +7,9 @@ import {
TextField, TextField,
} from "@material-ui/core"; } from "@material-ui/core";
import React, { ChangeEvent, useState, KeyboardEvent } from "react"; 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 type { WakuLight } from "js-waku/lib/interfaces";
import { AsymEncoder } from "js-waku/lib/waku_message/version_1";
import { PrivateMessage } from "./wire"; import { PrivateMessage } from "./wire";
import { PrivateMessageContentTopic } from "../waku"; import { PrivateMessageContentTopic } from "../waku";
@ -104,45 +105,26 @@ export default function SendMessage({ waku, recipients }: Props) {
); );
} }
async function encodeEncryptedWakuMessage( async function sendMessage(
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(
waku: WakuLight, waku: WakuLight,
recipientAddress: string, recipientAddress: string,
recipientPublicKey: Uint8Array, recipientPublicKey: Uint8Array,
message: string, message: string,
callback: (res: boolean) => void callback: (res: boolean) => void
) { ) {
encodeEncryptedWakuMessage(message, recipientPublicKey, recipientAddress) const privateMessage = new PrivateMessage({
.then((msg) => { toAddress: utils.hexToBytes(recipientAddress),
console.log("pushing"); message: message,
waku.lightPush });
.push(msg) const payload = privateMessage.encode();
.then((res) => {
console.log("Message sent", res); const encoder = new AsymEncoder(
callback(res?.isSuccess ?? false); PrivateMessageContentTopic,
}) recipientPublicKey
.catch((e) => { );
console.error("Failed to send message", e);
callback(false); console.log("pushing");
}); const res = await waku.lightPush.push(encoder, { payload });
}) console.log("Message sent", res);
.catch((e) => { callback(Boolean(res.recipients.length));
console.error("Cannot encode & encrypt message", e);
callback(false);
});
} }

View File

@ -1,6 +1,6 @@
import { Dispatch, SetStateAction } from "react"; import { Dispatch, SetStateAction } from "react";
import { Protocols, utils, WakuMessage } from "js-waku"; import { Protocols, utils } from "js-waku";
import type { WakuLight } from "js-waku/lib/interfaces"; import type { WakuLight, Message as WakuMessage } from "js-waku/lib/interfaces";
import { PrivateMessage, PublicKeyMessage } from "./messaging/wire"; import { PrivateMessage, PublicKeyMessage } from "./messaging/wire";
import { validatePublicKeyMessage } from "./crypto"; import { validatePublicKeyMessage } from "./crypto";
import { Message } from "./messaging/Messages"; import { Message } from "./messaging/Messages";

View File

@ -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. 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/.

View File

@ -36,14 +36,16 @@
<script type='module'> <script type='module'>
import { import {
utils, utils,
WakuMessage } from 'https://unpkg.com/js-waku@0.29.0/bundle/index.js';
} from 'https://unpkg.com/js-waku@0.28.1/bundle/index.js';
import { import {
createLightNode 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 { import {
waitForRemotePeer 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 peerIdDiv = document.getElementById('peer-id');
const remotePeerIdDiv = document.getElementById('remote-peer-id'); const remotePeerIdDiv = document.getElementById('remote-peer-id');
@ -57,10 +59,13 @@
const sendButton = document.getElementById('sendButton'); const sendButton = document.getElementById('sendButton');
const ContentTopic = "/js-waku-examples/1/chat/utf8"; const ContentTopic = "/js-waku-examples/1/chat/utf8";
let messages = [] const decoder = new DecoderV0(ContentTopic);
const encoder = new EncoderV0(ContentTopic);
let messages = [];
let unsubscribe; let unsubscribe;
subscribeButton.disabled = true dialButton.disabled = true;
subscribeButton.disabled = true;
textInput.disabled = true; textInput.disabled = true;
sendButton.disabled = true; sendButton.disabled = true;
unsubscribeButton.disabled = true; unsubscribeButton.disabled = true;
@ -78,6 +83,7 @@
await node.start(); await node.start();
statusDiv.innerHTML = '<p>Waku node started.</p>'; statusDiv.innerHTML = '<p>Waku node started.</p>';
peerIdDiv.innerHTML = '<p>' + node.libp2p.peerId.toString() + '</p>' peerIdDiv.innerHTML = '<p>' + node.libp2p.peerId.toString() + '</p>'
dialButton.disabled = false;
dialButton.onclick = async () => { dialButton.onclick = async () => {
const ma = remoteMultiAddrDiv.value const ma = remoteMultiAddrDiv.value
@ -104,7 +110,7 @@
} }
subscribeButton.onclick = async () => { subscribeButton.onclick = async () => {
unsubscribe = await node.filter.subscribe(callback, [ContentTopic]) unsubscribe = await node.filter.subscribe([decoder], callback)
unsubscribeButton.disabled = false; unsubscribeButton.disabled = false;
subscribeButton.disabled = true; subscribeButton.disabled = true;
} }
@ -119,8 +125,7 @@
sendButton.onclick = async () => { sendButton.onclick = async () => {
const text = textInput.value; const text = textInput.value;
const wakuMessage = await WakuMessage.fromUtf8String(text, ContentTopic); await node.lightPush.push(encoder, {payload: utils.utf8ToBytes(text)});
await node.lightPush.push(wakuMessage);
console.log('Message sent!'); console.log('Message sent!');
textInput.value = null; textInput.value = null;
}; };

View File

@ -10,15 +10,15 @@
A barebones messaging app to illustrate the [Angular Relay guide](https://docs.wakuconnect.dev/docs/guides/10_angular_relay/). 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: To run a development version locally, do:
```shell ```shell
git clone https://github.com/status-im/js-waku/ ; cd js-waku git clone https://github.com/waku-org/js-waku-examples
npm install # Install dependencies for js-waku cd relay-angular-chat
npm run build # Build js-waku npm install
cd examples/relay-reactjs-chat npm start
yarn # Install dependencies for the web app
yarn start # Start development server to serve the web app on http://localhost:4200/
``` ```
### Known issues ### Known issues

View File

@ -21,7 +21,7 @@
"@angular/platform-browser": "~14.2.0", "@angular/platform-browser": "~14.2.0",
"@angular/platform-browser-dynamic": "~14.2.0", "@angular/platform-browser-dynamic": "~14.2.0",
"@angular/router": "~14.2.0", "@angular/router": "~14.2.0",
"js-waku": "0.28.1", "js-waku": "0.29.0",
"protobufjs": "^7.1.0", "protobufjs": "^7.1.0",
"rxjs": "~7.5.0", "rxjs": "~7.5.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",

View File

@ -16,7 +16,7 @@ specifiers:
'@types/node': ^17.0.21 '@types/node': ^17.0.21
is-ci-cli: ^2.2.0 is-ci-cli: ^2.2.0
jasmine-core: ~4.3.0 jasmine-core: ~4.3.0
js-waku: 0.28.1 js-waku: 0.29.0
karma: ~6.4.0 karma: ~6.4.0
karma-chrome-launcher: ~3.1.0 karma-chrome-launcher: ~3.1.0
karma-coverage: ~2.2.0 karma-coverage: ~2.2.0
@ -37,7 +37,7 @@ dependencies:
'@angular/platform-browser': 14.2.0_afytwol7hs4qio34buyx2grhfa '@angular/platform-browser': 14.2.0_afytwol7hs4qio34buyx2grhfa
'@angular/platform-browser-dynamic': 14.2.0_owch6soaoexeadly32xw5vendq '@angular/platform-browser-dynamic': 14.2.0_owch6soaoexeadly32xw5vendq
'@angular/router': 14.2.0_6lk4yxyxfaqzosenawf2bqx6vy '@angular/router': 14.2.0_6lk4yxyxfaqzosenawf2bqx6vy
js-waku: 0.28.1 js-waku: 0.29.0
protobufjs: 7.1.0 protobufjs: 7.1.0
rxjs: 7.5.6 rxjs: 7.5.6
tslib: 2.4.0 tslib: 2.4.0
@ -5440,8 +5440,8 @@ packages:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true dev: true
/js-waku/0.28.1: /js-waku/0.29.0:
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==} resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
engines: {node: '>=16'} engines: {node: '>=16'}
dependencies: dependencies:
'@chainsafe/libp2p-gossipsub': 4.1.1 '@chainsafe/libp2p-gossipsub': 4.1.1

View File

@ -1,8 +1,9 @@
import { Component, OnInit } from "@angular/core"; import { Component, OnInit } from "@angular/core";
import { WakuService } from "../waku.service"; import { WakuService } from "../waku.service";
import { WakuMessage } from "js-waku";
import type { WakuPrivacy } from "js-waku/lib/interfaces"; import type { WakuPrivacy } from "js-waku/lib/interfaces";
import protobuf from "protobufjs"; 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") const ProtoChatMessage = new protobuf.Type("ChatMessage")
.add(new protobuf.Field("timestamp", 1, "uint32")) .add(new protobuf.Field("timestamp", 1, "uint32"))
@ -20,13 +21,18 @@ interface MessageInterface {
}) })
export class MessagesComponent implements OnInit { export class MessagesComponent implements OnInit {
contentTopic: string = `/js-waku-examples/1/chat/proto`; contentTopic: string = `/js-waku-examples/1/chat/proto`;
decoder: DecoderV0;
encoder: EncoderV0;
messages: MessageInterface[] = []; messages: MessageInterface[] = [];
messageCount: number = 0; messageCount: number = 0;
waku!: WakuPrivacy; waku!: WakuPrivacy;
wakuStatus!: string; wakuStatus!: string;
deleteObserver?: () => void; deleteObserver?: () => void;
constructor(private wakuService: WakuService) {} constructor(private wakuService: WakuService) {
this.decoder = new DecoderV0(this.contentTopic);
this.encoder = new EncoderV0(this.contentTopic);
}
ngOnInit(): void { ngOnInit(): void {
this.wakuService.wakuStatus.subscribe((wakuStatus) => { this.wakuService.wakuStatus.subscribe((wakuStatus) => {
@ -36,8 +42,8 @@ export class MessagesComponent implements OnInit {
this.wakuService.waku.subscribe((waku) => { this.wakuService.waku.subscribe((waku) => {
this.waku = waku; this.waku = waku;
this.deleteObserver = this.waku.relay.addObserver( this.deleteObserver = this.waku.relay.addObserver(
this.processIncomingMessages, this.decoder,
[this.contentTopic] this.processIncomingMessages
); );
}); });
@ -57,16 +63,13 @@ export class MessagesComponent implements OnInit {
}); });
const payload = ProtoChatMessage.encode(protoMsg).finish(); const payload = ProtoChatMessage.encode(protoMsg).finish();
this.waku.relay.send(this.encoder, { payload }).then(() => {
WakuMessage.fromBytes(payload, this.contentTopic).then((wakuMessage) => { console.log(`Message #${this.messageCount} sent`);
this.waku.relay.send(wakuMessage).then(() => { this.messageCount += 1;
console.log(`Message #${this.messageCount} sent`);
this.messageCount += 1;
});
}); });
} }
processIncomingMessages = (wakuMessage: WakuMessage) => { processIncomingMessages = (wakuMessage: MessageV0) => {
if (!wakuMessage.payload) return; if (!wakuMessage.payload) return;
const { text, timestamp } = ProtoChatMessage.decode( const { text, timestamp } = ProtoChatMessage.decode(

View File

@ -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. 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/.

View File

@ -26,15 +26,10 @@
* Recommended payload is protobuf. Using simple utf-8 string for demo purposes only. * Recommended payload is protobuf. Using simple utf-8 string for demo purposes only.
*/ */
import { import {utils} from 'https://unpkg.com/js-waku@0.29.0/bundle/index.js';
WakuMessage import {createPrivacyNode} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/create_waku.js'
} from 'https://unpkg.com/js-waku@0.28.1/bundle/index.js'; import {waitForRemotePeer} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/wait_for_remote_peer.js'
import { import {DecoderV0, EncoderV0} from "https://unpkg.com/js-waku@0.29.0/bundle/lib/waku_message/version_0.js";
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'
const statusDiv = document.getElementById('status'); const statusDiv = document.getElementById('status');
const messagesDiv = document.getElementById('messages'); const messagesDiv = document.getElementById('messages');
@ -52,6 +47,11 @@
// for simplicity's sake. // for simplicity's sake.
const contentTopic = '/js-waku-examples/1/chat/utf8'; 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 { try {
statusDiv.innerHTML = '<p>Starting</p>'; statusDiv.innerHTML = '<p>Starting</p>';
@ -59,20 +59,20 @@
// `default: true` bootstraps by connecting to pre-defined/hardcoded Waku nodes. // `default: true` bootstraps by connecting to pre-defined/hardcoded Waku nodes.
// We are currently working on migrating this method to DNS Discovery. // 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}); const waku = await createPrivacyNode({defaultBootstrap: true});
await waku.start(); await waku.start();
// Had a hook to process all incoming messages on a specified content topic. // Had a hook to process all incoming messages on a specified content topic.
// //
// https://js-waku.wakuconnect.dev/classes/waku_relay.WakuRelay.html#addObserver // 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. // Checks there is a payload on the message.
// Waku Message is encoded in protobuf, in proto v3 fields are always optional. // Waku Message is encoded in protobuf, in proto v3 fields are always optional.
// //
// https://js-waku.wakuconnect.dev/classes/waku_message.WakuMessage.html#payload // https://js-waku.wakuconnect.dev/classes/waku_message.WakuMessage.html#payload
if (!wakuMessage.payload) if (!message.payload)
return; return;
// Helper method to decode the payload to utf-8. A production dApp should // Helper method to decode the payload to utf-8. A production dApp should
@ -80,7 +80,7 @@
// structure of their choice. // structure of their choice.
// //
// https://js-waku.wakuconnect.dev/classes/waku_message.WakuMessage.html#payloadAsUtf8 // 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; messagesDiv.innerHTML = `<p>${text}</p><br />` + messagesDiv.innerHTML;
}, [contentTopic]); }, [contentTopic]);
@ -96,22 +96,8 @@
// function that sends the text input over Waku Relay, the gossipsub // function that sends the text input over Waku Relay, the gossipsub
// protocol. // protocol.
sendButton.onclick = async () => { sendButton.onclick = async () => {
const text = textInput.value; const payload = utils.utf8ToBytes(textInput.value)
await waku.relay.send(encoder, {payload});
// 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);
console.log('Message sent!'); console.log('Message sent!');
// Reset the text input. // Reset the text input.

View File

@ -10,11 +10,13 @@
A barebone chat app to illustrate the [ReactJS Relay guide](https://docs.wakuconnect.dev/docs/guides/07_reactjs_relay/). 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: To run a development version locally, do:
```shell ```shell
git clone https://github.com/waku-org/js-waku-examples/ git clone https://github.com/waku-org/js-waku-examples
cd js-waku-examples/relay-reactjs-chat cd relay-reactjs-chat
npm install npm install
npm run start npm run start
``` ```

View File

@ -7,7 +7,7 @@
"@testing-library/jest-dom": "^5.16.5", "@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.3.0", "@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"js-waku": "0.28.1", "js-waku": "0.29.0",
"protobufjs": "^7.0.0", "protobufjs": "^7.0.0",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",

View File

@ -6,7 +6,7 @@ specifiers:
'@testing-library/react': ^13.3.0 '@testing-library/react': ^13.3.0
'@testing-library/user-event': ^13.5.0 '@testing-library/user-event': ^13.5.0
eslint: ^8.22.0 eslint: ^8.22.0
js-waku: 0.28.1 js-waku: 0.29.0
protobufjs: ^7.0.0 protobufjs: ^7.0.0
react: ^18.2.0 react: ^18.2.0
react-dom: ^18.2.0 react-dom: ^18.2.0
@ -17,7 +17,7 @@ dependencies:
'@testing-library/jest-dom': 5.16.5 '@testing-library/jest-dom': 5.16.5
'@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y '@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y
'@testing-library/user-event': 13.5.0_wl4iynrlixafokvgqnhzlvigei '@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 protobufjs: 7.0.0
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
@ -7001,8 +7001,8 @@ packages:
/js-tokens/4.0.0: /js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
/js-waku/0.28.1_undici@5.10.0: /js-waku/0.29.0_undici@5.10.0:
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==} resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
engines: {node: '>=16'} engines: {node: '>=16'}
dependencies: dependencies:
'@chainsafe/libp2p-gossipsub': 4.1.1_undici@5.10.0 '@chainsafe/libp2p-gossipsub': 4.1.1_undici@5.10.0

View File

@ -1,10 +1,12 @@
import { WakuMessage } from "js-waku";
import * as React from "react"; import * as React from "react";
import protobuf from "protobufjs"; import protobuf from "protobufjs";
import { createPrivacyNode } from "js-waku/lib/create_waku"; import { createPrivacyNode } from "js-waku/lib/create_waku";
import { waitForRemotePeer } from "js-waku/lib/wait_for_remote_peer"; 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 ContentTopic = `/js-waku-examples/1/chat/proto`;
const Encoder = new EncoderV0(ContentTopic);
const Decoder = new DecoderV0(ContentTopic);
const SimpleChatMessage = new protobuf.Type("SimpleChatMessage") const SimpleChatMessage = new protobuf.Type("SimpleChatMessage")
.add(new protobuf.Field("timestamp", 1, "uint32")) .add(new protobuf.Field("timestamp", 1, "uint32"))
@ -34,6 +36,7 @@ function App() {
}, [waku, wakuStatus]); }, [waku, wakuStatus]);
const processIncomingMessage = React.useCallback((wakuMessage) => { const processIncomingMessage = React.useCallback((wakuMessage) => {
console.log("Message received", wakuMessage);
if (!wakuMessage.payload) return; if (!wakuMessage.payload) return;
const { text, timestamp } = SimpleChatMessage.decode(wakuMessage.payload); const { text, timestamp } = SimpleChatMessage.decode(wakuMessage.payload);
@ -52,9 +55,10 @@ function App() {
if (!waku) return; if (!waku) return;
// Pass the content topic to only process messages related to your dApp // Pass the content topic to only process messages related to your dApp
const deleteObserver = waku.relay.addObserver(processIncomingMessage, [ const deleteObserver = waku.relay.addObserver(
ContentTopic, Decoder,
]); processIncomingMessage
);
// Called when the component is unmounted, see ReactJS doc. // Called when the component is unmounted, see ReactJS doc.
return deleteObserver; return deleteObserver;
@ -105,11 +109,8 @@ function sendMessage(message, waku, timestamp) {
}); });
const payload = SimpleChatMessage.encode(protoMsg).finish(); const payload = SimpleChatMessage.encode(protoMsg).finish();
// Wrap in a Waku Message // Send over Waku Relay
return WakuMessage.fromBytes(payload, ContentTopic).then((wakuMessage) => return waku.relay.send(Encoder, { payload });
// Send over Waku Relay
waku.relay.send(wakuMessage)
);
} }
export default App; export default App;

View File

@ -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. 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/.

View File

@ -13,15 +13,10 @@
<div id='timestamp'></div> <div id='timestamp'></div>
<script type='module'> <script type='module'>
import { import {Protocols} from 'https://unpkg.com/js-waku@0.29.0/bundle/index.js';
Protocols import {createWaku} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/create_waku.js'
} from 'https://unpkg.com/js-waku@0.28.1/bundle/index.js'; import {waitForRemotePeer} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/wait_for_remote_peer.js'
import { import {DecoderV0} from 'https://unpkg.com/js-waku@0.29.0/bundle/lib/waku_message/version_0.js'
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'
/** /**
* This example demonstrates how to use the js-waku minified bundle * This example demonstrates how to use the js-waku minified bundle
@ -56,7 +51,7 @@
startTime.setTime(Date.now() - 7 * 24 * 60 * 60 * 1000); startTime.setTime(Date.now() - 7 * 24 * 60 * 60 * 1000);
try { try {
await node.store await node.store
.queryOrderedCallback([], .queryOrderedCallback([new DecoderV0("/relay-ping/1/ping/null")],
callback, callback,
{ {
pageDirection: 'backward', pageDirection: 'backward',

View File

@ -9,15 +9,13 @@
A simple app that retrieves chat messages using [Waku Store](https://rfc.vac.dev/spec/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/). 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: To run a development version locally, do:
```shell ```shell
git clone https://github.com/status-im/js-waku/ ; cd js-waku git clone https://github.com/waku-org/js-waku-examples
npm install # Install dependencies for js-waku cd store-reactjs-chat
npm run build # Build js-waku npm install
cd examples/store-reactjs-chat npm run start
npm install # Install dependencies for the web app
npm run start # Start development server to serve the web app on http://localhost:3000/
``` ```

View File

@ -7,7 +7,7 @@
"@testing-library/jest-dom": "^5.16.4", "@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0", "@testing-library/react": "^13.2.0",
"@testing-library/user-event": "^14.1.1", "@testing-library/user-event": "^14.1.1",
"js-waku": "0.28.1", "js-waku": "0.29.0",
"protobufjs": "^7.1.0", "protobufjs": "^7.1.0",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.1.0", "react-dom": "^18.1.0",

View File

@ -5,7 +5,7 @@ specifiers:
'@testing-library/jest-dom': ^5.16.4 '@testing-library/jest-dom': ^5.16.4
'@testing-library/react': ^13.2.0 '@testing-library/react': ^13.2.0
'@testing-library/user-event': ^14.1.1 '@testing-library/user-event': ^14.1.1
js-waku: 0.28.1 js-waku: 0.29.0
protobufjs: ^7.1.0 protobufjs: ^7.1.0
react: ^18.1.0 react: ^18.1.0
react-dom: ^18.1.0 react-dom: ^18.1.0
@ -17,7 +17,7 @@ dependencies:
'@testing-library/jest-dom': 5.16.5 '@testing-library/jest-dom': 5.16.5
'@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y '@testing-library/react': 13.3.0_biqbaboplfbrettd7655fr4n2y
'@testing-library/user-event': 14.4.2_znfriv3ismgf3ybh2woqwlpfea '@testing-library/user-event': 14.4.2_znfriv3ismgf3ybh2woqwlpfea
js-waku: 0.28.1 js-waku: 0.29.0
protobufjs: 7.1.0 protobufjs: 7.1.0
react: 18.2.0 react: 18.2.0
react-dom: 18.2.0_react@18.2.0 react-dom: 18.2.0_react@18.2.0
@ -7375,8 +7375,8 @@ packages:
/js-tokens/4.0.0: /js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
/js-waku/0.28.1: /js-waku/0.29.0:
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==} resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
engines: {node: '>=16'} engines: {node: '>=16'}
dependencies: dependencies:
'@chainsafe/libp2p-gossipsub': 4.1.1 '@chainsafe/libp2p-gossipsub': 4.1.1

View File

@ -8,8 +8,10 @@ import {
} from "js-waku/lib/predefined_bootstrap_nodes"; } from "js-waku/lib/predefined_bootstrap_nodes";
import { PeerDiscoveryStaticPeers } from "js-waku/lib/peer_discovery_static_list"; import { PeerDiscoveryStaticPeers } from "js-waku/lib/peer_discovery_static_list";
import { waitForRemotePeer } from "js-waku/lib/wait_for_remote_peer"; 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 ContentTopic = "/toy-chat/2/huilong/proto";
const Decoder = new DecoderV0(ContentTopic);
const ProtoChatMessage = new protobuf.Type("ChatMessage") const ProtoChatMessage = new protobuf.Type("ChatMessage")
.add(new protobuf.Field("timestamp", 1, "uint64")) .add(new protobuf.Field("timestamp", 1, "uint64"))
@ -65,7 +67,7 @@ function App() {
try { try {
for await (const messagesPromises of waku.store.queryGenerator( for await (const messagesPromises of waku.store.queryGenerator(
[ContentTopic], [Decoder],
{ {
timeFilter: { startTime, endTime: new Date() }, timeFilter: { startTime, endTime: new Date() },
pageDirection: "forward", pageDirection: "forward",

View File

@ -11,17 +11,15 @@
A ReactJS chat app is provided as a showcase of the library used in the browser. 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. 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: To run a development version locally, do:
```shell ```shell
git clone https://github.com/status-im/js-waku/ ; cd js-waku git clone https://github.com/waku-org/js-waku-examples
npm install # Install dependencies for js-waku cd web-chat
npm run build # Build js-waku npm install
cd examples/web-chat npm run start
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
``` ```
Use `/help` to see the available commands. Use `/help` to see the available commands.

View File

@ -6,7 +6,7 @@
"dependencies": { "dependencies": {
"@livechat/ui-kit": "^0.5.0-20", "@livechat/ui-kit": "^0.5.0-20",
"@multiformats/multiaddr": "^10.4.0", "@multiformats/multiaddr": "^10.4.0",
"js-waku": "0.28.1", "js-waku": "0.29.0",
"process": "^0.11.10", "process": "^0.11.10",
"protons-runtime": "^3.1.0", "protons-runtime": "^3.1.0",
"react": "^17.0.2", "react": "^17.0.2",

View File

@ -9,7 +9,7 @@ specifiers:
'@types/react-dom': ^17.0.11 '@types/react-dom': ^17.0.11
cspell: ^6.0.0 cspell: ^6.0.0
gh-pages: ^4.0.0 gh-pages: ^4.0.0
js-waku: 0.28.1 js-waku: 0.29.0
npm-run-all: ^4.1.5 npm-run-all: ^4.1.5
prettier: ^2.6.2 prettier: ^2.6.2
process: ^0.11.10 process: ^0.11.10
@ -26,7 +26,7 @@ specifiers:
dependencies: dependencies:
'@livechat/ui-kit': 0.5.0-20_ibvs32p3vr2bbtbo3dwziny444 '@livechat/ui-kit': 0.5.0-20_ibvs32p3vr2bbtbo3dwziny444
'@multiformats/multiaddr': 10.4.0 '@multiformats/multiaddr': 10.4.0
js-waku: 0.28.1 js-waku: 0.29.0
process: 0.11.10 process: 0.11.10
protons-runtime: 3.1.0_uint8arraylist@2.3.2 protons-runtime: 3.1.0_uint8arraylist@2.3.2
react: 17.0.2 react: 17.0.2
@ -8382,8 +8382,8 @@ packages:
/js-tokens/4.0.0: /js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
/js-waku/0.28.1: /js-waku/0.29.0:
resolution: {integrity: sha512-0h9TpV6jywyjdes8hr9tFV/5iJh3LQN3sQFYHcXyi4cK+4htNiMrCRjBSqRBtfhs/j+4tOkrht8gRJRLHdA5RA==} resolution: {integrity: sha512-44GOpNbkFt/1/bDZ3tcaeemehaZaxw404QmTvHw7FUwY6dtvGsDEERLEw1TERUljDESFjvEOcJjYnLcNDY1MHg==}
engines: {node: '>=16'} engines: {node: '>=16'}
dependencies: dependencies:
'@chainsafe/libp2p-gossipsub': 4.1.1 '@chainsafe/libp2p-gossipsub': 4.1.1

View File

@ -1,6 +1,6 @@
import { useEffect, useReducer, useState } from "react"; import { useEffect, useReducer, useState } from "react";
import "./App.css"; import "./App.css";
import { PageDirection, Protocols, WakuMessage } from "js-waku"; import { PageDirection, Protocols } from "js-waku";
import handleCommand from "./command"; import handleCommand from "./command";
import Room from "./Room"; import Room from "./Room";
import { WakuContext } from "./WakuContext"; 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 type { WakuLight } from "js-waku/lib/interfaces";
import process from "process"; import process from "process";
import { createLightNode } from "js-waku/lib/create_waku"; import { createLightNode } from "js-waku/lib/create_waku";
import { DecoderV0, MessageV0 } from "js-waku/lib/waku_message/version_0";
const themes = { const themes = {
AuthorName: { AuthorName: {
@ -47,6 +48,7 @@ const themes = {
}; };
export const ChatContentTopic = "/toy-chat/2/huilong/proto"; export const ChatContentTopic = "/toy-chat/2/huilong/proto";
const ChatDecoder = new DecoderV0(ChatContentTopic);
async function retrieveStoreMessages( async function retrieveStoreMessages(
waku: WakuLight, waku: WakuLight,
@ -60,7 +62,7 @@ async function retrieveStoreMessages(
try { try {
for await (const messagesPromises of waku.store.queryGenerator( for await (const messagesPromises of waku.store.queryGenerator(
[ChatContentTopic], [ChatDecoder],
{ {
pageSize: 5, pageSize: 5,
pageDirection: PageDirection.FORWARD, pageDirection: PageDirection.FORWARD,
@ -70,11 +72,11 @@ async function retrieveStoreMessages(
}, },
} }
)) { )) {
const messages: Message[] = [];
const wakuMessages = await Promise.all(messagesPromises); const wakuMessages = await Promise.all(messagesPromises);
const messages: Message[] = [];
wakuMessages wakuMessages
.filter(isWakuMessageDefined) .filter(isMessageDefined)
.map((wakuMsg) => Message.fromWakuMessage(wakuMsg)) .map((wakuMsg) => Message.fromWakuMessage(wakuMsg))
.forEach((message) => { .forEach((message) => {
if (message) { if (message) {
@ -113,7 +115,7 @@ export default function App() {
// Let's retrieve previous messages before listening to new messages // Let's retrieve previous messages before listening to new messages
if (!historicalMessagesRetrieved) return; if (!historicalMessagesRetrieved) return;
const handleIncomingMessage = (wakuMsg: WakuMessage) => { const handleIncomingMessage = (wakuMsg: MessageV0) => {
console.log("Message received: ", wakuMsg); console.log("Message received: ", wakuMsg);
const msg = Message.fromWakuMessage(wakuMsg); const msg = Message.fromWakuMessage(wakuMsg);
if (msg) { if (msg) {
@ -122,7 +124,7 @@ export default function App() {
}; };
let unsubscribe: undefined | (() => Promise<void>); let unsubscribe: undefined | (() => Promise<void>);
waku.filter.subscribe(handleIncomingMessage, [ChatContentTopic]).then( waku.filter.subscribe([ChatDecoder], handleIncomingMessage).then(
(_unsubscribe) => { (_unsubscribe) => {
console.log("subscribed to ", ChatContentTopic); console.log("subscribed to ", ChatContentTopic);
unsubscribe = _unsubscribe; unsubscribe = _unsubscribe;
@ -229,8 +231,6 @@ function reduceMessages(state: Message[], newMessages: Message[]) {
return state.concat(newMessages); return state.concat(newMessages);
} }
const isWakuMessageDefined = ( const isMessageDefined = (msg: MessageV0 | undefined): msg is MessageV0 => {
msg: WakuMessage | undefined
): msg is WakuMessage => {
return !!msg; return !!msg;
}; };

View File

@ -1,4 +1,4 @@
import { WakuMessage } from "js-waku"; import { MessageV0 } from "js-waku/lib/waku_message/version_0";
import { ChatMessage } from "./chat_message"; import { ChatMessage } from "./chat_message";
export class Message { export class Message {
@ -11,7 +11,7 @@ export class Message {
this.sentTimestamp = sentTimestamp; this.sentTimestamp = sentTimestamp;
} }
static fromWakuMessage(wakuMsg: WakuMessage): Message | undefined { static fromWakuMessage(wakuMsg: MessageV0): Message | undefined {
if (wakuMsg.payload) { if (wakuMsg.payload) {
try { try {
const chatMsg = ChatMessage.decode(wakuMsg.payload); const chatMsg = ChatMessage.decode(wakuMsg.payload);

View File

@ -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 { ChatContentTopic } from "./App";
import ChatList from "./ChatList"; import ChatList from "./ChatList";
import MessageInput from "./MessageInput"; import MessageInput from "./MessageInput";
@ -7,6 +7,7 @@ import { TitleBar } from "@livechat/ui-kit";
import { Message } from "./Message"; import { Message } from "./Message";
import { ChatMessage } from "./chat_message"; import { ChatMessage } from "./chat_message";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { EncoderV0 } from "js-waku/lib/waku_message/version_0";
interface Props { interface Props {
messages: Message[]; messages: Message[];
@ -21,6 +22,8 @@ export default function Room(props: Props) {
const [filterPeers, setFilterPeers] = useState(0); const [filterPeers, setFilterPeers] = useState(0);
const [lightPushPeers, setLightPushPeers] = useState(0); const [lightPushPeers, setLightPushPeers] = useState(0);
const ChatEncoder = new EncoderV0(ChatContentTopic);
useEffect(() => { useEffect(() => {
if (!waku) return; if (!waku) return;
@ -57,7 +60,9 @@ export default function Room(props: Props) {
messageToSend, messageToSend,
props.nick, props.nick,
props.commandHandler, props.commandHandler,
waku.lightPush.push.bind(waku.lightPush) async (msg) => {
await waku.lightPush.push(ChatEncoder, msg);
}
); );
} }
: undefined : undefined
@ -71,18 +76,15 @@ async function handleMessage(
message: string, message: string,
nick: string, nick: string,
commandHandler: (cmd: string) => void, commandHandler: (cmd: string) => void,
messageSender: (msg: WakuMessage) => Promise<PushResponse | null> sender: (wakuMsg: WakuMessage) => Promise<void>
) { ) {
if (message.startsWith("/")) { if (message.startsWith("/")) {
commandHandler(message); commandHandler(message);
} else { } else {
const timestamp = new Date(); const timestamp = new Date();
const chatMessage = ChatMessage.fromUtf8String(timestamp, nick, message); const chatMessage = ChatMessage.fromUtf8String(timestamp, nick, message);
const wakuMsg = await WakuMessage.fromBytes( const payload = chatMessage.encode();
chatMessage.encode(),
ChatContentTopic, await sender({ payload, timestamp });
{ timestamp }
);
await messageSender(wakuMsg);
} }
} }