2021-06-11 15:33:29 +10:00
|
|
|
import 'react-native-get-random-values';
|
|
|
|
|
|
|
|
|
|
import '@ethersproject/shims';
|
|
|
|
|
|
2021-05-28 15:35:50 +10:00
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
|
import './App.css';
|
|
|
|
|
import { Environment, getStatusFleetNodes, Waku, WakuMessage } from 'js-waku';
|
2021-06-11 15:33:29 +10:00
|
|
|
import { ethers } from 'ethers';
|
|
|
|
|
import { Web3Provider } from '@ethersproject/providers';
|
|
|
|
|
import {
|
|
|
|
|
createPublicKeyMessage,
|
|
|
|
|
PublicKeyMessage,
|
|
|
|
|
generateEthDmKeyPair,
|
|
|
|
|
KeyPair,
|
2021-06-11 16:00:48 +10:00
|
|
|
validatePublicKeyMessage,
|
2021-06-11 15:33:29 +10:00
|
|
|
} from './crypto';
|
|
|
|
|
|
2021-06-11 16:00:48 +10:00
|
|
|
const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
|
2021-05-28 15:35:50 +10:00
|
|
|
|
|
|
|
|
declare let window: any;
|
|
|
|
|
|
|
|
|
|
function App() {
|
|
|
|
|
const [waku, setWaku] = useState<Waku>();
|
2021-06-11 15:33:29 +10:00
|
|
|
const [provider, setProvider] = useState<Web3Provider>();
|
|
|
|
|
const [ethDmKeyPair, setEthDmKeyPair] = useState<KeyPair>();
|
2021-06-11 16:00:48 +10:00
|
|
|
const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>();
|
2021-05-28 15:35:50 +10:00
|
|
|
|
|
|
|
|
useEffect(() => {
|
2021-06-11 15:33:29 +10:00
|
|
|
if (provider) return;
|
2021-06-11 16:00:48 +10:00
|
|
|
try {
|
|
|
|
|
const _provider = new ethers.providers.Web3Provider(window.ethereum);
|
|
|
|
|
setProvider(_provider);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.error('No web3 provider available');
|
|
|
|
|
}
|
2021-06-11 15:33:29 +10:00
|
|
|
}, [provider]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (waku) return;
|
|
|
|
|
initWaku()
|
|
|
|
|
.then((wakuNode) => {
|
2021-06-11 16:00:48 +10:00
|
|
|
console.log('waku: ready');
|
2021-05-28 15:35:50 +10:00
|
|
|
setWaku(wakuNode);
|
2021-06-11 15:33:29 +10:00
|
|
|
})
|
|
|
|
|
.catch((e) => {
|
2021-05-28 15:35:50 +10:00
|
|
|
console.error('Failed to initiate Waku', e);
|
|
|
|
|
});
|
|
|
|
|
}, [waku]);
|
|
|
|
|
|
2021-06-11 16:00:48 +10:00
|
|
|
const generateKeyPair = () => {
|
2021-06-11 15:33:29 +10:00
|
|
|
if (ethDmKeyPair) return;
|
|
|
|
|
if (!provider) return;
|
|
|
|
|
|
|
|
|
|
generateEthDmKeyPair(provider.getSigner())
|
|
|
|
|
.then((keyPair) => {
|
|
|
|
|
setEthDmKeyPair(keyPair);
|
|
|
|
|
})
|
|
|
|
|
.catch((e) => {
|
|
|
|
|
console.error('Failed to generate Key Pair', e);
|
|
|
|
|
});
|
2021-06-11 16:00:48 +10:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (!waku) return;
|
|
|
|
|
waku.relay.addObserver(handlePublicKeyMessage, [PublicKeyContentTopic]);
|
|
|
|
|
});
|
2021-06-11 15:33:29 +10:00
|
|
|
|
2021-06-11 16:00:48 +10:00
|
|
|
const broadcastPublicKey = () => {
|
2021-06-11 15:33:29 +10:00
|
|
|
if (!ethDmKeyPair) return;
|
|
|
|
|
if (!provider) return;
|
|
|
|
|
if (!waku) return;
|
|
|
|
|
|
2021-06-11 16:00:48 +10:00
|
|
|
if (publicKeyMsg) {
|
|
|
|
|
const wakuMsg = createWakuMessage(publicKeyMsg);
|
|
|
|
|
waku.relay.send(wakuMsg).catch((e) => {
|
|
|
|
|
console.error('Failed to send Public Key Message');
|
2021-06-11 15:33:29 +10:00
|
|
|
});
|
2021-06-11 16:00:48 +10:00
|
|
|
} else {
|
|
|
|
|
createPublicKeyMessage(provider.getSigner(), ethDmKeyPair.publicKey)
|
|
|
|
|
.then((msg) => {
|
|
|
|
|
setPublicKeyMsg(msg);
|
|
|
|
|
const wakuMsg = createWakuMessage(msg);
|
|
|
|
|
waku.relay.send(wakuMsg).catch((e) => {
|
|
|
|
|
console.error('Failed to send Public Key Message');
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
.catch((e) => {
|
|
|
|
|
console.error('Failed to creat Eth-Dm Publication message', e);
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-06-11 15:33:29 +10:00
|
|
|
};
|
|
|
|
|
|
2021-05-28 15:35:50 +10:00
|
|
|
return (
|
2021-06-11 15:33:29 +10:00
|
|
|
<div className="App">
|
|
|
|
|
<header className="App-header">
|
2021-06-11 16:00:48 +10:00
|
|
|
<button onClick={generateKeyPair} disabled={!provider}>
|
|
|
|
|
Generate Eth-DM Key Pair
|
|
|
|
|
</button>
|
|
|
|
|
<button onClick={broadcastPublicKey} disabled={!ethDmKeyPair || !waku}>
|
2021-06-11 15:33:29 +10:00
|
|
|
Broadcast Eth-DM Public Key
|
|
|
|
|
</button>
|
2021-05-28 15:35:50 +10:00
|
|
|
</header>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default App;
|
|
|
|
|
|
|
|
|
|
async function initWaku(): Promise<Waku> {
|
|
|
|
|
const waku = await Waku.create({});
|
|
|
|
|
|
|
|
|
|
const nodes = await getNodes();
|
|
|
|
|
await Promise.all(
|
|
|
|
|
nodes.map((addr) => {
|
|
|
|
|
return waku.dial(addr);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return waku;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getNodes() {
|
|
|
|
|
// Works with react-scripts
|
|
|
|
|
if (process?.env?.NODE_ENV === 'development') {
|
|
|
|
|
return getStatusFleetNodes(Environment.Test);
|
|
|
|
|
} else {
|
|
|
|
|
return getStatusFleetNodes(Environment.Prod);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-06-11 15:33:29 +10:00
|
|
|
|
|
|
|
|
function createWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage {
|
2021-06-11 16:00:48 +10:00
|
|
|
const payload = encode(ethDmMsg);
|
|
|
|
|
return WakuMessage.fromBytes(payload, PublicKeyContentTopic);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function handlePublicKeyMessage(msg: WakuMessage) {
|
|
|
|
|
if (msg.payload) {
|
|
|
|
|
const publicKeyMsg = decode(msg.payload);
|
|
|
|
|
console.log('publicKeyMsg', publicKeyMsg);
|
|
|
|
|
const res = validatePublicKeyMessage(publicKeyMsg);
|
|
|
|
|
console.log(`Public Key Message Received, valid: ${res}`, publicKeyMsg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function encode(msg: PublicKeyMessage): Buffer {
|
|
|
|
|
const jsonStr = JSON.stringify(msg);
|
|
|
|
|
return Buffer.from(jsonStr, 'utf-8');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function decode(bytes: Uint8Array): PublicKeyMessage {
|
|
|
|
|
const buf = Buffer.from(bytes);
|
|
|
|
|
const str = buf.toString('utf-8');
|
|
|
|
|
return JSON.parse(str);
|
2021-06-11 15:33:29 +10:00
|
|
|
}
|