Merge branch 'master' of github.com:waku-org/js-waku-examples into weboko/create-waku-imp
This commit is contained in:
parent
5da4ca1751
commit
9ab90ef7d2
|
@ -9,10 +9,10 @@
|
|||
"@material-ui/core": "^4.12.4",
|
||||
"@material-ui/icons": "^4.11.3",
|
||||
"@waku/byte-utils": "0.0.2",
|
||||
"@waku/core": "0.0.6",
|
||||
"@waku/create": "0.0.4",
|
||||
"@waku/interfaces": "0.0.5",
|
||||
"@waku/message-encryption": "0.0.4",
|
||||
"@waku/core": "^0.0.8",
|
||||
"@waku/create": "^0.0.6",
|
||||
"@waku/interfaces": "^0.0.6",
|
||||
"@waku/message-encryption": "^0.0.7",
|
||||
"ethers": "5.7.1",
|
||||
"fontsource-roboto": "^4.0.0",
|
||||
"protobufjs": "^7.1.2",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,8 +2,9 @@ import "@ethersproject/shims";
|
|||
|
||||
import React, { useEffect, useState } from "react";
|
||||
import "./App.css";
|
||||
import type { WakuPrivacy } from "@waku/interfaces";
|
||||
import { AsymDecoder, SymDecoder } from "@waku/message-encryption";
|
||||
import type { RelayNode, IDecoder } from "@waku/interfaces";
|
||||
import { createDecoder as createSymmetricDecoder } from "@waku/message-encryption/symmetric";
|
||||
import { createDecoder, DecodedMessage } from "@waku/message-encryption/ecies";
|
||||
import { KeyPair, PublicKeyMessageEncryptionKey } from "./crypto";
|
||||
import { Message } from "./messaging/Messages";
|
||||
import "fontsource-roboto";
|
||||
|
@ -67,13 +68,13 @@ const useStyles = makeStyles({
|
|||
});
|
||||
|
||||
function App() {
|
||||
const [waku, setWaku] = useState<WakuPrivacy>();
|
||||
const [waku, setWaku] = useState<RelayNode>();
|
||||
const [provider, setProvider] = useState<Web3Provider>();
|
||||
const [encryptionKeyPair, setEncryptionKeyPair] = useState<
|
||||
KeyPair | undefined
|
||||
>();
|
||||
const [privateMessageDecoder, setPrivateMessageDecoder] =
|
||||
useState<AsymDecoder>();
|
||||
useState<IDecoder<DecodedMessage>>();
|
||||
const [publicKeys, setPublicKeys] = useState<Map<string, Uint8Array>>(
|
||||
new Map()
|
||||
);
|
||||
|
@ -109,7 +110,7 @@ function App() {
|
|||
setPublicKeys
|
||||
);
|
||||
|
||||
const publicKeyMessageDecoder = new SymDecoder(
|
||||
const publicKeyMessageDecoder = createSymmetricDecoder(
|
||||
PublicKeyContentTopic,
|
||||
PublicKeyMessageEncryptionKey
|
||||
);
|
||||
|
@ -134,7 +135,7 @@ function App() {
|
|||
if (!encryptionKeyPair) return;
|
||||
|
||||
setPrivateMessageDecoder(
|
||||
new AsymDecoder(PrivateMessageContentTopic, encryptionKeyPair.privateKey)
|
||||
createDecoder(PrivateMessageContentTopic, encryptionKeyPair.privateKey)
|
||||
);
|
||||
}, [encryptionKeyPair]);
|
||||
|
||||
|
|
|
@ -6,14 +6,14 @@ import {
|
|||
PublicKeyMessageEncryptionKey,
|
||||
} from "./crypto";
|
||||
import { PublicKeyMessage } from "./messaging/wire";
|
||||
import type { WakuPrivacy } from "@waku/interfaces";
|
||||
import { SymEncoder } from "@waku/message-encryption";
|
||||
import type { RelayNode } from "@waku/interfaces";
|
||||
import { createEncoder } from "@waku/message-encryption/symmetric";
|
||||
import { PublicKeyContentTopic } from "./waku";
|
||||
import type { TypedDataSigner } from "@ethersproject/abstract-signer";
|
||||
|
||||
interface Props {
|
||||
encryptionKeyPair: KeyPair | undefined;
|
||||
waku: WakuPrivacy | undefined;
|
||||
waku: RelayNode | undefined;
|
||||
address: string | undefined;
|
||||
signer: TypedDataSigner | undefined;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export default function BroadcastPublicKey({
|
|||
})();
|
||||
const payload = _publicKeyMessage.encode();
|
||||
|
||||
const publicKeyMessageEncoder = new SymEncoder(
|
||||
const publicKeyMessageEncoder = createEncoder(
|
||||
PublicKeyContentTopic,
|
||||
PublicKeyMessageEncryptionKey
|
||||
);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Messages, { Message } from "./Messages";
|
||||
import type { WakuPrivacy } from "@waku/interfaces";
|
||||
import type { RelayNode } from "@waku/interfaces";
|
||||
import SendMessage from "./SendMessage";
|
||||
import { makeStyles } from "@material-ui/core";
|
||||
|
||||
|
@ -13,7 +13,7 @@ const useStyles = makeStyles({
|
|||
});
|
||||
|
||||
interface Props {
|
||||
waku: WakuPrivacy | undefined;
|
||||
waku: RelayNode | undefined;
|
||||
recipients: Map<string, Uint8Array>;
|
||||
messages: Message[];
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import {
|
|||
TextField,
|
||||
} from "@material-ui/core";
|
||||
import React, { ChangeEvent, useState, KeyboardEvent } from "react";
|
||||
import type { WakuPrivacy } from "@waku/interfaces";
|
||||
import { AsymEncoder } from "@waku/message-encryption";
|
||||
import type { RelayNode } from "@waku/interfaces";
|
||||
import { createEncoder } from "@waku/message-encryption/ecies";
|
||||
import { PrivateMessage } from "./wire";
|
||||
import { PrivateMessageContentTopic } from "../waku";
|
||||
import { hexToBytes } from "@waku/byte-utils";
|
||||
|
@ -24,7 +24,7 @@ const useStyles = makeStyles((theme) => ({
|
|||
}));
|
||||
|
||||
export interface Props {
|
||||
waku: WakuPrivacy | undefined;
|
||||
waku: RelayNode | undefined;
|
||||
// address, public key
|
||||
recipients: Map<string, Uint8Array>;
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ export default function SendMessage({ waku, recipients }: Props) {
|
|||
}
|
||||
|
||||
async function sendMessage(
|
||||
waku: WakuPrivacy,
|
||||
waku: RelayNode,
|
||||
recipientAddress: string,
|
||||
recipientPublicKey: Uint8Array,
|
||||
message: string,
|
||||
|
@ -118,10 +118,7 @@ async function sendMessage(
|
|||
});
|
||||
const payload = privateMessage.encode();
|
||||
|
||||
const encoder = new AsymEncoder(
|
||||
PrivateMessageContentTopic,
|
||||
recipientPublicKey
|
||||
);
|
||||
const encoder = createEncoder(PrivateMessageContentTopic, recipientPublicKey);
|
||||
|
||||
console.log("pushing");
|
||||
const res = await waku.relay.send(encoder, { payload });
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
import { Dispatch, SetStateAction } from "react";
|
||||
import type { Message as WakuMessage, WakuPrivacy } from "@waku/interfaces";
|
||||
import type { RelayNode } from "@waku/interfaces";
|
||||
import { Protocols } from "@waku/interfaces";
|
||||
import { PrivateMessage, PublicKeyMessage } from "./messaging/wire";
|
||||
import { validatePublicKeyMessage } from "./crypto";
|
||||
import { Message } from "./messaging/Messages";
|
||||
import { equals } from "uint8arrays/equals";
|
||||
import { waitForRemotePeer } from "@waku/core/lib/wait_for_remote_peer";
|
||||
import { createPrivacyNode } from "@waku/create";
|
||||
import { waitForRemotePeer } from "@waku/core";
|
||||
import { createRelayNode } from "@waku/create";
|
||||
import { bytesToHex, hexToBytes } from "@waku/byte-utils";
|
||||
import type { DecodedMessage } from "@waku/message-encryption";
|
||||
|
||||
export const PublicKeyContentTopic = "/eth-pm/1/public-key/proto";
|
||||
export const PrivateMessageContentTopic = "/eth-pm/1/private-message/proto";
|
||||
|
||||
export async function initWaku(): Promise<WakuPrivacy> {
|
||||
const waku = await createPrivacyNode({ defaultBootstrap: true });
|
||||
export async function initWaku(): Promise<RelayNode> {
|
||||
const waku = await createRelayNode({ defaultBootstrap: true });
|
||||
await waku.start();
|
||||
await waitForRemotePeer(waku, [Protocols.Relay]);
|
||||
|
||||
|
@ -23,7 +24,7 @@ export async function initWaku(): Promise<WakuPrivacy> {
|
|||
export function handlePublicKeyMessage(
|
||||
myAddress: string | undefined,
|
||||
setter: Dispatch<SetStateAction<Map<string, Uint8Array>>>,
|
||||
msg: WakuMessage
|
||||
msg: DecodedMessage
|
||||
) {
|
||||
console.log("Public Key Message received:", msg);
|
||||
if (!msg.payload) return;
|
||||
|
@ -49,7 +50,7 @@ export function handlePublicKeyMessage(
|
|||
export async function handlePrivateMessage(
|
||||
setter: Dispatch<SetStateAction<Message[]>>,
|
||||
address: string,
|
||||
wakuMsg: WakuMessage
|
||||
wakuMsg: DecodedMessage
|
||||
) {
|
||||
console.log("Private Message received:", wakuMsg);
|
||||
if (!wakuMsg.payload) return;
|
||||
|
|
|
@ -1,164 +1,171 @@
|
|||
import * as utils from "https://unpkg.com/@waku/byte-utils@0.0.2/bundle/index.js";
|
||||
import * as wakuCreate from "https://unpkg.com/@waku/create@0.0.4/bundle/index.js";
|
||||
import { waitForRemotePeer } from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/wait_for_remote_peer.js";
|
||||
import * as wakuMessage from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/waku_message/version_0.js";
|
||||
import * as wakuCreate from "https://unpkg.com/@waku/create@0.0.5/bundle/index.js";
|
||||
import {
|
||||
waitForRemotePeer,
|
||||
createDecoder,
|
||||
createEncoder,
|
||||
} from "https://unpkg.com/@waku/core@0.0.7/bundle/index.js";
|
||||
|
||||
const MULTI_ADDR = "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm";
|
||||
const MULTI_ADDR =
|
||||
"/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm";
|
||||
const CONTENT_TOPIC = "/toy-chat/2/huilong/proto";
|
||||
const PROTOCOLS = ["filter", "lightpush"];
|
||||
|
||||
const ui = initUI();
|
||||
runApp(ui).catch((err) => {
|
||||
console.error(err);
|
||||
ui.setStatus(`error: ${err.message}`, "error");
|
||||
console.error(err);
|
||||
ui.setStatus(`error: ${err.message}`, "error");
|
||||
});
|
||||
|
||||
async function runApp(ui) {
|
||||
ui.setStatus("connecting...", "progress");
|
||||
ui.setStatus("connecting...", "progress");
|
||||
|
||||
const { info, sendMessage, unsubscribeFromMessages } = await initWakuContext({
|
||||
protocols: PROTOCOLS,
|
||||
multiAddr: MULTI_ADDR,
|
||||
contentTopic: CONTENT_TOPIC,
|
||||
onMessageReceived: ui.renderMessage,
|
||||
});
|
||||
const { info, sendMessage, unsubscribeFromMessages } = await initWakuContext({
|
||||
protocols: PROTOCOLS,
|
||||
multiAddr: MULTI_ADDR,
|
||||
contentTopic: CONTENT_TOPIC,
|
||||
onMessageReceived: ui.renderMessage,
|
||||
});
|
||||
|
||||
ui.setStatus("connected", "success");
|
||||
ui.setStatus("connected", "success");
|
||||
|
||||
ui.setLocalPeer(info.localPeerId);
|
||||
ui.setRemotePeer(info.remotePeerIds);
|
||||
ui.setRemoteMultiAddr(info.multiAddr);
|
||||
ui.setContentTopic(info.contentTopic);
|
||||
ui.setLocalPeer(info.localPeerId);
|
||||
ui.setRemotePeer(info.remotePeerIds);
|
||||
ui.setRemoteMultiAddr(info.multiAddr);
|
||||
ui.setContentTopic(info.contentTopic);
|
||||
|
||||
ui.onSendMessage(sendMessage);
|
||||
ui.onSendMessage(sendMessage);
|
||||
|
||||
ui.onExit(async () => {
|
||||
ui.setStatus("disconnecting...", "progress");
|
||||
await unsubscribeFromMessages();
|
||||
ui.setStatus("disconnected", "terminated");
|
||||
ui.resetMessages();
|
||||
});
|
||||
ui.onExit(async () => {
|
||||
ui.setStatus("disconnecting...", "progress");
|
||||
await unsubscribeFromMessages();
|
||||
ui.setStatus("disconnected", "terminated");
|
||||
ui.resetMessages();
|
||||
});
|
||||
}
|
||||
|
||||
async function initWakuContext({
|
||||
multiAddr,
|
||||
protocols,
|
||||
contentTopic,
|
||||
onMessageReceived,
|
||||
multiAddr,
|
||||
protocols,
|
||||
contentTopic,
|
||||
onMessageReceived,
|
||||
}) {
|
||||
const Decoder = new wakuMessage.DecoderV0(contentTopic);
|
||||
const Encoder = new wakuMessage.EncoderV0(contentTopic);
|
||||
const Decoder = createDecoder(contentTopic);
|
||||
const Encoder = createEncoder(contentTopic);
|
||||
|
||||
const ChatMessage = new protobuf.Type("ChatMessage")
|
||||
.add(new protobuf.Field("timestamp", 1, "uint64"))
|
||||
.add(new protobuf.Field("nick", 2, "string"))
|
||||
.add(new protobuf.Field("text", 3, "bytes"));
|
||||
const ChatMessage = new protobuf.Type("ChatMessage")
|
||||
.add(new protobuf.Field("timestamp", 1, "uint64"))
|
||||
.add(new protobuf.Field("nick", 2, "string"))
|
||||
.add(new protobuf.Field("text", 3, "bytes"));
|
||||
|
||||
const node = await wakuCreate.createLightNode({ defaultBootstrap: true });
|
||||
const node = await wakuCreate.createLightNode({ defaultBootstrap: true });
|
||||
|
||||
await node.start();
|
||||
await waitForRemotePeer(node, protocols);
|
||||
await node.start();
|
||||
await waitForRemotePeer(node, protocols);
|
||||
|
||||
// Set a filter by using Decoder for a given ContentTopic
|
||||
const unsubscribeFromMessages = await node.filter.subscribe([Decoder], (wakuMessage) => {
|
||||
const messageObj = ChatMessage.decode(wakuMessage.payload);
|
||||
onMessageReceived({
|
||||
...messageObj,
|
||||
text: utils.bytesToUtf8(messageObj.text),
|
||||
});
|
||||
});
|
||||
// Set a filter by using Decoder for a given ContentTopic
|
||||
const unsubscribeFromMessages = await node.filter.subscribe(
|
||||
[Decoder],
|
||||
(wakuMessage) => {
|
||||
const messageObj = ChatMessage.decode(wakuMessage.payload);
|
||||
onMessageReceived({
|
||||
...messageObj,
|
||||
text: utils.bytesToUtf8(messageObj.text),
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const localPeerId = node.libp2p.peerId.toString();
|
||||
const localPeerId = node.libp2p.peerId.toString();
|
||||
|
||||
const remotePeers = await node.libp2p.peerStore.all();
|
||||
const remotePeerIds = remotePeers.map(peer => peer.id.toString());
|
||||
const remotePeers = await node.libp2p.peerStore.all();
|
||||
const remotePeerIds = remotePeers.map((peer) => peer.id.toString());
|
||||
|
||||
return {
|
||||
unsubscribeFromMessages,
|
||||
info: {
|
||||
multiAddr,
|
||||
contentTopic,
|
||||
localPeerId,
|
||||
remotePeerIds,
|
||||
},
|
||||
sendMessage: async ({ text, nick }) => {
|
||||
if (!text || !nick) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
unsubscribeFromMessages,
|
||||
info: {
|
||||
multiAddr,
|
||||
contentTopic,
|
||||
localPeerId,
|
||||
remotePeerIds,
|
||||
},
|
||||
sendMessage: async ({ text, nick }) => {
|
||||
if (!text || !nick) {
|
||||
return;
|
||||
}
|
||||
|
||||
const protoMessage = ChatMessage.create({
|
||||
nick,
|
||||
timestamp: Date.now(),
|
||||
text: utils.utf8ToBytes(text),
|
||||
});
|
||||
const protoMessage = ChatMessage.create({
|
||||
nick,
|
||||
timestamp: Date.now(),
|
||||
text: utils.utf8ToBytes(text),
|
||||
});
|
||||
|
||||
await node.lightPush.push(Encoder, {
|
||||
payload: ChatMessage.encode(protoMessage).finish(),
|
||||
});
|
||||
}
|
||||
};
|
||||
await node.lightPush.push(Encoder, {
|
||||
payload: ChatMessage.encode(protoMessage).finish(),
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// UI adapter
|
||||
function initUI() {
|
||||
const exitButton = document.getElementById("exit");
|
||||
const sendButton = document.getElementById("send");
|
||||
const exitButton = document.getElementById("exit");
|
||||
const sendButton = document.getElementById("send");
|
||||
|
||||
const statusBlock = document.getElementById("status");
|
||||
const localPeerBlock = document.getElementById("localPeerId");
|
||||
const remotePeerId = document.getElementById("remotePeerId");
|
||||
const remoteMultiAddr = document.getElementById("remoteMultiAddr");
|
||||
const contentTopicBlock = document.getElementById("contentTopic");
|
||||
const statusBlock = document.getElementById("status");
|
||||
const localPeerBlock = document.getElementById("localPeerId");
|
||||
const remotePeerId = document.getElementById("remotePeerId");
|
||||
const remoteMultiAddr = document.getElementById("remoteMultiAddr");
|
||||
const contentTopicBlock = document.getElementById("contentTopic");
|
||||
|
||||
const messagesBlock = document.getElementById("messages");
|
||||
const messagesBlock = document.getElementById("messages");
|
||||
|
||||
const nickText = document.getElementById("nickText");
|
||||
const messageText = document.getElementById("messageText");
|
||||
const nickText = document.getElementById("nickText");
|
||||
const messageText = document.getElementById("messageText");
|
||||
|
||||
return {
|
||||
// UI events
|
||||
onExit: (cb) => {
|
||||
exitButton.addEventListener("click", cb);
|
||||
},
|
||||
onSendMessage: (cb) => {
|
||||
sendButton.addEventListener("click", async () => {
|
||||
await cb({
|
||||
nick: nickText.value,
|
||||
text: messageText.value,
|
||||
});
|
||||
messageText.value = "";
|
||||
});
|
||||
},
|
||||
// UI renderers
|
||||
setStatus: (value, className) => {
|
||||
statusBlock.innerHTML = `<span class=${className || ""}>${value}</span>`;
|
||||
},
|
||||
setLocalPeer: (id) => {
|
||||
localPeerBlock.innerText = id.toString();
|
||||
},
|
||||
setRemotePeer: (ids) => {
|
||||
remotePeerId.innerText = ids.join("\n");
|
||||
},
|
||||
setRemoteMultiAddr: (multiAddr) => {
|
||||
remoteMultiAddr.innerText = multiAddr.toString();
|
||||
},
|
||||
setContentTopic: (topic) => {
|
||||
contentTopicBlock.innerText = topic.toString();
|
||||
},
|
||||
renderMessage: (messageObj) => {
|
||||
const { nick, text, timestamp } = messageObj;
|
||||
const date = new Date(timestamp);
|
||||
return {
|
||||
// UI events
|
||||
onExit: (cb) => {
|
||||
exitButton.addEventListener("click", cb);
|
||||
},
|
||||
onSendMessage: (cb) => {
|
||||
sendButton.addEventListener("click", async () => {
|
||||
await cb({
|
||||
nick: nickText.value,
|
||||
text: messageText.value,
|
||||
});
|
||||
messageText.value = "";
|
||||
});
|
||||
},
|
||||
// UI renderers
|
||||
setStatus: (value, className) => {
|
||||
statusBlock.innerHTML = `<span class=${className || ""}>${value}</span>`;
|
||||
},
|
||||
setLocalPeer: (id) => {
|
||||
localPeerBlock.innerText = id.toString();
|
||||
},
|
||||
setRemotePeer: (ids) => {
|
||||
remotePeerId.innerText = ids.join("\n");
|
||||
},
|
||||
setRemoteMultiAddr: (multiAddr) => {
|
||||
remoteMultiAddr.innerText = multiAddr.toString();
|
||||
},
|
||||
setContentTopic: (topic) => {
|
||||
contentTopicBlock.innerText = topic.toString();
|
||||
},
|
||||
renderMessage: (messageObj) => {
|
||||
const { nick, text, timestamp } = messageObj;
|
||||
const date = new Date(timestamp);
|
||||
|
||||
// WARNING: XSS vulnerable
|
||||
messagesBlock.innerHTML += `
|
||||
// WARNING: XSS vulnerable
|
||||
messagesBlock.innerHTML += `
|
||||
<div class="message">
|
||||
<p>${nick} <span>(${date.toDateString()})</span>:</p>
|
||||
<p>${text}</p>
|
||||
<div>
|
||||
`;
|
||||
},
|
||||
resetMessages: () => {
|
||||
messagesBlock.innerHTML = "";
|
||||
},
|
||||
};
|
||||
},
|
||||
resetMessages: () => {
|
||||
messagesBlock.innerHTML = "";
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -39,12 +39,12 @@
|
|||
|
||||
<script type="module">
|
||||
import * as utils from "https://unpkg.com/@waku/byte-utils@0.0.2/bundle/index.js";
|
||||
import { createLightNode } from "https://unpkg.com/@waku/create@0.0.4/bundle/index.js";
|
||||
import { waitForRemotePeer } from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/wait_for_remote_peer.js";
|
||||
import { createLightNode } from "https://unpkg.com/@waku/create@0.0.5/bundle/index.js";
|
||||
import {
|
||||
EncoderV0,
|
||||
DecoderV0,
|
||||
} from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/waku_message/version_0.js";
|
||||
waitForRemotePeer,
|
||||
createEncoder,
|
||||
createDecoder,
|
||||
} from "https://unpkg.com/@waku/core@0.0.7/bundle/index.js";
|
||||
|
||||
const peerIdDiv = document.getElementById("peer-id");
|
||||
const remotePeerIdDiv = document.getElementById("remote-peer-id");
|
||||
|
@ -58,8 +58,8 @@
|
|||
const sendButton = document.getElementById("sendButton");
|
||||
|
||||
const ContentTopic = "/js-waku-examples/1/chat/utf8";
|
||||
const decoder = new DecoderV0(ContentTopic);
|
||||
const encoder = new EncoderV0(ContentTopic);
|
||||
const decoder = createDecoder(ContentTopic);
|
||||
const encoder = createEncoder(ContentTopic);
|
||||
let messages = [];
|
||||
let unsubscribe;
|
||||
|
||||
|
|
|
@ -34,12 +34,12 @@
|
|||
bytesToUtf8,
|
||||
utf8ToBytes,
|
||||
} from "https://unpkg.com/@waku/byte-utils@0.0.2/bundle/index.js";
|
||||
import { createPrivacyNode } from "https://unpkg.com/@waku/create@0.0.4/bundle/index.js";
|
||||
import { waitForRemotePeer } from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/wait_for_remote_peer.js";
|
||||
import { createRelayNode } from "https://unpkg.com/@waku/create@0.0.5/bundle/index.js";
|
||||
import {
|
||||
DecoderV0,
|
||||
EncoderV0,
|
||||
} from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/waku_message/version_0.js";
|
||||
waitForRemotePeer,
|
||||
createDecoder,
|
||||
createEncoder,
|
||||
} from "https://unpkg.com/@waku/core@0.0.7/bundle/index.js";
|
||||
|
||||
const statusDiv = document.getElementById("status");
|
||||
const messagesDiv = document.getElementById("messages");
|
||||
|
@ -55,8 +55,8 @@
|
|||
|
||||
// Prepare encoder and decoder, `V0` for clear text messages.
|
||||
|
||||
const encoder = new EncoderV0(contentTopic);
|
||||
const decoder = new DecoderV0(contentTopic);
|
||||
const encoder = createEncoder(contentTopic);
|
||||
const decoder = createDecoder(contentTopic);
|
||||
|
||||
try {
|
||||
statusDiv.innerHTML = "<p>Starting</p>";
|
||||
|
@ -66,7 +66,7 @@
|
|||
// We are currently working on migrating this method to DNS Discovery.
|
||||
//
|
||||
// https://js.waku.org/functions/lib_create_waku.createPrivacyNode.html
|
||||
const waku = await createPrivacyNode({ defaultBootstrap: true });
|
||||
const waku = await createRelayNode({ defaultBootstrap: true });
|
||||
await waku.start();
|
||||
|
||||
// Add a hook to process all incoming messages on a specified content topic.
|
||||
|
|
|
@ -44,29 +44,33 @@
|
|||
|
||||
<div class="row">
|
||||
<div class="w50">
|
||||
<h4>You can either generate new credentials:</h4>
|
||||
<button disabled id="generate-credentials" type="button">
|
||||
Generate RLN Credentials
|
||||
</button>
|
||||
<h4>Generate new, or import existing, credentials from wallet:</h4>
|
||||
<br />
|
||||
<div id="import-from-wallet">
|
||||
<button id="import-from-wallet-button" type="button">
|
||||
Generate RLN Credentials
|
||||
</button>
|
||||
</div>
|
||||
<br />
|
||||
<button disabled id="register-button" type="button">
|
||||
Register Credentials in Contract
|
||||
</button>
|
||||
</div>
|
||||
<div class="w50">
|
||||
<h4>Or import existing ones:</h4>
|
||||
<label for="membership-id"
|
||||
>Membership ID (your index in the RLN smart contract):</label
|
||||
>
|
||||
<input id="membership-id" name="membership-id" type="text" />
|
||||
<label for="id-key">RLN Identity Key (hex string):</label>
|
||||
<input id="id-key" name="id-key" type="text" />
|
||||
<label for="commitment-key">RLN Commitment Key (hex string):</label>
|
||||
<input id="commitment-key" name="commitment-key" type="text" />
|
||||
<button disabled id="import-button" type="button">
|
||||
Import RLN Credentials
|
||||
</button>
|
||||
<h4>Import existing credentials manually:</h4>
|
||||
<div>
|
||||
<label for="membership-id"
|
||||
>Membership ID (your index in the RLN smart contract):</label
|
||||
>
|
||||
<input id="membership-id" name="membership-id" type="text" />
|
||||
<label for="id-key">RLN Identity Key (hex string):</label>
|
||||
<input id="id-key" name="id-key" type="text" />
|
||||
<label for="commitment-key">RLN Commitment Key (hex string):</label>
|
||||
<input id="commitment-key" name="commitment-key" type="text" />
|
||||
<button disabled id="import-manually-button" type="button">
|
||||
Import RLN Credentials
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row rcenter mu1">
|
||||
|
@ -140,7 +144,7 @@
|
|||
MembershipKey,
|
||||
RLNDecoder,
|
||||
RLNEncoder,
|
||||
} from "https://unpkg.com/@waku/rln@0.0.12-6875952/bundle/index.js";
|
||||
} from "https://unpkg.com/@waku/rln@0.0.13/bundle/index.js";
|
||||
|
||||
import { ethers } from "https://unpkg.com/ethers@5.7.2/dist/ethers.esm.min.js";
|
||||
|
||||
|
@ -158,14 +162,14 @@
|
|||
);
|
||||
|
||||
// Credentials Elements
|
||||
const generateCredsButton = document.getElementById(
|
||||
"generate-credentials"
|
||||
);
|
||||
|
||||
const membershipIdInput = document.getElementById("membership-id");
|
||||
const identityKeyInput = document.getElementById("id-key");
|
||||
const commitmentKeyInput = document.getElementById("commitment-key");
|
||||
const importButton = document.getElementById("import-button");
|
||||
const importManually = document.getElementById("import-manually-button");
|
||||
const importFromWalletButton = document.getElementById(
|
||||
"import-from-wallet-button"
|
||||
);
|
||||
|
||||
const idDiv = document.getElementById("id");
|
||||
const keyDiv = document.getElementById("key");
|
||||
|
@ -193,9 +197,14 @@
|
|||
node,
|
||||
nodeConnected,
|
||||
rlnInstance;
|
||||
|
||||
const allMemberships = [];
|
||||
let retrievedRLNEvents = false;
|
||||
const rlnInstancePromise = create();
|
||||
|
||||
const DEFAULT_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";
|
||||
|
||||
// Load zero-kit WASM blob.
|
||||
|
||||
statusSpan.innerText = "WASM Blob download in progress...";
|
||||
|
@ -232,15 +241,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
generateCredsButton.disabled = !rlnInstance;
|
||||
|
||||
registerButton.disabled = !(
|
||||
membershipKey &&
|
||||
retrievedRLNEvents &&
|
||||
!membershipId
|
||||
);
|
||||
|
||||
importButton.disabled = !(
|
||||
importManually.disabled = !(
|
||||
membershipIdInput.value &&
|
||||
identityKeyInput.value &&
|
||||
commitmentKeyInput.value
|
||||
|
@ -258,16 +265,11 @@
|
|||
|
||||
// Blockchain
|
||||
|
||||
generateCredsButton.onclick = () => {
|
||||
membershipKey = rlnInstance.generateMembershipKey();
|
||||
updateFields();
|
||||
};
|
||||
|
||||
membershipIdInput.onchange = updateFields;
|
||||
identityKeyInput.onchange = updateFields;
|
||||
commitmentKeyInput.onchange = updateFields;
|
||||
|
||||
importButton.onclick = () => {
|
||||
importManually.onclick = () => {
|
||||
const idKey = utils.hexToBytes(identityKeyInput.value);
|
||||
const idCommitment = utils.hexToBytes(commitmentKeyInput.value);
|
||||
membershipKey = new MembershipKey(idKey, idCommitment);
|
||||
|
@ -275,6 +277,26 @@
|
|||
updateFields();
|
||||
};
|
||||
|
||||
importFromWalletButton.onclick = async () => {
|
||||
const signer = provider.getSigner();
|
||||
|
||||
const signature = await signer.signMessage(signatureMessage);
|
||||
|
||||
membershipKey = await rlnInstance.generateSeededMembershipKey(
|
||||
signature
|
||||
);
|
||||
|
||||
const idCommitment = ethers.utils.hexlify(membershipKey.IDCommitment);
|
||||
|
||||
allMemberships.forEach((m) => {
|
||||
if (m.pubkey._hex === idCommitment) {
|
||||
membershipId = m.index.toString();
|
||||
}
|
||||
});
|
||||
|
||||
updateFields();
|
||||
};
|
||||
|
||||
const checkChain = async (chainId) => {
|
||||
retrieveRLNDetailsButton.disabled = retrievedRLNEvents || chainId !== 5;
|
||||
registerButton.disabled = !(chainId === 5 && retrievedRLNEvents);
|
||||
|
@ -303,6 +325,8 @@
|
|||
|
||||
const handleMembership = (pubkey, index) => {
|
||||
try {
|
||||
allMemberships.push({ pubkey, index });
|
||||
|
||||
const idCommitment = ethers.utils.zeroPad(
|
||||
ethers.utils.arrayify(pubkey),
|
||||
32
|
||||
|
@ -337,6 +361,8 @@
|
|||
setAccounts(accounts);
|
||||
const network = await provider.getNetwork();
|
||||
checkChain(network.chainId);
|
||||
|
||||
importFromWalletButton.disabled = false;
|
||||
} catch (e) {
|
||||
console.log("No web3 provider available", e);
|
||||
}
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
import {
|
||||
defaultLibp2p,
|
||||
defaultPeerDiscovery,
|
||||
} from "https://unpkg.com/@waku/create@0.0.4/bundle/index.js";
|
||||
import { waitForRemotePeer } from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/wait_for_remote_peer.js";
|
||||
} from "https://unpkg.com/@waku/create@0.0.5/bundle/index.js";
|
||||
import {
|
||||
wakuStore,
|
||||
WakuNode,
|
||||
} from "https://unpkg.com/@waku/core@0.0.6/bundle/index.js";
|
||||
import { DecoderV0 } from "https://unpkg.com/@waku/core@0.0.6/bundle/lib/waku_message/version_0.js";
|
||||
waitForRemotePeer,
|
||||
createDecoder,
|
||||
} from "https://unpkg.com/@waku/core@0.0.7/bundle/index.js";
|
||||
|
||||
/**
|
||||
* This example demonstrates how to use the js-waku minified bundle
|
||||
|
@ -56,7 +56,7 @@
|
|||
};
|
||||
|
||||
await node.store.queryOrderedCallback(
|
||||
[new DecoderV0("/relay-ping/1/ping/null")],
|
||||
[createDecoder("/relay-ping/1/ping/null")],
|
||||
callback,
|
||||
{ pageDirection: "backward" }
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue