mirror of
https://github.com/logos-messaging/examples.waku.org.git
synced 2026-01-05 22:33:08 +00:00
add creation of a node
This commit is contained in:
parent
ad3656c3f9
commit
1b30a24183
3507
examples/rln-js/package-lock.json
generated
3507
examples/rln-js/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,8 +9,11 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@waku/rln": "0.1.1-fa49e29",
|
"@waku/rln": "0.1.1-7e8cb89",
|
||||||
|
"@waku/sdk": "^0.0.20",
|
||||||
|
"@waku/utils": "^0.0.12",
|
||||||
"ethers": "^5.7.2",
|
"ethers": "^5.7.2",
|
||||||
|
"multiaddr": "^10.0.1",
|
||||||
"next": "13.5.6",
|
"next": "13.5.6",
|
||||||
"protobufjs": "^7.2.5",
|
"protobufjs": "^7.2.5",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
|
|||||||
@ -1,18 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Block, BlockTypes } from "@/components/Block";
|
import { Block } from "@/components/Block";
|
||||||
import { Subtitle } from "@/components/Subtitle";
|
import { Subtitle } from "@/components/Subtitle";
|
||||||
import { Status } from "@/components/Status";
|
import { Status } from "@/components/Status";
|
||||||
import { Button } from "@/components/Button";
|
import { Button } from "@/components/Button";
|
||||||
import { useStore, useWaku } from "@/hooks";
|
import { useStore, useWaku } from "@/hooks";
|
||||||
|
|
||||||
const DEFAULT_MA =
|
|
||||||
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm";
|
|
||||||
|
|
||||||
export const Waku: React.FunctionComponent<{}> = () => {
|
export const Waku: React.FunctionComponent<{}> = () => {
|
||||||
const { wakuStatus } = useStore();
|
const { wakuStatus } = useStore();
|
||||||
const { onDial, onSend, messages } = useWaku();
|
const { onSend, messages } = useWaku();
|
||||||
|
|
||||||
const { multiaddr, onMultiaddrChange } = useMultiaddr();
|
|
||||||
const { nick, message, onNickChange, onMessageChange } = useMessage();
|
const { nick, message, onNickChange, onMessageChange } = useMessage();
|
||||||
|
|
||||||
const renderedMessages = React.useMemo(
|
const renderedMessages = React.useMemo(
|
||||||
@ -25,27 +21,6 @@ export const Waku: React.FunctionComponent<{}> = () => {
|
|||||||
<Subtitle>Waku</Subtitle>
|
<Subtitle>Waku</Subtitle>
|
||||||
<Status text="Waku status" mark={wakuStatus} />
|
<Status text="Waku status" mark={wakuStatus} />
|
||||||
|
|
||||||
<Block className="mt-4">
|
|
||||||
<label
|
|
||||||
htmlFor="remote-multiaddr"
|
|
||||||
className="block mb-2 text-sm font-medium text-gray-900 dark:text-white"
|
|
||||||
>
|
|
||||||
Password(used for reading/saving into Keystore)
|
|
||||||
</label>
|
|
||||||
<Block type={BlockTypes.FlexHorizontal}>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={multiaddr}
|
|
||||||
id="remote-multiaddr"
|
|
||||||
onChange={onMultiaddrChange}
|
|
||||||
className="w-full mb-2 mr-2 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
|
||||||
/>
|
|
||||||
<Button className="mb-2" onClick={() => onDial(multiaddr)}>
|
|
||||||
Dial
|
|
||||||
</Button>
|
|
||||||
</Block>
|
|
||||||
</Block>
|
|
||||||
|
|
||||||
<Block className="mt-4">
|
<Block className="mt-4">
|
||||||
<label
|
<label
|
||||||
htmlFor="nick-input"
|
htmlFor="nick-input"
|
||||||
@ -93,19 +68,6 @@ export const Waku: React.FunctionComponent<{}> = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
function useMultiaddr() {
|
|
||||||
const [multiaddr, setMultiaddr] = React.useState<string>(DEFAULT_MA);
|
|
||||||
|
|
||||||
const onMultiaddrChange = (e: React.SyntheticEvent<HTMLInputElement>) => {
|
|
||||||
setMultiaddr(e.currentTarget.value || "");
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
multiaddr,
|
|
||||||
onMultiaddrChange,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function useMessage() {
|
function useMessage() {
|
||||||
const [nick, setNick] = React.useState<string>("");
|
const [nick, setNick] = React.useState<string>("");
|
||||||
const [message, setMessage] = React.useState<string>("");
|
const [message, setMessage] = React.useState<string>("");
|
||||||
|
|||||||
@ -5,7 +5,7 @@ export const ProtoChatMessage = new protobuf.Type("ChatMessage")
|
|||||||
.add(new protobuf.Field("nick", 2, "string"))
|
.add(new protobuf.Field("nick", 2, "string"))
|
||||||
.add(new protobuf.Field("text", 3, "bytes"));
|
.add(new protobuf.Field("text", 3, "bytes"));
|
||||||
|
|
||||||
export const ContentTopic = "/toy-chat/2/luzhou/proto";
|
export const CONTENT_TOPIC = "/toy-chat/2/luzhou/proto";
|
||||||
|
|
||||||
export const SIGNATURE_MESSAGE =
|
export const SIGNATURE_MESSAGE =
|
||||||
"The signature of this message will be used to generate your RLN credentials. Anyone accessing it may send messages on your behalf, please only share with the RLN dApp";
|
"The signature of this message will be used to generate your RLN credentials. Anyone accessing it may send messages on your behalf, please only share with the RLN dApp";
|
||||||
|
|||||||
@ -45,8 +45,7 @@ export const useStore = create<StoreResult>((set) => {
|
|||||||
|
|
||||||
const wakuModule = {
|
const wakuModule = {
|
||||||
wakuStatus: DEFAULT_VALUE,
|
wakuStatus: DEFAULT_VALUE,
|
||||||
setWakuStatus: (v: string) =>
|
setWakuStatus: (v: string) => set((state) => ({ ...state, wakuStatus: v })),
|
||||||
set((state) => ({ ...state, keystoreStatus: v })),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const keystoreModule = {
|
const keystoreModule = {
|
||||||
|
|||||||
@ -1,7 +1,61 @@
|
|||||||
export const useWaku = () => {
|
import React from "react";
|
||||||
const onDial = console.log;
|
import { waku, Waku, WakuEventsNames } from "@/services/waku";
|
||||||
const onSend = console.log;
|
import { useStore } from "./useStore";
|
||||||
const messages: string[] = [];
|
import { useRLN } from "./useRLN";
|
||||||
|
|
||||||
return { onDial, onSend, messages };
|
export const useWaku = () => {
|
||||||
|
const messages: string[] = [];
|
||||||
|
const wakuRef = React.useRef<Waku>();
|
||||||
|
|
||||||
|
const { rln } = useRLN();
|
||||||
|
const { activeMembershipID, credentials, setWakuStatus } = useStore();
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!credentials || !activeMembershipID || !rln) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const statusListener = (event: CustomEvent) => {
|
||||||
|
setWakuStatus(event.detail || "");
|
||||||
|
};
|
||||||
|
waku.addEventListener(WakuEventsNames.Status, statusListener);
|
||||||
|
|
||||||
|
let terminated = false;
|
||||||
|
const run = async () => {
|
||||||
|
if (terminated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const options = {
|
||||||
|
rln,
|
||||||
|
credentials,
|
||||||
|
membershipID: activeMembershipID,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!wakuRef.current) {
|
||||||
|
await waku.init(options);
|
||||||
|
wakuRef.current = waku;
|
||||||
|
} else {
|
||||||
|
wakuRef.current.initEncoder(options);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
run();
|
||||||
|
return () => {
|
||||||
|
terminated = true;
|
||||||
|
waku.removeEventListener(WakuEventsNames.Status, statusListener);
|
||||||
|
};
|
||||||
|
}, [activeMembershipID, credentials, rln, setWakuStatus]);
|
||||||
|
|
||||||
|
const onSend = React.useCallback(
|
||||||
|
async (nick: string, message: string) => {
|
||||||
|
if (!wakuRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// await wakuRef.current.node?.lightPush.send()
|
||||||
|
},
|
||||||
|
[wakuRef]
|
||||||
|
);
|
||||||
|
|
||||||
|
return { onSend, messages };
|
||||||
};
|
};
|
||||||
|
|||||||
@ -145,4 +145,5 @@ export class RLN implements IRLN {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Next.js sometimes executes code in server env where there is no window object
|
||||||
export const rln = typeof window === "undefined" ? undefined : new RLN();
|
export const rln = typeof window === "undefined" ? undefined : new RLN();
|
||||||
|
|||||||
113
examples/rln-js/src/services/waku.ts
Normal file
113
examples/rln-js/src/services/waku.ts
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import {
|
||||||
|
createLightNode,
|
||||||
|
createEncoder,
|
||||||
|
createDecoder,
|
||||||
|
IDecodedMessage,
|
||||||
|
LightNode,
|
||||||
|
waitForRemotePeer,
|
||||||
|
} from "@waku/sdk";
|
||||||
|
import { CONTENT_TOPIC } from "@/constants";
|
||||||
|
import { RLNDecoder, RLNEncoder, IdentityCredential } from "@waku/rln";
|
||||||
|
import { RLN } from "@/services/rln";
|
||||||
|
|
||||||
|
type InitOptions = {
|
||||||
|
membershipID: number;
|
||||||
|
credentials: IdentityCredential;
|
||||||
|
rln: RLN;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum WakuEventsNames {
|
||||||
|
Status = "status",
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum WakuStatusEventPayload {
|
||||||
|
INITIALIZING = "Initializing",
|
||||||
|
WAITING_FOR_PEERS = "Waiting for peers",
|
||||||
|
STARTING = "Starting the node",
|
||||||
|
READY = "Ready",
|
||||||
|
}
|
||||||
|
|
||||||
|
type EventListener = (event: CustomEvent) => void;
|
||||||
|
|
||||||
|
interface IWaku {
|
||||||
|
init: (options: InitOptions) => void;
|
||||||
|
initEncoder: (options: InitOptions) => void;
|
||||||
|
addEventListener: (name: WakuEventsNames, fn: EventListener) => void;
|
||||||
|
removeEventListener: (name: WakuEventsNames, fn: EventListener) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Waku implements IWaku {
|
||||||
|
private contentTopic = CONTENT_TOPIC;
|
||||||
|
private readonly emitter = new EventTarget();
|
||||||
|
|
||||||
|
public node: undefined | LightNode;
|
||||||
|
|
||||||
|
private encoder: undefined | RLNEncoder;
|
||||||
|
private decoder: undefined | RLNDecoder<IDecodedMessage>;
|
||||||
|
|
||||||
|
private initialized = false;
|
||||||
|
private initializing = false;
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
public async init(options: InitOptions) {
|
||||||
|
const { rln } = options;
|
||||||
|
if (this.initialized || this.initializing || !options.rln.rlnInstance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initializing = true;
|
||||||
|
|
||||||
|
this.initEncoder(options);
|
||||||
|
this.decoder = new RLNDecoder(
|
||||||
|
options.rln.rlnInstance,
|
||||||
|
createDecoder(this.contentTopic)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this.node) {
|
||||||
|
this.emitStatusEvent(WakuStatusEventPayload.INITIALIZING);
|
||||||
|
this.node = await createLightNode({ defaultBootstrap: true });
|
||||||
|
this.emitStatusEvent(WakuStatusEventPayload.STARTING);
|
||||||
|
await this.node.start();
|
||||||
|
this.emitStatusEvent(WakuStatusEventPayload.WAITING_FOR_PEERS);
|
||||||
|
await waitForRemotePeer(this.node);
|
||||||
|
this.emitStatusEvent(WakuStatusEventPayload.READY);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initialized = true;
|
||||||
|
this.initializing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public initEncoder(options: InitOptions) {
|
||||||
|
const { rln, membershipID, credentials } = options;
|
||||||
|
if (!rln.rlnInstance) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.encoder = new RLNEncoder(
|
||||||
|
createEncoder({
|
||||||
|
ephemeral: false,
|
||||||
|
contentTopic: this.contentTopic,
|
||||||
|
}),
|
||||||
|
rln.rlnInstance,
|
||||||
|
membershipID,
|
||||||
|
credentials
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public addEventListener(name: WakuEventsNames, fn: EventListener) {
|
||||||
|
return this.emitter.addEventListener(name, fn as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeEventListener(name: WakuEventsNames, fn: EventListener) {
|
||||||
|
return this.emitter.removeEventListener(name, fn as any);
|
||||||
|
}
|
||||||
|
|
||||||
|
private emitStatusEvent(payload: WakuStatusEventPayload) {
|
||||||
|
this.emitter.dispatchEvent(
|
||||||
|
new CustomEvent(WakuEventsNames.Status, { detail: payload })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const waku = new Waku();
|
||||||
Loading…
x
Reference in New Issue
Block a user