Send Dummy messages

This commit is contained in:
Franck Royer 2021-06-15 15:29:41 +10:00
parent 69033f4ea5
commit ed5b7ba542
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
4 changed files with 82 additions and 24 deletions

View File

@ -56,6 +56,7 @@
"@ethereum-waffle/jest": "^3.2.2", "@ethereum-waffle/jest": "^3.2.2",
"@ethersproject/shims": "^5.3.0", "@ethersproject/shims": "^5.3.0",
"ethereum-waffle": "^3.3.0", "ethereum-waffle": "^3.3.0",
"npm-run-all": "^4.1.5",
"react-native-get-random-values": "^1.7.0" "react-native-get-random-values": "^1.7.0"
} }
} }

View File

@ -2,20 +2,22 @@ import 'react-native-get-random-values';
import '@ethersproject/shims'; import '@ethersproject/shims';
import React, { useEffect, useState } from 'react'; import React, { Dispatch, SetStateAction, useEffect, useState } from 'react';
import './App.css'; import './App.css';
import { Environment, getStatusFleetNodes, Waku, WakuMessage } from 'js-waku'; import { Environment, getStatusFleetNodes, Waku, WakuMessage } from 'js-waku';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { Web3Provider } from '@ethersproject/providers'; import { Web3Provider } from '@ethersproject/providers';
import { import {
createPublicKeyMessage, createPublicKeyMessage,
PublicKeyMessage,
generateEthDmKeyPair, generateEthDmKeyPair,
KeyPair, KeyPair,
validatePublicKeyMessage, validatePublicKeyMessage,
} from './crypto'; } from './crypto';
import * as EthCrypto from 'eth-crypto';
import { DirectMessage, PublicKeyMessage } from './messages';
const PublicKeyContentTopic = '/eth-dm/1/public-key/json'; const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
const DirectMessageContentTopic = '/eth-dm/1/direct-message/json';
declare let window: any; declare let window: any;
@ -24,6 +26,7 @@ function App() {
const [provider, setProvider] = useState<Web3Provider>(); const [provider, setProvider] = useState<Web3Provider>();
const [ethDmKeyPair, setEthDmKeyPair] = useState<KeyPair>(); const [ethDmKeyPair, setEthDmKeyPair] = useState<KeyPair>();
const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>(); const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>();
const [publicKeys, setPublicKeys] = useState<Map<string, string>>(new Map());
useEffect(() => { useEffect(() => {
if (provider) return; if (provider) return;
@ -60,9 +63,14 @@ function App() {
}); });
}; };
const observerPublicKeyMessage = handlePublicKeyMessage.bind(
{},
setPublicKeys
);
useEffect(() => { useEffect(() => {
if (!waku) return; if (!waku) return;
waku.relay.addObserver(handlePublicKeyMessage, [PublicKeyContentTopic]); waku.relay.addObserver(observerPublicKeyMessage, [PublicKeyContentTopic]);
}); });
const broadcastPublicKey = () => { const broadcastPublicKey = () => {
@ -71,7 +79,7 @@ function App() {
if (!waku) return; if (!waku) return;
if (publicKeyMsg) { if (publicKeyMsg) {
const wakuMsg = createWakuMessage(publicKeyMsg); const wakuMsg = encodePublicKeyWakuMessage(publicKeyMsg);
waku.relay.send(wakuMsg).catch((e) => { waku.relay.send(wakuMsg).catch((e) => {
console.error('Failed to send Public Key Message'); console.error('Failed to send Public Key Message');
}); });
@ -79,7 +87,7 @@ function App() {
createPublicKeyMessage(provider.getSigner(), ethDmKeyPair.publicKey) createPublicKeyMessage(provider.getSigner(), ethDmKeyPair.publicKey)
.then((msg) => { .then((msg) => {
setPublicKeyMsg(msg); setPublicKeyMsg(msg);
const wakuMsg = createWakuMessage(msg); const wakuMsg = encodePublicKeyWakuMessage(msg);
waku.relay.send(wakuMsg).catch((e) => { waku.relay.send(wakuMsg).catch((e) => {
console.error('Failed to send Public Key Message'); console.error('Failed to send Public Key Message');
}); });
@ -90,6 +98,17 @@ function App() {
} }
}; };
const sendDummyMessage = () => {
publicKeys.forEach(async (publicKey, address) => {
const msg = await encodeEncryptedWakuMessage(
'Here is a secret message',
publicKey,
address
);
await waku?.relay.send(msg);
});
};
return ( return (
<div className="App"> <div className="App">
<header className="App-header"> <header className="App-header">
@ -99,6 +118,12 @@ function App() {
<button onClick={broadcastPublicKey} disabled={!ethDmKeyPair || !waku}> <button onClick={broadcastPublicKey} disabled={!ethDmKeyPair || !waku}>
Broadcast Eth-DM Public Key Broadcast Eth-DM Public Key
</button> </button>
<button
onClick={sendDummyMessage}
disabled={!waku || publicKeys.size === 0}
>
Public Direct Message
</button>
</header> </header>
</div> </div>
); );
@ -128,26 +153,48 @@ function getNodes() {
} }
} }
function createWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage { function encodePublicKeyWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage {
const payload = encode(ethDmMsg); const payload = encode(ethDmMsg);
return WakuMessage.fromBytes(payload, PublicKeyContentTopic); return WakuMessage.fromBytes(payload, PublicKeyContentTopic);
} }
function handlePublicKeyMessage(msg: WakuMessage) { async function encodeEncryptedWakuMessage(
if (msg.payload) { message: string,
const publicKeyMsg = decode(msg.payload); publicKey: string,
console.log('publicKeyMsg', publicKeyMsg); address: string
const res = validatePublicKeyMessage(publicKeyMsg); ): Promise<WakuMessage> {
console.log(`Public Key Message Received, valid: ${res}`, publicKeyMsg); const encryptedMsg = await EthCrypto.encryptWithPublicKey(publicKey, message);
}
const directMsg: DirectMessage = {
toAddress: address,
encMessage: encryptedMsg,
};
const payload = encode(directMsg);
return WakuMessage.fromBytes(payload, DirectMessageContentTopic);
} }
function encode(msg: PublicKeyMessage): Buffer { function handlePublicKeyMessage(
setter: Dispatch<SetStateAction<Map<string, string>>>,
msg: WakuMessage
) {
if (!msg.payload) return;
const publicKeyMsg: PublicKeyMessage = decode(msg.payload);
const res = validatePublicKeyMessage(publicKeyMsg);
console.log(`Public Key Message Received, valid: ${res}`, publicKeyMsg);
setter((prevPks: Map<string, string>) => {
prevPks.set(publicKeyMsg.ethAddress, publicKeyMsg.ethDmPublicKey);
return new Map(prevPks);
});
}
function encode<T>(msg: T): Buffer {
const jsonStr = JSON.stringify(msg); const jsonStr = JSON.stringify(msg);
return Buffer.from(jsonStr, 'utf-8'); return Buffer.from(jsonStr, 'utf-8');
} }
function decode(bytes: Uint8Array): PublicKeyMessage { function decode<T>(bytes: Uint8Array): T {
const buf = Buffer.from(bytes); const buf = Buffer.from(bytes);
const str = buf.toString('utf-8'); const str = buf.toString('utf-8');
return JSON.parse(str); return JSON.parse(str);

View File

@ -6,6 +6,7 @@ import * as EthCrypto from 'eth-crypto';
import { toUtf8Bytes } from '@ethersproject/strings'; import { toUtf8Bytes } from '@ethersproject/strings';
import { ethers } from 'ethers'; import { ethers } from 'ethers';
import { Signer } from '@ethersproject/abstract-signer'; import { Signer } from '@ethersproject/abstract-signer';
import { PublicKeyMessage } from './messages';
const Salt = const Salt =
'Salt for Eth-Dm, do not share a signature of this message or others could decrypt your messages'; 'Salt for Eth-Dm, do not share a signature of this message or others could decrypt your messages';
@ -30,15 +31,6 @@ export async function generateEthDmKeyPair(
return keys; return keys;
} }
/**
* Message used to communicate the Eth-Dm public key linked to a given Ethereum account
*/
export interface PublicKeyMessage {
ethDmPublicKey: string;
ethAddress: string;
sig: string;
}
/** /**
* Sign the Eth-DM public key with Web3. This can then be published to let other * Sign the Eth-DM public key with Web3. This can then be published to let other
* users know to use this Eth-DM public key to encrypt messages destinated to the * users know to use this Eth-DM public key to encrypt messages destinated to the

View File

@ -0,0 +1,18 @@
import * as EthCrypto from 'eth-crypto';
/**
* Message used to communicate the Eth-Dm public key linked to a given Ethereum account
*/
export interface PublicKeyMessage {
ethDmPublicKey: string;
ethAddress: string;
sig: string;
}
/**
* Direct Encrypted Message used for private communication over the Waku network.
*/
export interface DirectMessage {
toAddress: string;
encMessage: EthCrypto.Encrypted;
}