183 lines
5.1 KiB
TypeScript
Raw Normal View History

2021-06-11 15:33:29 +10:00
import '@ethersproject/shims';
import React, { useEffect, useState } from 'react';
2021-05-28 15:35:50 +10:00
import './App.css';
import { Waku, WakuMessage } from 'js-waku';
2021-06-11 15:33:29 +10:00
import { ethers } from 'ethers';
import { Web3Provider } from '@ethersproject/providers';
import { createPublicKeyMessage, KeyPair } from './crypto';
import { encode, PublicKeyMessage } from './messages';
import Messages, { Message } from './Messages';
2021-06-18 13:53:12 +10:00
import 'fontsource-roboto';
2021-06-29 15:32:29 +10:00
import {
AppBar,
Button,
IconButton,
Toolbar,
Typography,
} from '@material-ui/core';
import SendMessage from './SendMessage';
import KeyPairHandling from './key_pair_handling/KeyPairHandling';
import InitWaku from './InitWaku';
2021-06-29 15:32:29 +10:00
import {
createMuiTheme,
ThemeProvider,
makeStyles,
} from '@material-ui/core/styles';
import { teal, purple, green } from '@material-ui/core/colors';
import WifiIcon from '@material-ui/icons/Wifi';
2021-06-11 15:33:29 +10:00
export const PublicKeyContentTopic = '/eth-dm/1/public-key/json';
export const DirectMessageContentTopic = '/eth-dm/1/direct-message/json';
2021-05-28 15:35:50 +10:00
declare let window: any;
2021-06-29 15:32:29 +10:00
const theme = createMuiTheme({
palette: {
primary: {
main: purple[500],
},
secondary: {
main: teal[600],
},
},
});
const useStyles = makeStyles({
root: {
textAlign: 'center',
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
},
appBar: {
// height: '200p',
},
container: {
display: 'flex',
flex: 1,
},
main: {
flex: 1,
margin: '10px',
},
wakuStatus: {},
});
2021-05-28 15:35:50 +10:00
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 | undefined>();
const [publicKeyMsg, setPublicKeyMsg] = useState<PublicKeyMessage>();
2021-06-15 15:29:41 +10:00
const [publicKeys, setPublicKeys] = useState<Map<string, string>>(new Map());
2021-06-18 10:04:38 +10:00
const [messages, setMessages] = useState<Message[]>([]);
const [address, setAddress] = useState<string>();
2021-05-28 15:35:50 +10:00
2021-06-29 15:32:29 +10:00
const classes = useStyles();
2021-05-28 15:35:50 +10:00
useEffect(() => {
2021-06-11 15:33:29 +10:00
if (provider) return;
try {
2021-06-28 13:54:22 +10:00
window.ethereum.request({ method: 'eth_requestAccounts' });
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(() => {
provider
?.getSigner()
.getAddress()
.then((address) => setAddress(address));
});
const broadcastPublicKey = () => {
2021-06-11 15:33:29 +10:00
if (!ethDmKeyPair) return;
if (!provider) return;
if (!waku) return;
if (publicKeyMsg) {
2021-06-15 15:29:41 +10:00
const wakuMsg = encodePublicKeyWakuMessage(publicKeyMsg);
2021-06-18 15:11:09 +10:00
waku.lightPush.push(wakuMsg).catch((e) => {
console.error('Failed to send Public Key Message', e);
2021-06-11 15:33:29 +10:00
});
} else {
createPublicKeyMessage(provider.getSigner(), ethDmKeyPair.publicKey)
.then((msg) => {
setPublicKeyMsg(msg);
2021-06-15 15:29:41 +10:00
const wakuMsg = encodePublicKeyWakuMessage(msg);
2021-06-18 15:11:09 +10:00
waku.lightPush.push(wakuMsg).catch((e) => {
console.error('Failed to send Public Key Message', e);
});
})
.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-29 15:32:29 +10:00
<ThemeProvider theme={theme}>
<div className={classes.root}>
<AppBar className={classes.appBar} position="static">
<Toolbar>
<Typography>Ethereum Direct Message</Typography>
<IconButton
edge="end"
className={classes.wakuStatus}
aria-label="waku-status"
>
<WifiIcon
color={waku ? undefined : 'disabled'}
style={waku ? { color: green[500] } : {}}
/>
</IconButton>
</Toolbar>
</AppBar>
<div className={classes.container}>
<main className={classes.main}>
<InitWaku
ethDmKeyPair={ethDmKeyPair}
setMessages={setMessages}
setPublicKeys={setPublicKeys}
setWaku={setWaku}
waku={waku}
address={address}
/>
<fieldset>
<legend>Eth-DM Key Pair</legend>
<KeyPairHandling
ethDmKeyPair={ethDmKeyPair}
setEthDmKeyPair={(keyPair) => setEthDmKeyPair(keyPair)}
/>
<Button
variant="contained"
color="primary"
onClick={broadcastPublicKey}
disabled={!ethDmKeyPair || !waku}
>
Broadcast Eth-DM Public Key
</Button>
</fieldset>
<fieldset>
<legend>Messaging</legend>
<SendMessage recipients={publicKeys} waku={waku} />
<Messages messages={messages} />
</fieldset>
</main>
2021-06-18 13:53:12 +10:00
</div>
2021-06-29 15:32:29 +10:00
</div>
</ThemeProvider>
2021-05-28 15:35:50 +10:00
);
}
export default App;
2021-06-15 15:29:41 +10:00
function encodePublicKeyWakuMessage(ethDmMsg: PublicKeyMessage): WakuMessage {
const payload = encode(ethDmMsg);
return WakuMessage.fromBytes(payload, PublicKeyContentTopic);
}