2017-12-06 23:02:38 -08:00
|
|
|
import React, { Component } from 'react';
|
|
|
|
import getWeb3 from './getWeb3'
|
|
|
|
import KeysManager from './keysManager';
|
|
|
|
import Keys from './Keys';
|
|
|
|
import swal from 'sweetalert';
|
|
|
|
import './index/index.css';
|
|
|
|
import ReactDOM from 'react-dom';
|
2018-01-05 12:14:52 -08:00
|
|
|
import { error } from 'util';
|
2018-01-09 16:44:55 -08:00
|
|
|
import addressGenerator from './addressGenerator'
|
2018-01-19 20:12:37 -08:00
|
|
|
import JSzip from 'jszip';
|
|
|
|
import FileSaver from 'file-saver';
|
2018-01-29 10:02:05 -08:00
|
|
|
import { constants } from './constants';
|
2018-01-05 12:14:52 -08:00
|
|
|
|
|
|
|
function generateElement(msg){
|
|
|
|
let errorNode = document.createElement("div");
|
|
|
|
errorNode.innerHTML = `<div>
|
|
|
|
${msg}
|
|
|
|
</div>`;
|
|
|
|
return errorNode;
|
|
|
|
}
|
2017-12-06 23:02:38 -08:00
|
|
|
|
|
|
|
const Loading = () => (
|
|
|
|
<div className="loading-container">
|
|
|
|
<div className="loading">
|
|
|
|
<div className="loading-i"></div>
|
|
|
|
<div className="loading-i"></div>
|
|
|
|
<div className="loading-i"></div>
|
|
|
|
<div className="loading-i"></div>
|
|
|
|
<div className="loading-i"></div>
|
|
|
|
<div className="loading-i"></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
|
|
|
|
class App extends Component {
|
|
|
|
constructor(props){
|
|
|
|
super(props);
|
|
|
|
this.onClick = this.onClick.bind(this);
|
2018-01-23 22:23:53 -08:00
|
|
|
this.saveFile = (blob) => {
|
|
|
|
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,
|
|
|
|
isDisabledBtn: false
|
2017-12-06 23:02:38 -08:00
|
|
|
}
|
|
|
|
this.keysManager = null;
|
2018-01-29 11:39:28 -08:00
|
|
|
getWeb3().then(async (web3Config) => {
|
2017-12-06 23:02:38 -08:00
|
|
|
this.setState({web3Config})
|
2018-01-29 10:02:05 -08:00
|
|
|
this.keysManager = new KeysManager()
|
2018-01-29 11:39:28 -08:00
|
|
|
await this.keysManager.init({
|
2018-01-04 16:46:11 -08:00
|
|
|
web3: web3Config.web3Instance,
|
|
|
|
netId: web3Config.netId
|
2017-12-06 23:02:38 -08:00
|
|
|
});
|
|
|
|
}).catch((error) => {
|
|
|
|
if(error.msg){
|
2017-12-06 23:11:01 -08:00
|
|
|
this.setState({isDisabledBtn: true});
|
2017-12-06 23:02:38 -08:00
|
|
|
swal({
|
|
|
|
icon: 'warning',
|
|
|
|
title: 'Warning',
|
|
|
|
content: error.node
|
|
|
|
});
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
2018-01-09 16:44:55 -08:00
|
|
|
componentDidMount(){
|
|
|
|
if(window.location.hash.indexOf('just-generate-keys') !== -1) {
|
2018-01-19 20:12:37 -08:00
|
|
|
this.setState({loading:true});
|
2018-01-23 22:23:53 -08:00
|
|
|
setTimeout(async () => {
|
|
|
|
const {mining, voting, payout} = await this.generateKeys();
|
2018-01-19 20:12:37 -08:00
|
|
|
this.setState({loading:false});
|
2018-01-23 22:23:53 -08:00
|
|
|
await this.generateZip({mining, voting, payout, netIdName: "manualCreation"});
|
|
|
|
}, 150)
|
2018-01-09 16:44:55 -08:00
|
|
|
}
|
|
|
|
}
|
2018-01-23 22:23:53 -08:00
|
|
|
async generateKeys(cb) {
|
2018-01-09 16:44:55 -08:00
|
|
|
const mining = await addressGenerator();
|
|
|
|
const voting = await addressGenerator();
|
|
|
|
const payout = await addressGenerator();
|
|
|
|
this.setState({
|
|
|
|
mining,
|
|
|
|
voting,
|
|
|
|
payout,
|
|
|
|
keysGenerated: true
|
|
|
|
})
|
|
|
|
return {
|
|
|
|
mining, voting, payout
|
|
|
|
}
|
|
|
|
}
|
2018-01-23 22:23:53 -08:00
|
|
|
async generateZip({mining, voting, payout, netIdName}){
|
|
|
|
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);
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
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`);
|
|
|
|
});
|
|
|
|
}
|
2017-12-06 23:02:38 -08:00
|
|
|
async onClick() {
|
|
|
|
this.setState({loading:true});
|
|
|
|
const initialKey = window.web3.eth.defaultAccount;
|
|
|
|
const isValid = await this.keysManager.isInitialKeyValid(initialKey);
|
|
|
|
console.log(isValid);
|
|
|
|
if(Number(isValid) !== 1){
|
2017-12-07 22:02:32 -08:00
|
|
|
this.setState({loading:false});
|
2018-01-05 12:14:52 -08:00
|
|
|
const invalidKeyMsg = `The key is not valid initial Key!<br/>
|
|
|
|
Please make sure you have loaded correct initial key in metamask.<br/>
|
|
|
|
Your current selected key is ${initialKey}`
|
|
|
|
swal({
|
|
|
|
icon: 'error',
|
|
|
|
title: 'Error',
|
|
|
|
content: generateElement(invalidKeyMsg)
|
|
|
|
})
|
2017-12-06 23:02:38 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
if(Number(isValid) === 1){
|
2018-01-09 16:44:55 -08:00
|
|
|
const {mining, voting, payout} = await this.generateKeys()
|
2017-12-06 23:02:38 -08:00
|
|
|
// add loading screen
|
|
|
|
await this.keysManager.createKeys({
|
|
|
|
mining: mining.jsonStore.address,
|
|
|
|
voting: voting.jsonStore.address,
|
|
|
|
payout: payout.jsonStore.address,
|
|
|
|
sender: initialKey
|
2018-01-23 22:23:53 -08:00
|
|
|
}).then(async (receipt) => {
|
2017-12-06 23:02:38 -08:00
|
|
|
console.log(receipt);
|
|
|
|
this.setState({loading: false})
|
|
|
|
swal("Congratulations!", "Your keys are generated!", "success");
|
2018-01-29 10:02:05 -08:00
|
|
|
await this.generateZip({mining, voting, payout, netIdName: this.state.web3Config.netIdName});
|
2017-12-06 23:02:38 -08:00
|
|
|
}).catch((error) => {
|
|
|
|
console.error(error.message);
|
2018-01-04 16:46:11 -08:00
|
|
|
this.setState({loading: false, keysGenerated: false})
|
2017-12-06 23:02:38 -08:00
|
|
|
var content = document.createElement("div");
|
2018-01-29 10:02:05 -08:00
|
|
|
let msg;
|
|
|
|
if (error.message.includes(constants.userDeniedTransactionPattern))
|
|
|
|
msg = `Error: User ${constants.userDeniedTransactionPattern}`
|
|
|
|
else
|
|
|
|
msg = error.message
|
2017-12-06 23:02:38 -08: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}
|
2017-12-06 23:02:38 -08:00
|
|
|
</div>`;
|
|
|
|
swal({
|
|
|
|
icon: 'error',
|
|
|
|
title: 'Error',
|
|
|
|
content: content
|
|
|
|
});
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
render() {
|
|
|
|
let loader = this.state.loading ? <Loading /> : '';
|
|
|
|
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">
|
2017-12-06 23:11:01 -08:00
|
|
|
<button className="create-keys-button" onClick={this.onClick} disabled={this.state.isDisabledBtn}>Generate keys</button>
|
2017-12-06 23:02:38 -08:00
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>)
|
|
|
|
let content;
|
|
|
|
if(this.state.keysGenerated){
|
|
|
|
content = <Keys mining={this.state.mining} voting={this.state.voting} payout={this.state.payout}/>
|
|
|
|
} else {
|
|
|
|
content = createKeyBtn
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<div className="App">
|
|
|
|
{loader}
|
|
|
|
<section className="content">
|
|
|
|
{content}
|
|
|
|
</section>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default App;
|