.prettierrc and .prettierignore are added

This commit is contained in:
Victor Baranov 2018-10-17 11:56:56 +03:00
parent ff7877aac6
commit ca5fbb9a5e
17 changed files with 381 additions and 447 deletions

7
.prettierignore Normal file
View File

@ -0,0 +1,7 @@
assets
build_scripts
config
public
scripts
submodules
*.js

5
.prettierrc Normal file
View File

@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"printWidth": 120
}

View File

@ -1,169 +1,151 @@
import React, { Component } from "react"; import React, { Component } from 'react'
import getWeb3 from "./getWeb3"; import getWeb3 from './getWeb3'
import KeysManager from "./keysManager"; import KeysManager from './keysManager'
import Keys from "./Keys"; import Keys from './Keys'
import swal from "sweetalert"; import swal from 'sweetalert'
import "./index/index.css"; import './index/index.css'
import addressGenerator from "./addressGenerator"; import addressGenerator from './addressGenerator'
import JSzip from "jszip"; import JSzip from 'jszip'
import FileSaver from "file-saver"; import FileSaver from 'file-saver'
import { constants } from "./constants"; import { constants } from './constants'
import networkAddresses from "./addresses"; import networkAddresses from './addresses'
import Header from "./Header"; import Header from './Header'
import Footer from "./Footer"; import Footer from './Footer'
import Loading from "./Loading"; import Loading from './Loading'
function generateElement(msg) { function generateElement(msg) {
let errorNode = document.createElement("div"); let errorNode = document.createElement('div')
errorNode.innerHTML = `<div style="line-height: 1.6;"> errorNode.innerHTML = `<div style="line-height: 1.6;">
${msg} ${msg}
</div>`; </div>`
return errorNode; return errorNode
} }
class App extends Component { class App extends Component {
constructor(props) { constructor(props) {
super(props); super(props)
this.onClick = this.onClick.bind(this); this.onClick = this.onClick.bind(this)
this.saveFile = blob => { this.saveFile = blob => {
FileSaver.saveAs(blob, `poa_network_validator_keys.zip`); FileSaver.saveAs(blob, `poa_network_validator_keys.zip`)
}; }
this.state = { this.state = {
web3Config: {}, web3Config: {},
mining: null, mining: null,
isDisabledBtn: props.generateKeysIsDisabled isDisabledBtn: props.generateKeysIsDisabled
}; }
this.keysManager = null; this.keysManager = null
getWeb3() getWeb3()
.then(async web3Config => { .then(async web3Config => {
return networkAddresses(web3Config); return networkAddresses(web3Config)
}) })
.then(async config => { .then(async config => {
const { web3Config, addresses } = config; const { web3Config, addresses } = config
this.keysManager = new KeysManager(); this.keysManager = new KeysManager()
await this.keysManager.init({ await this.keysManager.init({
web3: web3Config.web3Instance, web3: web3Config.web3Instance,
netId: web3Config.netId, netId: web3Config.netId,
addresses addresses
}); })
this.setState({ this.setState({
isDisabledBtn: false, isDisabledBtn: false,
web3Config web3Config
}) })
.then(async config => { .then(async config => {
const { web3Config, addresses } = config; const { web3Config, addresses } = config
this.keysManager = new KeysManager(); this.keysManager = new KeysManager()
await this.keysManager.init({ await this.keysManager.init({
web3: web3Config.web3Instance, web3: web3Config.web3Instance,
netId: web3Config.netId, netId: web3Config.netId,
addresses addresses
}); })
this.setState({ this.setState({
isDisabledBtn: false, isDisabledBtn: false,
web3Config web3Config
}); })
}) })
.catch(error => { .catch(error => {
if (error.msg) { if (error.msg) {
this.setState({ isDisabledBtn: true }); this.setState({ isDisabledBtn: true })
swal({ swal({
icon: "warning", icon: 'warning',
title: "Warning", title: 'Warning',
content: error.node content: error.node
}); })
} }
}); })
}); })
} }
componentDidMount() { componentDidMount() {
if (window.location.hash.indexOf("just-generate-keys") !== -1) { if (window.location.hash.indexOf('just-generate-keys') !== -1) {
this.setState({ loading: true }); this.setState({ loading: true })
setTimeout(async () => { setTimeout(async () => {
const { mining, voting, payout } = await this.generateKeys(); const { mining, voting, payout } = await this.generateKeys()
this.setState({ loading: false }); this.setState({ loading: false })
await this.generateZip({ await this.generateZip({
mining, mining,
voting, voting,
payout, payout,
netIdName: "manualCreation" netIdName: 'manualCreation'
}); })
}, 150); }, 150)
} }
} }
async generateKeys(cb) { async generateKeys(cb) {
const mining = await addressGenerator(); const mining = await addressGenerator()
const voting = await addressGenerator(); const voting = await addressGenerator()
const payout = await addressGenerator(); const payout = await addressGenerator()
this.setState({ this.setState({
mining, mining,
voting, voting,
payout, payout,
keysGenerated: true keysGenerated: true
}); })
return { return {
mining, mining,
voting, voting,
payout payout
}; }
} }
async generateZip({ mining, voting, payout, netIdName }) { async generateZip({ mining, voting, payout, netIdName }) {
const zip = new JSzip(); const zip = new JSzip()
zip.file( zip.file(`${netIdName}_keys/mining_key_${mining.jsonStore.address}.json`, JSON.stringify(mining.jsonStore))
`${netIdName}_keys/mining_key_${mining.jsonStore.address}.json`, zip.file(`${netIdName}_keys/mining_password_${mining.jsonStore.address}.txt`, mining.password)
JSON.stringify(mining.jsonStore)
);
zip.file(
`${netIdName}_keys/mining_password_${mining.jsonStore.address}.txt`,
mining.password
);
zip.file( zip.file(`${netIdName}_keys/voting_key_${voting.jsonStore.address}.json`, JSON.stringify(voting.jsonStore))
`${netIdName}_keys/voting_key_${voting.jsonStore.address}.json`, zip.file(`${netIdName}_keys/voting_password_${voting.jsonStore.address}.txt`, voting.password)
JSON.stringify(voting.jsonStore)
);
zip.file(
`${netIdName}_keys/voting_password_${voting.jsonStore.address}.txt`,
voting.password
);
zip.file( zip.file(`${netIdName}_keys/payout_key_${payout.jsonStore.address}.json`, JSON.stringify(payout.jsonStore))
`${netIdName}_keys/payout_key_${payout.jsonStore.address}.json`, zip.file(`${netIdName}_keys/payout_password_${payout.jsonStore.address}.txt`, payout.password)
JSON.stringify(payout.jsonStore) zip.generateAsync({ type: 'blob' }).then(blob => {
); FileSaver.saveAs(blob, `poa_network_validator_keys.zip`)
zip.file( })
`${netIdName}_keys/payout_password_${payout.jsonStore.address}.txt`,
payout.password
);
zip.generateAsync({ type: "blob" }).then(blob => {
FileSaver.saveAs(blob, `poa_network_validator_keys.zip`);
});
} }
async onClick() { async onClick() {
this.setState({ loading: true }); this.setState({ loading: true })
const initialKey = this.state.web3Config.defaultAccount; const initialKey = this.state.web3Config.defaultAccount
let isValid; let isValid
try { try {
isValid = await this.keysManager.isInitialKeyValid(initialKey); isValid = await this.keysManager.isInitialKeyValid(initialKey)
} catch (e) { } catch (e) {
isValid = false; isValid = false
} }
console.log(isValid); console.log(isValid)
if (Number(isValid) !== 1) { if (Number(isValid) !== 1) {
this.setState({ loading: false }); this.setState({ loading: false })
const invalidKeyMsg = `The key is an invalid Initial key<br/> const invalidKeyMsg = `The key is an invalid Initial key<br/>
or you're connected to the incorrect chain!<br/> or you're connected to the incorrect chain!<br/>
Please make sure you have loaded correct Initial key in MetaMask.<br/><br/> Please make sure you have loaded correct Initial key in MetaMask.<br/><br/>
<b>Your current selected key is</b> <i>${initialKey}</i><br/> <b>Your current selected key is</b> <i>${initialKey}</i><br/>
<b>Current Network ID</b> is <i>${this.state.web3Config.netId}</i>`; <b>Current Network ID</b> is <i>${this.state.web3Config.netId}</i>`
swal({ swal({
icon: "error", icon: 'error',
title: "Error", title: 'Error',
content: generateElement(invalidKeyMsg) content: generateElement(invalidKeyMsg)
}); })
return; return
} }
if (Number(isValid) === 1) { if (Number(isValid) === 1) {
const { mining, voting, payout } = await this.generateKeys(); const { mining, voting, payout } = await this.generateKeys()
// add loading screen // add loading screen
await this.keysManager await this.keysManager
.createKeys({ .createKeys({
@ -173,89 +155,74 @@ class App extends Component {
sender: initialKey sender: initialKey
}) })
.then(async receipt => { .then(async receipt => {
console.log(receipt); console.log(receipt)
if (receipt.status === true || receipt.status === "0x1") { if (receipt.status === true || receipt.status === '0x1') {
this.setState({ loading: false }); this.setState({ loading: false })
swal("Congratulations!", "Your keys are generated!", "success"); swal('Congratulations!', 'Your keys are generated!', 'success')
await this.generateZip({ await this.generateZip({
mining, mining,
voting, voting,
payout, payout,
netIdName: this.state.web3Config.netIdName netIdName: this.state.web3Config.netIdName
}); })
} else { } else {
this.setState({ loading: false, keysGenerated: false }); this.setState({ loading: false, keysGenerated: false })
let content = document.createElement("div"); let content = document.createElement('div')
let msg = `Transaction failed`; let msg = `Transaction failed`
content.innerHTML = `<div> content.innerHTML = `<div>
Something went wrong!<br/><br/> Something went wrong!<br/><br/>
Please contact Master Of Ceremony<br/><br/> Please contact Master Of Ceremony<br/><br/>
${msg} ${msg}
</div>`; </div>`
swal({ swal({
icon: "error", icon: 'error',
title: "Error", title: 'Error',
content: content content: content
}); })
} }
}) })
.catch(error => { .catch(error => {
console.error(error.message); console.error(error.message)
this.setState({ loading: false, keysGenerated: false }); this.setState({ loading: false, keysGenerated: false })
let content = document.createElement("div"); let content = document.createElement('div')
let msg; let msg
if (error.message.includes(constants.userDeniedTransactionPattern)) if (error.message.includes(constants.userDeniedTransactionPattern))
msg = `Error: ${constants.userDeniedTransactionPattern}`; msg = `Error: ${constants.userDeniedTransactionPattern}`
else msg = error.message; else msg = error.message
content.innerHTML = `<div> content.innerHTML = `<div>
Something went wrong!<br/><br/> Something went wrong!<br/><br/>
Please contact Master Of Ceremony<br/><br/> Please contact Master Of Ceremony<br/><br/>
${msg} ${msg}
</div>`; </div>`
swal({ swal({
icon: "error", icon: 'error',
title: "Error", title: 'Error',
content: content content: content
}); })
}); })
} }
} }
render() { render() {
let loader = this.state.loading ? ( let loader = this.state.loading ? <Loading netId={this.state.web3Config.netId} /> : ''
<Loading netId={this.state.web3Config.netId} />
) : (
""
);
let createKeyBtn = ( let createKeyBtn = (
<div className="create-keys"> <div className="create-keys">
<h1>Create keys from initial key</h1> <h1>Create keys from initial key</h1>
<h2> <h2>
In this application, you will create mining, payout and voting keys. In this application, you will create mining, payout and voting keys. The app will make your initial key
The app will make your initial key unusable after the process. Please unusable after the process. Please proceed with care, don't lose your keys and follow instructions.
proceed with care, don't lose your keys and follow instructions.
</h2> </h2>
<div className="create-keys-button-container"> <div className="create-keys-button-container">
<button <button className="create-keys-button" onClick={this.onClick} disabled={this.state.isDisabledBtn}>
className="create-keys-button"
onClick={this.onClick}
disabled={this.state.isDisabledBtn}
>
Generate keys Generate keys
</button> </button>
</div> </div>
</div> </div>
); )
let content; let content
if (this.state.keysGenerated) { if (this.state.keysGenerated) {
content = ( content = <Keys mining={this.state.mining} voting={this.state.voting} payout={this.state.payout} />
<Keys
mining={this.state.mining}
voting={this.state.voting}
payout={this.state.payout}
/>
);
} else { } else {
content = createKeyBtn; content = createKeyBtn
} }
return ( return (
<div className="App"> <div className="App">
@ -264,8 +231,8 @@ class App extends Component {
<section className="content">{content}</section> <section className="content">{content}</section>
<Footer netId={this.state.web3Config.netId} /> <Footer netId={this.state.web3Config.netId} />
</div> </div>
); )
} }
} }
export default App; export default App

View File

@ -1,8 +1,8 @@
import React from "react"; import React from 'react'
import ReactDOM from "react-dom"; import ReactDOM from 'react-dom'
import App from "./App"; import App from './App'
it("renders without crashing", () => { it('renders without crashing', () => {
const div = document.createElement("div"); const div = document.createElement('div')
ReactDOM.render(<App />, div); ReactDOM.render(<App />, div)
}); })

View File

@ -1,46 +1,32 @@
import React from "react"; import React from 'react'
import moment from "moment"; import moment from 'moment'
import { constants } from "./constants"; import { constants } from './constants'
const Footer = ({ netId }) => { const Footer = ({ netId }) => {
const footerClassName = const footerClassName = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET ? 'sokol' : ''
netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET
? "sokol"
: "";
return ( return (
<footer className={`footer ${footerClassName}`}> <footer className={`footer ${footerClassName}`}>
<div className="container"> <div className="container">
<p className="footer-rights"> <p className="footer-rights">{moment().format('YYYY')} POA Network. All rights reserved.</p>
{moment().format("YYYY")} POA Network. All rights reserved.
</p>
<a href="/poa-dapps-keys-generation" className="footer-logo" /> <a href="/poa-dapps-keys-generation" className="footer-logo" />
<div className="socials"> <div className="socials">
<a <a href="https://twitter.com/poanetwork" className="socials-i socials-i_twitter">
href="https://twitter.com/poanetwork"
className="socials-i socials-i_twitter"
>
Twitter Twitter
</a> </a>
<a href="https://poa.network" className="socials-i socials-i_oracles"> <a href="https://poa.network" className="socials-i socials-i_oracles">
POA Network POA Network
</a> </a>
<a <a href="https://t.me/oraclesnetwork" className="socials-i socials-i_telegram">
href="https://t.me/oraclesnetwork"
className="socials-i socials-i_telegram"
>
Telegram Telegram
</a> </a>
<a <a href="https://github.com/poanetwork/" className="socials-i socials-i_github">
href="https://github.com/poanetwork/"
className="socials-i socials-i_github"
>
GitHub GitHub
</a> </a>
</div> </div>
</div> </div>
</footer> </footer>
); )
}; }
export default Footer; export default Footer

View File

@ -1,18 +1,17 @@
import React from "react"; import React from 'react'
import { constants } from "./constants"; import { constants } from './constants'
let Header = ({ netId }) => { let Header = ({ netId }) => {
const thisIsTestnet = const thisIsTestnet = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET
netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET; const headerClassName = thisIsTestnet ? 'sokol' : ''
const headerClassName = thisIsTestnet ? "sokol" : ""; const logoClassName = thisIsTestnet ? 'header-logo-sokol' : 'header-logo'
const logoClassName = thisIsTestnet ? "header-logo-sokol" : "header-logo";
return ( return (
<header className={`header ${headerClassName}`}> <header className={`header ${headerClassName}`}>
<div className="container"> <div className="container">
<a href="/poa-dapps-keys-generation" className={logoClassName} /> <a href="/poa-dapps-keys-generation" className={logoClassName} />
</div> </div>
</header> </header>
); )
}; }
export default Header; export default Header

View File

@ -1,76 +1,76 @@
import React, { Component } from "react"; import React, { Component } from 'react'
import Tooltip from "rc-tooltip"; import Tooltip from 'rc-tooltip'
import "rc-tooltip/assets/bootstrap.css"; import 'rc-tooltip/assets/bootstrap.css'
const encodeJson = json => { const encodeJson = json => {
const encoded = window.encodeURIComponent(JSON.stringify(json)); const encoded = window.encodeURIComponent(JSON.stringify(json))
return `data:application/json;charset=utf-8,${encoded}`; return `data:application/json;charset=utf-8,${encoded}`
}; }
export default class Keys extends Component { export default class Keys extends Component {
constructor(props) { constructor(props) {
super(props); super(props)
this.onVisibleChange = this.onVisibleChange.bind(this); this.onVisibleChange = this.onVisibleChange.bind(this)
this.onCopyBtnClick = this.onCopyBtnClick.bind(this); this.onCopyBtnClick = this.onCopyBtnClick.bind(this)
this.state = { this.state = {
copyBtns: { copyBtns: {
copyMiningPass: { copyMiningPass: {
visible: false, visible: false,
text: "Copy" text: 'Copy'
}, },
copyVotingPass: { copyVotingPass: {
visible: false, visible: false,
text: "Copy" text: 'Copy'
}, },
copyPayoutPass: { copyPayoutPass: {
visible: false, visible: false,
text: "Copy" text: 'Copy'
}, },
copyMiningKey: { copyMiningKey: {
visible: false, visible: false,
text: "Copy" text: 'Copy'
}, },
copyVotingKey: { copyVotingKey: {
visible: false, visible: false,
text: "Copy" text: 'Copy'
}, },
copyPayoutKey: { copyPayoutKey: {
visible: false, visible: false,
text: "Copy" text: 'Copy'
} }
} }
}; }
} }
componentWillUpdate(nextProps, nextState) { componentWillUpdate(nextProps, nextState) {
if (this.refs.miningKeyAddress) { if (this.refs.miningKeyAddress) {
const Clipboard = require("clipboard"); const Clipboard = require('clipboard')
// this.clipboard = new Clipboard(this.refs.copyBtn); // this.clipboard = new Clipboard(this.refs.copyBtn);
new Clipboard(this.refs.miningKeyAddress); new Clipboard(this.refs.miningKeyAddress)
new Clipboard(this.refs.miningKeyPass); new Clipboard(this.refs.miningKeyPass)
new Clipboard(this.refs.payoutKeyAddress); new Clipboard(this.refs.payoutKeyAddress)
new Clipboard(this.refs.payoutKeyPass); new Clipboard(this.refs.payoutKeyPass)
new Clipboard(this.refs.votingKeyAddress); new Clipboard(this.refs.votingKeyAddress)
new Clipboard(this.refs.votingKeyPass); new Clipboard(this.refs.votingKeyPass)
} }
} }
onVisibleChange(id) { onVisibleChange(id) {
console.log(id); console.log(id)
let copyBtns = this.state.copyBtns; let copyBtns = this.state.copyBtns
copyBtns[id].visible = !copyBtns[id].visible; copyBtns[id].visible = !copyBtns[id].visible
copyBtns[id].text = "Copy"; copyBtns[id].text = 'Copy'
this.setState({ this.setState({
copyBtns copyBtns
}); })
// const id = e.target.id; // const id = e.target.id;
} }
onCopyBtnClick(e) { onCopyBtnClick(e) {
const id = e.target.id; const id = e.target.id
let copyBtns = this.state.copyBtns; let copyBtns = this.state.copyBtns
copyBtns[id].text = "Copied!"; copyBtns[id].text = 'Copied!'
this.setState({ this.setState({
copyBtns copyBtns
}); })
} }
render() { render() {
return ( return (
@ -88,7 +88,7 @@ export default class Keys extends Component {
animation="zoom" animation="zoom"
trigger="hover" trigger="hover"
onVisibleChange={() => { onVisibleChange={() => {
this.onVisibleChange("copyMiningKey"); this.onVisibleChange('copyMiningKey')
}} }}
placement="right" placement="right"
overlay={this.state.copyBtns.copyMiningKey.text} overlay={this.state.copyBtns.copyMiningKey.text}
@ -98,9 +98,7 @@ export default class Keys extends Component {
onClick={this.onCopyBtnClick} onClick={this.onCopyBtnClick}
className="copy" className="copy"
ref="miningKeyAddress" ref="miningKeyAddress"
data-clipboard-text={ data-clipboard-text={'0x' + this.props.mining.jsonStore.address}
"0x" + this.props.mining.jsonStore.address
}
/> />
</Tooltip> </Tooltip>
</div> </div>
@ -118,7 +116,7 @@ export default class Keys extends Component {
animation="zoom" animation="zoom"
trigger="hover" trigger="hover"
onVisibleChange={() => { onVisibleChange={() => {
this.onVisibleChange("copyMiningPass"); this.onVisibleChange('copyMiningPass')
}} }}
placement="right" placement="right"
overlay={this.state.copyBtns.copyMiningPass.text} overlay={this.state.copyBtns.copyMiningPass.text}
@ -133,9 +131,8 @@ export default class Keys extends Component {
</Tooltip> </Tooltip>
</p> </p>
<p className="keys-description"> <p className="keys-description">
Download this key and use it in your mining node to validate Download this key and use it in your mining node to validate blocks in the network. Mined coins will be
blocks in the network. Mined coins will be deposited to your deposited to your payout account.
payout account.
</p> </p>
<div className="keys-footer"> <div className="keys-footer">
<a <a
@ -160,7 +157,7 @@ export default class Keys extends Component {
animation="zoom" animation="zoom"
trigger="hover" trigger="hover"
onVisibleChange={() => { onVisibleChange={() => {
this.onVisibleChange("copyPayoutKey"); this.onVisibleChange('copyPayoutKey')
}} }}
placement="right" placement="right"
overlay={this.state.copyBtns.copyPayoutKey.text} overlay={this.state.copyBtns.copyPayoutKey.text}
@ -170,9 +167,7 @@ export default class Keys extends Component {
onClick={this.onCopyBtnClick} onClick={this.onCopyBtnClick}
className="copy" className="copy"
ref="payoutKeyAddress" ref="payoutKeyAddress"
data-clipboard-text={ data-clipboard-text={'0x' + this.props.payout.jsonStore.address}
"0x" + this.props.payout.jsonStore.address
}
/> />
</Tooltip> </Tooltip>
</div> </div>
@ -190,7 +185,7 @@ export default class Keys extends Component {
animation="zoom" animation="zoom"
trigger="hover" trigger="hover"
onVisibleChange={() => { onVisibleChange={() => {
this.onVisibleChange("copyPayoutPass"); this.onVisibleChange('copyPayoutPass')
}} }}
placement="right" placement="right"
overlay={this.state.copyBtns.copyPayoutPass.text} overlay={this.state.copyBtns.copyPayoutPass.text}
@ -205,8 +200,7 @@ export default class Keys extends Component {
</Tooltip> </Tooltip>
</p> </p>
<p className="keys-description"> <p className="keys-description">
Download this key and use it on your client node/wallet to spend Download this key and use it on your client node/wallet to spend earned coins.
earned coins.
</p> </p>
<div className="keys-footer"> <div className="keys-footer">
<a <a
@ -231,7 +225,7 @@ export default class Keys extends Component {
animation="zoom" animation="zoom"
trigger="hover" trigger="hover"
onVisibleChange={() => { onVisibleChange={() => {
this.onVisibleChange("copyVotingKey"); this.onVisibleChange('copyVotingKey')
}} }}
placement="right" placement="right"
overlay={this.state.copyBtns.copyVotingKey.text} overlay={this.state.copyBtns.copyVotingKey.text}
@ -241,9 +235,7 @@ export default class Keys extends Component {
onClick={this.onCopyBtnClick} onClick={this.onCopyBtnClick}
className="copy" className="copy"
ref="votingKeyAddress" ref="votingKeyAddress"
data-clipboard-text={ data-clipboard-text={'0x' + this.props.voting.jsonStore.address}
"0x" + this.props.voting.jsonStore.address
}
/> />
</Tooltip> </Tooltip>
</div> </div>
@ -261,7 +253,7 @@ export default class Keys extends Component {
animation="zoom" animation="zoom"
trigger="hover" trigger="hover"
onVisibleChange={() => { onVisibleChange={() => {
this.onVisibleChange("copyVotingPass"); this.onVisibleChange('copyVotingPass')
}} }}
placement="right" placement="right"
overlay={this.state.copyBtns.copyVotingPass.text} overlay={this.state.copyBtns.copyVotingPass.text}
@ -276,9 +268,8 @@ export default class Keys extends Component {
</Tooltip> </Tooltip>
</p> </p>
<p className="keys-description"> <p className="keys-description">
Download this key and use it on your client node to vote for Download this key and use it on your client node to vote for necessary ballots, such as adding or removing
necessary ballots, such as adding or removing miners from the miners from the network.
network.
</p> </p>
<div className="keys-footer"> <div className="keys-footer">
<a <a
@ -295,12 +286,11 @@ export default class Keys extends Component {
<div className="keys-note"> <div className="keys-note">
<p className="keys-note-title">Important</p> <p className="keys-note-title">Important</p>
<p className="keys-note-description"> <p className="keys-note-description">
Do not close this tab until you download all keys and save Do not close this tab until you download all keys and save passwords. Keep keys secure and protected. If you
passwords. Keep keys secure and protected. If you lose your keys, lose your keys, you will need to get a new initial key using Voting DAPP.
you will need to get a new initial key using Voting DAPP.
</p> </p>
</div> </div>
</div> </div>
); )
} }
} }

View File

@ -1,20 +1,20 @@
import React from "react"; import React from 'react'
import { constants } from "./constants"; import { constants } from './constants'
const styles = netId => { const styles = netId => {
const core = { const core = {
backgroundColor: "rgba(35, 29, 115, 0.8)" backgroundColor: 'rgba(35, 29, 115, 0.8)'
}; }
const sokol = { const sokol = {
backgroundColor: "rgba(47, 109, 99, 0.8)" backgroundColor: 'rgba(47, 109, 99, 0.8)'
};
if (netId in constants.NETWORKS) {
return constants.NETWORKS[netId].TESTNET ? sokol : core;
} }
return core; if (netId in constants.NETWORKS) {
}; return constants.NETWORKS[netId].TESTNET ? sokol : core
}
return core
}
const Loading = ({ netId }) => ( const Loading = ({ netId }) => (
<div className="loading-container" style={styles(netId)}> <div className="loading-container" style={styles(netId)}>
<div className="loading"> <div className="loading">
@ -26,5 +26,5 @@ const Loading = ({ netId }) => (
<div className="loading-i" /> <div className="loading-i" />
</div> </div>
</div> </div>
); )
export default Loading; export default Loading

View File

@ -1,23 +1,16 @@
import keythereum from "keythereum"; import keythereum from 'keythereum'
import passwordGenerator from "password-generator"; import passwordGenerator from 'password-generator'
export default function generateAddress(cb) { export default function generateAddress(cb) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
var params = { keyBytes: 32, ivBytes: 16 }; var params = { keyBytes: 32, ivBytes: 16 }
keythereum.create(params, function(dk) { keythereum.create(params, function(dk) {
var options = {}; var options = {}
var password = passwordGenerator(20, false); var password = passwordGenerator(20, false)
keythereum.dump( keythereum.dump(password, dk.privateKey, dk.salt, dk.iv, options, function(jsonStore) {
password, resolve({ jsonStore, password })
dk.privateKey, })
dk.salt, })
dk.iv, })
options,
function(jsonStore) {
resolve({ jsonStore, password });
}
);
});
});
} }

View File

@ -1,22 +1,22 @@
import { constants } from "./constants"; import { constants } from './constants'
import helpers from "./helpers"; import helpers from './helpers'
//const local = { //const local = {
// "KEYS_MANAGER_ADDRESS": "0x3ef32bb244016ad9af8c8f45398511e7e551b581" // "KEYS_MANAGER_ADDRESS": "0x3ef32bb244016ad9af8c8f45398511e7e551b581"
//} //}
export default web3Config => { export default web3Config => {
const branch = constants.NETWORKS[web3Config.netId].BRANCH; const branch = constants.NETWORKS[web3Config.netId].BRANCH
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fetch(helpers.addressesURL(branch)) fetch(helpers.addressesURL(branch))
.then(response => { .then(response => {
response.json().then(json => { response.json().then(json => {
resolve({ addresses: json, web3Config }); resolve({ addresses: json, web3Config })
}); })
}) })
.catch(function(err) { .catch(function(err) {
let addr = helpers.addressesURL(branch); let addr = helpers.addressesURL(branch)
helpers.wrongRepoAlert(addr); helpers.wrongRepoAlert(addr)
reject(err); reject(err)
}); })
}); })
}; }

View File

@ -1,35 +1,35 @@
let constants = {}; let constants = {}
constants.organization = "poanetwork"; constants.organization = 'poanetwork'
constants.repoName = "poa-chain-spec"; constants.repoName = 'poa-chain-spec'
constants.addressesSourceFile = "contracts.json"; constants.addressesSourceFile = 'contracts.json'
constants.ABIsSources = { constants.ABIsSources = {
KeysManager: "KeysManager.abi.json" KeysManager: 'KeysManager.abi.json'
}; }
constants.userDeniedTransactionPattern = "User denied transaction"; constants.userDeniedTransactionPattern = 'User denied transaction'
constants.NETWORKS = { constants.NETWORKS = {
"77": { '77': {
NAME: "Sokol", NAME: 'Sokol',
BRANCH: "sokol", BRANCH: 'sokol',
TESTNET: true TESTNET: true
}, },
"99": { '99': {
NAME: "Core", NAME: 'Core',
BRANCH: "core", BRANCH: 'core',
TESTNET: false TESTNET: false
}, },
"79": { '79': {
NAME: "Dai-Test", NAME: 'Dai-Test',
BRANCH: "dai-test", BRANCH: 'dai-test',
TESTNET: true TESTNET: true
}, },
"100": { '100': {
NAME: "Dai", NAME: 'Dai',
BRANCH: "dai", BRANCH: 'dai',
TESTNET: false TESTNET: false
} }
}; }
module.exports = { module.exports = {
constants constants
}; }

View File

@ -1,83 +1,83 @@
import Web3 from "web3"; import Web3 from 'web3'
import { constants } from "./constants"; import { constants } from './constants'
const errorMsgNoMetamaskAccount = `You haven't chosen any account in MetaMask. const errorMsgNoMetamaskAccount = `You haven't chosen any account in MetaMask.
Please choose your initial key in MetaMask and reload the page. Please choose your initial key in MetaMask and reload the page.
Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>wiki</a> for more info.`; Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>wiki</a> for more info.`
const errorMsgDeniedAccess = "You have denied access to your accounts"; const errorMsgDeniedAccess = 'You have denied access to your accounts'
function generateElement(msg) { function generateElement(msg) {
let errorNode = document.createElement("div"); let errorNode = document.createElement('div')
errorNode.innerHTML = `<div style="line-height: 1.6;"> errorNode.innerHTML = `<div style="line-height: 1.6;">
${msg} ${msg}
</div>`; </div>`
return errorNode; return errorNode
} }
let getWeb3 = () => { let getWeb3 = () => {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
// Wait for loading completion to avoid race conditions with web3 injection timing. // Wait for loading completion to avoid race conditions with web3 injection timing.
window.addEventListener("load", async function() { window.addEventListener('load', async function() {
let web3; let web3
// Checking if Web3 has been injected by the browser (Mist/MetaMask) // Checking if Web3 has been injected by the browser (Mist/MetaMask)
if (window.ethereum) { if (window.ethereum) {
web3 = new Web3(window.ethereum); web3 = new Web3(window.ethereum)
console.log("Injected web3 detected."); console.log('Injected web3 detected.')
try { try {
await window.ethereum.enable(); await window.ethereum.enable()
} catch (e) { } catch (e) {
reject({ reject({
msg: errorMsgDeniedAccess, msg: errorMsgDeniedAccess,
node: generateElement(errorMsgDeniedAccess) node: generateElement(errorMsgDeniedAccess)
}); })
return; return
} }
} else if (window.web3) { } else if (window.web3) {
web3 = new Web3(window.web3.currentProvider); web3 = new Web3(window.web3.currentProvider)
console.log("Injected web3 detected."); console.log('Injected web3 detected.')
} else { } else {
console.error("Metamask not found"); console.error('Metamask not found')
reject({ reject({
msg: errorMsgNoMetamaskAccount, msg: errorMsgNoMetamaskAccount,
node: generateElement(errorMsgNoMetamaskAccount) node: generateElement(errorMsgNoMetamaskAccount)
}); })
return; return
} }
const netId = await web3.eth.net.getId(); const netId = await web3.eth.net.getId()
console.log("netId", netId); console.log('netId', netId)
let netIdName; let netIdName
let errorMsg = null; let errorMsg = null
if (netId in constants.NETWORKS) { if (netId in constants.NETWORKS) {
netIdName = constants.NETWORKS[netId].NAME; netIdName = constants.NETWORKS[netId].NAME
console.log(`This is ${netIdName}`); console.log(`This is ${netIdName}`)
} else { } else {
netIdName = "ERROR"; netIdName = 'ERROR'
errorMsg = `You aren't connected to POA Network. errorMsg = `You aren't connected to POA Network.
Please switch on Metamask and refresh the page. Please switch on Metamask and refresh the page.
Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>wiki</a> for more info. Check POA Network <a href='https://github.com/poanetwork/wiki' target='blank'>wiki</a> for more info.
<b>Current Network ID</b> is <i>${netId}</i>`; <b>Current Network ID</b> is <i>${netId}</i>`
console.log("This is an unknown network."); console.log('This is an unknown network.')
} }
document.title = `${netIdName} - DApp Keys Generation`; document.title = `${netIdName} - DApp Keys Generation`
if (errorMsg !== null) { if (errorMsg !== null) {
reject({ msg: errorMsg, node: generateElement(errorMsg) }); reject({ msg: errorMsg, node: generateElement(errorMsg) })
return; return
} }
const accounts = await web3.eth.getAccounts(); const accounts = await web3.eth.getAccounts()
const defaultAccount = accounts[0] || null; const defaultAccount = accounts[0] || null
if (defaultAccount === null) { if (defaultAccount === null) {
reject({ reject({
msg: errorMsgNoMetamaskAccount, msg: errorMsgNoMetamaskAccount,
node: generateElement(errorMsgNoMetamaskAccount) node: generateElement(errorMsgNoMetamaskAccount)
}); })
return; return
} }
resolve({ resolve({
@ -85,9 +85,9 @@ let getWeb3 = () => {
netIdName, netIdName,
netId, netId,
defaultAccount defaultAccount
}); })
}); })
}); })
}; }
export default getWeb3; export default getWeb3

View File

@ -1,54 +1,54 @@
import { constants } from "./constants"; import { constants } from './constants'
import { messages } from "./messages"; import { messages } from './messages'
import swal from "sweetalert"; import swal from 'sweetalert'
var toAscii = function(hex) { var toAscii = function(hex) {
var str = "", var str = '',
i = 0, i = 0,
l = hex.length; l = hex.length
if (hex.substring(0, 2) === "0x") { if (hex.substring(0, 2) === '0x') {
i = 2; i = 2
} }
for (; i < l; i += 2) { for (; i < l; i += 2) {
var code = parseInt(hex.substr(i, 2), 16); var code = parseInt(hex.substr(i, 2), 16)
if (code === 0) continue; // this is added if (code === 0) continue // this is added
str += String.fromCharCode(code); str += String.fromCharCode(code)
} }
return str; return str
}; }
function addressesURL(branch) { function addressesURL(branch) {
const URL = `https://raw.githubusercontent.com/${constants.organization}/${ const URL = `https://raw.githubusercontent.com/${constants.organization}/${constants.repoName}/${branch}/${
constants.repoName constants.addressesSourceFile
}/${branch}/${constants.addressesSourceFile}`; }`
return URL; return URL
} }
function ABIURL(branch, contract) { function ABIURL(branch, contract) {
const URL = `https://raw.githubusercontent.com/${constants.organization}/${ const URL = `https://raw.githubusercontent.com/${constants.organization}/${constants.repoName}/${branch}/abis/${
constants.repoName constants.ABIsSources[contract]
}/${branch}/abis/${constants.ABIsSources[contract]}`; }`
return URL; return URL
} }
function getABI(branch, contract) { function getABI(branch, contract) {
let addr = ABIURL(branch, contract); let addr = ABIURL(branch, contract)
return fetch(addr).then(function(response) { return fetch(addr).then(function(response) {
return response.json(); return response.json()
}); })
} }
function wrongRepoAlert(addr) { function wrongRepoAlert(addr) {
var content = document.createElement("div"); var content = document.createElement('div')
content.innerHTML = `<div> content.innerHTML = `<div>
Something went wrong!<br/><br/> Something went wrong!<br/><br/>
${messages.wrongRepo(addr)} ${messages.wrongRepo(addr)}
</div>`; </div>`
swal({ swal({
icon: "error", icon: 'error',
title: "Error", title: 'Error',
content: content content: content
}); })
} }
let helpers = { let helpers = {
@ -57,6 +57,6 @@ let helpers = {
ABIURL, ABIURL,
getABI, getABI,
wrongRepoAlert wrongRepoAlert
}; }
export default helpers; export default helpers

View File

@ -1,12 +1,9 @@
import React from "react"; import React from 'react'
import ReactDOM from "react-dom"; import ReactDOM from 'react-dom'
import App from "./App"; import App from './App'
import registerServiceWorker from "./registerServiceWorker"; import registerServiceWorker from './registerServiceWorker'
window.addEventListener("beforeunload", function(event) { window.addEventListener('beforeunload', function(event) {
event.returnValue = "Are you sure?"; event.returnValue = 'Are you sure?'
}); })
ReactDOM.render( ReactDOM.render(<App generateKeysIsDisabled={true} />, document.getElementById('root'))
<App generateKeysIsDisabled={true} />, registerServiceWorker()
document.getElementById("root")
);
registerServiceWorker();

View File

@ -1,55 +1,52 @@
import addressGenerator from "./addressGenerator"; import addressGenerator from './addressGenerator'
import helpers from "./helpers"; import helpers from './helpers'
import { constants } from "./constants"; import { constants } from './constants'
export default class KeysManager { export default class KeysManager {
async init({ web3, netId, addresses }) { async init({ web3, netId, addresses }) {
const { KEYS_MANAGER_ADDRESS } = addresses; const { KEYS_MANAGER_ADDRESS } = addresses
console.log("Keys Manager ", KEYS_MANAGER_ADDRESS); console.log('Keys Manager ', KEYS_MANAGER_ADDRESS)
const KeysManagerAbi = await helpers.getABI( const KeysManagerAbi = await helpers.getABI(constants.NETWORKS[netId].BRANCH, 'KeysManager')
constants.NETWORKS[netId].BRANCH,
"KeysManager"
);
this.instance = new web3.eth.Contract(KeysManagerAbi, KEYS_MANAGER_ADDRESS); this.instance = new web3.eth.Contract(KeysManagerAbi, KEYS_MANAGER_ADDRESS)
const networkName = constants.NETWORKS[netId].NAME.toLowerCase(); const networkName = constants.NETWORKS[netId].NAME.toLowerCase()
if (networkName === "dai-test" || networkName === "dai") { if (networkName === 'dai-test' || networkName === 'dai') {
this.gasPrice = web3.utils.toWei("0", "gwei"); this.gasPrice = web3.utils.toWei('0', 'gwei')
} else { } else {
this.gasPrice = web3.utils.toWei("2", "gwei"); this.gasPrice = web3.utils.toWei('2', 'gwei')
} }
} }
async isInitialKeyValid(initialKey) { async isInitialKeyValid(initialKey) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const methods = this.instance.methods; const methods = this.instance.methods
let getInitialKeyStatus; let getInitialKeyStatus
if (methods.getInitialKeyStatus) { if (methods.getInitialKeyStatus) {
getInitialKeyStatus = methods.getInitialKeyStatus; getInitialKeyStatus = methods.getInitialKeyStatus
} else { } else {
getInitialKeyStatus = methods.initialKeys; getInitialKeyStatus = methods.initialKeys
} }
getInitialKeyStatus(initialKey) getInitialKeyStatus(initialKey)
.call() .call()
.then(function(result) { .then(function(result) {
resolve(result); resolve(result)
}) })
.catch(function(e) { .catch(function(e) {
reject(false); reject(false)
}); })
}); })
} }
async generateKeys() { async generateKeys() {
return await addressGenerator(); return await addressGenerator()
} }
createKeys({ mining, voting, payout, sender }) { createKeys({ mining, voting, payout, sender }) {
return this.instance.methods.createKeys(mining, voting, payout).send({ return this.instance.methods.createKeys(mining, voting, payout).send({
from: sender, from: sender,
gasPrice: this.gasPrice gasPrice: this.gasPrice
}); })
} }
} }

