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
|
## Current Master
|
||||||
|
|
||||||
|
|
||||||
|
- Add two most recently used custom RPCs to network dropdown menu.
|
||||||
- Add personal_sign method support.
|
- Add personal_sign method support.
|
||||||
- Add ability to customize gas and gasPrice on the transaction approval screen.
|
- Add ability to customize gas and gasPrice on the transaction approval screen.
|
||||||
- Increase default gas buffer to 1.5x estimated gas value.
|
- 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 MetaMaskProvider = require('web3-provider-engine/zero.js')
|
||||||
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
|
||||||
const KeyringController = require('./keyring-controller')
|
const KeyringController = require('./keyring-controller')
|
||||||
const PreferencesController = require('./lib/controllers/preferences')
|
const PreferencesController = require('./controllers/preferences')
|
||||||
const CurrencyController = require('./lib/controllers/currency')
|
const CurrencyController = require('./controllers/currency')
|
||||||
const NoticeController = require('./notice-controller')
|
const NoticeController = require('./notice-controller')
|
||||||
const ShapeShiftController = require('./lib/controllers/shapeshift')
|
const ShapeShiftController = require('./controllers/shapeshift')
|
||||||
const MessageManager = require('./lib/message-manager')
|
const MessageManager = require('./lib/message-manager')
|
||||||
const PersonalMessageManager = require('./lib/personal-message-manager')
|
const PersonalMessageManager = require('./lib/personal-message-manager')
|
||||||
const TxManager = require('./transaction-manager')
|
const TxManager = require('./transaction-manager')
|
||||||
@ -244,7 +244,6 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
return {
|
return {
|
||||||
// etc
|
// etc
|
||||||
getState: (cb) => cb(null, this.getState()),
|
getState: (cb) => cb(null, this.getState()),
|
||||||
setRpcTarget: this.setRpcTarget.bind(this),
|
|
||||||
setProviderType: this.setProviderType.bind(this),
|
setProviderType: this.setProviderType.bind(this),
|
||||||
useEtherscanProvider: this.useEtherscanProvider.bind(this),
|
useEtherscanProvider: this.useEtherscanProvider.bind(this),
|
||||||
setCurrentCurrency: this.setCurrentCurrency.bind(this),
|
setCurrentCurrency: this.setCurrentCurrency.bind(this),
|
||||||
@ -265,6 +264,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
|
|
||||||
// PreferencesController
|
// PreferencesController
|
||||||
setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController),
|
setSelectedAddress: nodeify(preferencesController.setSelectedAddress).bind(preferencesController),
|
||||||
|
setDefaultRpc: nodeify(this.setDefaultRpc).bind(this),
|
||||||
|
setCustomRpc: nodeify(this.setCustomRpc).bind(this),
|
||||||
|
|
||||||
// KeyringController
|
// KeyringController
|
||||||
setLocked: nodeify(keyringController.setLocked).bind(keyringController),
|
setLocked: nodeify(keyringController.setLocked).bind(keyringController),
|
||||||
@ -661,10 +662,21 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
if (this.isNetworkLoading()) this.lookupNetwork()
|
if (this.isNetworkLoading()) this.lookupNetwork()
|
||||||
}
|
}
|
||||||
|
|
||||||
setRpcTarget (rpcTarget) {
|
setDefaultRpc () {
|
||||||
this.configManager.setRpcTarget(rpcTarget)
|
this.configManager.setRpcTarget('http://localhost:8545')
|
||||||
extension.runtime.reload()
|
extension.runtime.reload()
|
||||||
this.lookupNetwork()
|
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) {
|
setProviderType (type) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
"isUnlocked": false,
|
"isUnlocked": false,
|
||||||
"rpcTarget": "https://rawtestrpc.metamask.io/",
|
"rpcTarget": "https://rawtestrpc.metamask.io/",
|
||||||
"identities": {},
|
"identities": {},
|
||||||
|
"frequentRpcList": [],
|
||||||
"unapprovedTxs": {},
|
"unapprovedTxs": {},
|
||||||
"currentFiat": "USD",
|
"currentFiat": "USD",
|
||||||
"conversionRate": 12.7527416,
|
"conversionRate": 12.7527416,
|
||||||
|
@ -11,6 +11,7 @@ describe ('config view actions', function() {
|
|||||||
var initialState = {
|
var initialState = {
|
||||||
metamask: {
|
metamask: {
|
||||||
rpcTarget: 'foo',
|
rpcTarget: 'foo',
|
||||||
|
frequentRpcList: []
|
||||||
},
|
},
|
||||||
appState: {
|
appState: {
|
||||||
currentView: {
|
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() {
|
it('sets the state.metamask.rpcTarget property of the state to the action.value', function() {
|
||||||
const action = {
|
const action = {
|
||||||
type: actions.SET_RPC_TARGET,
|
type: actions.SET_RPC_TARGET,
|
||||||
value: 'bar',
|
value: 'foo',
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = reducers(initialState, action)
|
var result = reducers(initialState, action)
|
||||||
assert.equal(result.metamask.provider.type, 'rpc')
|
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 extend = require('xtend')
|
||||||
const rp = require('request-promise')
|
const rp = require('request-promise')
|
||||||
const nock = require('nock')
|
const nock = require('nock')
|
||||||
const CurrencyController = require('../../app/scripts/lib/controllers/currency')
|
const CurrencyController = require('../../app/scripts/controllers/currency')
|
||||||
|
|
||||||
describe('config-manager', function() {
|
describe('config-manager', function() {
|
||||||
var currencyController
|
var currencyController
|
||||||
|
@ -4,7 +4,7 @@ const rp = require('request-promise')
|
|||||||
const nock = require('nock')
|
const nock = require('nock')
|
||||||
const configManagerGen = require('../lib/mock-config-manager')
|
const configManagerGen = require('../lib/mock-config-manager')
|
||||||
const NoticeController = require('../../app/scripts/notice-controller')
|
const NoticeController = require('../../app/scripts/notice-controller')
|
||||||
const STORAGE_KEY = 'metamask-persistance-key'
|
const STORAGE_KEY = 'metamask-persistence-key'
|
||||||
|
|
||||||
describe('notice-controller', function() {
|
describe('notice-controller', function() {
|
||||||
var noticeController
|
var noticeController
|
||||||
|
@ -112,11 +112,13 @@ var actions = {
|
|||||||
// config screen
|
// config screen
|
||||||
SHOW_CONFIG_PAGE: 'SHOW_CONFIG_PAGE',
|
SHOW_CONFIG_PAGE: 'SHOW_CONFIG_PAGE',
|
||||||
SET_RPC_TARGET: 'SET_RPC_TARGET',
|
SET_RPC_TARGET: 'SET_RPC_TARGET',
|
||||||
|
SET_DEFAULT_RPC_TARGET: 'SET_DEFAULT_RPC_TARGET',
|
||||||
SET_PROVIDER_TYPE: 'SET_PROVIDER_TYPE',
|
SET_PROVIDER_TYPE: 'SET_PROVIDER_TYPE',
|
||||||
USE_ETHERSCAN_PROVIDER: 'USE_ETHERSCAN_PROVIDER',
|
USE_ETHERSCAN_PROVIDER: 'USE_ETHERSCAN_PROVIDER',
|
||||||
useEtherscanProvider: useEtherscanProvider,
|
useEtherscanProvider: useEtherscanProvider,
|
||||||
showConfigPage: showConfigPage,
|
showConfigPage: showConfigPage,
|
||||||
setRpcTarget: setRpcTarget,
|
setRpcTarget: setRpcTarget,
|
||||||
|
setDefaultRpcTarget: setDefaultRpcTarget,
|
||||||
setProviderType: setProviderType,
|
setProviderType: setProviderType,
|
||||||
// loading overlay
|
// loading overlay
|
||||||
SHOW_LOADING: 'SHOW_LOADING_INDICATION',
|
SHOW_LOADING: 'SHOW_LOADING_INDICATION',
|
||||||
@ -669,12 +671,28 @@ function markAccountsFound() {
|
|||||||
// config
|
// 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) {
|
function setRpcTarget (newRpc) {
|
||||||
log.debug(`background.setRpcTarget`)
|
log.debug(`background.setRpcTarget`)
|
||||||
background.setRpcTarget(newRpc)
|
return (dispatch) => {
|
||||||
return {
|
background.setCustomRpc(newRpc, (err, result) => {
|
||||||
type: actions.SET_RPC_TARGET,
|
if (err) {
|
||||||
value: newRpc,
|
log.error(err)
|
||||||
|
return dispatch(self.displayWarning('Had a problem changing networks!'))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,7 +768,7 @@ function exportAccount (address) {
|
|||||||
dispatch(self.hideLoadingIndication())
|
dispatch(self.hideLoadingIndication())
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err)
|
log.error(err)
|
||||||
return dispatch(self.displayWarning('Had a problem exporting the account.'))
|
return dispatch(self.displayWarning('Had a problem exporting the account.'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ function mapStateToProps (state) {
|
|||||||
forgottenPassword: state.appState.forgottenPassword,
|
forgottenPassword: state.appState.forgottenPassword,
|
||||||
lastUnreadNotice: state.metamask.lastUnreadNotice,
|
lastUnreadNotice: state.metamask.lastUnreadNotice,
|
||||||
lostAccounts: state.metamask.lostAccounts,
|
lostAccounts: state.metamask.lostAccounts,
|
||||||
|
frequentRpcList: state.metamask.frequentRpcList || [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,6 +212,7 @@ App.prototype.renderAppBar = function () {
|
|||||||
|
|
||||||
App.prototype.renderNetworkDropdown = function () {
|
App.prototype.renderNetworkDropdown = function () {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
|
const rpcList = props.frequentRpcList
|
||||||
const state = this.state || {}
|
const state = this.state || {}
|
||||||
const isOpen = state.isNetworkMenuOpen
|
const isOpen = state.isNetworkMenuOpen
|
||||||
|
|
||||||
@ -256,12 +258,13 @@ App.prototype.renderNetworkDropdown = function () {
|
|||||||
h(DropMenuItem, {
|
h(DropMenuItem, {
|
||||||
label: 'Localhost 8545',
|
label: 'Localhost 8545',
|
||||||
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
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'),
|
icon: h('i.fa.fa-question-circle.fa-lg'),
|
||||||
activeNetworkRender: props.provider.rpcTarget,
|
activeNetworkRender: props.provider.rpcTarget,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
this.renderCustomOption(props.provider),
|
this.renderCustomOption(props.provider),
|
||||||
|
this.renderCommonRpc(rpcList, props.provider),
|
||||||
|
|
||||||
props.isUnlocked && h(DropMenuItem, {
|
props.isUnlocked && h(DropMenuItem, {
|
||||||
label: 'Custom RPC',
|
label: 'Custom RPC',
|
||||||
@ -496,6 +499,12 @@ App.prototype.renderCustomOption = function (provider) {
|
|||||||
const { rpcTarget, type } = provider
|
const { rpcTarget, type } = provider
|
||||||
if (type !== 'rpc') return null
|
if (type !== 'rpc') return null
|
||||||
|
|
||||||
|
// Concatenate long URLs
|
||||||
|
let label = rpcTarget
|
||||||
|
if (rpcTarget.length > 31) {
|
||||||
|
label = label.substr(0, 34) + '...'
|
||||||
|
}
|
||||||
|
|
||||||
switch (rpcTarget) {
|
switch (rpcTarget) {
|
||||||
|
|
||||||
case 'http://localhost:8545':
|
case 'http://localhost:8545':
|
||||||
@ -503,10 +512,32 @@ App.prototype.renderCustomOption = function (provider) {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
return h(DropMenuItem, {
|
return h(DropMenuItem, {
|
||||||
label: `${rpcTarget}`,
|
label,
|
||||||
|
key: rpcTarget,
|
||||||
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
|
||||||
icon: h('i.fa.fa-question-circle.fa-lg'),
|
icon: h('i.fa.fa-question-circle.fa-lg'),
|
||||||
activeNetworkRender: 'custom',
|
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 actions = require('./actions')
|
||||||
const currencies = require('./conversion.json').rows
|
const currencies = require('./conversion.json').rows
|
||||||
const validUrl = require('valid-url')
|
const validUrl = require('valid-url')
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(ConfigScreen)
|
module.exports = connect(mapStateToProps)(ConfigScreen)
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
|
@ -18,6 +18,7 @@ function reduceMetamask (state, action) {
|
|||||||
conversionDate: 'N/A',
|
conversionDate: 'N/A',
|
||||||
noActiveNotices: true,
|
noActiveNotices: true,
|
||||||
lastUnreadNotice: undefined,
|
lastUnreadNotice: undefined,
|
||||||
|
frequentRpcList: [],
|
||||||
}, state.metamask)
|
}, state.metamask)
|
||||||
|
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
@ -53,6 +54,11 @@ function reduceMetamask (state, action) {
|
|||||||
isUnlocked: false,
|
isUnlocked: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
case actions.SET_RPC_LIST:
|
||||||
|
return extend(metamaskState, {
|
||||||
|
frequentRpcList: action.value,
|
||||||
|
})
|
||||||
|
|
||||||
case actions.SET_RPC_TARGET:
|
case actions.SET_RPC_TARGET:
|
||||||
return extend(metamaskState, {
|
return extend(metamaskState, {
|
||||||
provider: {
|
provider: {
|
||||||
|
Loading…
Reference in New Issue
Block a user