diff options
Diffstat (limited to 'app/scripts/controllers')
-rw-r--r-- | app/scripts/controllers/network.js | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js new file mode 100644 index 000000000..82eabb573 --- /dev/null +++ b/app/scripts/controllers/network.js @@ -0,0 +1,152 @@ +const EventEmitter = require('events') +const MetaMaskProvider = require('web3-provider-engine/zero.js') +const ObservableStore = require('obs-store') +const extend = require('xtend') +const EthQuery = require('eth-query') +const MetamaskConfig = require('../config.js') + +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 { + constructor (providerOpts) { + super() + this.networkStore = new ObservableStore({ network: 'loading' }) + providerOpts.provider.rpcTarget = this.getRpcAddressForType(providerOpts.provider.type) + this.providerStore = new ObservableStore(providerOpts) + this._claimed = 0 + } + + getState () { + return extend({}, + this.networkStore.getState(), + this.providerStore.getState() + ) + } + + initializeProvider (opts) { + this.providerConfig = opts + this.provider = MetaMaskProvider(opts) + this.ethQuery = new EthQuery(this.provider) + this.lookupNetwork() + return Promise.resolve(this.provider) + } + switchNetwork (providerConfig) { + delete this.provider + delete this.ethQuery + const newConfig = extend(this.providerConfig, providerConfig) + this.providerConfig = newConfig + this.provider = MetaMaskProvider(newConfig) + this.ethQuery = new EthQuery(this.provider) + this.emit('networkSwitch', { + provider: this.provider, + ethQuery: this.ethQuery, + }, this.claim.bind(this)) + } + + subscribe (cb) { + this.networkStore.subscribe(cb) + this.providerStore.subscribe(cb) + } + + verifyNetwork () { + // Check network when restoring connectivity: + if (this.isNetworkLoading()) this.lookupNetwork() + } + + getNetworkState () { + return this.networkStore.getState().network + } + + setNetworkState (network) { + return this.networkStore.updateState({ network }) + } + + isNetworkLoading () { + return this.getNetworkState() === 'loading' + } + + lookupNetwork (err) { + if (err) this.setNetworkState('loading') + + 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({ + provider: { + type: 'rpc', + rpcTarget: rpcUrl, + }, + }) + } + + getCurrentRpcAddress () { + var provider = this.getProvider() + if (!provider) return null + return this.getRpcAddressForType(provider.type) + } + + setProviderType (type) { + if (type === this.getProvider().type) return + const rpcTarget = this.getRpcAddressForType(type) + this.networkStore.updateState({network: 'loading'}) + this.switchNetwork({ + rpcUrl: rpcTarget, + }) + this.once('claimed', () => { + this.providerStore.updateState({provider: {type, rpcTarget}}) + console.log('CLAIMED') + this.lookupNetwork() + }) + + } + + useEtherscanProvider () { + this.setProviderType('etherscan') + } + + getProvider () { + return this.providerStore.getState().provider + } + + getRpcAddressForType (type) { + const provider = this.getProvider() + switch (type) { + + 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: + return provider && provider.rpcTarget ? provider.rpcTarget : TESTNET_RPC + } + } + + claim () { + this._claimed += 1 + if (this._claimed === this.listenerCount('networkSwitch')) { + this.emit('claimed') + this._claimed = 0 + } + } +} |