View File

@ -1,7 +1,7 @@
let messages = {}; let messages = {}
messages.wrongRepo = function(repo) { messages.wrongRepo = function(repo) {
return `There is no contracts.json in configured repo ${repo}`; return `There is no contracts.json in configured repo ${repo}`
}; }
module.exports = { module.exports = {
messages messages
}; }

View File

@ -9,37 +9,35 @@
// This link also includes instructions on opting out of this behavior. // This link also includes instructions on opting out of this behavior.
const isLocalhost = Boolean( const isLocalhost = Boolean(
window.location.hostname === "localhost" || window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address. // [::1] is the IPv6 localhost address.
window.location.hostname === "[::1]" || window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4. // 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match( window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ )
)
);
export default function register() { export default function register() {
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW. // The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location); const publicUrl = new URL(process.env.PUBLIC_URL, window.location)
if (publicUrl.origin !== window.location.origin) { if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin // Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to // from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374 // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
return; return
} }
window.addEventListener("load", () => { window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
if (isLocalhost) { if (isLocalhost) {
// This is running on localhost. Lets check if a service worker still exists or not. // This is running on localhost. Lets check if a service worker still exists or not.
checkValidServiceWorker(swUrl); checkValidServiceWorker(swUrl)
} else { } else {
// Is not local host. Just register service worker // Is not local host. Just register service worker
registerValidSW(swUrl); registerValidSW(swUrl)
} }
}); })
} }
} }
@ -48,28 +46,28 @@ function registerValidSW(swUrl) {
.register(swUrl) .register(swUrl)
.then(registration => { .then(registration => {
registration.onupdatefound = () => { registration.onupdatefound = () => {
const installingWorker = registration.installing; const installingWorker = registration.installing
installingWorker.onstatechange = () => { installingWorker.onstatechange = () => {
if (installingWorker.state === "installed") { if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) { if (navigator.serviceWorker.controller) {
// At this point, the old content will have been purged and // At this point, the old content will have been purged and
// the fresh content will have been added to the cache. // the fresh content will have been added to the cache.
// It's the perfect time to display a "New content is // It's the perfect time to display a "New content is
// available; please refresh." message in your web app. // available; please refresh." message in your web app.
console.log("New content is available; please refresh."); console.log('New content is available; please refresh.')
} else { } else {
// At this point, everything has been precached. // At this point, everything has been precached.
// It's the perfect time to display a // It's the perfect time to display a
// "Content is cached for offline use." message. // "Content is cached for offline use." message.
console.log("Content is cached for offline use."); console.log('Content is cached for offline use.')
} }
} }
}; }
}; }
}) })
.catch(error => { .catch(error => {
console.error("Error during service worker registration:", error); console.error('Error during service worker registration:', error)
}); })
} }
function checkValidServiceWorker(swUrl) { function checkValidServiceWorker(swUrl) {
@ -77,32 +75,27 @@ function checkValidServiceWorker(swUrl) {
fetch(swUrl) fetch(swUrl)
.then(response => { .then(response => {
// Ensure service worker exists, and that we really are getting a JS file. // Ensure service worker exists, and that we really are getting a JS file.
if ( if (response.status === 404 || response.headers.get('content-type').indexOf('javascript') === -1) {
response.status === 404 ||
response.headers.get("content-type").indexOf("javascript") === -1
) {
// No service worker found. Probably a different app. Reload the page. // No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => { navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => { registration.unregister().then(() => {
window.location.reload(); window.location.reload()
}); })
}); })
} else { } else {
// Service worker found. Proceed as normal. // Service worker found. Proceed as normal.
registerValidSW(swUrl); registerValidSW(swUrl)
} }
}) })
.catch(() => { .catch(() => {
console.log( console.log('No internet connection found. App is running in offline mode.')
"No internet connection found. App is running in offline mode." })
);
});
} }
export function unregister() { export function unregister() {
if ("serviceWorker" in navigator) { if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => { navigator.serviceWorker.ready.then(registration => {
registration.unregister(); registration.unregister()
}); })
} }
} }