Wrap the provider in a proxy

feature/default_network_editable
frankiebee 8 years ago
parent e08c1541e5
commit 529304c005
  1. 110
      app/scripts/controllers/network.js
  2. 27
      app/scripts/controllers/transactions.js
  3. 6
      app/scripts/keyring-controller.js
  4. 5
      app/scripts/lib/config-manager.js
  5. 42
      app/scripts/metamask-controller.js

@ -3,21 +3,29 @@ const MetaMaskProvider = require('web3-provider-engine/zero.js')
const ObservableStore = require('obs-store') const ObservableStore = require('obs-store')
const extend = require('xtend') const extend = require('xtend')
const EthQuery = require('eth-query') const EthQuery = require('eth-query')
const MetamaskConfig = require('../config.js') const RPC_ADDRESS_LIST = require('../config.js').network
const TESTNET_RPC = MetamaskConfig.network.testnet
const MAINNET_RPC = MetamaskConfig.network.mainnet
const MORDEN_RPC = MetamaskConfig.network.morden
const KOVAN_RPC = MetamaskConfig.network.kovan
const RINKEBY_RPC = MetamaskConfig.network.rinkeby
module.exports = class NetworkController extends EventEmitter { module.exports = class NetworkController extends EventEmitter {
constructor (providerOpts) { constructor (providerOpts) {
super() super()
this.networkStore = new ObservableStore({ network: 'loading' }) this.networkStore = new ObservableStore({ network: 'loading' })
providerOpts.provider.rpcTarget = this.getRpcAddressForType(providerOpts.provider.type) providerOpts.provider.rpcTarget = this.getRpcAddressForType(providerOpts.provider.type, providerOpts.provider)
this.providerStore = new ObservableStore(providerOpts) this.providerStore = new ObservableStore(providerOpts)
this._claimed = 0 this.store = new ObservableStore(extend(this.networkStore.getState(), this.providerStore.getState()))
this._providerListners = {}
this.networkStore.subscribe((state) => this.store.updateState(state))
this.providerStore.subscribe((state) => this.store.updateState(state))
this.on('networkSwitch', this.lookupNetwork)
}
get provider () {
return this._proxy
}
set provider (provider) {
this._provider = provider
} }
getState () { getState () {
@ -29,28 +37,35 @@ module.exports = class NetworkController extends EventEmitter {
initializeProvider (opts) { initializeProvider (opts) {
this.providerConfig = opts this.providerConfig = opts
this.provider = MetaMaskProvider(opts) this._provider = MetaMaskProvider(opts)
this._proxy = new Proxy(this._provider, {
get: (obj, name) => {
if (name === 'on') return this._on.bind(this)
return this._provider[name]
},
set: (obj, name, value) => {
this._provider[name] = value
},
})
this.provider.on('block', this._logBlock.bind(this))
this.provider.on('error', this.verifyNetwork.bind(this))
this.ethQuery = new EthQuery(this.provider) this.ethQuery = new EthQuery(this.provider)
this.lookupNetwork() this.lookupNetwork()
return Promise.resolve(this.provider) return this.provider
} }
switchNetwork (providerConfig) { switchNetwork (providerConfig) {
delete this.provider
delete this.ethQuery
const newConfig = extend(this.providerConfig, providerConfig) const newConfig = extend(this.providerConfig, providerConfig)
this.providerConfig = newConfig this.providerConfig = newConfig
this.provider = MetaMaskProvider(newConfig) this.provider = MetaMaskProvider(newConfig)
this.ethQuery = new EthQuery(this.provider) // apply the listners created by other controllers
this.emit('networkSwitch', { Object.keys(this._providerListners).forEach((key) => {
provider: this.provider, this._providerListners[key].forEach((handler) => this._provider.addListener(key, handler))
ethQuery: this.ethQuery, })
}, this.claim.bind(this)) this.emit('networkSwitch', this.provider)
} }
subscribe (cb) {
this.networkStore.subscribe(cb)
this.providerStore.subscribe(cb)
}
verifyNetwork () { verifyNetwork () {
// Check network when restoring connectivity: // Check network when restoring connectivity:
@ -74,7 +89,6 @@ module.exports = class NetworkController extends EventEmitter {
this.ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { this.ethQuery.sendAsync({ method: 'net_version' }, (err, network) => {
if (err) return this.setNetworkState('loading') if (err) return this.setNetworkState('loading')
log.info('web3.getNetwork returned ' + network) log.info('web3.getNetwork returned ' + network)
this.setNetworkState(network) this.setNetworkState(network)
}) })
@ -102,51 +116,27 @@ module.exports = class NetworkController extends EventEmitter {
this.switchNetwork({ this.switchNetwork({
rpcUrl: rpcTarget, rpcUrl: rpcTarget,
}) })
this.once('claimed', () => { this.providerStore.updateState({provider: {type, rpcTarget}})
this.providerStore.updateState({provider: {type, rpcTarget}})
console.log('CLAIMED')
this.lookupNetwork()
})
}
useEtherscanProvider () {
this.setProviderType('etherscan')
} }
getProvider () { getProvider () {
return this.providerStore.getState().provider return this.providerStore.getState().provider
} }
getRpcAddressForType (type) { getRpcAddressForType (type, provider = this.getProvider()) {
const provider = this.getProvider() console.log(`#getRpcAddressForType: ${type}`)
switch (type) { if (type in RPC_ADDRESS_LIST) return RPC_ADDRESS_LIST[type]
return provider && provider.rpcTarget ? provider.rpcTarget : RPC_ADDRESS_LIST['rinkeby']
case 'mainnet': }
return MAINNET_RPC
case 'testnet':
return TESTNET_RPC
case 'morden':
return MORDEN_RPC
case 'kovan':
return KOVAN_RPC
case 'rinkeby':
return RINKEBY_RPC
default: _logBlock (block) {
return provider && provider.rpcTarget ? provider.rpcTarget : TESTNET_RPC log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`)
} this.verifyNetwork()
} }
claim () { _on (event, handler) {
this._claimed += 1 if (!this._providerListners[event]) this._providerListners[event] = []
if (this._claimed === this.listenerCount('networkSwitch')) { this._providerListners[event].push(handler)
this.emit('claimed') this._provider.on(event, handler)
this._claimed = 0
}
} }
} }

@ -4,7 +4,6 @@ const extend = require('xtend')
const Semaphore = require('semaphore') const Semaphore = require('semaphore')
const ObservableStore = require('obs-store') const ObservableStore = require('obs-store')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const EthQuery = require('eth-query')
const TxProviderUtil = require('../lib/tx-utils') const TxProviderUtil = require('../lib/tx-utils')
const createId = require('../lib/random-id') const createId = require('../lib/random-id')
@ -18,11 +17,13 @@ module.exports = class TransactionManager extends EventEmitter {
this.networkStore = opts.networkStore || new ObservableStore({}) this.networkStore = opts.networkStore || new ObservableStore({})
this.preferencesStore = opts.preferencesStore || new ObservableStore({}) this.preferencesStore = opts.preferencesStore || new ObservableStore({})
this.txHistoryLimit = opts.txHistoryLimit this.txHistoryLimit = opts.txHistoryLimit
this.setupProviderAndEthQuery({ this.provider = opts.provider
provider: opts.provider, this.blockTracker = opts.blockTracker
blockTracker: opts.blockTracker, this.query = opts.ethQuery
ethQuery: opts.ethQuery, this.txProviderUtils = new TxProviderUtil(this.query)
}) this.networkStore.subscribe((_) => this.blockTracker.on('block', this.checkForTxInBlock.bind(this)))
this.blockTracker.on('block', this.checkForTxInBlock.bind(this))
this.signEthTx = opts.signTransaction this.signEthTx = opts.signTransaction
this.nonceLock = Semaphore(1) this.nonceLock = Semaphore(1)
@ -41,20 +42,6 @@ module.exports = class TransactionManager extends EventEmitter {
return this.networkStore.getState().network return this.networkStore.getState().network
} }
setupProviderAndEthQuery ({provider, blockTracker, ethQuery}) {
if (this.provider) {
delete this.provider
delete this.blockTracker
delete this.query
delete this.txProviderUtils
}
this.provider = provider
this.query = ethQuery
this.txProviderUtils = new TxProviderUtil(ethQuery)
blockTracker ? this.blockTracker = blockTracker : this.blockTracker = provider
this.blockTracker.on('block', this.checkForTxInBlock.bind(this))
}
getSelectedAddress () { getSelectedAddress () {
return this.preferencesStore.getState().selectedAddress return this.preferencesStore.getState().selectedAddress
} }

@ -41,12 +41,6 @@ class KeyringController extends EventEmitter {
this.getNetwork = opts.getNetwork this.getNetwork = opts.getNetwork
} }
setEthStore (ethStore) {
delete this.ethStore
this.ethStore = ethStore
return this.setupAccounts()
}
// Full Update // Full Update
// returns Promise( @object state ) // returns Promise( @object state )
// //

@ -1,14 +1,13 @@
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const normalize = require('eth-sig-util').normalize const normalize = require('eth-sig-util').normalize
const MetamaskConfig = require('../config.js')
<<<<<<< HEAD
=======
const MAINNET_RPC = MetamaskConfig.network.mainnet const MAINNET_RPC = MetamaskConfig.network.mainnet
const ROPSTEN_RPC = MetamaskConfig.network.ropsten const ROPSTEN_RPC = MetamaskConfig.network.ropsten
const KOVAN_RPC = MetamaskConfig.network.kovan const KOVAN_RPC = MetamaskConfig.network.kovan
const RINKEBY_RPC = MetamaskConfig.network.rinkeby const RINKEBY_RPC = MetamaskConfig.network.rinkeby
>>>>>>> master
/* The config-manager is a convenience object /* The config-manager is a convenience object
* wrapping a pojo-migrator. * wrapping a pojo-migrator.
* *

@ -40,6 +40,7 @@ module.exports = class MetamaskController extends EventEmitter {
this.store = new ObservableStore(initState) this.store = new ObservableStore(initState)
// network store // network store
this.networkController = new NetworkController(initState.NetworkController) this.networkController = new NetworkController(initState.NetworkController)
// config manager // config manager
this.configManager = new ConfigManager({ this.configManager = new ConfigManager({
@ -60,12 +61,11 @@ module.exports = class MetamaskController extends EventEmitter {
// rpc provider // rpc provider
this.provider = this.initializeProvider() this.provider = this.initializeProvider()
this.provider.on('block', this.logBlock.bind(this))
this.provider.on('error', this.networkController.verifyNetwork.bind(this.networkController))
// eth data query tools // eth data query tools
this.ethQuery = new EthQuery(this.provider) this.ethQuery = new EthQuery(this.provider)
this.ethStore = new EthStore({ this.ethStore = new EthStore({
network: this.networkController.networkStore,
provider: this.provider, provider: this.provider,
blockTracker: this.provider, blockTracker: this.provider,
}) })
@ -111,32 +111,6 @@ module.exports = class MetamaskController extends EventEmitter {
this.shapeshiftController = new ShapeShiftController({ this.shapeshiftController = new ShapeShiftController({
initState: initState.ShapeShiftController, initState: initState.ShapeShiftController,
}) })
this.networkController.on('networkSwitch', (providerUtil, claimed) => {
delete this.provider
delete this.ethQuery
delete this.ethStore
console.log('order:@? 1')
this.provider = providerUtil.provider
this.provider.on('block', this.logBlock.bind(this))
this.provider.on('error', this.networkController.verifyNetwork.bind(this.networkController))
this.ethQuery = providerUtil.ethQuery
this.ethStore = new EthStore({
provider: this.provider,
blockTracker: this.provider,
})
this.provider.once('block', claimed)
})
this.networkController.on('networkSwitch', (_, claimed) => {
console.log('order:@? 2')
this.txManager.setupProviderAndEthQuery({
provider: this.provider,
blockTracker: this.provider,
ethQuery: this.ethQuery,
})
this.keyringController.setEthStore(this.ethStore)
.then(claimed)
})
this.networkController.lookupNetwork() this.networkController.lookupNetwork()
this.messageManager = new MessageManager() this.messageManager = new MessageManager()
@ -170,7 +144,7 @@ module.exports = class MetamaskController extends EventEmitter {
}) })
// manual mem state subscriptions // manual mem state subscriptions
this.networkController.subscribe(this.sendUpdate.bind(this)) this.networkController.store.subscribe(this.sendUpdate.bind(this))
this.ethStore.subscribe(this.sendUpdate.bind(this)) this.ethStore.subscribe(this.sendUpdate.bind(this))
this.txController.memStore.subscribe(this.sendUpdate.bind(this)) this.txController.memStore.subscribe(this.sendUpdate.bind(this))
this.messageManager.memStore.subscribe(this.sendUpdate.bind(this)) this.messageManager.memStore.subscribe(this.sendUpdate.bind(this))
@ -188,7 +162,7 @@ module.exports = class MetamaskController extends EventEmitter {
// //
initializeProvider () { initializeProvider () {
this.networkController.initializeProvider({ return this.networkController.initializeProvider({
static: { static: {
eth_syncing: false, eth_syncing: false,
web3_clientVersion: `MetaMask/v${version}`, web3_clientVersion: `MetaMask/v${version}`,
@ -213,7 +187,6 @@ module.exports = class MetamaskController extends EventEmitter {
// new style msg signing // new style msg signing
processPersonalMessage: this.newUnsignedPersonalMessage.bind(this), processPersonalMessage: this.newUnsignedPersonalMessage.bind(this),
}) })
return this.networkController.provider
} }
initPublicConfigStore () { initPublicConfigStore () {
@ -249,7 +222,7 @@ module.exports = class MetamaskController extends EventEmitter {
{ {
isInitialized, isInitialized,
}, },
this.networkController.getState(), this.networkController.store.getState(),
this.ethStore.getState(), this.ethStore.getState(),
this.txController.memStore.getState(), this.txController.memStore.getState(),
this.messageManager.memStore.getState(), this.messageManager.memStore.getState(),
@ -284,7 +257,6 @@ module.exports = class MetamaskController extends EventEmitter {
// etc // etc
getState: (cb) => cb(null, this.getState()), getState: (cb) => cb(null, this.getState()),
setProviderType: this.networkController.setProviderType.bind(this.networkController), setProviderType: this.networkController.setProviderType.bind(this.networkController),
useEtherscanProvider: this.networkController.useEtherscanProvider.bind(this.networkController),
setCurrentCurrency: this.setCurrentCurrency.bind(this), setCurrentCurrency: this.setCurrentCurrency.bind(this),
markAccountsFound: this.markAccountsFound.bind(this), markAccountsFound: this.markAccountsFound.bind(this),
// coinbase // coinbase
@ -618,10 +590,6 @@ module.exports = class MetamaskController extends EventEmitter {
// //
// Log blocks // Log blocks
logBlock (block) {
log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`)
this.networkController.verifyNetwork()
}
setCurrentCurrency (currencyCode, cb) { setCurrentCurrency (currencyCode, cb) {
try { try {

Loading…
Cancel
Save