diff --git a/app/scripts/config.js b/app/scripts/config.js index 1d4ff7c0d..74c5b576e 100644 --- a/app/scripts/config.js +++ b/app/scripts/config.js @@ -4,6 +4,15 @@ const KOVAN_RPC_URL = 'https://kovan.infura.io/metamask' const RINKEBY_RPC_URL = 'https://rinkeby.infura.io/metamask' const LOCALHOST_RPC_URL = 'http://localhost:8545' +const MAINET_RPC_URL_BETA = 'https://mainnet.infura.io/metamask2' +const ROPSTEN_RPC_URL_BETA = 'https://ropsten.infura.io/metamask2' +const KOVAN_RPC_URL_BETA = 'https://kovan.infura.io/metamask2' +const RINKEBY_RPC_URL_BETA = 'https://rinkeby.infura.io/metamask2' + +const DEFAULT_RPC = 'rinkeby' +const OLD_UI_NETWORK_TYPE = 'network' +const BETA_UI_NETWORK_TYPE = 'networkBeta' + global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG' module.exports = { @@ -14,9 +23,22 @@ module.exports = { kovan: KOVAN_RPC_URL, rinkeby: RINKEBY_RPC_URL, }, + // Used for beta UI + networkBeta: { + localhost: LOCALHOST_RPC_URL, + mainnet: MAINET_RPC_URL_BETA, + ropsten: ROPSTEN_RPC_URL_BETA, + kovan: KOVAN_RPC_URL_BETA, + rinkeby: RINKEBY_RPC_URL_BETA, + }, networkNames: { 3: 'Ropsten', 4: 'Rinkeby', 42: 'Kovan', }, + enums: { + DEFAULT_RPC, + OLD_UI_NETWORK_TYPE, + BETA_UI_NETWORK_TYPE, + }, } diff --git a/app/scripts/controllers/network.js b/app/scripts/controllers/network.js index 377ba6eca..db1a5b374 100644 --- a/app/scripts/controllers/network.js +++ b/app/scripts/controllers/network.js @@ -7,14 +7,19 @@ const ComposedStore = require('obs-store/lib/composed') const extend = require('xtend') const EthQuery = require('eth-query') const createEventEmitterProxy = require('../lib/events-proxy.js') -const RPC_ADDRESS_LIST = require('../config.js').network -const DEFAULT_RPC = RPC_ADDRESS_LIST['rinkeby'] +const networkConfig = require('../config.js') +const { OLD_UI_NETWORK_TYPE, DEFAULT_RPC } = networkConfig.enums const INFURA_PROVIDER_TYPES = ['ropsten', 'rinkeby', 'kovan', 'mainnet'] module.exports = class NetworkController extends EventEmitter { constructor (config) { super() + + this._networkEndpointVersion = OLD_UI_NETWORK_TYPE + this._networkEndpoints = this.getNetworkEndpoints(OLD_UI_NETWORK_TYPE) + this._defaultRpc = this._networkEndpoints[DEFAULT_RPC] + config.provider.rpcTarget = this.getRpcAddressForType(config.provider.type, config.provider) this.networkStore = new ObservableStore('loading') this.providerStore = new ObservableStore(config.provider) @@ -24,6 +29,23 @@ module.exports = class NetworkController extends EventEmitter { this.on('networkDidChange', this.lookupNetwork) } + async setNetworkEndpoints (version) { + if (version === this._networkEndpointVersion) { + return + } + + this._networkEndpointVersion = version + this._networkEndpoints = this.getNetworkEndpoints(version) + this._defaultRpc = this._networkEndpoints[DEFAULT_RPC] + const { type } = this.getProviderConfig() + + return this.setProviderType(type, true) + } + + getNetworkEndpoints (version = OLD_UI_NETWORK_TYPE) { + return networkConfig[version] + } + initializeProvider (_providerParams) { this._baseProviderParams = _providerParams const { type, rpcTarget } = this.providerStore.getState() @@ -83,10 +105,13 @@ module.exports = class NetworkController extends EventEmitter { return this.getRpcAddressForType(provider.type) } - async setProviderType (type) { + async setProviderType (type, forceUpdate = false) { assert(type !== 'rpc', `NetworkController.setProviderType - cannot connect by type "rpc"`) // skip if type already matches - if (type === this.getProviderConfig().type) return + if (type === this.getProviderConfig().type && !forceUpdate) { + return + } + const rpcTarget = this.getRpcAddressForType(type) assert(rpcTarget, `NetworkController - unknown rpc address for type "${type}"`) this.providerStore.updateState({ type, rpcTarget }) @@ -98,8 +123,11 @@ module.exports = class NetworkController extends EventEmitter { } getRpcAddressForType (type, provider = this.getProviderConfig()) { - if (RPC_ADDRESS_LIST[type]) return RPC_ADDRESS_LIST[type] - return provider && provider.rpcTarget ? provider.rpcTarget : DEFAULT_RPC + if (this._networkEndpoints[type]) { + return this._networkEndpoints[type] + } + + return provider && provider.rpcTarget ? provider.rpcTarget : this._defaultRpc } // diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index e2a911598..b50a04703 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -353,6 +353,7 @@ module.exports = class MetamaskController extends EventEmitter { submitPassword: nodeify(keyringController.submitPassword, keyringController), // network management + setNetworkEndpoints: nodeify(networkController.setNetworkEndpoints, networkController), setProviderType: nodeify(networkController.setProviderType, networkController), setCustomRpc: nodeify(this.setCustomRpc, this), diff --git a/old-ui/app/app.js b/old-ui/app/app.js index 24649367b..4869bf72e 100644 --- a/old-ui/app/app.js +++ b/old-ui/app/app.js @@ -34,6 +34,7 @@ const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete') const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation') const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns +const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums module.exports = connect(mapStateToProps)(App) @@ -405,7 +406,10 @@ App.prototype.renderDropdown = function () { h(DropdownMenuItem, { closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }), - onClick: () => { this.props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')) }, + onClick: () => { + this.props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')) + .then(() => this.props.dispatch(actions.setNetworkEndpoints(BETA_UI_NETWORK_TYPE))) + }, }, 'Try Beta!'), ]) } diff --git a/ui/app/actions.js b/ui/app/actions.js index e8271c9a7..bd3aab45a 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -240,12 +240,17 @@ var actions = { SET_USE_BLOCKIE: 'SET_USE_BLOCKIE', setUseBlockie, - + // Feature Flags setFeatureFlag, updateFeatureFlags, UPDATE_FEATURE_FLAGS: 'UPDATE_FEATURE_FLAGS', - + + // Network + setNetworkEndpoints, + updateNetworkEndpointType, + UPDATE_NETWORK_ENDPOINT_TYPE: 'UPDATE_NETWORK_ENDPOINT_TYPE', + retryTransaction, } @@ -1489,7 +1494,7 @@ function reshowQrCode (data, coin) { dispatch(actions.showLoadingIndication()) shapeShiftRequest('marketinfo', {pair: `${coin.toLowerCase()}_eth`}, (mktResponse) => { if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error)) - + var message = [ `Deposit your ${coin} to the address bellow:`, `Deposit Limit: ${mktResponse.limit}`, @@ -1565,7 +1570,7 @@ function setFeatureFlag (feature, activated, notificationType) { dispatch(actions.hideLoadingIndication()) if (err) { dispatch(actions.displayWarning(err.message)) - reject(err) + return reject(err) } dispatch(actions.updateFeatureFlags(updatedFeatureFlags)) notificationType && dispatch(actions.showModal({ name: notificationType })) @@ -1646,3 +1651,27 @@ function setUseBlockie (val) { }) } } + +function setNetworkEndpoints (networkEndpointType) { + return dispatch => { + log.debug('background.setNetworkEndpoints') + return new Promise((resolve, reject) => { + background.setNetworkEndpoints(networkEndpointType, err => { + if (err) { + dispatch(actions.displayWarning(err.message)) + return reject(err) + } + + dispatch(actions.updateNetworkEndpointType(networkEndpointType)) + resolve(networkEndpointType) + }) + }) + } +} + +function updateNetworkEndpointType (networkEndpointType) { + return { + type: actions.UPDATE_NETWORK_ENDPOINT_TYPE, + value: networkEndpointType, + } +} diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js index 95b41e5f3..294c29948 100644 --- a/ui/app/reducers/metamask.js +++ b/ui/app/reducers/metamask.js @@ -1,6 +1,7 @@ const extend = require('xtend') const actions = require('../actions') const MetamascaraPlatform = require('../../../app/scripts/platforms/window') +const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/config').enums module.exports = reduceMetamask @@ -39,6 +40,7 @@ function reduceMetamask (state, action) { coinOptions: {}, useBlockie: false, featureFlags: {}, + networkEndpointType: OLD_UI_NETWORK_TYPE, }, state.metamask) switch (action.type) { @@ -335,6 +337,11 @@ function reduceMetamask (state, action) { featureFlags: action.value, }) + case actions.UPDATE_NETWORK_ENDPOINT_TYPE: + return extend(metamaskState, { + networkEndpointType: action.value, + }) + default: return metamaskState diff --git a/ui/app/select-app.js b/ui/app/select-app.js index 0b837b547..ac6867aeb 100644 --- a/ui/app/select-app.js +++ b/ui/app/select-app.js @@ -5,7 +5,8 @@ const h = require('react-hyperscript') const App = require('./app') const OldApp = require('../../old-ui/app/app') const { autoAddToBetaUI } = require('./selectors') -const { setFeatureFlag } = require('./actions') +const { setFeatureFlag, setNetworkEndpoints } = require('./actions') +const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums function mapStateToProps (state) { return { @@ -19,8 +20,14 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - setFeatureFlagWithModal: () => dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')), - setFeatureFlagWithoutModal: () => dispatch(setFeatureFlag('betaUI', true)), + setFeatureFlagWithModal: () => { + return dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')) + .then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE))) + }, + setFeatureFlagWithoutModal: () => { + return dispatch(setFeatureFlag('betaUI', true)) + .then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE))) + }, } } module.exports = connect(mapStateToProps, mapDispatchToProps)(SelectedApp) diff --git a/ui/app/settings.js b/ui/app/settings.js index 74b282a98..a3dd65f14 100644 --- a/ui/app/settings.js +++ b/ui/app/settings.js @@ -9,6 +9,7 @@ const { exportAsFile } = require('./util') const TabBar = require('./components/tab-bar') const SimpleDropdown = require('./components/dropdowns/simple-dropdown') const ToggleButton = require('react-toggle-button') +const { OLD_UI_NETWORK_TYPE } = require('../../app/scripts/config').enums const getInfuraCurrencyOptions = () => { const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => { @@ -228,7 +229,7 @@ class Settings extends Component { ]) ) } - + renderOldUI () { const { setFeatureFlagToBeta } = this.props @@ -265,7 +266,7 @@ class Settings extends Component { ]) ) } - + renderLogo () { return ( h('div.settings__info-logo-wrapper', [ @@ -405,7 +406,10 @@ const mapDispatchToProps = dispatch => { displayWarning: warning => dispatch(actions.displayWarning(warning)), revealSeedConfirmation: () => dispatch(actions.revealSeedConfirmation()), setUseBlockie: value => dispatch(actions.setUseBlockie(value)), - setFeatureFlagToBeta: () => dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')), + setFeatureFlagToBeta: () => { + return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')) + .then(() => dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE))) + }, } } diff --git a/ui/index.js b/ui/index.js index 2aa30d3fe..bc3676c1f 100644 --- a/ui/index.js +++ b/ui/index.js @@ -4,6 +4,8 @@ const Root = require('./app/root') const actions = require('./app/actions') const configureStore = require('./app/store') const txHelper = require('./lib/tx-helper') +const { OLD_UI_NETWORK_TYPE, BETA_UI_NETWORK_TYPE } = require('../app/scripts/config').enums + global.log = require('loglevel') module.exports = launchMetamaskUi @@ -35,6 +37,10 @@ function startApp (metamaskState, accountManager, opts) { networkVersion: opts.networkVersion, }) + const useBetaUi = metamaskState.featureFlags.betaUI + const networkEndpointType = useBetaUi ? BETA_UI_NETWORK_TYPE : OLD_UI_NETWORK_TYPE + store.dispatch(actions.setNetworkEndpoints(networkEndpointType)) + // if unconfirmed txs, start on txConf page const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network) const numberOfUnapprivedTx = unapprovedTxsAll.length