custom RPC validation: JSON RPC request instead of HTTP request

This commit is contained in:
Victor Baranov 2018-11-27 15:27:11 +03:00
parent 3c3d49fe6d
commit 768a065a15
1 changed files with 44 additions and 33 deletions

View File

@ -3,9 +3,8 @@ const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const connect = require('react-redux').connect const connect = require('react-redux').connect
const actions = require('../../ui/app/actions') const actions = require('../../ui/app/actions')
const url = require('url') const LoadingIndicator = require('./components/loading')
const http = require('http') const Web3 = require('web3')
const https = require('https')
const infuraCurrencies = require('./infura-conversion.json').objects.sort((a, b) => { const infuraCurrencies = require('./infura-conversion.json').objects.sort((a, b) => {
return a.quote.name.toLocaleLowerCase().localeCompare(b.quote.name.toLocaleLowerCase()) return a.quote.name.toLocaleLowerCase().localeCompare(b.quote.name.toLocaleLowerCase())
}) })
@ -25,13 +24,16 @@ function mapStateToProps (state) {
inherits(ConfigScreen, Component) inherits(ConfigScreen, Component)
function ConfigScreen () { function ConfigScreen () {
this.state = {
loading: false,
}
Component.call(this) Component.call(this)
} }
ConfigScreen.prototype.render = function () { ConfigScreen.prototype.render = function () {
var state = this.props const state = this.props
var metamaskState = state.metamask const metamaskState = state.metamask
var warning = state.warning const warning = state.warning
return ( return (
h('.flex-column.flex-grow', { h('.flex-column.flex-grow', {
@ -41,6 +43,10 @@ ConfigScreen.prototype.render = function () {
}, },
}, [ }, [
h(LoadingIndicator, {
isLoading: this.state.loading,
}),
h(Modal, {}, []), h(Modal, {}, []),
// subtitle and nav // subtitle and nav
@ -92,11 +98,11 @@ ConfigScreen.prototype.render = function () {
border: '1px solid #e2e2e2', border: '1px solid #e2e2e2',
padding: '10px', padding: '10px',
}, },
onKeyPress (event) { onKeyPress: (event) => {
if (event.key === 'Enter') { if (event.key === 'Enter') {
var element = event.target const element = event.target
var newRpc = element.value const newRpc = element.value
rpcValidation(newRpc, state) this.rpcValidation(newRpc, state)
} }
}, },
}), }),
@ -105,11 +111,11 @@ ConfigScreen.prototype.render = function () {
alignSelf: 'center', alignSelf: 'center',
marginTop: '20px', marginTop: '20px',
}, },
onClick (event) { onClick: (event) => {
event.preventDefault() event.preventDefault()
var element = document.querySelector('input#new_rpc') const element = document.querySelector('input#new_rpc')
var newRpc = element.value const newRpc = element.value
rpcValidation(newRpc, state) this.rpcValidation(newRpc, state)
}, },
}, 'Save'), }, 'Save'),
]), ]),
@ -234,41 +240,46 @@ ConfigScreen.prototype.componentWillUnmount = function () {
this.props.dispatch(actions.displayWarning('')) this.props.dispatch(actions.displayWarning(''))
} }
function rpcValidation (newRpc, state) { ConfigScreen.prototype.rpcValidation = (newRpc, state) => {
this.setState({
loading: true,
})
if (validUrl.isWebUri(newRpc)) { if (validUrl.isWebUri(newRpc)) {
const rpc = url.parse(newRpc) const web3 = new Web3(new Web3.providers.HttpProvider(newRpc))
const protocolName = rpc.protocol.replace(/:/g, '') web3.eth.getBlockNumber((err, res) => {
const protocol = protocolName === 'https' ? https : http if (err) {
const options = {method: 'GET', host: rpc.hostname, port: rpc.port, path: rpc.pathname} state.dispatch(actions.displayWarning('Invalid RPC endpoint'))
const req = protocol.request(options) } else {
.on('response', () => { state.dispatch(actions.setRpcTarget(newRpc))
state.dispatch(actions.setRpcTarget(newRpc)) }
this.setState({
loading: false,
})
}) })
.on('error', () => {
state.dispatch(actions.displayWarning('Invalid RPC endpoint'))
})
req.end()
} else { } else {
var appendedRpc = `http://${newRpc}` const appendedRpc = `http://${newRpc}`
if (validUrl.isWebUri(appendedRpc)) { if (validUrl.isWebUri(appendedRpc)) {
state.dispatch(actions.displayWarning('URIs require the appropriate HTTP/HTTPS prefix.')) state.dispatch(actions.displayWarning('URIs require the appropriate HTTP/HTTPS prefix.'))
} else { } else {
state.dispatch(actions.displayWarning('Invalid RPC URI')) state.dispatch(actions.displayWarning('Invalid RPC URI'))
} }
this.setState({
loading: false,
})
} }
} }
function currentConversionInformation (metamaskState, state) { function currentConversionInformation (metamaskState, state) {
var currentCurrency = metamaskState.currentCurrency const currentCurrency = metamaskState.currentCurrency
var conversionDate = metamaskState.conversionDate const conversionDate = metamaskState.conversionDate
return h('div', [ return h('div', [
h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, 'Current Conversion'), h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, 'Current Conversion'),
h('span', {style: { fontWeight: 'bold', paddingRight: '10px', fontSize: '13px'}}, `Updated ${Date(conversionDate)}`), h('span', {style: { fontWeight: 'bold', paddingRight: '10px', fontSize: '13px'}}, `Updated ${Date(conversionDate)}`),
h('select#currentCurrency', { h('select#currentCurrency', {
onChange (event) { onChange (event) {
event.preventDefault() event.preventDefault()
var element = document.getElementById('currentCurrency') const element = document.getElementById('currentCurrency')
var newCurrency = element.value const newCurrency = element.value
state.dispatch(actions.setCurrentCurrency(newCurrency)) state.dispatch(actions.setCurrentCurrency(newCurrency))
}, },
defaultValue: currentCurrency, defaultValue: currentCurrency,
@ -280,8 +291,8 @@ function currentConversionInformation (metamaskState, state) {
} }
function currentProviderDisplay (metamaskState, state) { function currentProviderDisplay (metamaskState, state) {
var provider = metamaskState.provider const provider = metamaskState.provider
var title, value let title, value
switch (provider.type) { switch (provider.type) {