.prettierrc and .prettierignore are added
This commit is contained in:
parent
ff7877aac6
commit
ca5fbb9a5e
|
@ -0,0 +1,7 @@
|
|||
assets
|
||||
build_scripts
|
||||
config
|
||||
public
|
||||
scripts
|
||||
submodules
|
||||
*.js
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"printWidth": 120
|
||||
}
|
243
src/App.js
243
src/App.js
|
@ -1,169 +1,151 @@
|
|||
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";
|
||||
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'
|
||||
|
||||
function generateElement(msg) {
|
||||
let errorNode = document.createElement("div");
|
||||
let errorNode = document.createElement('div')
|
||||
errorNode.innerHTML = `<div style="line-height: 1.6;">
|
||||
${msg}
|
||||
</div>`;
|
||||
return errorNode;
|
||||
</div>`
|
||||
return errorNode
|
||||
}
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onClick = this.onClick.bind(this);
|
||||
super(props)
|
||||
this.onClick = this.onClick.bind(this)
|
||||
this.saveFile = blob => {
|
||||
FileSaver.saveAs(blob, `poa_network_validator_keys.zip`);
|
||||
};
|
||||
FileSaver.saveAs(blob, `poa_network_validator_keys.zip`)
|
||||
}
|
||||
this.state = {
|
||||
web3Config: {},
|
||||
mining: null,
|
||||
isDisabledBtn: props.generateKeysIsDisabled
|
||||
};
|
||||
this.keysManager = null;
|
||||
}
|
||||
this.keysManager = null
|
||||
getWeb3()
|
||||
.then(async web3Config => {
|
||||
return networkAddresses(web3Config);
|
||||
return networkAddresses(web3Config)
|
||||
})
|
||||
.then(async config => {
|
||||
const { web3Config, addresses } = config;
|
||||
this.keysManager = new KeysManager();
|
||||
const { web3Config, addresses } = config
|
||||
this.keysManager = new KeysManager()
|
||||
await this.keysManager.init({
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId,
|
||||
addresses
|
||||
});
|
||||
})
|
||||
this.setState({
|
||||
isDisabledBtn: false,
|
||||
web3Config
|
||||
})
|
||||
.then(async config => {
|
||||
const { web3Config, addresses } = config;
|
||||
this.keysManager = new KeysManager();
|
||||
const { web3Config, addresses } = config
|
||||
this.keysManager = new KeysManager()
|
||||
await this.keysManager.init({
|
||||
web3: web3Config.web3Instance,
|
||||
netId: web3Config.netId,
|
||||
addresses
|
||||
});
|
||||
})
|
||||
this.setState({
|
||||
isDisabledBtn: false,
|
||||
web3Config
|
||||
});
|
||||
})
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.msg) {
|
||||
this.setState({ isDisabledBtn: true });
|
||||
this.setState({ isDisabledBtn: true })
|
||||
swal({
|
||||
icon: "warning",
|
||||
title: "Warning",
|
||||
icon: 'warning',
|
||||
title: 'Warning',
|
||||
content: error.node
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
componentDidMount() {
|
||||
if (window.location.hash.indexOf("just-generate-keys") !== -1) {
|
||||
this.setState({ loading: true });
|
||||
if (window.location.hash.indexOf('just-generate-keys') !== -1) {
|
||||
this.setState({ loading: true })
|
||||
setTimeout(async () => {
|
||||
const { mining, voting, payout } = await this.generateKeys();
|
||||
this.setState({ loading: false });
|
||||
const { mining, voting, payout } = await this.generateKeys()
|
||||
this.setState({ loading: false })
|
||||
await this.generateZip({
|
||||
mining,
|
||||
voting,
|
||||
payout,
|
||||
netIdName: "manualCreation"
|
||||
});
|
||||
}, 150);
|
||||
netIdName: 'manualCreation'
|
||||
})
|
||||
}, 150)
|
||||
}
|
||||
}
|
||||
async generateKeys(cb) {
|
||||
const mining = await addressGenerator();
|
||||
const voting = await addressGenerator();
|
||||
const payout = await addressGenerator();
|
||||
const mining = await addressGenerator()
|
||||
const voting = await addressGenerator()
|
||||
const payout = await addressGenerator()
|
||||
this.setState({
|
||||
mining,
|
||||
voting,
|
||||
payout,
|
||||
keysGenerated: true
|
||||
});
|
||||
})
|
||||
return {
|
||||
mining,
|
||||
voting,
|
||||
payout
|
||||
};
|
||||
}
|
||||
}
|
||||
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
|
||||
);
|
||||
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/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`);
|
||||
});
|
||||
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`)
|
||||
})
|
||||
}
|
||||
async onClick() {
|
||||
this.setState({ loading: true });
|
||||
const initialKey = this.state.web3Config.defaultAccount;
|
||||
let isValid;
|
||||
this.setState({ loading: true })
|
||||
const initialKey = this.state.web3Config.defaultAccount
|
||||
let isValid
|
||||
try {
|
||||
isValid = await this.keysManager.isInitialKeyValid(initialKey);
|
||||
isValid = await this.keysManager.isInitialKeyValid(initialKey)
|
||||
} catch (e) {
|
||||
isValid = false;
|
||||
isValid = false
|
||||
}
|
||||
console.log(isValid);
|
||||
console.log(isValid)
|
||||
if (Number(isValid) !== 1) {
|
||||
this.setState({ loading: false });
|
||||
this.setState({ loading: false })
|
||||
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/>
|
||||
<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({
|
||||
icon: "error",
|
||||
title: "Error",
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
content: generateElement(invalidKeyMsg)
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
if (Number(isValid) === 1) {
|
||||
const { mining, voting, payout } = await this.generateKeys();
|
||||
const { mining, voting, payout } = await this.generateKeys()
|
||||
// add loading screen
|
||||
await this.keysManager
|
||||
.createKeys({
|
||||
|
@ -173,89 +155,74 @@ class App extends Component {
|
|||
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");
|
||||
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`;
|
||||
this.setState({ loading: false, keysGenerated: false })
|
||||
let content = document.createElement('div')
|
||||
let msg = `Transaction failed`
|
||||
content.innerHTML = `<div>
|
||||
Something went wrong!<br/><br/>
|
||||
Please contact Master Of Ceremony<br/><br/>
|
||||
${msg}
|
||||
</div>`;
|
||||
</div>`
|
||||
swal({
|
||||
icon: "error",
|
||||
title: "Error",
|
||||
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;
|
||||
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;
|
||||
msg = `Error: ${constants.userDeniedTransactionPattern}`
|
||||
else msg = error.message
|
||||
content.innerHTML = `<div>
|
||||
Something went wrong!<br/><br/>
|
||||
Please contact Master Of Ceremony<br/><br/>
|
||||
${msg}
|
||||
</div>`;
|
||||
</div>`
|
||||
swal({
|
||||
icon: "error",
|
||||
title: "Error",
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
content: content
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
render() {
|
||||
let loader = this.state.loading ? (
|
||||
<Loading netId={this.state.web3Config.netId} />
|
||||
) : (
|
||||
""
|
||||
);
|
||||
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.
|
||||
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}
|
||||
>
|
||||
<button className="create-keys-button" onClick={this.onClick} disabled={this.state.isDisabledBtn}>
|
||||
Generate keys
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
let content;
|
||||
)
|
||||
let content
|
||||
if (this.state.keysGenerated) {
|
||||
content = (
|
||||
<Keys
|
||||
mining={this.state.mining}
|
||||
voting={this.state.voting}
|
||||
payout={this.state.payout}
|
||||
/>
|
||||
);
|
||||
content = <Keys mining={this.state.mining} voting={this.state.voting} payout={this.state.payout} />
|
||||
} else {
|
||||
content = createKeyBtn;
|
||||
content = createKeyBtn
|
||||
}
|
||||
return (
|
||||
<div className="App">
|
||||
|
@ -264,8 +231,8 @@ class App extends Component {
|
|||
<section className="content">{content}</section>
|
||||
<Footer netId={this.state.web3Config.netId} />
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
export default App
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
|
||||
it("renders without crashing", () => {
|
||||
const div = document.createElement("div");
|
||||
ReactDOM.render(<App />, div);
|
||||
});
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div')
|
||||
ReactDOM.render(<App />, div)
|
||||
})
|
||||
|
|
|
@ -1,46 +1,32 @@
|
|||
import React from "react";
|
||||
import moment from "moment";
|
||||
import { constants } from "./constants";
|
||||
import React from 'react'
|
||||
import moment from 'moment'
|
||||
import { constants } from './constants'
|
||||
|
||||
const Footer = ({ netId }) => {
|
||||
const footerClassName =
|
||||
netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET
|
||||
? "sokol"
|
||||
: "";
|
||||
const footerClassName = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET ? 'sokol' : ''
|
||||
|
||||
return (
|
||||
<footer className={`footer ${footerClassName}`}>
|
||||
<div className="container">
|
||||
<p className="footer-rights">
|
||||
{moment().format("YYYY")} POA Network. All rights reserved.
|
||||
</p>
|
||||
<p className="footer-rights">{moment().format('YYYY')} POA Network. All rights reserved.</p>
|
||||
<a href="/poa-dapps-keys-generation" className="footer-logo" />
|
||||
<div className="socials">
|
||||
<a
|
||||
href="https://twitter.com/poanetwork"
|
||||
className="socials-i socials-i_twitter"
|
||||
>
|
||||
<a href="https://twitter.com/poanetwork" className="socials-i socials-i_twitter">
|
||||
Twitter
|
||||
</a>
|
||||
<a href="https://poa.network" className="socials-i socials-i_oracles">
|
||||
POA Network
|
||||
</a>
|
||||
<a
|
||||
href="https://t.me/oraclesnetwork"
|
||||
className="socials-i socials-i_telegram"
|
||||
>
|
||||
<a href="https://t.me/oraclesnetwork" className="socials-i socials-i_telegram">
|
||||
Telegram
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/poanetwork/"
|
||||
className="socials-i socials-i_github"
|
||||
>
|
||||
<a href="https://github.com/poanetwork/" className="socials-i socials-i_github">
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer;
|
||||
export default Footer
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import React from "react";
|
||||
import { constants } from "./constants";
|
||||
import React from 'react'
|
||||
import { constants } from './constants'
|
||||
|
||||
let Header = ({ netId }) => {
|
||||
const thisIsTestnet =
|
||||
netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET;
|
||||
const headerClassName = thisIsTestnet ? "sokol" : "";
|
||||
const logoClassName = thisIsTestnet ? "header-logo-sokol" : "header-logo";
|
||||
const thisIsTestnet = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET
|
||||
const headerClassName = thisIsTestnet ? 'sokol' : ''
|
||||
const logoClassName = thisIsTestnet ? 'header-logo-sokol' : 'header-logo'
|
||||
return (
|
||||
<header className={`header ${headerClassName}`}>
|
||||
<div className="container">
|
||||
<a href="/poa-dapps-keys-generation" className={logoClassName} />
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
||||
export default Header;
|
||||
export default Header
|
||||
|
|
108
src/Keys.js
108
src/Keys.js
|
@ -1,76 +1,76 @@
|
|||
import React, { Component } from "react";
|
||||
import Tooltip from "rc-tooltip";
|
||||
import "rc-tooltip/assets/bootstrap.css";
|
||||
import React, { Component } from 'react'
|
||||
import Tooltip from 'rc-tooltip'
|
||||
import 'rc-tooltip/assets/bootstrap.css'
|
||||
|
||||
const encodeJson = json => {
|
||||
const encoded = window.encodeURIComponent(JSON.stringify(json));
|
||||
return `data:application/json;charset=utf-8,${encoded}`;
|
||||
};
|
||||
const encoded = window.encodeURIComponent(JSON.stringify(json))
|
||||
return `data:application/json;charset=utf-8,${encoded}`
|
||||
}
|
||||
|
||||
export default class Keys extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onVisibleChange = this.onVisibleChange.bind(this);
|
||||
this.onCopyBtnClick = this.onCopyBtnClick.bind(this);
|
||||
super(props)
|
||||
this.onVisibleChange = this.onVisibleChange.bind(this)
|
||||
this.onCopyBtnClick = this.onCopyBtnClick.bind(this)
|
||||
this.state = {
|
||||
copyBtns: {
|
||||
copyMiningPass: {
|
||||
visible: false,
|
||||
text: "Copy"
|
||||
text: 'Copy'
|
||||
},
|
||||
copyVotingPass: {
|
||||
visible: false,
|
||||
text: "Copy"
|
||||
text: 'Copy'
|
||||
},
|
||||
copyPayoutPass: {
|
||||
visible: false,
|
||||
text: "Copy"
|
||||
text: 'Copy'
|
||||
},
|
||||
copyMiningKey: {
|
||||
visible: false,
|
||||
text: "Copy"
|
||||
text: 'Copy'
|
||||
},
|
||||
copyVotingKey: {
|
||||
visible: false,
|
||||
text: "Copy"
|
||||
text: 'Copy'
|
||||
},
|
||||
copyPayoutKey: {
|
||||
visible: false,
|
||||
text: "Copy"
|
||||
text: 'Copy'
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
componentWillUpdate(nextProps, nextState) {
|
||||
if (this.refs.miningKeyAddress) {
|
||||
const Clipboard = require("clipboard");
|
||||
const Clipboard = require('clipboard')
|
||||
// this.clipboard = new Clipboard(this.refs.copyBtn);
|
||||
new Clipboard(this.refs.miningKeyAddress);
|
||||
new Clipboard(this.refs.miningKeyPass);
|
||||
new Clipboard(this.refs.payoutKeyAddress);
|
||||
new Clipboard(this.refs.payoutKeyPass);
|
||||
new Clipboard(this.refs.votingKeyAddress);
|
||||
new Clipboard(this.refs.votingKeyPass);
|
||||
new Clipboard(this.refs.miningKeyAddress)
|
||||
new Clipboard(this.refs.miningKeyPass)
|
||||
new Clipboard(this.refs.payoutKeyAddress)
|
||||
new Clipboard(this.refs.payoutKeyPass)
|
||||
new Clipboard(this.refs.votingKeyAddress)
|
||||
new Clipboard(this.refs.votingKeyPass)
|
||||
}
|
||||
}
|
||||
onVisibleChange(id) {
|
||||
console.log(id);
|
||||
let copyBtns = this.state.copyBtns;
|
||||
copyBtns[id].visible = !copyBtns[id].visible;
|
||||
copyBtns[id].text = "Copy";
|
||||
console.log(id)
|
||||
let copyBtns = this.state.copyBtns
|
||||
copyBtns[id].visible = !copyBtns[id].visible
|
||||
copyBtns[id].text = 'Copy'
|
||||
this.setState({
|
||||
copyBtns
|
||||
});
|
||||
})
|
||||
|
||||
// const id = e.target.id;
|
||||
}
|
||||
onCopyBtnClick(e) {
|
||||
const id = e.target.id;
|
||||
let copyBtns = this.state.copyBtns;
|
||||
copyBtns[id].text = "Copied!";
|
||||
const id = e.target.id
|
||||
let copyBtns = this.state.copyBtns
|
||||
copyBtns[id].text = 'Copied!'
|
||||
this.setState({
|
||||
copyBtns
|
||||
});
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
|
@ -88,7 +88,7 @@ export default class Keys extends Component {
|
|||
animation="zoom"
|
||||
trigger="hover"
|
||||
onVisibleChange={() => {
|
||||
this.onVisibleChange("copyMiningKey");
|
||||
this.onVisibleChange('copyMiningKey')
|
||||
}}
|
||||
placement="right"
|
||||
overlay={this.state.copyBtns.copyMiningKey.text}
|
||||
|
@ -98,9 +98,7 @@ export default class Keys extends Component {
|
|||
onClick={this.onCopyBtnClick}
|
||||
className="copy"
|
||||
ref="miningKeyAddress"
|
||||
data-clipboard-text={
|
||||
"0x" + this.props.mining.jsonStore.address
|
||||
}
|
||||
data-clipboard-text={'0x' + this.props.mining.jsonStore.address}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -118,7 +116,7 @@ export default class Keys extends Component {
|
|||
animation="zoom"
|
||||
trigger="hover"
|
||||
onVisibleChange={() => {
|
||||
this.onVisibleChange("copyMiningPass");
|
||||
this.onVisibleChange('copyMiningPass')
|
||||
}}
|
||||
placement="right"
|
||||
overlay={this.state.copyBtns.copyMiningPass.text}
|
||||
|
@ -133,9 +131,8 @@ export default class Keys extends Component {
|
|||
</Tooltip>
|
||||
</p>
|
||||
<p className="keys-description">
|
||||
Download this key and use it in your mining node to validate
|
||||
blocks in the network. Mined coins will be deposited to your
|
||||
payout account.
|
||||
Download this key and use it in your mining node to validate blocks in the network. Mined coins will be
|
||||
deposited to your payout account.
|
||||
</p>
|
||||
<div className="keys-footer">
|
||||
<a
|
||||
|
@ -160,7 +157,7 @@ export default class Keys extends Component {
|
|||
animation="zoom"
|
||||
trigger="hover"
|
||||
onVisibleChange={() => {
|
||||
this.onVisibleChange("copyPayoutKey");
|
||||
this.onVisibleChange('copyPayoutKey')
|
||||
}}
|
||||
placement="right"
|
||||
overlay={this.state.copyBtns.copyPayoutKey.text}
|
||||
|
@ -170,9 +167,7 @@ export default class Keys extends Component {
|
|||
onClick={this.onCopyBtnClick}
|
||||
className="copy"
|
||||
ref="payoutKeyAddress"
|
||||
data-clipboard-text={
|
||||
"0x" + this.props.payout.jsonStore.address
|
||||
}
|
||||
data-clipboard-text={'0x' + this.props.payout.jsonStore.address}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -190,7 +185,7 @@ export default class Keys extends Component {
|
|||
animation="zoom"
|
||||
trigger="hover"
|
||||
onVisibleChange={() => {
|
||||
this.onVisibleChange("copyPayoutPass");
|
||||
this.onVisibleChange('copyPayoutPass')
|
||||
}}
|
||||
placement="right"
|
||||
overlay={this.state.copyBtns.copyPayoutPass.text}
|
||||
|
@ -205,8 +200,7 @@ export default class Keys extends Component {
|
|||
</Tooltip>
|
||||
</p>
|
||||
<p className="keys-description">
|
||||
Download this key and use it on your client node/wallet to spend
|
||||
earned coins.
|
||||
Download this key and use it on your client node/wallet to spend earned coins.
|
||||
</p>
|
||||
<div className="keys-footer">
|
||||
<a
|
||||
|
@ -231,7 +225,7 @@ export default class Keys extends Component {
|
|||
animation="zoom"
|
||||
trigger="hover"
|
||||
onVisibleChange={() => {
|
||||
this.onVisibleChange("copyVotingKey");
|
||||
this.onVisibleChange('copyVotingKey')
|
||||
}}
|
||||
placement="right"
|
||||
overlay={this.state.copyBtns.copyVotingKey.text}
|
||||
|
@ -241,9 +235,7 @@ export default class Keys extends Component {
|
|||
onClick={this.onCopyBtnClick}
|
||||
className="copy"
|
||||
ref="votingKeyAddress"
|
||||
data-clipboard-text={
|
||||
"0x" + this.props.voting.jsonStore.address
|
||||
}
|
||||
data-clipboard-text={'0x' + this.props.voting.jsonStore.address}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
|
@ -261,7 +253,7 @@ export default class Keys extends Component {
|
|||
animation="zoom"
|
||||
trigger="hover"
|
||||
onVisibleChange={() => {
|
||||
this.onVisibleChange("copyVotingPass");
|
||||
this.onVisibleChange('copyVotingPass')
|
||||
}}
|
||||
placement="right"
|
||||
overlay={this.state.copyBtns.copyVotingPass.text}
|
||||
|
@ -276,9 +268,8 @@ export default class Keys extends Component {
|
|||
</Tooltip>
|
||||
</p>
|
||||
<p className="keys-description">
|
||||
Download this key and use it on your client node to vote for
|
||||
necessary ballots, such as adding or removing miners from the
|
||||
network.
|
||||
Download this key and use it on your client node to vote for necessary ballots, such as adding or removing
|
||||
miners from the network.
|
||||
</p>
|
||||
<div className="keys-footer">
|
||||
<a
|
||||
|
@ -295,12 +286,11 @@ export default class Keys extends Component {
|
|||
<div className="keys-note">
|
||||
<p className="keys-note-title">Important</p>
|
||||
<p className="keys-note-description">
|
||||
Do not close this tab until you download all keys and save
|
||||
passwords. Keep keys secure and protected. If you lose your keys,
|
||||
you will need to get a new initial key using Voting DAPP.
|
||||
Do not close this tab until you download all keys and save passwords. Keep keys secure and protected. If you
|
||||
lose your keys, you will need to get a new initial key using Voting DAPP.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
import React from "react";
|
||||
import { constants } from "./constants";
|
||||
import React from 'react'
|
||||
import { constants } from './constants'
|
||||
|
||||
const styles = netId => {
|
||||
const core = {
|
||||
backgroundColor: "rgba(35, 29, 115, 0.8)"
|
||||
};
|
||||
backgroundColor: 'rgba(35, 29, 115, 0.8)'
|
||||
}
|
||||
const sokol = {
|
||||
backgroundColor: "rgba(47, 109, 99, 0.8)"
|
||||
};
|
||||
|
||||
if (netId in constants.NETWORKS) {
|
||||
return constants.NETWORKS[netId].TESTNET ? sokol : core;
|
||||
backgroundColor: 'rgba(47, 109, 99, 0.8)'
|
||||
}
|
||||
|
||||
return core;
|
||||
};
|
||||
if (netId in constants.NETWORKS) {
|
||||
return constants.NETWORKS[netId].TESTNET ? sokol : core
|
||||
}
|
||||
|
||||
return core
|
||||
}
|
||||
const Loading = ({ netId }) => (
|
||||
<div className="loading-container" style={styles(netId)}>
|
||||
<div className="loading">
|
||||
|
@ -26,5 +26,5 @@ const Loading = ({ netId }) => (
|
|||
<div className="loading-i" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
export default Loading;
|
||||
)
|
||||
export default Loading
|
||||
|
|
|
@ -1,23 +1,16 @@
|
|||
import keythereum from "keythereum";
|
||||
import passwordGenerator from "password-generator";
|
||||
import keythereum from 'keythereum'
|
||||
import passwordGenerator from 'password-generator'
|
||||
|
||||
export default function generateAddress(cb) {
|
||||
return new Promise((resolve, reject) => {
|
||||
var params = { keyBytes: 32, ivBytes: 16 };
|
||||
var params = { keyBytes: 32, ivBytes: 16 }
|
||||
|
||||
keythereum.create(params, function(dk) {
|
||||
var options = {};
|
||||
var password = passwordGenerator(20, false);
|
||||
keythereum.dump(
|
||||
password,
|
||||
dk.privateKey,
|
||||
dk.salt,
|
||||
dk.iv,
|
||||
options,
|
||||
function(jsonStore) {
|
||||
resolve({ jsonStore, password });
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
var options = {}
|
||||
var password = passwordGenerator(20, false)
|
||||
keythereum.dump(password, dk.privateKey, dk.salt, dk.iv, options, function(jsonStore) {
|
||||
resolve({ jsonStore, password })
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
import { constants } from "./constants";
|
||||
import helpers from "./helpers";
|
||||
import { constants } from './constants'
|
||||
import helpers from './helpers'
|
||||
//const local = {
|
||||
// "KEYS_MANAGER_ADDRESS": "0x3ef32bb244016ad9af8c8f45398511e7e551b581"
|
||||
//}
|
||||
|
||||
export default web3Config => {
|
||||
const branch = constants.NETWORKS[web3Config.netId].BRANCH;
|
||||
const branch = constants.NETWORKS[web3Config.netId].BRANCH
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(helpers.addressesURL(branch))
|
||||
.then(response => {
|
||||
response.json().then(json => {
|
||||
resolve({ addresses: json, web3Config });
|
||||
});
|
||||
resolve({ addresses: json, web3Config })
|
||||
})
|
||||
})
|
||||
.catch(function(err) {
|
||||
let addr = helpers.addressesURL(branch);
|
||||
helpers.wrongRepoAlert(addr);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
let addr = helpers.addressesURL(branch)
|
||||
helpers.wrongRepoAlert(addr)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
let constants = {};
|
||||
constants.organization = "poanetwork";
|
||||
constants.repoName = "poa-chain-spec";
|
||||
constants.addressesSourceFile = "contracts.json";
|
||||
let constants = {}
|
||||
constants.organization = 'poanetwork'
|
||||
constants.repoName = 'poa-chain-spec'
|
||||
constants.addressesSourceFile = 'contracts.json'
|
||||
constants.ABIsSources = {
|
||||
KeysManager: "KeysManager.abi.json"
|
||||
};
|
||||
constants.userDeniedTransactionPattern = "User denied transaction";
|
||||
KeysManager: 'KeysManager.abi.json'
|
||||
}
|
||||
constants.userDeniedTransactionPattern = 'User denied transaction'
|
||||
|
||||
constants.NETWORKS = {
|
||||
"77": {
|
||||
NAME: "Sokol",
|
||||
BRANCH: "sokol",
|
||||
'77': {
|
||||
NAME: 'Sokol',
|
||||
BRANCH: 'sokol',
|
||||
TESTNET: true
|
||||
},
|
||||
"99": {
|
||||
NAME: "Core",
|
||||
BRANCH: "core",
|
||||
'99': {
|
||||
NAME: 'Core',
|
||||
BRANCH: 'core',
|
||||
TESTNET: false
|
||||
},
|
||||
"79": {
|
||||
NAME: "Dai-Test",
|
||||
BRANCH: "dai-test",
|
||||
'79': {
|
||||
NAME: 'Dai-Test',
|
||||
BRANCH: 'dai-test',
|
||||
TESTNET: true
|
||||
},
|
||||
"100": {
|
||||
NAME: "Dai",
|
||||
BRANCH: "dai",
|
||||
'100': {
|
||||
NAME: 'Dai',
|
||||
BRANCH: 'dai',
|
||||
TESTNET: false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
constants
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,83 +1,83 @@
|
|||
import Web3 from "web3";
|
||||
import { constants } from "./constants";
|
||||
import Web3 from 'web3'
|
||||
import { constants } from './constants'
|
||||
|
||||
const errorMsgNoMetamaskAccount = `You haven't chosen any account in MetaMask.
|
||||
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) {
|
||||
let errorNode = document.createElement("div");
|
||||
let errorNode = document.createElement('div')
|
||||
errorNode.innerHTML = `<div style="line-height: 1.6;">
|
||||
${msg}
|
||||
</div>`;
|
||||
return errorNode;
|
||||
</div>`
|
||||
return errorNode
|
||||
}
|
||||
let getWeb3 = () => {
|
||||
return new Promise(function(resolve, reject) {
|
||||
// Wait for loading completion to avoid race conditions with web3 injection timing.
|
||||
window.addEventListener("load", async function() {
|
||||
let web3;
|
||||
window.addEventListener('load', async function() {
|
||||
let web3
|
||||
|
||||
// Checking if Web3 has been injected by the browser (Mist/MetaMask)
|
||||
if (window.ethereum) {
|
||||
web3 = new Web3(window.ethereum);
|
||||
console.log("Injected web3 detected.");
|
||||
web3 = new Web3(window.ethereum)
|
||||
console.log('Injected web3 detected.')
|
||||
try {
|
||||
await window.ethereum.enable();
|
||||
await window.ethereum.enable()
|
||||
} catch (e) {
|
||||
reject({
|
||||
msg: errorMsgDeniedAccess,
|
||||
node: generateElement(errorMsgDeniedAccess)
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
} else if (window.web3) {
|
||||
web3 = new Web3(window.web3.currentProvider);
|
||||
console.log("Injected web3 detected.");
|
||||
web3 = new Web3(window.web3.currentProvider)
|
||||
console.log('Injected web3 detected.')
|
||||
} else {
|
||||
console.error("Metamask not found");
|
||||
console.error('Metamask not found')
|
||||
reject({
|
||||
msg: errorMsgNoMetamaskAccount,
|
||||
node: generateElement(errorMsgNoMetamaskAccount)
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const netId = await web3.eth.net.getId();
|
||||
console.log("netId", netId);
|
||||
const netId = await web3.eth.net.getId()
|
||||
console.log('netId', netId)
|
||||
|
||||
let netIdName;
|
||||
let errorMsg = null;
|
||||
let netIdName
|
||||
let errorMsg = null
|
||||
|
||||
if (netId in constants.NETWORKS) {
|
||||
netIdName = constants.NETWORKS[netId].NAME;
|
||||
console.log(`This is ${netIdName}`);
|
||||
netIdName = constants.NETWORKS[netId].NAME
|
||||
console.log(`This is ${netIdName}`)
|
||||
} else {
|
||||
netIdName = "ERROR";
|
||||
netIdName = 'ERROR'
|
||||
errorMsg = `You aren't connected to POA Network.
|
||||
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.
|
||||
<b>Current Network ID</b> is <i>${netId}</i>`;
|
||||
console.log("This is an unknown network.");
|
||||
<b>Current Network ID</b> is <i>${netId}</i>`
|
||||
console.log('This is an unknown network.')
|
||||
}
|
||||
|
||||
document.title = `${netIdName} - DApp Keys Generation`;
|
||||
document.title = `${netIdName} - DApp Keys Generation`
|
||||
|
||||
if (errorMsg !== null) {
|
||||
reject({ msg: errorMsg, node: generateElement(errorMsg) });
|
||||
return;
|
||||
reject({ msg: errorMsg, node: generateElement(errorMsg) })
|
||||
return
|
||||
}
|
||||
|
||||
const accounts = await web3.eth.getAccounts();
|
||||
const defaultAccount = accounts[0] || null;
|
||||
const accounts = await web3.eth.getAccounts()
|
||||
const defaultAccount = accounts[0] || null
|
||||
if (defaultAccount === null) {
|
||||
reject({
|
||||
msg: errorMsgNoMetamaskAccount,
|
||||
node: generateElement(errorMsgNoMetamaskAccount)
|
||||
});
|
||||
return;
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
resolve({
|
||||
|
@ -85,9 +85,9 @@ let getWeb3 = () => {
|
|||
netIdName,
|
||||
netId,
|
||||
defaultAccount
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default getWeb3;
|
||||
export default getWeb3
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
import { constants } from "./constants";
|
||||
import { messages } from "./messages";
|
||||
import swal from "sweetalert";
|
||||
import { constants } from './constants'
|
||||
import { messages } from './messages'
|
||||
import swal from 'sweetalert'
|
||||
|
||||
var toAscii = function(hex) {
|
||||
var str = "",
|
||||
var str = '',
|
||||
i = 0,
|
||||
l = hex.length;
|
||||
if (hex.substring(0, 2) === "0x") {
|
||||
i = 2;
|
||||
l = hex.length
|
||||
if (hex.substring(0, 2) === '0x') {
|
||||
i = 2
|
||||
}
|
||||
for (; i < l; i += 2) {
|
||||
var code = parseInt(hex.substr(i, 2), 16);
|
||||
if (code === 0) continue; // this is added
|
||||
str += String.fromCharCode(code);
|
||||
var code = parseInt(hex.substr(i, 2), 16)
|
||||
if (code === 0) continue // this is added
|
||||
str += String.fromCharCode(code)
|
||||
}
|
||||
return str;
|
||||
};
|
||||
return str
|
||||
}
|
||||
|
||||
function addressesURL(branch) {
|
||||
const URL = `https://raw.githubusercontent.com/${constants.organization}/${
|
||||
constants.repoName
|
||||
}/${branch}/${constants.addressesSourceFile}`;
|
||||
return URL;
|
||||
const URL = `https://raw.githubusercontent.com/${constants.organization}/${constants.repoName}/${branch}/${
|
||||
constants.addressesSourceFile
|
||||
}`
|
||||
return URL
|
||||
}
|
||||
|
||||
function ABIURL(branch, contract) {
|
||||
const URL = `https://raw.githubusercontent.com/${constants.organization}/${
|
||||
constants.repoName
|
||||
}/${branch}/abis/${constants.ABIsSources[contract]}`;
|
||||
return URL;
|
||||
const URL = `https://raw.githubusercontent.com/${constants.organization}/${constants.repoName}/${branch}/abis/${
|
||||
constants.ABIsSources[contract]
|
||||
}`
|
||||
return URL
|
||||
}
|
||||
|
||||
function getABI(branch, contract) {
|
||||
let addr = ABIURL(branch, contract);
|
||||
let addr = ABIURL(branch, contract)
|
||||
return fetch(addr).then(function(response) {
|
||||
return response.json();
|
||||
});
|
||||
return response.json()
|
||||
})
|
||||
}
|
||||
|
||||
function wrongRepoAlert(addr) {
|
||||
var content = document.createElement("div");
|
||||
var content = document.createElement('div')
|
||||
content.innerHTML = `<div>
|
||||
Something went wrong!<br/><br/>
|
||||
${messages.wrongRepo(addr)}
|
||||
</div>`;
|
||||
</div>`
|
||||
swal({
|
||||
icon: "error",
|
||||
title: "Error",
|
||||
icon: 'error',
|
||||
title: 'Error',
|
||||
content: content
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
let helpers = {
|
||||
|
@ -57,6 +57,6 @@ let helpers = {
|
|||
ABIURL,
|
||||
getABI,
|
||||
wrongRepoAlert
|
||||
};
|
||||
}
|
||||
|
||||
export default helpers;
|
||||
export default helpers
|
||||
|
|
21
src/index.js
21
src/index.js
|
@ -1,12 +1,9 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import App from "./App";
|
||||
import registerServiceWorker from "./registerServiceWorker";
|
||||
window.addEventListener("beforeunload", function(event) {
|
||||
event.returnValue = "Are you sure?";
|
||||
});
|
||||
ReactDOM.render(
|
||||
<App generateKeysIsDisabled={true} />,
|
||||
document.getElementById("root")
|
||||
);
|
||||
registerServiceWorker();
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import registerServiceWorker from './registerServiceWorker'
|
||||
window.addEventListener('beforeunload', function(event) {
|
||||
event.returnValue = 'Are you sure?'
|
||||
})
|
||||
ReactDOM.render(<App generateKeysIsDisabled={true} />, document.getElementById('root'))
|
||||
registerServiceWorker()
|
||||
|
|
|
@ -1,55 +1,52 @@
|
|||
import addressGenerator from "./addressGenerator";
|
||||
import helpers from "./helpers";
|
||||
import { constants } from "./constants";
|
||||
import addressGenerator from './addressGenerator'
|
||||
import helpers from './helpers'
|
||||
import { constants } from './constants'
|
||||
|
||||
export default class KeysManager {
|
||||
async init({ web3, netId, addresses }) {
|
||||
const { KEYS_MANAGER_ADDRESS } = addresses;
|
||||
console.log("Keys Manager ", KEYS_MANAGER_ADDRESS);
|
||||
const { KEYS_MANAGER_ADDRESS } = addresses
|
||||
console.log('Keys Manager ', KEYS_MANAGER_ADDRESS)
|
||||
|
||||
const KeysManagerAbi = await helpers.getABI(
|
||||
constants.NETWORKS[netId].BRANCH,
|
||||
"KeysManager"
|
||||
);
|
||||
const KeysManagerAbi = await helpers.getABI(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();
|
||||
if (networkName === "dai-test" || networkName === "dai") {
|
||||
this.gasPrice = web3.utils.toWei("0", "gwei");
|
||||
const networkName = constants.NETWORKS[netId].NAME.toLowerCase()
|
||||
if (networkName === 'dai-test' || networkName === 'dai') {
|
||||
this.gasPrice = web3.utils.toWei('0', 'gwei')
|
||||
} else {
|
||||
this.gasPrice = web3.utils.toWei("2", "gwei");
|
||||
this.gasPrice = web3.utils.toWei('2', 'gwei')
|
||||
}
|
||||
}
|
||||
|
||||
async isInitialKeyValid(initialKey) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const methods = this.instance.methods;
|
||||
let getInitialKeyStatus;
|
||||
const methods = this.instance.methods
|
||||
let getInitialKeyStatus
|
||||
if (methods.getInitialKeyStatus) {
|
||||
getInitialKeyStatus = methods.getInitialKeyStatus;
|
||||
getInitialKeyStatus = methods.getInitialKeyStatus
|
||||
} else {
|
||||
getInitialKeyStatus = methods.initialKeys;
|
||||
getInitialKeyStatus = methods.initialKeys
|
||||
}
|
||||
getInitialKeyStatus(initialKey)
|
||||
.call()
|
||||
.then(function(result) {
|
||||
resolve(result);
|
||||
resolve(result)
|
||||
})
|
||||
.catch(function(e) {
|
||||
reject(false);
|
||||
});
|
||||
});
|
||||
reject(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async generateKeys() {
|
||||
return await addressGenerator();
|
||||
return await addressGenerator()
|
||||
}
|
||||
|
||||
createKeys({ mining, voting, payout, sender }) {
|
||||
return this.instance.methods.createKeys(mining, voting, payout).send({
|
||||
from: sender,
|
||||
gasPrice: this.gasPrice
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
let messages = {};
|
||||
let messages = {}
|
||||
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 = {
|
||||
messages
|
||||
};
|
||||
}
|
||||
|
|
|
@ -9,37 +9,35 @@
|
|||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === "localhost" ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === "[::1]" ||
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||
)
|
||||
|
||||
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.
|
||||
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) {
|
||||
// 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
|
||||
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl);
|
||||
checkValidServiceWorker(swUrl)
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl);
|
||||
registerValidSW(swUrl)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,28 +46,28 @@ function registerValidSW(swUrl) {
|
|||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
const installingWorker = registration.installing
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === "installed") {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// 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 {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "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 => {
|
||||
console.error("Error during service worker registration:", error);
|
||||
});
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl) {
|
||||
|
@ -77,32 +75,27 @@ function checkValidServiceWorker(swUrl) {
|
|||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get("content-type").indexOf("javascript") === -1
|
||||
) {
|
||||
if (response.status === 404 || response.headers.get('content-type').indexOf('javascript') === -1) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
window.location.reload()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl);
|
||||
registerValidSW(swUrl)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
"No internet connection found. App is running in offline mode."
|
||||
);
|
||||
});
|
||||
console.log('No internet connection found. App is running in offline mode.')
|
||||
})
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ("serviceWorker" in navigator) {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue