diff options
author | kumavis <kumavis@users.noreply.github.com> | 2017-05-24 08:57:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-24 08:57:58 +0800 |
commit | e8288ad4bfaa5b65b23f0a03d0c036457a24893f (patch) | |
tree | b1ed4d382b3008fe3271b0c10a8f6dab41b6ee9f /app/scripts/controllers | |
parent | 9c316664de2eb82bdd10ab9cd6fa0a33f5185e20 (diff) | |
parent | 97ea7454b353acb8f87dac087eeae61f945325d7 (diff) | |
download | tangerine-wallet-browser-e8288ad4bfaa5b65b23f0a03d0c036457a24893f.tar tangerine-wallet-browser-e8288ad4bfaa5b65b23f0a03d0c036457a24893f.tar.gz tangerine-wallet-browser-e8288ad4bfaa5b65b23f0a03d0c036457a24893f.tar.bz2 tangerine-wallet-browser-e8288ad4bfaa5b65b23f0a03d0c036457a24893f.tar.lz tangerine-wallet-browser-e8288ad4bfaa5b65b23f0a03d0c036457a24893f.tar.xz tangerine-wallet-browser-e8288ad4bfaa5b65b23f0a03d0c036457a24893f.tar.zst tangerine-wallet-browser-e8288ad4bfaa5b65b23f0a03d0c036457a24893f.zip |
Merge pull request #1455 from MetaMask/networkController
Create a network controller to manage switching networks an updating t…
Diffstat (limited to 'app/scripts/controllers')
-rw-r--r-- | app/scripts/controllers/network.js | 128 | ||||
-rw-r--r-- | app/scripts/controllers/transactions.js | 7 |
2 files changed, 131 insertions, 4 deletions
diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js new file mode 100644 index 000000000..4fdd92921 --- /dev/null +++ b/app/scripts/controllers/network.js @@ -0,0 +1,128 @@ +const EventEmitter = require('events') +const MetaMaskProvider = require('web3-provider-engine/zero.js') +const ObservableStore = require('obs-store') +const ComposedStore = require('obs-store/lib/composed') +const extend = require('xtend') +const EthQuery = require('eth-query') +const RPC_ADDRESS_LIST = require('../config.js').network +const DEFAULT_RPC = RPC_ADDRESS_LIST['rinkeby'] + +module.exports = class NetworkController extends EventEmitter { + constructor (config) { + super() + this.networkStore = new ObservableStore('loading') + config.provider.rpcTarget = this.getRpcAddressForType(config.provider.type, config.provider) + this.providerStore = new ObservableStore(config.provider) + this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore }) + this._providerListeners = {} + + this.on('networkDidChange', this.lookupNetwork) + this.providerStore.subscribe((state) => this.switchNetwork({rpcUrl: state.rpcTarget})) + } + + get provider () { + return this._proxy + } + + set provider (provider) { + this._provider = provider + } + + initializeProvider (opts) { + this.providerInit = 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.lookupNetwork() + return this.provider + } + + switchNetwork (providerInit) { + this.setNetworkState('loading') + const newInit = extend(this.providerInit, providerInit) + this.providerInit = newInit + + this._provider.removeAllListeners() + this.provider = MetaMaskProvider(newInit) + // apply the listners created by other controllers + Object.keys(this._providerListeners).forEach((key) => { + this._providerListeners[key].forEach((handler) => this._provider.addListener(key, handler)) + }) + this.emit('networkDidChange') + } + + + verifyNetwork () { + // Check network when restoring connectivity: + if (this.isNetworkLoading()) this.lookupNetwork() + } + + getNetworkState () { + return this.networkStore.getState() + } + + setNetworkState (network) { + return this.networkStore.putState(network) + } + + isNetworkLoading () { + return this.getNetworkState() === 'loading' + } + + lookupNetwork () { + this.ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { + if (err) return this.setNetworkState('loading') + log.info('web3.getNetwork returned ' + network) + this.setNetworkState(network) + }) + } + + setRpcTarget (rpcUrl) { + this.providerStore.updateState({ + type: 'rpc', + rpcTarget: rpcUrl, + }) + } + + getCurrentRpcAddress () { + const provider = this.getProviderConfig() + if (!provider) return null + return this.getRpcAddressForType(provider.type) + } + + setProviderType (type) { + if (type === this.getProviderConfig().type) return + const rpcTarget = this.getRpcAddressForType(type) + this.providerStore.updateState({type, rpcTarget}) + } + + getProviderConfig () { + return this.providerStore.getState() + } + + getRpcAddressForType (type, provider = this.getProviderConfig()) { + if (RPC_ADDRESS_LIST[type]) return RPC_ADDRESS_LIST[type] + return provider && provider.rpcTarget ? provider.rpcTarget : DEFAULT_RPC + } + + _logBlock (block) { + log.info(`BLOCK CHANGED: #${block.number.toString('hex')} 0x${block.hash.toString('hex')}`) + this.verifyNetwork() + } + + _on (event, handler) { + if (!this._providerListeners[event]) this._providerListeners[event] = [] + this._providerListeners[event].push(handler) + this._provider.on(event, handler) + } +} diff --git a/app/scripts/controllers/transactions.js b/app/scripts/controllers/transactions.js index 4d3197cba..faccf1ab1 100644 --- a/app/scripts/controllers/transactions.js +++ b/app/scripts/controllers/transactions.js @@ -4,7 +4,6 @@ const extend = require('xtend') const Semaphore = require('semaphore') const ObservableStore = require('obs-store') const ethUtil = require('ethereumjs-util') -const EthQuery = require('eth-query') const TxProviderUtil = require('../lib/tx-utils') const createId = require('../lib/random-id') const denodeify = require('denodeify') @@ -24,8 +23,8 @@ module.exports = class TransactionController extends EventEmitter { this.txHistoryLimit = opts.txHistoryLimit this.provider = opts.provider this.blockTracker = opts.blockTracker - this.query = new EthQuery(this.provider) - this.txProviderUtils = new TxProviderUtil(this.provider) + this.query = opts.ethQuery + this.txProviderUtils = new TxProviderUtil(this.query) this.blockTracker.on('block', this.checkForTxInBlock.bind(this)) this.signEthTx = opts.signTransaction this.nonceLock = Semaphore(1) @@ -44,7 +43,7 @@ module.exports = class TransactionController extends EventEmitter { } getNetwork () { - return this.networkStore.getState().network + return this.networkStore.getState() } getSelectedAddress () { |