mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge branch 'master' into kumavis-patch-1
This commit is contained in:
commit
67c3126e63
@ -2,6 +2,8 @@
|
||||
|
||||
## Current Master
|
||||
|
||||
|
||||
- Add two most recently used custom RPCs to network dropdown menu.
|
||||
- Add personal_sign method support.
|
||||
- Add ability to customize gas and gasPrice on the transaction approval screen.
|
||||
- Increase default gas buffer to 1.5x estimated gas value.
|
||||
|
63
app/scripts/controllers/preferences.js
Normal file
63
app/scripts/controllers/preferences.js
Normal file
@ -0,0 +1,63 @@
|
||||
const ObservableStore = require('obs-store')
|
||||
const normalizeAddress = require('eth-sig-util').normalize
|
||||
const extend = require('xtend')
|
||||
|
||||
class PreferencesController {
|
||||
|
||||
constructor (opts = {}) {
|
||||
const initState = extend({ frequentRpcList: [] }, opts.initState)
|
||||
this.store = new ObservableStore(initState)
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC METHODS
|
||||
//
|
||||
|
||||
setSelectedAddress (_address) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const address = normalizeAddress(_address)
|
||||
this.store.updateState({ selectedAddress: address })
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
getSelectedAddress (_address) {
|
||||
return this.store.getState().selectedAddress
|
||||
}
|
||||
|
||||
updateFrequentRpcList (_url) {
|
||||
return this.addToFrequentRpcList(_url)
|
||||
.then((rpcList) => {
|
||||
this.store.updateState({ frequentRpcList: rpcList })
|
||||
return Promise.resolve()
|
||||
})
|
||||
}
|
||||
|
||||
addToFrequentRpcList (_url) {
|
||||
let rpcList = this.getFrequentRpcList()
|
||||
let index = rpcList.findIndex((element) => { return element === _url })
|
||||
if (index !== -1) {
|
||||
rpcList.splice(index, 1)
|
||||
}
|
||||
if (_url !== 'http://localhost:8545') {
|
||||
rpcList.push(_url)
|
||||
}
|
||||
if (rpcList.length > 2) {
|
||||
rpcList.shift()
|
||||
}
|
||||
return Promise.resolve(rpcList)
|
||||
}
|
||||
|
||||
getFrequentRpcList () {
|
||||
return this.store.getState().frequentRpcList
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE METHODS
|
||||
//
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
module.exports = PreferencesController
|
@ -1,33 +0,0 @@
|
||||
const ObservableStore = require('obs-store')
|
||||
const normalizeAddress = require('eth-sig-util').normalize
|
||||
|
||||
class PreferencesController {
|
||||
|
||||
constructor (opts = {}) {
|
||||
const initState = opts.initState || {}
|
||||
this.store = new ObservableStore(initState)
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC METHODS
|
||||
//
|
||||
|
||||
setSelectedAddress(_address) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const address = normalizeAddress(_address)
|
||||
this.store.updateState({ selectedAddress: address })
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
||||
getSelectedAddress(_address) {
|
||||
return this.store.getState().selectedAddress
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE METHODS
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
module.exports = PreferencesController
|
@ -11,10 +11,10 @@ const streamIntoProvider = require('web3-stream-provider/handler')
|
||||
const MetaMaskProvider = require('web3-provider-engine/zero.js')
|
||||
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
||||
const KeyringController = require('./keyring-controller')
|
||||
const PreferencesController = require('./lib/controllers/preferences')
|
||||
const CurrencyController = require('./lib/controllers/currency')
|
||||
const PreferencesController = require('./controllers/preferences')
|
||||
const CurrencyController = require('./controllers/currency')
|
||||
const NoticeController = require('./notice-controller')
|
||||
const ShapeShiftController = require('./lib/controllers/shapeshift')
|
||||
const ShapeShiftController = require('./controllers/shapeshift')
|
||||
const MessageManager = require('./lib/message-manager')
|
||||
const PersonalMessageManager = require('./lib/personal-message-manager')
|
||||
const TxManager = require('./transaction-manager')
|
||||
@ -244,7 +244,6 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
return {
|
||||
// etc
|
||||
getState: (cb) => cb(null, this.getState()),
|
||||
setRpcTarget: this.setRpcTarget.bind(this),
|
||||
setProviderType: this.setProviderType.bind(this),
|
||||
useEtherscanProvider: this.useEtherscanProvider.bind(this),
|
||||
setCurrentCurrency: this.setCurrentCurrency.bind(this),
|
||||
@ -265,6 +264,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
|
||||
// PreferencesController
|
||||
setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController),
|
||||
setDefaultRpc: nodeify(this.setDefaultRpc).bind(this),
|
||||
setCustomRpc: nodeify(this.setCustomRpc).bind(this),
|
||||
|
||||
// KeyringController
|
||||
setLocked: nodeify(keyringController.setLocked).bind(keyringController),
|
||||
@ -661,10 +662,21 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
if (this.isNetworkLoading()) this.lookupNetwork()
|
||||
}
|
||||
|
||||
setRpcTarget (rpcTarget) {
|
||||
this.configManager.setRpcTarget(rpcTarget)
|
||||
setDefaultRpc () {
|
||||
this.configManager.setRpcTarget('http://localhost:8545')
|
||||
extension.runtime.reload()
|
||||
this.lookupNetwork()
|
||||
return Promise.resolve('http://localhost:8545')
|
||||
}
|
||||
|
||||
setCustomRpc (rpcTarget, rpcList) {
|
||||
this.configManager.setRpcTarget(rpcTarget)
|
||||
return this.preferencesController.updateFrequentRpcList(rpcTarget)
|
||||
.then(() => {
|
||||
extension.runtime.reload()
|
||||
this.lookupNetwork()
|
||||
return Promise.resolve(rpcTarget)
|
||||
})
|
||||
}
|
||||
|
||||
setProviderType (type) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
"isUnlocked": false,
|
||||
"rpcTarget": "https://rawtestrpc.metamask.io/",
|
||||
"identities": {},
|
||||
"frequentRpcList": [],
|
||||
"unapprovedTxs": {},
|
||||
"currentFiat": "USD",
|
||||
"conversionRate": 12.7527416,
|
||||
|
@ -11,6 +11,7 @@ describe ('config view actions', function() {
|
||||
var initialState = {
|
||||
metamask: {
|
||||
rpcTarget: 'foo',
|
||||
frequentRpcList: []
|
||||
},
|
||||
appState: {
|
||||
currentView: {
|
||||
@ -32,13 +33,13 @@ describe ('config view actions', function() {
|
||||
it('sets the state.metamask.rpcTarget property of the state to the action.value', function() {
|
||||
const action = {
|
||||
type: actions.SET_RPC_TARGET,
|
||||
value: 'bar',
|
||||
value: 'foo',
|
||||
}
|
||||
|
||||
var result = reducers(initialState, action)
|
||||
assert.equal(result.metamask.provider.type, 'rpc')
|
||||
assert.equal(result.metamask.provider.rpcTarget, action.value)
|
||||
assert.equal(result.metamask.provider.rpcTarget, 'foo')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
@ -5,7 +5,7 @@ const assert = require('assert')
|
||||
const extend = require('xtend')
|
||||
const rp = require('request-promise')
|
||||
const nock = require('nock')
|
||||
const CurrencyController = require('../../app/scripts/lib/controllers/currency')
|
||||
const CurrencyController = require('../../app/scripts/controllers/currency')
|
||||
|
||||
describe('config-manager', function() {
|
||||
var currencyController
|
||||
|
@ -4,7 +4,7 @@ const rp = require('request-promise')
|
||||
const nock = require('nock')
|
||||
const configManagerGen = require('../lib/mock-config-manager')
|
||||
const NoticeController = require('../../app/scripts/notice-controller')
|
||||
const STORAGE_KEY = 'metamask-persistance-key'
|
||||
const STORAGE_KEY = 'metamask-persistence-key'
|
||||
|
||||
describe('notice-controller', function() {
|
||||
var noticeController
|
||||
|
@ -112,11 +112,13 @@ var actions = {
|
||||
// config screen
|
||||
SHOW_CONFIG_PAGE: 'SHOW_CONFIG_PAGE',
|
||||
SET_RPC_TARGET: 'SET_RPC_TARGET',
|
||||
SET_DEFAULT_RPC_TARGET: 'SET_DEFAULT_RPC_TARGET',
|
||||
SET_PROVIDER_TYPE: 'SET_PROVIDER_TYPE',
|
||||
USE_ETHERSCAN_PROVIDER: 'USE_ETHERSCAN_PROVIDER',
|
||||
useEtherscanProvider: useEtherscanProvider,
|
||||
showConfigPage: showConfigPage,
|
||||
setRpcTarget: setRpcTarget,
|
||||
setDefaultRpcTarget: setDefaultRpcTarget,
|
||||
setProviderType: setProviderType,
|
||||
// loading overlay
|
||||
SHOW_LOADING: 'SHOW_LOADING_INDICATION',
|
||||
@ -669,12 +671,28 @@ function markAccountsFound() {
|
||||
// config
|
||||
//
|
||||
|
||||
// default rpc target refers to localhost:8545 in this instance.
|
||||
function setDefaultRpcTarget (rpcList) {
|
||||
log.debug(`background.setDefaultRpcTarget`)
|
||||
return (dispatch) => {
|
||||
background.setDefaultRpc((err, result) => {
|
||||
if (err) {
|
||||
log.error(err)
|
||||
return dispatch(self.displayWarning('Had a problem changing networks.'))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function setRpcTarget (newRpc) {
|
||||
log.debug(`background.setRpcTarget`)
|
||||
background.setRpcTarget(newRpc)
|
||||
return {
|
||||
type: actions.SET_RPC_TARGET,
|
||||
value: newRpc,
|
||||
return (dispatch) => {
|
||||
background.setCustomRpc(newRpc, (err, result) => {
|
||||
if (err) {
|
||||
log.error(err)
|
||||
return dispatch(self.displayWarning('Had a problem changing networks!'))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,7 +768,7 @@ function exportAccount (address) {
|
||||
dispatch(self.hideLoadingIndication())
|
||||
|
||||
if (err) {
|
||||
console.error(err)
|
||||
log.error(err)
|
||||
return dispatch(self.displayWarning('Had a problem exporting the account.'))
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ function mapStateToProps (state) {
|
||||
forgottenPassword: state.appState.forgottenPassword,
|
||||
lastUnreadNotice: state.metamask.lastUnreadNotice,
|
||||
lostAccounts: state.metamask.lostAccounts,
|
||||
frequentRpcList: state.metamask.frequentRpcList || [],
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,6 +212,7 @@ App.prototype.renderAppBar = function () {
|
||||
|
||||
App.prototype.renderNetworkDropdown = function () {
|
||||
const props = this.props
|
||||
const rpcList = props.frequentRpcList
|
||||
const state = this.state || {}
|
||||
const isOpen = state.isNetworkMenuOpen
|
||||
|
||||
@ -256,12 +258,13 @@ App.prototype.renderNetworkDropdown = function () {
|
||||
h(DropMenuItem, {
|
||||
label: 'Localhost 8545',
|
||||
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
||||
action: () => props.dispatch(actions.setRpcTarget('http://localhost:8545')),
|
||||
action: () => props.dispatch(actions.setDefaultRpcTarget(rpcList)),
|
||||
icon: h('i.fa.fa-question-circle.fa-lg'),
|
||||
activeNetworkRender: props.provider.rpcTarget,
|
||||
}),
|
||||
|
||||
this.renderCustomOption(props.provider),
|
||||
this.renderCommonRpc(rpcList, props.provider),
|
||||
|
||||
props.isUnlocked && h(DropMenuItem, {
|
||||
label: 'Custom RPC',
|
||||
@ -496,6 +499,12 @@ App.prototype.renderCustomOption = function (provider) {
|
||||
const { rpcTarget, type } = provider
|
||||
if (type !== 'rpc') return null
|
||||
|
||||
// Concatenate long URLs
|
||||
let label = rpcTarget
|
||||
if (rpcTarget.length > 31) {
|
||||
label = label.substr(0, 34) + '...'
|
||||
}
|
||||
|
||||
switch (rpcTarget) {
|
||||
|
||||
case 'http://localhost:8545':
|
||||
@ -503,10 +512,32 @@ App.prototype.renderCustomOption = function (provider) {
|
||||
|
||||
default:
|
||||
return h(DropMenuItem, {
|
||||
label: `${rpcTarget}`,
|
||||
label,
|
||||
key: rpcTarget,
|
||||
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
||||
icon: h('i.fa.fa-question-circle.fa-lg'),
|
||||
activeNetworkRender: 'custom',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
App.prototype.renderCommonRpc = function (rpcList, provider) {
|
||||
const { rpcTarget } = provider
|
||||
const props = this.props
|
||||
|
||||
return rpcList.map((rpc) => {
|
||||
if ((rpc === 'http://localhost:8545') || (rpc === rpcTarget)) {
|
||||
return null
|
||||
} else {
|
||||
return h(DropMenuItem, {
|
||||
label: rpc,
|
||||
key: rpc,
|
||||
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
||||
action: () => props.dispatch(actions.setRpcTarget(rpc)),
|
||||
icon: h('i.fa.fa-question-circle.fa-lg'),
|
||||
activeNetworkRender: rpc,
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ const connect = require('react-redux').connect
|
||||
const actions = require('./actions')
|
||||
const currencies = require('./conversion.json').rows
|
||||
const validUrl = require('valid-url')
|
||||
|
||||
module.exports = connect(mapStateToProps)(ConfigScreen)
|
||||
|
||||
function mapStateToProps (state) {
|
||||
|
@ -18,6 +18,7 @@ function reduceMetamask (state, action) {
|
||||
conversionDate: 'N/A',
|
||||
noActiveNotices: true,
|
||||
lastUnreadNotice: undefined,
|
||||
frequentRpcList: [],
|
||||
}, state.metamask)
|
||||
|
||||
switch (action.type) {
|
||||
@ -53,6 +54,11 @@ function reduceMetamask (state, action) {
|
||||
isUnlocked: false,
|
||||
})
|
||||
|
||||
case actions.SET_RPC_LIST:
|
||||
return extend(metamaskState, {
|
||||
frequentRpcList: action.value,
|
||||
})
|
||||
|
||||
case actions.SET_RPC_TARGET:
|
||||
return extend(metamaskState, {
|
||||
provider: {
|
||||
|
Loading…
Reference in New Issue
Block a user