feat: use filter+light push instead of relay
The node already leaks IP by using store. There would be some advantages to use relay to send messages but not as much as if only relay was used.
This commit is contained in:
parent
fa4c9ed042
commit
491062154b
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
- Group chat
|
- Group chat
|
||||||
- React/TypeScript
|
- React/TypeScript
|
||||||
- Waku Relay
|
- Waku Filter
|
||||||
|
- Waku Light Push
|
||||||
- Waku Store
|
- Waku Store
|
||||||
|
|
||||||
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.
|
||||||
|
|
|
@ -121,7 +121,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 handleRelayMessage = (wakuMsg: WakuMessage) => {
|
const handleIncomingMessage = (wakuMsg: WakuMessage) => {
|
||||||
console.log("Message received: ", wakuMsg);
|
console.log("Message received: ", wakuMsg);
|
||||||
const msg = Message.fromWakuMessage(wakuMsg);
|
const msg = Message.fromWakuMessage(wakuMsg);
|
||||||
if (msg) {
|
if (msg) {
|
||||||
|
@ -129,10 +129,26 @@ export default function App() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
waku.relay.addObserver(handleRelayMessage, [ChatContentTopic]);
|
let unsubscribe: undefined | (() => Promise<void>);
|
||||||
|
waku.filter.subscribe(handleIncomingMessage, [ChatContentTopic]).then(
|
||||||
|
(_unsubscribe) => {
|
||||||
|
console.log("subscribed to ", ChatContentTopic);
|
||||||
|
unsubscribe = _unsubscribe;
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
console.error("Failed to subscribe", e);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return function cleanUp() {
|
return function cleanUp() {
|
||||||
waku?.relay.deleteObserver(handleRelayMessage, [ChatContentTopic]);
|
if (!waku) return;
|
||||||
|
if (typeof unsubscribe === "undefined") return;
|
||||||
|
unsubscribe().then(
|
||||||
|
() => {
|
||||||
|
console.log("unsubscribed to ", ChatContentTopic);
|
||||||
|
},
|
||||||
|
(e) => console.error("Failed to unsubscribe", e)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}, [waku, historicalMessagesRetrieved]);
|
}, [waku, historicalMessagesRetrieved]);
|
||||||
|
|
||||||
|
@ -141,7 +157,11 @@ export default function App() {
|
||||||
if (historicalMessagesRetrieved) return;
|
if (historicalMessagesRetrieved) return;
|
||||||
|
|
||||||
const retrieveMessages = async () => {
|
const retrieveMessages = async () => {
|
||||||
await waitForRemotePeer(waku, [Protocols.Relay, Protocols.Store]);
|
await waitForRemotePeer(waku, [
|
||||||
|
Protocols.Store,
|
||||||
|
Protocols.Filter,
|
||||||
|
Protocols.LightPush,
|
||||||
|
]);
|
||||||
console.log(`Retrieving archived messages`);
|
console.log(`Retrieving archived messages`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -186,7 +206,9 @@ export default function App() {
|
||||||
|
|
||||||
async function initWaku(setter: (waku: Waku) => void) {
|
async function initWaku(setter: (waku: Waku) => void) {
|
||||||
try {
|
try {
|
||||||
|
// TODO: Remove this declaration once there are optional in js-waku
|
||||||
const wakuRelay = new WakuRelay({ emitSelf: true });
|
const wakuRelay = new WakuRelay({ emitSelf: true });
|
||||||
|
|
||||||
const libp2p = await defaultLibp2p(wakuRelay, {
|
const libp2p = await defaultLibp2p(wakuRelay, {
|
||||||
peerDiscovery: [
|
peerDiscovery: [
|
||||||
new PeerDiscoveryStaticPeers(
|
new PeerDiscoveryStaticPeers(
|
||||||
|
@ -196,7 +218,6 @@ async function initWaku(setter: (waku: Waku) => void) {
|
||||||
});
|
});
|
||||||
const wakuStore = new WakuStore(libp2p);
|
const wakuStore = new WakuStore(libp2p);
|
||||||
|
|
||||||
// TODO: Remove these two declarations once there are optional in js-waku
|
|
||||||
const wakuLightPush = new WakuLightPush(libp2p);
|
const wakuLightPush = new WakuLightPush(libp2p);
|
||||||
const wakuFilter = new WakuFilter(libp2p);
|
const wakuFilter = new WakuFilter(libp2p);
|
||||||
|
|
||||||
|
@ -211,7 +232,8 @@ async function initWaku(setter: (waku: Waku) => void) {
|
||||||
|
|
||||||
function selectFleetEnv() {
|
function selectFleetEnv() {
|
||||||
// Works with react-scripts
|
// Works with react-scripts
|
||||||
if (process?.env?.NODE_ENV === "development") {
|
// TODO: Re-enable the switch once nwaku v0.12 is deployed
|
||||||
|
if (true || process?.env?.NODE_ENV === "development") {
|
||||||
return Fleet.Test;
|
return Fleet.Test;
|
||||||
} else {
|
} else {
|
||||||
return Fleet.Prod;
|
return Fleet.Prod;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ChangeEvent, KeyboardEvent, useState } from "react";
|
import { ChangeEvent, KeyboardEvent, useEffect, useState } from "react";
|
||||||
import { useWaku } from "./WakuContext";
|
import { useWaku } from "./WakuContext";
|
||||||
import {
|
import {
|
||||||
TextInput,
|
TextInput,
|
||||||
|
@ -15,6 +15,7 @@ interface Props {
|
||||||
|
|
||||||
export default function MessageInput(props: Props) {
|
export default function MessageInput(props: Props) {
|
||||||
const [inputText, setInputText] = useState<string>("");
|
const [inputText, setInputText] = useState<string>("");
|
||||||
|
const [activeButton, setActiveButton] = useState<boolean>(false);
|
||||||
const { waku } = useWaku();
|
const { waku } = useWaku();
|
||||||
|
|
||||||
const sendMessage = async () => {
|
const sendMessage = async () => {
|
||||||
|
@ -39,10 +40,21 @@ export default function MessageInput(props: Props) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enable the button if there are relay peers available or the user is sending a command
|
// Enable the button if there are peers available or the user is sending a command
|
||||||
const activeButton =
|
useEffect(() => {
|
||||||
(waku && waku.relay.getMeshPeers().length !== 0) ||
|
if (inputText.startsWith("/")) {
|
||||||
inputText.startsWith("/");
|
setActiveButton(true);
|
||||||
|
} else if (waku) {
|
||||||
|
(async () => {
|
||||||
|
const peers = await waku.lightPush.peers();
|
||||||
|
if (!!peers) {
|
||||||
|
setActiveButton(true);
|
||||||
|
} else {
|
||||||
|
setActiveButton(false);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}, [activeButton, inputText, waku]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TextComposer
|
<TextComposer
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { WakuMessage } from "js-waku";
|
import { PushResponse, WakuMessage } from "js-waku";
|
||||||
import { ChatContentTopic } from "./App";
|
import { ChatContentTopic } from "./App";
|
||||||
import ChatList from "./ChatList";
|
import ChatList from "./ChatList";
|
||||||
import MessageInput from "./MessageInput";
|
import MessageInput from "./MessageInput";
|
||||||
|
@ -18,24 +18,22 @@ export default function Room(props: Props) {
|
||||||
const { waku } = useWaku();
|
const { waku } = useWaku();
|
||||||
|
|
||||||
const [storePeers, setStorePeers] = useState(0);
|
const [storePeers, setStorePeers] = useState(0);
|
||||||
const [relayPeers, setRelayPeers] = useState(0);
|
const [filterPeers, setFilterPeers] = useState(0);
|
||||||
|
const [lightPushPeers, setLightPushPeers] = useState(0);
|
||||||
useEffect(() => {
|
|
||||||
if (!waku) return;
|
|
||||||
|
|
||||||
// Update relay peer count on heartbeat
|
|
||||||
waku.relay.addEventListener("gossipsub:heartbeat", () => {
|
|
||||||
setRelayPeers(waku.relay.getMeshPeers().length);
|
|
||||||
});
|
|
||||||
}, [waku]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!waku) return;
|
if (!waku) return;
|
||||||
|
|
||||||
// Update store peer when new peer connected & identified
|
// Update store peer when new peer connected & identified
|
||||||
waku.libp2p.peerStore.addEventListener("change:protocols", async () => {
|
waku.libp2p.peerStore.addEventListener("change:protocols", async () => {
|
||||||
const peers = await waku.store.peers();
|
const storePeers = await waku.store.peers();
|
||||||
setStorePeers(peers.length);
|
setStorePeers(storePeers.length);
|
||||||
|
|
||||||
|
const filterPeers = await waku.filter.peers();
|
||||||
|
setFilterPeers(filterPeers.length);
|
||||||
|
|
||||||
|
const lightPushPeers = await waku.lightPush.peers();
|
||||||
|
setLightPushPeers(lightPushPeers.length);
|
||||||
});
|
});
|
||||||
}, [waku]);
|
}, [waku]);
|
||||||
|
|
||||||
|
@ -45,7 +43,9 @@ export default function Room(props: Props) {
|
||||||
style={{ height: "98vh", display: "flex", flexDirection: "column" }}
|
style={{ height: "98vh", display: "flex", flexDirection: "column" }}
|
||||||
>
|
>
|
||||||
<TitleBar
|
<TitleBar
|
||||||
leftIcons={[`Peers: ${relayPeers} relay ${storePeers} store.`]}
|
leftIcons={[
|
||||||
|
`Peers: ${lightPushPeers} light push, ${filterPeers} filter, ${storePeers} store.`,
|
||||||
|
]}
|
||||||
title="Waku v2 chat app"
|
title="Waku v2 chat app"
|
||||||
/>
|
/>
|
||||||
<ChatList messages={props.messages} />
|
<ChatList messages={props.messages} />
|
||||||
|
@ -57,7 +57,7 @@ export default function Room(props: Props) {
|
||||||
messageToSend,
|
messageToSend,
|
||||||
props.nick,
|
props.nick,
|
||||||
props.commandHandler,
|
props.commandHandler,
|
||||||
waku.relay.send.bind(waku.relay)
|
waku.lightPush.push.bind(waku.lightPush)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
: undefined
|
: undefined
|
||||||
|
@ -71,7 +71,7 @@ async function handleMessage(
|
||||||
message: string,
|
message: string,
|
||||||
nick: string,
|
nick: string,
|
||||||
commandHandler: (cmd: string) => void,
|
commandHandler: (cmd: string) => void,
|
||||||
messageSender: (msg: WakuMessage) => Promise<void>
|
messageSender: (msg: WakuMessage) => Promise<PushResponse | null>
|
||||||
) {
|
) {
|
||||||
if (message.startsWith("/")) {
|
if (message.startsWith("/")) {
|
||||||
commandHandler(message);
|
commandHandler(message);
|
||||||
|
@ -83,6 +83,6 @@ async function handleMessage(
|
||||||
ChatContentTopic,
|
ChatContentTopic,
|
||||||
{ timestamp }
|
{ timestamp }
|
||||||
);
|
);
|
||||||
return messageSender(wakuMsg);
|
await messageSender(wakuMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,6 @@ export class ChatMessage {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Buffer.from(this.proto.payload).toString("utf-8");
|
return utils.bytesToUtf8(this.proto.payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue