import React, { useEffect, useState } from "react"; import { generate } from "server-name-generator"; import { Message } from "./Message"; import { Decoder } from "@waku/core/lib/message/version_0"; import { LightNode, StoreQueryOptions } from "@waku/interfaces"; import type { PeerId } from "@libp2p/interface-peer-id"; import { useFilterMessages, useStoreMessages } from "@waku/react"; export const usePersistentNick = (): [ string, React.Dispatch> ] => { const [nick, setNick] = useState(() => { const persistedNick = window.localStorage.getItem("nick"); return persistedNick !== null ? persistedNick : generate(); }); useEffect(() => { localStorage.setItem("nick", nick); }, [nick]); return [nick, setNick]; }; type UseMessagesParams = { node: undefined | LightNode; decoder: undefined | Decoder; options: StoreQueryOptions; }; type UseMessagesResult = [Message[], (v: Message[]) => void]; export const useMessages = (params: UseMessagesParams): UseMessagesResult => { const { messages: newMessages } = useFilterMessages(params); const { messages: storedMessages } = useStoreMessages(params); const [localMessages, setLocalMessages] = useState([]); const pushMessages = (msgs: Message[]) => { if (!msgs || !msgs.length) { return; } setLocalMessages((prev) => [...prev, ...msgs]); }; const allMessages = React.useMemo((): Message[] => { return [...storedMessages, ...newMessages] .map(Message.fromWakuMessage) .concat(localMessages) .filter((v): v is Message => !!v) .filter((v) => v.payloadAsUtf8 !== "") .sort( (left, right) => left.timestamp.getTime() - right.timestamp.getTime() ); }, [storedMessages, newMessages, localMessages]); return [allMessages, pushMessages]; }; // can be safely ignored // this is for experiments on waku side around new discovery options export const useNodePeers = (node: undefined | LightNode) => { const [bootstrapPeers, setBootstrapPeers] = useState(new Set()); const [peerExchangePeers, setPeerExchangePeers] = useState(new Set()); useEffect(() => { if (!node) return; // Update store peer when new peer connected & identified node.libp2p.peerStore.addEventListener("change:protocols", async (evt) => { const { peerId } = evt.detail; const tags = (await node.libp2p.peerStore.getTags(peerId)).map( (t) => t.name ); if (tags.includes("peer-exchange")) { setPeerExchangePeers((peers) => new Set(peers).add(peerId)); } else { setBootstrapPeers((peers) => new Set(peers).add(peerId)); } }); }, [node]); useEffect(() => { console.log("Bootstrap Peers:"); console.table(bootstrapPeers); console.log("Peer Exchange Peers:"); console.table(peerExchangePeers); }, [bootstrapPeers, peerExchangePeers]); return { bootstrapPeers, peerExchangePeers, }; };