2018-10-15 07:52:03 -07: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 addressGenerator from "./addressGenerator";
|
|
|
|
import JSzip from "jszip";
|
|
|
|
import FileSaver from "file-saver";
|
|
|
|
import { constants } from "./constants";
|
|
|
|
import networkAddresses from "./addresses";
|
|
|
|
import Header from "./Header";
|
|
|
|
import Footer from "./Footer";
|
|
|
|
import Loading from "./Loading";
|
2018-01-05 12:14:52 -08:00
|
|
|
|
2018-10-15 07:52:03 -07:00
|
|
|
function generateElement(msg) {
|
2018-01-05 12:14:52 -08: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}
|
|
|
|
</div>`;
|
|
|
|
return errorNode;
|
|
|
|
}
|
2017-12-06 23:02:38 -08:00
|
|
|
|
|
|
|
class App extends Component {
|
2018-10-15 07:52:03 -07:00
|
|
|
constructor(props) {
|
2017-12-06 23:02:38 -08:00
|
|
|
super(props);
|
|
|
|
this.onClick = this.onClick.bind(this);
|
2018-10-15 07:52:03 -07:00
|
|
|
this.saveFile = blob => {
|
2018-01-23 22:23:53 -08: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-02-13 03:42:17 -08:00
|
|
|
isDisabledBtn: props.generateKeysIsDisabled
|
2018-10-15 07:52:03 -07:00
|
|
|
};
|
2017-12-06 23:02:38 -08:00
|
|
|
this.keysManager = null;
|
2018-10-15 07:52:03 -07:00
|
|
|
getWeb3()
|
|
|
|
.then(async web3Config => {
|
|
|
|
return networkAddresses(web3Config);
|
2018-02-13 03:14:59 -08:00
|
|
|
})
|
2018-10-15 07:52:03 -07:00
|
|
|
.then(async config => {
|
|
|
|
const { web3Config, addresses } = config;
|
|
|
|
this.keysManager = new KeysManager();
|
|
|
|
await this.keysManager.init({
|
|
|
|
web3: web3Config.web3Instance,
|
|
|
|
netId: web3Config.netId,
|
|
|
|
addresses
|
2017-12-06 23:02:38 -08:00
|
|
|
});
|
2018-10-15 07:52:03 -07:00
|
|
|
this.setState({
|
|
|
|
isDisabledBtn: false,
|
|
|
|
web3Config
|
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
if (error.msg) {
|
|
|
|
this.setState({ isDisabledBtn: true });
|
|
|
|
swal({
|
|
|
|
icon: "warning",
|
|
|
|
title: "Warning",
|
|
|
|
content: error.node
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2017-12-06 23:02:38 -08:00
|
|
|
}
|
2018-10-15 07:52:03 -07:00
|
|
|
componentDidMount() {
|
|
|
|
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-15 07:52:03 -07:00
|
|
|
const { mining, voting, payout } = await this.generateKeys();
|
|
|
|
this.setState({ loading: false });
|
|
|
|
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
|
2018-10-15 07:52:03 -07:00
|
|
|
});
|
2018-01-09 16:44:55 -08:00
|
|
|
return {
|
2018-10-15 07:52:03 -07:00
|
|
|
mining,
|
|
|
|
voting,
|
|
|
|
payout
|
|
|
|
};
|
2018-01-09 16:44:55 -08:00
|
|
|
}
|
2018-10-15 07:52:03 -07:00
|
|
|
async generateZip({ mining, voting, payout, netIdName }) {
|
2018-01-23 22:23:53 -08:00
|
|
|
const zip = new JSzip();
|
2018-10-15 07:52:03 -07:00
|
|
|
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-15 07:52:03 -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-15 07:52:03 -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 => {
|
2018-01-23 22:23:53 -08:00
|
|
|
FileSaver.saveAs(blob, `poa_network_validator_keys.zip`);
|
|
|
|
});
|
|
|
|
}
|
2017-12-06 23:02:38 -08:00
|
|
|
async onClick() {
|
2018-10-15 07:52:03 -07:00
|
|
|
this.setState({ loading: true });
|
2017-12-06 23:02:38 -08:00
|
|
|
const initialKey = window.web3.eth.defaultAccount;
|
2018-10-15 07:52:03 -07:00
|
|
|
let isValid;
|
2018-02-23 05:31:56 -08:00
|
|
|
try {
|
|
|
|
isValid = await this.keysManager.isInitialKeyValid(initialKey);
|
2018-10-15 07:52:03 -07:00
|
|
|
} catch (e) {
|
2018-02-23 05:31:56 -08:00
|
|
|
isValid = false;
|
|
|
|
}
|
2017-12-06 23:02:38 -08:00
|
|
|
console.log(isValid);
|
2018-10-15 07:52:03 -07:00
|
|
|
if (Number(isValid) !== 1) {
|
|
|
|
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-15 07:52:03 -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-15 07:52:03 -07:00
|
|
|
icon: "error",
|
|
|
|
title: "Error",
|
2018-01-05 12:14:52 -08:00
|
|
|
content: generateElement(invalidKeyMsg)
|
2018-10-15 07:52:03 -07:00
|
|
|
});
|
2017-12-06 23:02:38 -08:00
|
|
|
return;
|
|
|
|
}
|
2018-10-15 07:52:03 -07:00
|
|
|
if (Number(isValid) === 1) {
|
|
|
|
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 => {
|
|
|
|
console.log(receipt);
|
|
|
|
if (receipt.status === true || receipt.status === "0x1") {
|
|
|
|
this.setState({ loading: false });
|
|
|
|
swal("Congratulations!", "Your keys are generated!", "success");
|
|
|
|
await this.generateZip({
|
|
|
|
mining,
|
|
|
|
voting,
|
|
|
|
payout,
|
|
|
|
netIdName: this.state.web3Config.netIdName
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.setState({ loading: false, keysGenerated: false });
|
|
|
|
let content = document.createElement("div");
|
|
|
|
let msg = `Transaction failed`;
|
|
|
|
content.innerHTML = `<div>
|
2018-02-13 05:23:41 -08:00
|
|
|
Something went wrong!<br/><br/>
|
|
|
|
Please contact Master Of Ceremony<br/><br/>
|
|
|
|
${msg}
|
|
|
|
</div>`;
|
2018-10-15 07:52:03 -07:00
|
|
|
swal({
|
|
|
|
icon: "error",
|
|
|
|
title: "Error",
|
|
|
|
content: content
|
|
|
|
});
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
console.error(error.message);
|
|
|
|
this.setState({ loading: false, keysGenerated: false });
|
|
|
|
let content = document.createElement("div");
|
|
|
|
let msg;
|
|
|
|
if (error.message.includes(constants.userDeniedTransactionPattern))
|
|
|
|
msg = `Error: ${constants.userDeniedTransactionPattern}`;
|
|
|
|
else msg = error.message;
|
|
|
|
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>`;
|
2018-10-15 07:52:03 -07:00
|
|
|
swal({
|
|
|
|
icon: "error",
|
|
|
|
title: "Error",
|
|
|
|
content: content
|
|
|
|
});
|
2017-12-06 23:02:38 -08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2018-10-15 07:52:03 -07:00
|
|
|
render() {
|
|
|
|
let loader = this.state.loading ? (
|
|
|
|
<Loading netId={this.state.web3Config.netId} />
|
|
|
|
) : (
|
|
|
|
""
|
|
|
|
);
|
|
|
|
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>
|
|
|
|
);
|
2017-12-06 23:02:38 -08:00
|
|
|
let content;
|
2018-10-15 07:52:03 -07:00
|
|
|
if (this.state.keysGenerated) {
|
|
|
|
content = (
|
|
|
|
<Keys
|
|
|
|
mining={this.state.mining}
|
|
|
|
voting={this.state.voting}
|
|
|
|
payout={this.state.payout}
|
|
|
|
/>
|
|
|
|
);
|
2017-12-06 23:02:38 -08:00
|
|
|
} else {
|
2018-10-15 07:52:03 -07:00
|
|
|
content = createKeyBtn;
|
2017-12-06 23:02:38 -08:00
|
|
|
}
|
|
|
|
return (
|
|
|
|
<div className="App">
|
2018-10-15 07:52:03 -07:00
|
|
|
<Header netId={this.state.web3Config.netId} />
|
2017-12-06 23:02:38 -08:00
|
|
|
{loader}
|
2018-10-15 07:52:03 -07:00
|
|
|
<section className="content">{content}</section>
|
|
|
|
<Footer netId={this.state.web3Config.netId} />
|
2017-12-06 23:02:38 -08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default App;
|