nifty-wallet/old-ui/app/config.js

377 lines
11 KiB
JavaScript

const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
import PropTypes from 'prop-types'
const actions = require('../../ui/app/actions')
const LoadingIndicator = require('./components/loading')
const Web3 = require('web3')
const infuraCurrencies = require('./infura-conversion.json').objects.sort((a, b) => {
return a.quote.name.toLocaleLowerCase().localeCompare(b.quote.name.toLocaleLowerCase())
})
const validUrl = require('valid-url')
const exportAsFile = require('./util').exportAsFile
const Modal = require('../../ui/app/components/modals/index').Modal
const ethNetProps = require('eth-net-props')
const { networks } = require('../../app/scripts/controllers/network/util')
const {
ROPSTEN,
RINKEBY,
KOVAN,
MAINNET,
POA,
DAI,
POA_SOKOL,
GOERLI_TESTNET,
} = require('../../app/scripts/controllers/network/enums')
const POCKET_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET, POA, DAI, GOERLI_TESTNET, POA_SOKOL]
class ConfigScreen extends Component {
static propTypes = {
metamask: PropTypes.object,
warning: PropTypes.string,
provider: PropTypes.object,
dProviderStore: PropTypes.object,
setProviderType: PropTypes.func,
showDeleteRPC: PropTypes.func,
displayWarning: PropTypes.func,
goHome: PropTypes.func,
setDProvider: PropTypes.func,
setRpcTarget: PropTypes.func,
confirmChangePassword: PropTypes.func,
revealSeedConfirmation: PropTypes.func,
resetAccount: PropTypes.func,
setCurrentCurrency: PropTypes.func,
}
constructor (props) {
super(props)
this.state = {
loading: false,
dProvider: props.dProviderStore.dProvider,
}
}
render () {
const props = this.props
const metamaskState = props.metamask
const warning = props.warning
if (props.dProviderStore.dProvider !== this.state.dProvider) {
this.setState({
dProvider: props.dProviderStore.dProvider,
})
}
return (
h('.flex-column.flex-grow', {
style: {
maxHeight: '585px',
overflowY: 'auto',
},
}, [
h(LoadingIndicator, {
isLoading: this.state.loading,
}),
h(Modal, {}, []),
// subtitle and nav
h('.section-title.flex-row.flex-center', [
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
onClick: () => {
props.goHome()
},
style: {
position: 'absolute',
left: '30px',
},
}),
h('h2', 'Settings'),
]),
h('div', {
style: {
margin: '0 30px',
},
}, [
h('.error', {
style: {
display: warning ? 'block' : 'none',
},
}, warning),
]),
// conf view
h('.flex-column.flex-justify-center.flex-grow.select-none', [
h('.flex-space-around', {
style: {
padding: '30px',
overflow: 'auto',
},
}, [
this.currentProviderDisplay(metamaskState),
h('div', { style: {display: 'flex'} }, [
h('input#new_rpc', {
placeholder: 'New RPC URL',
style: {
width: 'inherit',
flex: '1 0 auto',
height: '32px',
borderRadius: '3px',
border: '1px solid #e2e2e2',
padding: '10px',
marginBottom: '20px',
},
onKeyPress: (event) => {
if (event.key === 'Enter') {
const element = event.target
const newRpc = element.value
this.rpcValidation(newRpc)
}
},
}),
]),
h('button.btn-spread', {
onClick: (event) => {
event.preventDefault()
const element = document.querySelector('input#new_rpc')
const newRpc = element.value
this.rpcValidation(newRpc)
},
}, 'Save'),
h('hr.horizontal-line'),
this.currentConversionInformation(metamaskState),
h('hr.horizontal-line'),
h('div', [
h('p.config-title', `State logs`),
h('p.config-description', `State logs contain your public account addresses and sent transactions.`),
h('button.btn-spread', {
style: {
alignSelf: 'center',
},
onClick (event) {
window.logStateString((err, result) => {
if (err) {
props.displayWarning('Error in retrieving state logs.')
} else {
exportAsFile('Nifty Wallet State Logs.json', result)
}
})
},
}, 'Download State Logs'),
]),
h('hr.horizontal-line'),
h('div', [
h('p.config-title', `Seed words`),
h('p.config-description', `Reveal seed words.`),
h('button.btn-spread', {
style: {
alignSelf: 'center',
},
onClick (event) {
event.preventDefault()
props.revealSeedConfirmation()
},
}, 'Reveal Seed Words'),
]),
h('hr.horizontal-line', {
style: {
marginTop: '20px',
},
}),
h('p.config-title', `Provider`),
h('div', {
style: {
display: 'table',
width: '100%',
},
}, [
h('div', {
style: {
display: 'table-cell',
}}, [
h('p.config-description', 'Switch to Decentralized Provider (Pocket)'),
]),
h('div', { style: {
display: 'table-cell',
}}, [
h('input', {
type: 'checkbox',
name: 'pocket-checkbox',
checked: this.state.dProvider,
onChange: (event) => {
event.preventDefault()
this.toggleProvider()
},
}),
]),
]),
h('hr.horizontal-line'),
h('div', [
h('p.config-title', `Account`),
h('p.config-description', `Resetting is for developer use only.`),
h('button.btn-spread', {
style: {
alignSelf: 'center',
},
onClick (event) {
event.preventDefault()
props.resetAccount()
},
}, 'Reset Account'),
h('p.config-description', 'Changing of password'),
h('button.btn-spread', {
onClick (event) {
event.preventDefault()
props.confirmChangePassword()
},
}, 'Change password'),
]),
]),
]),
])
)
}
toggleProvider () {
const props = this.props
const isPocket = POCKET_PROVIDER_TYPES.includes(props.provider.type)
if (isPocket) {
if (!this.state.dProvider) {
props.setDProvider(true)
this.setState({
dProvider: true,
})
} else {
props.setDProvider(false)
this.setState({
dProvider: false,
})
}
props.setProviderType(props.provider.type)
} else {
alert('Pocket does not support this network, using centralized provider')
}
}
componentWillUnmount () {
this.props.displayWarning('')
}
rpcValidation (newRpc) {
const props = this.props
if (validUrl.isWebUri(newRpc)) {
this.setState({
loading: true,
})
const web3 = new Web3(new Web3.providers.HttpProvider(newRpc))
web3.eth.getBlockNumber((err, res) => {
if (err) {
props.displayWarning('Invalid RPC endpoint')
} else {
props.setRpcTarget(newRpc)
}
this.setState({
loading: false,
})
})
} else {
if (!newRpc.startsWith('http')) {
props.displayWarning('URIs require the appropriate HTTP/HTTPS prefix.')
} else {
props.displayWarning('Invalid RPC URI')
}
}
}
currentConversionInformation (metamaskState) {
const props = this.props
const currentCurrency = metamaskState.currentCurrency
const conversionDate = metamaskState.conversionDate
return h('div', [
h('div.config-title', 'Current Conversion'),
h('div.config-description', `Updated ${Date(conversionDate)}`),
h('select.config-select-currency#currentCurrency', {
onChange (event) {
event.preventDefault()
const element = document.getElementById('currentCurrency')
const newCurrency = element.value
props.setCurrentCurrency(newCurrency)
},
defaultValue: currentCurrency,
}, infuraCurrencies.map((currency) => {
return h('option', {key: currency.quote.code, value: currency.quote.code}, `${currency.quote.code.toUpperCase()} - ${currency.quote.name}`)
}),
),
])
}
currentProviderDisplay (metamaskState) {
const props = this.props
const provider = metamaskState.provider
let title, value
if (networks[provider.type]) {
title = 'Current Network'
value = ethNetProps.props.getNetworkDisplayName(networks[provider.type].networkID)
} else {
title = 'Current RPC'
value = metamaskState.provider.rpcTarget
}
return h('div', [
h('div.config-title', title),
h('div.config-description', value),
provider.type === 'rpc' && h('button.btn-spread', {
onClick (event) {
event.preventDefault()
props.showDeleteRPC()
},
}, 'Delete'),
])
}
}
function mapStateToProps (state) {
return {
metamask: state.metamask,
provider: state.metamask.provider,
dProviderStore: state.metamask.dProviderStore,
warning: state.appState.warning,
}
}
const mapDispatchToProps = dispatch => {
return {
setProviderType: (providerType) => dispatch(actions.setProviderType(providerType)),
showDeleteRPC: (label, transitionForward) => dispatch(actions.showDeleteRPC(label, transitionForward)),
displayWarning: (msg) => dispatch(actions.displayWarning(msg)),
goHome: () => dispatch(actions.goHome()),
setDProvider: (set) => dispatch(actions.setDProvider(set)),
setRpcTarget: (rpcTarget) => dispatch(actions.setRpcTarget(rpcTarget)),
setCurrentCurrency: (newCurrency) => dispatch(actions.setRpcTarget(newCurrency)),
confirmChangePassword: () => dispatch(actions.confirmChangePassword()),
resetAccount: () => dispatch(actions.resetAccount()),
revealSeedConfirmation: () => dispatch(actions.revealSeedConfirmation()),
}
}
module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfigScreen)