2018-12-07 06:01:02 -08:00
|
|
|
import FileSaver from 'file-saver'
|
|
|
|
import JSzip from 'jszip'
|
|
|
|
import Keys from './components/Keys'
|
|
|
|
import KeysManager from './utils/keysManager'
|
|
|
|
import Loading from './components/Loading'
|
2018-10-17 01:56:56 -07:00
|
|
|
import React, { Component } from 'react'
|
2018-12-07 06:01:02 -08:00
|
|
|
import addressGenerator from './utils/addressGenerator'
|
|
|
|
import getWeb3 from './utils/getWeb3'
|
|
|
|
import networkAddresses from './utils/addresses'
|
2018-10-17 01:56:56 -07:00
|
|
|
import swal from 'sweetalert'
|
2018-12-07 11:19:14 -08:00
|
|
|
import { Footer } from './components/Footer'
|
|
|
|
import { Header } from './components/Header'
|
2018-12-07 12:04:29 -08:00
|
|
|
import { Home } from './components/Home'
|
2018-12-07 06:01:02 -08:00
|
|
|
import { constants } from './utils/constants'
|
2018-12-07 11:19:14 -08:00
|
|
|
import { isTestnet } from './utils/utils'
|
|
|
|
import './assets/stylesheets/index.css'
|
2018-01-05 12:14:52 -08:00
|
|
|
|
2018-10-15 07:52:03 -07:00
|
|
|
function generateElement(msg) {
|
2018-10-17 01:56:56 -07:00
|
|
|
let errorNode = document.createElement('div')
|
2018-02-23 05:13:37 -08:00
|
|
|
errorNode.innerHTML = `<div style="line-height: 1.6;">
|
2018-01-05 12:14:52 -08:00
|
|
|
${msg}
|
2018-10-17 01:56:56 -07:00
|
|
|
</div>`
|
|
|
|
return errorNode
|
2018-01-05 12:14:52 -08:00
|
|
|
}
|
2017-12-06 23:02:38 -08:00
|
|
|
|
|
|
|
class App extends Component {
|
2018-10-15 07:52:03 -07:00
|
|
|
constructor(props) {
|
2018-10-17 01:56:56 -07:00
|
|
|
super(props)
|
|
|
|
this.onClick = this.onClick.bind(this)
|
2018-10-15 07:52:03 -07:00
|
|
|
this.saveFile = blob => {
|
2018-10-17 01:56:56 -07:00
|
|
|
FileSaver.saveAs(blob, `poa_network_validator_keys.zip`)
|
|
|
|
}
|
2017-12-06 23:02:38 -08:00
|
|
|
this.state = {
|
|
|
|
web3Config: {},
|
2017-12-06 23:11:01 -08:00
|
|
|
mining: null,
|
2018-12-07 11:19:14 -08:00
|
|
|
isDisabledBtn: props.generateKeysIsDisabled,
|
|
|
|
isTestnet: false
|
2018-10-17 01:56:56 -07:00
|
|
|
}
|
|
|
|
this.keysManager = null
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2018-10-15 07:52:03 -07:00
|
|
|
getWeb3()
|
|
|
|
.then(async web3Config => {
|
2018-10-17 01:56:56 -07:00
|
|
|
return networkAddresses(web3Config)
|
2018-02-13 03:14:59 -08:00
|
|
|
})
|
2018-10-15 07:52:03 -07:00
|
|
|
.then(async config => {
|
2018-10-17 01:56:56 -07:00
|
|
|
const { web3Config, addresses } = config
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2018-10-17 01:56:56 -07:00
|
|
|
this.keysManager = new KeysManager()
|
2018-10-15 07:52:03 -07:00
|
|
|
await this.keysManager.init({
|
|
|
|
web3: web3Config.web3Instance,
|
|
|
|
netId: web3Config.netId,
|
|
|
|
addresses
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
2018-12-07 11:19:14 -08:00
|
|
|
|
|
|
|
console.log('culo ' + isTestnet(web3Config.netId))
|
2018-10-15 07:52:03 -07:00
|
|
|
this.setState({
|
2018-12-07 11:19:14 -08:00
|
|
|
isTestnet: isTestnet(web3Config.netId),
|
2018-10-15 07:52:03 -07:00
|
|
|
isDisabledBtn: false,
|
|
|
|
web3Config
|
2018-10-16 06:09:49 -07:00
|
|
|
})
|
2018-10-18 04:24:20 -07:00
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
if (error.msg) {
|
|
|
|
this.setState({ isDisabledBtn: true })
|
|
|
|
swal({
|
|
|
|
icon: 'warning',
|
|
|
|
title: 'Warning',
|
|
|
|
content: error.node
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
2018-10-18 04:24:20 -07:00
|
|
|
}
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
2017-12-06 23:02:38 -08:00
|
|
|
}
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2018-10-15 07:52:03 -07:00
|
|
|
componentDidMount() {
|
2018-10-17 01:56:56 -07:00
|
|
|
if (window.location.hash.indexOf('just-generate-keys') !== -1) {
|
|
|
|
this.setState({ loading: true })
|
2018-01-23 22:23:53 -08:00
|
|
|
setTimeout(async () => {
|
2018-10-17 01:56:56 -07:00
|
|
|
const { mining, voting, payout } = await this.generateKeys()
|
|
|
|
this.setState({ loading: false })
|
2018-10-15 07:52:03 -07:00
|
|
|
await this.generateZip({
|
|
|
|
mining,
|
|
|
|
voting,
|
|
|
|
payout,
|
2018-10-17 01:56:56 -07:00
|
|
|
netIdName: 'manualCreation'
|
|
|
|
})
|
|
|
|
}, 150)
|
2018-01-09 16:44:55 -08:00
|
|
|
}
|
|
|
|
}
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2018-01-23 22:23:53 -08:00
|
|
|
async generateKeys(cb) {
|
2018-10-17 01:56:56 -07:00
|
|
|
const mining = await addressGenerator()
|
|
|
|
const voting = await addressGenerator()
|
|
|
|
const payout = await addressGenerator()
|
2018-01-09 16:44:55 -08:00
|
|
|
this.setState({
|
|
|
|
mining,
|
|
|
|
voting,
|
|
|
|
payout,
|
|
|
|
keysGenerated: true
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
2018-01-09 16:44:55 -08:00
|
|
|
return {
|
2018-10-15 07:52:03 -07:00
|
|
|
mining,
|
|
|
|
voting,
|
|
|
|
payout
|
2018-10-17 01:56:56 -07:00
|
|
|
}
|
2018-01-09 16:44:55 -08:00
|
|
|
}
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2018-10-15 07:52:03 -07:00
|
|
|
async generateZip({ mining, voting, payout, netIdName }) {
|
2018-10-17 01:56:56 -07:00
|
|
|
const zip = new JSzip()
|
|
|
|
zip.file(`${netIdName}_keys/mining_key_${mining.jsonStore.address}.json`, JSON.stringify(mining.jsonStore))
|
|
|
|
zip.file(`${netIdName}_keys/mining_password_${mining.jsonStore.address}.txt`, mining.password)
|
2018-01-23 22:23:53 -08:00
|
|
|
|
2018-10-17 01:56:56 -07:00
|
|
|
zip.file(`${netIdName}_keys/voting_key_${voting.jsonStore.address}.json`, JSON.stringify(voting.jsonStore))
|
|
|
|
zip.file(`${netIdName}_keys/voting_password_${voting.jsonStore.address}.txt`, voting.password)
|
2018-01-23 22:23:53 -08:00
|
|
|
|
2018-10-17 01:56:56 -07:00
|
|
|
zip.file(`${netIdName}_keys/payout_key_${payout.jsonStore.address}.json`, JSON.stringify(payout.jsonStore))
|
|
|
|
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`)
|
|
|
|
})
|
2018-01-23 22:23:53 -08:00
|
|
|
}
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2017-12-06 23:02:38 -08:00
|
|
|
async onClick() {
|
2018-10-17 01:56:56 -07:00
|
|
|
this.setState({ loading: true })
|
|
|
|
const initialKey = this.state.web3Config.defaultAccount
|
|
|
|
let isValid
|
2018-02-23 05:31:56 -08:00
|
|
|
try {
|
2018-10-17 01:56:56 -07:00
|
|
|
isValid = await this.keysManager.isInitialKeyValid(initialKey)
|
2018-10-15 07:52:03 -07:00
|
|
|
} catch (e) {
|
2018-10-17 01:56:56 -07:00
|
|
|
isValid = false
|
2018-02-23 05:31:56 -08:00
|
|
|
}
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2018-10-15 07:52:03 -07:00
|
|
|
if (Number(isValid) !== 1) {
|
2018-10-17 01:56:56 -07:00
|
|
|
this.setState({ loading: false })
|
2018-10-04 05:36:03 -07:00
|
|
|
const invalidKeyMsg = `The key is an invalid Initial key<br/>
|
|
|
|
or you're connected to the incorrect chain!<br/>
|
|
|
|
Please make sure you have loaded correct Initial key in MetaMask.<br/><br/>
|
2018-02-23 05:13:37 -08:00
|
|
|
<b>Your current selected key is</b> <i>${initialKey}</i><br/>
|
2018-10-17 01:56:56 -07:00
|
|
|
<b>Current Network ID</b> is <i>${this.state.web3Config.netId}</i>`
|
2018-01-05 12:14:52 -08:00
|
|
|
swal({
|
2018-10-17 01:56:56 -07:00
|
|
|
icon: 'error',
|
|
|
|
title: 'Error',
|
2018-01-05 12:14:52 -08:00
|
|
|
content: generateElement(invalidKeyMsg)
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
|
|
|
return
|
2017-12-06 23:02:38 -08:00
|
|
|
}
|
2018-10-15 07:52:03 -07:00
|
|
|
if (Number(isValid) === 1) {
|
2018-10-17 01:56:56 -07:00
|
|
|
const { mining, voting, payout } = await this.generateKeys()
|
2017-12-06 23:02:38 -08:00
|
|
|
// add loading screen
|
2018-10-15 07:52:03 -07:00
|
|
|
await this.keysManager
|
|
|
|
.createKeys({
|
|
|
|
mining: mining.jsonStore.address,
|
|
|
|
voting: voting.jsonStore.address,
|
|
|
|
payout: payout.jsonStore.address,
|
|
|
|
sender: initialKey
|
|
|
|
})
|
|
|
|
.then(async receipt => {
|
2018-10-17 01:56:56 -07:00
|
|
|
if (receipt.status === true || receipt.status === '0x1') {
|
|
|
|
this.setState({ loading: false })
|
|
|
|
swal('Congratulations!', 'Your keys are generated!', 'success')
|
2018-10-15 07:52:03 -07:00
|
|
|
await this.generateZip({
|
|
|
|
mining,
|
|
|
|
voting,
|
|
|
|
payout,
|
|
|
|
netIdName: this.state.web3Config.netIdName
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
2018-10-15 07:52:03 -07:00
|
|
|
} else {
|
2018-10-17 01:56:56 -07:00
|
|
|
this.setState({ loading: false, keysGenerated: false })
|
|
|
|
let content = document.createElement('div')
|
|
|
|
let msg = `Transaction failed`
|
2018-10-15 07:52:03 -07:00
|
|
|
content.innerHTML = `<div>
|
2018-02-13 05:23:41 -08:00
|
|
|
Something went wrong!<br/><br/>
|
|
|
|
Please contact Master Of Ceremony<br/><br/>
|
|
|
|
${msg}
|
2018-10-17 01:56:56 -07:00
|
|
|
</div>`
|
2018-10-15 07:52:03 -07:00
|
|
|
swal({
|
2018-10-17 01:56:56 -07:00
|
|
|
icon: 'error',
|
|
|
|
title: 'Error',
|
2018-10-15 07:52:03 -07:00
|
|
|
content: content
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
2018-10-15 07:52:03 -07:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(error => {
|
2018-10-17 01:56:56 -07:00
|
|
|
this.setState({ loading: false, keysGenerated: false })
|
|
|
|
let content = document.createElement('div')
|
|
|
|
let msg
|
2018-10-15 07:52:03 -07:00
|
|
|
if (error.message.includes(constants.userDeniedTransactionPattern))
|
2018-10-17 01:56:56 -07:00
|
|
|
msg = `Error: ${constants.userDeniedTransactionPattern}`
|
|
|
|
else msg = error.message
|
2018-10-15 07:52:03 -07:00
|
|
|
content.innerHTML = `<div>
|
2018-01-04 16:58:06 -08:00
|
|
|
Something went wrong!<br/><br/>
|
2018-01-05 12:14:52 -08:00
|
|
|
Please contact Master Of Ceremony<br/><br/>
|
2018-01-29 10:02:05 -08:00
|
|
|
${msg}
|
2018-10-17 01:56:56 -07:00
|
|
|
</div>`
|
2018-10-15 07:52:03 -07:00
|
|
|
swal({
|
2018-10-17 01:56:56 -07:00
|
|
|
icon: 'error',
|
|
|
|
title: 'Error',
|
2018-10-15 07:52:03 -07:00
|
|
|
content: content
|
2018-10-17 01:56:56 -07:00
|
|
|
})
|
|
|
|
})
|
2017-12-06 23:02:38 -08:00
|
|
|
}
|
|
|
|
}
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2018-10-15 07:52:03 -07:00
|
|
|
render() {
|
2018-10-17 01:56:56 -07:00
|
|
|
let loader = this.state.loading ? <Loading netId={this.state.web3Config.netId} /> : ''
|
2018-12-07 12:04:29 -08:00
|
|
|
// let createKeyBtn = (
|
|
|
|
// <div className="create-keys">
|
|
|
|
// <h1>Create keys from initial key</h1>
|
|
|
|
// <h2>
|
|
|
|
// In this application, you will create mining, payout and voting keys. The app will make your initial key
|
|
|
|
// unusable after the process. Please proceed with care, don't lose your keys and follow instructions.
|
|
|
|
// </h2>
|
|
|
|
// <div className="create-keys-button-container">
|
|
|
|
// <button className="create-keys-button" onClick={this.onClick} disabled={this.state.isDisabledBtn}>
|
|
|
|
// Generate keys
|
|
|
|
// </button>
|
|
|
|
// </div>
|
|
|
|
// </div>
|
|
|
|
// )
|
2018-12-07 11:19:14 -08:00
|
|
|
|
2017-12-06 23:02:38 -08:00
|
|
|
return (
|
2018-12-07 11:19:14 -08:00
|
|
|
<div className="lo-App">
|
|
|
|
<Header isTestnet={this.state.isTestnet} />
|
2017-12-06 23:02:38 -08:00
|
|
|
{loader}
|
2018-12-07 12:04:29 -08:00
|
|
|
<section className="lo-App_Content">
|
|
|
|
{this.state.keysGenerated ? (
|
|
|
|
<Keys mining={this.state.mining} voting={this.state.voting} payout={this.state.payout} />
|
|
|
|
) : (
|
|
|
|
<Home />
|
|
|
|
)}
|
|
|
|
</section>
|
2018-12-07 11:19:14 -08:00
|
|
|
<Footer isTestnet={this.state.isTestnet} />
|
2017-12-06 23:02:38 -08:00
|
|
|
</div>
|
2018-10-17 01:56:56 -07:00
|
|
|
)
|
2017-12-06 23:02:38 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-17 01:56:56 -07:00
|
|
|
export default App
|