Merge branch 'develop' into testing

feature/default_network_editable
Thomas 7 years ago
commit 770379c3da
  1. 26
      app/scripts/controllers/network/enums.js
  2. 121
      app/scripts/controllers/network/network.js
  3. 36
      app/scripts/controllers/network/util.js
  4. 21
      app/scripts/controllers/transactions/lib/tx-state-history-helper.js
  5. 2
      app/scripts/controllers/transactions/tx-state-manager.js
  6. 9
      app/scripts/first-time-state.js
  7. 42
      app/scripts/lib/setupRaven.js
  8. 1
      app/scripts/metamask-controller.js
  9. 96
      docs/send-screen-QA-checklist.md
  10. 3
      old-ui/app/app.js
  11. 30
      test/unit/network-contoller-test.js
  12. 139
      test/unit/tx-state-history-helper-test.js
  13. 46
      test/unit/tx-state-history-helper.js
  14. 9
      test/unit/tx-state-manager-test.js
  15. 18
      ui/app/actions.js
  16. 13
      ui/app/app.js
  17. 44
      ui/app/components/app-header/app-header.component.js
  18. 2
      ui/app/components/pages/settings/settings.js
  19. 1
      ui/app/components/pages/unlock-page/unlock-page.component.js
  20. 2
      ui/app/components/pages/unlock-page/unlock-page.container.js
  21. 14
      ui/app/components/pending-tx/confirm-send-ether.js
  22. 4
      ui/app/css/itcss/components/account-menu.scss
  23. 4
      ui/app/css/itcss/components/header.scss
  24. 2
      ui/app/first-time/init-menu.js
  25. 5
      ui/app/select-app.js
  26. 9
      ui/index.js

@ -13,20 +13,6 @@ const RINKEBY_DISPLAY_NAME = 'Rinkeby'
const KOVAN_DISPLAY_NAME = 'Kovan' const KOVAN_DISPLAY_NAME = 'Kovan'
const MAINNET_DISPLAY_NAME = 'Main Ethereum Network' const MAINNET_DISPLAY_NAME = 'Main Ethereum Network'
const MAINNET_RPC_URL = 'https://mainnet.infura.io/metamask'
const ROPSTEN_RPC_URL = 'https://ropsten.infura.io/metamask'
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 MAINNET_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_NETWORK = 'rinkeby'
const OLD_UI_NETWORK_TYPE = 'network'
const BETA_UI_NETWORK_TYPE = 'networkBeta'
module.exports = { module.exports = {
ROPSTEN, ROPSTEN,
@ -41,16 +27,4 @@ module.exports = {
RINKEBY_DISPLAY_NAME, RINKEBY_DISPLAY_NAME,
KOVAN_DISPLAY_NAME, KOVAN_DISPLAY_NAME,
MAINNET_DISPLAY_NAME, MAINNET_DISPLAY_NAME,
MAINNET_RPC_URL,
ROPSTEN_RPC_URL,
KOVAN_RPC_URL,
RINKEBY_RPC_URL,
LOCALHOST_RPC_URL,
MAINNET_RPC_URL_BETA,
ROPSTEN_RPC_URL_BETA,
KOVAN_RPC_URL_BETA,
RINKEBY_RPC_URL_BETA,
DEFAULT_NETWORK,
OLD_UI_NETWORK_TYPE,
BETA_UI_NETWORK_TYPE,
} }

@ -14,52 +14,40 @@ const {
RINKEBY, RINKEBY,
KOVAN, KOVAN,
MAINNET, MAINNET,
OLD_UI_NETWORK_TYPE, LOCALHOST,
DEFAULT_NETWORK,
} = require('./enums') } = require('./enums')
const { getNetworkEndpoints } = require('./util') const LOCALHOST_RPC_URL = 'http://localhost:8545'
const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET] const INFURA_PROVIDER_TYPES = [ROPSTEN, RINKEBY, KOVAN, MAINNET]
const env = process.env.METAMASK_ENV
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
const testMode = (METAMASK_DEBUG || env === 'test')
const defaultProviderConfig = {
type: testMode ? RINKEBY : MAINNET,
}
module.exports = class NetworkController extends EventEmitter { module.exports = class NetworkController extends EventEmitter {
constructor (config) { constructor (opts = {}) {
super() super()
this._networkEndpointVersion = OLD_UI_NETWORK_TYPE // parse options
this._networkEndpoints = getNetworkEndpoints(OLD_UI_NETWORK_TYPE) const providerConfig = opts.provider || defaultProviderConfig
this._defaultRpc = this._networkEndpoints[DEFAULT_NETWORK] // create stores
this.providerStore = new ObservableStore(providerConfig)
config.provider.rpcTarget = this.getRpcAddressForType(config.provider.type, config.provider)
this.networkStore = new ObservableStore('loading') this.networkStore = new ObservableStore('loading')
this.providerStore = new ObservableStore(config.provider)
this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore }) this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore })
// create event emitter proxy
this._proxy = createEventEmitterProxy() this._proxy = createEventEmitterProxy()
this.on('networkDidChange', this.lookupNetwork) this.on('networkDidChange', this.lookupNetwork)
} }
async setNetworkEndpoints (version) {
if (version === this._networkEndpointVersion) {
return
}
this._networkEndpointVersion = version
this._networkEndpoints = getNetworkEndpoints(version)
this._defaultRpc = this._networkEndpoints[DEFAULT_NETWORK]
const { type } = this.getProviderConfig()
return this.setProviderType(type, true)
}
initializeProvider (_providerParams) { initializeProvider (_providerParams) {
this._baseProviderParams = _providerParams this._baseProviderParams = _providerParams
const { type, rpcTarget } = this.providerStore.getState() const { type, rpcTarget } = this.providerStore.getState()
// map rpcTarget to rpcUrl this._configureProvider({ type, rpcTarget })
const opts = {
type,
rpcUrl: rpcTarget,
}
this._configureProvider(opts)
this._proxy.on('block', this._logBlock.bind(this)) this._proxy.on('block', this._logBlock.bind(this))
this._proxy.on('error', this.verifyNetwork.bind(this)) this._proxy.on('error', this.verifyNetwork.bind(this))
this.ethQuery = new EthQuery(this._proxy) this.ethQuery = new EthQuery(this._proxy)
@ -96,45 +84,27 @@ module.exports = class NetworkController extends EventEmitter {
}) })
} }
setRpcTarget (rpcUrl) { setRpcTarget (rpcTarget) {
this.providerStore.updateState({ const providerConfig = {
type: 'rpc', type: 'rpc',
rpcTarget: rpcUrl, rpcTarget,
})
this._switchNetwork({ rpcUrl })
}
getCurrentRpcAddress () {
const provider = this.getProviderConfig()
if (!provider) return null
return this.getRpcAddressForType(provider.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 && !forceUpdate) {
return
} }
this.providerStore.updateState(providerConfig)
this._switchNetwork(providerConfig)
}
const rpcTarget = this.getRpcAddressForType(type) async setProviderType (type) {
assert(rpcTarget, `NetworkController - unknown rpc address for type "${type}"`) assert.notEqual(type, 'rpc', `NetworkController - cannot call "setProviderType" with type 'rpc'. use "setRpcTarget"`)
this.providerStore.updateState({ type, rpcTarget }) assert(INFURA_PROVIDER_TYPES.includes(type) || type === LOCALHOST, `NetworkController - Unknown rpc type "${type}"`)
this._switchNetwork({ type }) const providerConfig = { type }
this.providerStore.updateState(providerConfig)
this._switchNetwork(providerConfig)
} }
getProviderConfig () { getProviderConfig () {
return this.providerStore.getState() return this.providerStore.getState()
} }
getRpcAddressForType (type, provider = this.getProviderConfig()) {
if (this._networkEndpoints[type]) {
return this._networkEndpoints[type]
}
return provider && provider.rpcTarget ? provider.rpcTarget : this._defaultRpc
}
// //
// Private // Private
// //
@ -146,32 +116,27 @@ module.exports = class NetworkController extends EventEmitter {
} }
_configureProvider (opts) { _configureProvider (opts) {
// type-based rpc endpoints const { type, rpcTarget } = opts
const { type } = opts // infura type-based endpoints
if (type) { const isInfura = INFURA_PROVIDER_TYPES.includes(type)
// type-based infura rpc endpoints if (isInfura) {
const isInfura = INFURA_PROVIDER_TYPES.includes(type) this._configureInfuraProvider(opts)
opts.rpcUrl = this.getRpcAddressForType(type) // other type-based rpc endpoints
if (isInfura) { } else if (type === LOCALHOST) {
this._configureInfuraProvider(opts) this._configureStandardProvider({ rpcUrl: LOCALHOST_RPC_URL })
// other type-based rpc endpoints
} else {
this._configureStandardProvider(opts)
}
// url-based rpc endpoints // url-based rpc endpoints
} else if (type === 'rpc'){
this._configureStandardProvider({ rpcUrl: rpcTarget })
} else { } else {
this._configureStandardProvider(opts) throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`)
} }
} }
_configureInfuraProvider (opts) { _configureInfuraProvider ({ type }) {
log.info('_configureInfuraProvider', opts) log.info('_configureInfuraProvider', type)
const infuraProvider = createInfuraProvider({ const infuraProvider = createInfuraProvider({ network: type })
network: opts.type,
})
const infuraSubprovider = new SubproviderFromProvider(infuraProvider) const infuraSubprovider = new SubproviderFromProvider(infuraProvider)
const providerParams = extend(this._baseProviderParams, { const providerParams = extend(this._baseProviderParams, {
rpcUrl: opts.rpcUrl,
engineParams: { engineParams: {
pollingInterval: 8000, pollingInterval: 8000,
blockTrackerProvider: infuraProvider, blockTrackerProvider: infuraProvider,

@ -3,7 +3,6 @@ const {
RINKEBY, RINKEBY,
KOVAN, KOVAN,
MAINNET, MAINNET,
LOCALHOST,
ROPSTEN_CODE, ROPSTEN_CODE,
RINKEYBY_CODE, RINKEYBY_CODE,
KOVAN_CODE, KOVAN_CODE,
@ -11,17 +10,6 @@ const {
RINKEBY_DISPLAY_NAME, RINKEBY_DISPLAY_NAME,
KOVAN_DISPLAY_NAME, KOVAN_DISPLAY_NAME,
MAINNET_DISPLAY_NAME, MAINNET_DISPLAY_NAME,
MAINNET_RPC_URL,
ROPSTEN_RPC_URL,
KOVAN_RPC_URL,
RINKEBY_RPC_URL,
LOCALHOST_RPC_URL,
MAINNET_RPC_URL_BETA,
ROPSTEN_RPC_URL_BETA,
KOVAN_RPC_URL_BETA,
RINKEBY_RPC_URL_BETA,
OLD_UI_NETWORK_TYPE,
BETA_UI_NETWORK_TYPE,
} = require('./enums') } = require('./enums')
const networkToNameMap = { const networkToNameMap = {
@ -34,32 +22,8 @@ const networkToNameMap = {
[KOVAN_CODE]: KOVAN_DISPLAY_NAME, [KOVAN_CODE]: KOVAN_DISPLAY_NAME,
} }
const networkEndpointsMap = {
[OLD_UI_NETWORK_TYPE]: {
[LOCALHOST]: LOCALHOST_RPC_URL,
[MAINNET]: MAINNET_RPC_URL,
[ROPSTEN]: ROPSTEN_RPC_URL,
[KOVAN]: KOVAN_RPC_URL,
[RINKEBY]: RINKEBY_RPC_URL,
},
[BETA_UI_NETWORK_TYPE]: {
[LOCALHOST]: LOCALHOST_RPC_URL,
[MAINNET]: MAINNET_RPC_URL_BETA,
[ROPSTEN]: ROPSTEN_RPC_URL_BETA,
[KOVAN]: KOVAN_RPC_URL_BETA,
[RINKEBY]: RINKEBY_RPC_URL_BETA,
},
}
const getNetworkDisplayName = key => networkToNameMap[key] const getNetworkDisplayName = key => networkToNameMap[key]
const getNetworkEndpoints = (networkType = OLD_UI_NETWORK_TYPE) => {
return {
...networkEndpointsMap[networkType],
}
}
module.exports = { module.exports = {
getNetworkDisplayName, getNetworkDisplayName,
getNetworkEndpoints,
} }

@ -25,26 +25,31 @@ function migrateFromSnapshotsToDiffs (longHistory) {
} }
/** /**
generates an array of history objects sense the previous state. Generates an array of history objects sense the previous state.
The object has the keys opp(the operation preformed), The object has the keys
path(the key and if a nested object then each key will be seperated with a `/`) op (the operation performed),
value path (the key and if a nested object then each key will be seperated with a `/`)
with the first entry having the note value
with the first entry having the note and a timestamp when the change took place
@param previousState {object} - the previous state of the object @param previousState {object} - the previous state of the object
@param newState {object} - the update object @param newState {object} - the update object
@param note {string} - a optional note for the state change @param note {string} - a optional note for the state change
@reurns {array} @returns {array}
*/ */
function generateHistoryEntry (previousState, newState, note) { function generateHistoryEntry (previousState, newState, note) {
const entry = jsonDiffer.compare(previousState, newState) const entry = jsonDiffer.compare(previousState, newState)
// Add a note to the first op, since it breaks if we append it to the entry // Add a note to the first op, since it breaks if we append it to the entry
if (note && entry[0]) entry[0].note = note if (entry[0]) {
if (note) entry[0].note = note
entry[0].timestamp = Date.now()
}
return entry return entry
} }
/** /**
Recovers previous txMeta state obj Recovers previous txMeta state obj
@return {object} @returns {object}
*/ */
function replayHistory (_shortHistory) { function replayHistory (_shortHistory) {
const shortHistory = clone(_shortHistory) const shortHistory = clone(_shortHistory)

@ -158,7 +158,7 @@ class TransactionStateManager extends EventEmitter {
/** /**
updates the txMeta in the list and adds a history entry updates the txMeta in the list and adds a history entry
@param txMeta {Object} - the txMeta to update @param txMeta {Object} - the txMeta to update
@param [note] {string} - a not about the update for history @param [note] {string} - a note about the update for history
*/ */
updateTx (txMeta, note) { updateTx (txMeta, note) {
// validate txParams // validate txParams

@ -1,7 +1,3 @@
// test and development environment variables
const env = process.env.METAMASK_ENV
const METAMASK_DEBUG = process.env.METAMASK_DEBUG
const { DEFAULT_NETWORK, MAINNET } = require('./controllers/network/enums')
/** /**
* @typedef {Object} FirstTimeState * @typedef {Object} FirstTimeState
@ -14,11 +10,6 @@ const { DEFAULT_NETWORK, MAINNET } = require('./controllers/network/enums')
*/ */
const initialState = { const initialState = {
config: {}, config: {},
NetworkController: {
provider: {
type: (METAMASK_DEBUG || env === 'test') ? DEFAULT_NETWORK : MAINNET,
},
},
} }
module.exports = initialState module.exports = initialState

@ -25,7 +25,7 @@ function setupRaven(opts) {
const report = opts.data const report = opts.data
try { try {
// handle error-like non-error exceptions // handle error-like non-error exceptions
nonErrorException(report) rewriteErrorLikeExceptions(report)
// simplify certain complex error messages (e.g. Ethjs) // simplify certain complex error messages (e.g. Ethjs)
simplifyErrorMessages(report) simplifyErrorMessages(report)
// modify report urls // modify report urls
@ -42,27 +42,35 @@ function setupRaven(opts) {
return Raven return Raven
} }
function nonErrorException(report) { function rewriteErrorLikeExceptions(report) {
// handle errors that lost their error-ness in serialization // handle errors that lost their error-ness in serialization (e.g. dnode)
if (report.message.includes('Non-Error exception captured with keys: message')) { rewriteErrorMessages(report, (errorMessage) => {
if (!(report.extra && report.extra.__serialized__)) return if (!errorMessage.includes('Non-Error exception captured with keys:')) return errorMessage
report.message = `Non-Error Exception: ${report.extra.__serialized__.message}` if (!(report.extra && report.extra.__serialized__ && report.extra.__serialized__.message)) return errorMessage
} return `Non-Error Exception: ${report.extra.__serialized__.message}`
})
} }
function simplifyErrorMessages(report) { function simplifyErrorMessages(report) {
rewriteErrorMessages(report, (errorMessage) => {
// simplify ethjs error messages
errorMessage = extractEthjsErrorMessage(errorMessage)
// simplify 'Transaction Failed: known transaction'
if (errorMessage.indexOf('Transaction Failed: known transaction') === 0) {
// cut the hash from the error message
errorMessage = 'Transaction Failed: known transaction'
}
return errorMessage
})
}
function rewriteErrorMessages(report, rewriteFn) {
// rewrite top level message
report.message = rewriteFn(report.message)
// rewrite each exception message
if (report.exception && report.exception.values) { if (report.exception && report.exception.values) {
report.exception.values.forEach(item => { report.exception.values.forEach(item => {
let errorMessage = item.value item.value = rewriteFn(item.value)
// simplify ethjs error messages
errorMessage = extractEthjsErrorMessage(errorMessage)
// simplify 'Transaction Failed: known transaction'
if (errorMessage.indexOf('Transaction Failed: known transaction') === 0) {
// cut the hash from the error message
errorMessage = 'Transaction Failed: known transaction'
}
// finalize
item.value = errorMessage
}) })
} }
} }

@ -355,7 +355,6 @@ module.exports = class MetamaskController extends EventEmitter {
submitPassword: nodeify(keyringController.submitPassword, keyringController), submitPassword: nodeify(keyringController.submitPassword, keyringController),
// network management // network management
setNetworkEndpoints: nodeify(networkController.setNetworkEndpoints, networkController),
setProviderType: nodeify(networkController.setProviderType, networkController), setProviderType: nodeify(networkController.setProviderType, networkController),
setCustomRpc: nodeify(this.setCustomRpc, this), setCustomRpc: nodeify(this.setCustomRpc, this),

@ -0,0 +1,96 @@
# Send screen QA checklist:
This checklist can be to guide QA of the send screen. It can also be used to guide e2e tests for the send screen.
Once all of these are QA verified on master, resolutions to any bugs related to the send screen should include and update to this list.
Additional features or functionality on the send screen should include an update to this list.
## Send Eth mode
- [ ] **Header** _It should:_
- [ ] have title "Send ETH"
- [ ] have sub title "Only send ETH to an Ethereum address."
- [ ] return user to main screen when top right X is clicked
- [ ] **From row** _It should:_
- [ ] show the currently selected account by default
- [ ] show a dropdown with all of the users accounts
- [ ] contain the following info for each account: identicon, account name, balance in ETH, balance in current currency
- [ ] change the account selected in the dropdown (but not the app-wide selected account) when one in the dropdown is clicked
- [ ] close the dropdown, without changing the dropdown selected account, when the dropdown is open and then a click happens outside it
- [ ] **To row** _It should:_
- [ ] Show a placeholder with the text 'Recipient Address' by default
- [ ] Show, when clicked, a dropdown list of all 'to accounts': the users accounts, plus any other accounts they have previously sent to
- [ ] Show account address, and account name if it exists, of each item in the dropdown list
- [ ] Show a dropdown list of all to accounts (see above) whose address matches an address currently being typed in
- [ ] Set the input text to the address of an account clicked in the dropdown list, and also hide the dropdown
- [ ] Hide the dropdown without changing what is in the input if the user clicks outside the dropdown list while it is open
- [ ] Select the text in the input (i.e. the address) if an address is displayed and then clicked
- [ ] Show a 'required' error if the dropdown is opened but no account is selected
- [ ] Show an 'invalid address' error if text is entered in the input that cannot be a valid hex address or ens address
- [ ] Support ens names. (enter dinodan.eth on mainnet) After entering the plain text address, the hex address should appear in the input with a green checkmark beside
- [ ] Should show a 'no such address' error if a non-existent ens address is entered
- [ ] **Amount row** _It should:_
- [ ] allow user to enter any rational number >= 0
- [ ] allow user to copy and paste into the field
- [ ] show an insufficient funds error if an amount > balance - gas fee
- [ ] display 'ETH' after the number amount. The position of 'ETH' should change as the length of the input amount text changes
- [ ] display the value of the amount of ETH in the current currency, formatted in that currency
- [ ] show a 'max' but if amount < balance - gas fee
- [ ] show no max button or error if amount === balance - gas fee
- [ ] set the amount to balance - gas fee if the 'max' button is clicked
- [ ] **Gas Fee Display row** _It should:_
- [ ] Default to the fee given by the estimated gas price
- [ ] display the fee in ETH and the current currency
- [ ] update when changes are made using the customize gas modal
- [ ] **Cancel button** _It should:_
- [ ] Take the user back to the main screen
- [ ] **submit button** _It should:_
- [ ] be disabled if no recipient address is provided or if any field is in error
- [ ] sign a transaction with the info in the above form, and display the details of that transaction on the confirm screen
## Send token mode
- [ ] **Header** _It should:_
- [ ] have title "Send Tokens"
- [ ] have sub title "Only send [token symbol] to an Ethereum address."
- [ ] return user to main screen when top right X is clicked
- [ ] **From row** _It should:_
- [ ] Behave the same as 'Send ETH mode' (see above)
- [ ] **To row** _It should:_
- [ ] Behave the same as 'Send ETH mode' (see above)
- [ ] **Amount row** _It should:_
- [ ] allow user to enter any rational number >= 0
- [ ] allow user to copy and paste into the field
- [ ] show an 'insufficient tokens' error if an amount > token balance
- [ ] show an 'insufficient funds' error if an gas fee > eth balance
- [ ] display [token symbol] after the number amount. The position of [token symbol] should change as the length of the input amount text changes
- [ ] display the value of the amount of tokens in the current currency, formatted in that currency
- [ ] show a 'max' but if amount < token balance
- [ ] show no max button or error if amount === token balance
- [ ] set the amount to token balance if the 'max' button is clicked
- [ ] **Gas Fee Display row** _It should:_
- [ ] Behave the same as 'Send ETH mode' (see above)
- [ ] **Cancel button** _It should:_
- [ ] Take the user back to the main screen
- [ ] **submit button** _It should:_
- [ ] be disabled if no recipient address is provided or if any field is in error
- [ ] sign a token transaction with the info in the above form, and display the details of that transaction on the confirm screen
## Edit send Eth mode
- [ ] Say 'Editing transaction' in the header
- [ ] display a button to go back to the confirmation screen without applying update
- [ ] say 'update transaction' on the submit button
- [ ] update the existing transaction, instead of signing a new one, when clicking the submit button
- [ ] Otherwise, behave the same as 'Send ETH mode' (see above)
## Edit send token mode
- [ ] Behave the same as 'Edit send Eth mode' (see above)
## Specific cases to test
- [ ] Send eth to a hex address
- [ ] Send eth to an ENS address
- [ ] Donate to the faucet at https://faucet.metamask.io/ and edit the transaction before confirming
- [ ] Send a token that is available on the 'Add Token' screen search to a hex address
- [ ] Create a custom token at https://tokenfactory.surge.sh/ and send it to a hex address
- [ ] Send a token to an ENS address
- [ ] Create a token transaction using https://tokenfactory.surge.sh/#/, and edit the transaction before confirming
- [ ] Send each of MKR, EOS and ICON using myetherwallet, and edit the transaction before confirming

@ -35,7 +35,6 @@ const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
const HDRestoreVaultScreen = require('./keychains/hd/restore-vault') const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation') const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/controllers/network/enums')
module.exports = connect(mapStateToProps)(App) module.exports = connect(mapStateToProps)(App)
@ -409,7 +408,6 @@ App.prototype.renderDropdown = function () {
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }), closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
onClick: () => { onClick: () => {
this.props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')) this.props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
.then(() => this.props.dispatch(actions.setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
}, },
}, 'Try Beta!'), }, 'Try Beta!'),
]) ])
@ -472,7 +470,6 @@ App.prototype.renderPrimary = function () {
onClick: () => { onClick: () => {
global.platform.openExtensionInBrowser() global.platform.openExtensionInBrowser()
props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')) props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
.then(() => props.dispatch(actions.setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
}, },
style: { style: {
fontSize: '0.8em', fontSize: '0.8em',

@ -3,17 +3,15 @@ const nock = require('nock')
const NetworkController = require('../../app/scripts/controllers/network') const NetworkController = require('../../app/scripts/controllers/network')
const { const {
getNetworkDisplayName, getNetworkDisplayName,
getNetworkEndpoints,
} = require('../../app/scripts/controllers/network/util') } = require('../../app/scripts/controllers/network/util')
const { createTestProviderTools } = require('../stub/provider') const { createTestProviderTools } = require('../stub/provider')
const providerResultStub = {} const providerResultStub = {}
const provider = createTestProviderTools({ scaffold: providerResultStub }).provider
describe('# Network Controller', function () { describe('# Network Controller', function () {
let networkController let networkController
const noop = () => {} const noop = () => {}
const networkControllerProviderInit = { const networkControllerProviderConfig = {
getAccounts: noop, getAccounts: noop,
} }
@ -24,11 +22,9 @@ describe('# Network Controller', function () {
.post('/metamask') .post('/metamask')
.reply(200) .reply(200)
networkController = new NetworkController({ networkController = new NetworkController()
provider,
})
networkController.initializeProvider(networkControllerProviderInit, provider) networkController.initializeProvider(networkControllerProviderConfig)
}) })
afterEach(function () { afterEach(function () {
@ -38,7 +34,7 @@ describe('# Network Controller', function () {
describe('network', function () { describe('network', function () {
describe('#provider', function () { describe('#provider', function () {
it('provider should be updatable without reassignment', function () { it('provider should be updatable without reassignment', function () {
networkController.initializeProvider(networkControllerProviderInit, provider) networkController.initializeProvider(networkControllerProviderConfig)
const proxy = networkController._proxy const proxy = networkController._proxy
proxy.setTarget({ test: true, on: () => {} }) proxy.setTarget({ test: true, on: () => {} })
assert.ok(proxy.test) assert.ok(proxy.test)
@ -59,12 +55,6 @@ describe('# Network Controller', function () {
}) })
}) })
describe('#getRpcAddressForType', function () {
it('should return the right rpc address', function () {
const rpcTarget = networkController.getRpcAddressForType('mainnet')
assert.equal(rpcTarget, 'https://mainnet.infura.io/metamask', 'returns the right rpcAddress')
})
})
describe('#setProviderType', function () { describe('#setProviderType', function () {
it('should update provider.type', function () { it('should update provider.type', function () {
networkController.setProviderType('mainnet') networkController.setProviderType('mainnet')
@ -76,16 +66,11 @@ describe('# Network Controller', function () {
const loading = networkController.isNetworkLoading() const loading = networkController.isNetworkLoading()
assert.ok(loading, 'network is loading') assert.ok(loading, 'network is loading')
}) })
it('should set the right rpcTarget', function () {
networkController.setProviderType('mainnet')
const rpcTarget = networkController.getProviderConfig().rpcTarget
assert.equal(rpcTarget, 'https://mainnet.infura.io/metamask', 'returns the right rpcAddress')
})
}) })
}) })
}) })
describe('# Network utils', () => { describe('Network utils', () => {
it('getNetworkDisplayName should return the correct network name', () => { it('getNetworkDisplayName should return the correct network name', () => {
const tests = [ const tests = [
{ {
@ -114,9 +99,4 @@ describe('# Network utils', () => {
tests.forEach(({ input, expected }) => assert.equal(getNetworkDisplayName(input), expected)) tests.forEach(({ input, expected }) => assert.equal(getNetworkDisplayName(input), expected))
}) })
it('getNetworkEndpoints should return the correct endpoints', () => {
assert.equal(getNetworkEndpoints('networkBeta').ropsten, 'https://ropsten.infura.io/metamask2')
assert.equal(getNetworkEndpoints('network').rinkeby, 'https://rinkeby.infura.io/metamask')
})
}) })

@ -1,26 +1,129 @@
const assert = require('assert') const assert = require('assert')
const clone = require('clone')
const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper') const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
const testVault = require('../data/v17-long-history.json')
describe('deepCloneFromTxMeta', function () { describe ('Transaction state history helper', function () {
it('should clone deep', function () {
const input = { describe('#snapshotFromTxMeta', function () {
foo: { it('should clone deep', function () {
bar: { const input = {
bam: 'baz' foo: {
bar: {
bam: 'baz'
}
} }
} }
} const output = txStateHistoryHelper.snapshotFromTxMeta(input)
const output = txStateHistoryHelper.snapshotFromTxMeta(input) assert('foo' in output, 'has a foo key')
assert('foo' in output, 'has a foo key') assert('bar' in output.foo, 'has a bar key')
assert('bar' in output.foo, 'has a bar key') assert('bam' in output.foo.bar, 'has a bar key')
assert('bam' in output.foo.bar, 'has a bar key') assert.equal(output.foo.bar.bam, 'baz', 'has a baz value')
assert.equal(output.foo.bar.bam, 'baz', 'has a baz value') })
it('should remove the history key', function () {
const input = { foo: 'bar', history: 'remembered' }
const output = txStateHistoryHelper.snapshotFromTxMeta(input)
assert(typeof output.history, 'undefined', 'should remove history')
})
}) })
it('should remove the history key', function () { describe('#migrateFromSnapshotsToDiffs', function () {
const input = { foo: 'bar', history: 'remembered' } it('migrates history to diffs and can recover original values', function () {
const output = txStateHistoryHelper.snapshotFromTxMeta(input) testVault.data.TransactionController.transactions.forEach((tx, index) => {
assert(typeof output.history, 'undefined', 'should remove history') const newHistory = txStateHistoryHelper.migrateFromSnapshotsToDiffs(tx.history)
newHistory.forEach((newEntry, index) => {
if (index === 0) {
assert.equal(Array.isArray(newEntry), false, 'initial history item IS NOT a json patch obj')
} else {
assert.equal(Array.isArray(newEntry), true, 'non-initial history entry IS a json patch obj')
}
const oldEntry = tx.history[index]
const historySubset = newHistory.slice(0, index + 1)
const reconstructedValue = txStateHistoryHelper.replayHistory(historySubset)
assert.deepEqual(oldEntry, reconstructedValue, 'was able to reconstruct old entry from diffs')
})
})
})
})
describe('#replayHistory', function () {
it('replaying history does not mutate the original obj', function () {
const initialState = { test: true, message: 'hello', value: 1 }
const diff1 = [{
"op": "replace",
"path": "/message",
"value": "haay",
}]
const diff2 = [{
"op": "replace",
"path": "/value",
"value": 2,
}]
const history = [initialState, diff1, diff2]
const beforeStateSnapshot = JSON.stringify(initialState)
const latestState = txStateHistoryHelper.replayHistory(history)
const afterStateSnapshot = JSON.stringify(initialState)
assert.notEqual(initialState, latestState, 'initial state is not the same obj as the latest state')
assert.equal(beforeStateSnapshot, afterStateSnapshot, 'initial state is not modified during run')
})
})
describe('#generateHistoryEntry', function () {
function generateHistoryEntryTest(note) {
const prevState = {
someValue: 'value 1',
foo: {
bar: {
bam: 'baz'
}
}
}
const nextState = {
newPropRoot: 'new property - root',
someValue: 'value 2',
foo: {
newPropFirstLevel: 'new property - first level',
bar: {
bam: 'baz'
}
}
}
const before = new Date().getTime()
const result = txStateHistoryHelper.generateHistoryEntry(prevState, nextState, note)
const after = new Date().getTime()
assert.ok(Array.isArray(result))
assert.equal(result.length, 3)
const expectedEntry1 = { op: 'add', path: '/foo/newPropFirstLevel', value: 'new property - first level' }
assert.equal(result[0].op, expectedEntry1.op)
assert.equal(result[0].path, expectedEntry1.path)
assert.equal(result[0].value, expectedEntry1.value)
assert.equal(result[0].value, expectedEntry1.value)
if (note)
assert.equal(result[0].note, note)
assert.ok(result[0].timestamp >= before && result[0].timestamp <= after)
const expectedEntry2 = { op: 'replace', path: '/someValue', value: 'value 2' }
assert.deepEqual(result[1], expectedEntry2)
const expectedEntry3 = { op: 'add', path: '/newPropRoot', value: 'new property - root' }
assert.deepEqual(result[2], expectedEntry3)
}
it('should generate history entries', function () {
generateHistoryEntryTest()
})
it('should add note to first entry', function () {
generateHistoryEntryTest('custom note')
})
}) })
}) })

@ -1,46 +0,0 @@
const assert = require('assert')
const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
const testVault = require('../data/v17-long-history.json')
describe('tx-state-history-helper', function () {
it('migrates history to diffs and can recover original values', function () {
testVault.data.TransactionController.transactions.forEach((tx, index) => {
const newHistory = txStateHistoryHelper.migrateFromSnapshotsToDiffs(tx.history)
newHistory.forEach((newEntry, index) => {
if (index === 0) {
assert.equal(Array.isArray(newEntry), false, 'initial history item IS NOT a json patch obj')
} else {
assert.equal(Array.isArray(newEntry), true, 'non-initial history entry IS a json patch obj')
}
const oldEntry = tx.history[index]
const historySubset = newHistory.slice(0, index + 1)
const reconstructedValue = txStateHistoryHelper.replayHistory(historySubset)
assert.deepEqual(oldEntry, reconstructedValue, 'was able to reconstruct old entry from diffs')
})
})
})
it('replaying history does not mutate the original obj', function () {
const initialState = { test: true, message: 'hello', value: 1 }
const diff1 = [{
"op": "replace",
"path": "/message",
"value": "haay",
}]
const diff2 = [{
"op": "replace",
"path": "/value",
"value": 2,
}]
const history = [initialState, diff1, diff2]
const beforeStateSnapshot = JSON.stringify(initialState)
const latestState = txStateHistoryHelper.replayHistory(history)
const afterStateSnapshot = JSON.stringify(initialState)
assert.notEqual(initialState, latestState, 'initial state is not the same obj as the latest state')
assert.equal(beforeStateSnapshot, afterStateSnapshot, 'initial state is not modified during run')
})
})

@ -176,14 +176,21 @@ describe('TransactionStateManager', function () {
assert.deepEqual(updatedTx.history[0], txStateHistoryHelper.snapshotFromTxMeta(updatedTx), 'first history item is initial state') assert.deepEqual(updatedTx.history[0], txStateHistoryHelper.snapshotFromTxMeta(updatedTx), 'first history item is initial state')
// modify value and updateTx // modify value and updateTx
updatedTx.txParams.gasPrice = desiredGasPrice updatedTx.txParams.gasPrice = desiredGasPrice
const before = new Date().getTime()
txStateManager.updateTx(updatedTx) txStateManager.updateTx(updatedTx)
const after = new Date().getTime()
// check updated value // check updated value
const result = txStateManager.getTx('1') const result = txStateManager.getTx('1')
assert.equal(result.txParams.gasPrice, desiredGasPrice, 'gas price updated') assert.equal(result.txParams.gasPrice, desiredGasPrice, 'gas price updated')
// validate history was updated // validate history was updated
assert.equal(result.history.length, 2, 'two history items (initial + diff)') assert.equal(result.history.length, 2, 'two history items (initial + diff)')
assert.equal(result.history[1].length, 1, 'two history state items (initial + diff)')
const expectedEntry = { op: 'replace', path: '/txParams/gasPrice', value: desiredGasPrice } const expectedEntry = { op: 'replace', path: '/txParams/gasPrice', value: desiredGasPrice }
assert.deepEqual(result.history[1], [expectedEntry], 'two history items (initial + diff)') assert.deepEqual(result.history[1][0].op, expectedEntry.op, 'two history items (initial + diff) operation')
assert.deepEqual(result.history[1][0].path, expectedEntry.path, 'two history items (initial + diff) path')
assert.deepEqual(result.history[1][0].value, expectedEntry.value, 'two history items (initial + diff) value')
assert.ok(result.history[1][0].timestamp >= before && result.history[1][0].timestamp <= after)
}) })
}) })

@ -271,7 +271,6 @@ var actions = {
SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE', SET_MOUSE_USER_STATE: 'SET_MOUSE_USER_STATE',
// Network // Network
setNetworkEndpoints,
updateNetworkEndpointType, updateNetworkEndpointType,
UPDATE_NETWORK_ENDPOINT_TYPE: 'UPDATE_NETWORK_ENDPOINT_TYPE', UPDATE_NETWORK_ENDPOINT_TYPE: 'UPDATE_NETWORK_ENDPOINT_TYPE',
@ -1924,23 +1923,6 @@ function setLocaleMessages (localeMessages) {
} }
} }
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) { function updateNetworkEndpointType (networkEndpointType) {
return { return {
type: actions.UPDATE_NETWORK_ENDPOINT_TYPE, type: actions.UPDATE_NETWORK_ENDPOINT_TYPE,

@ -1,7 +1,7 @@
const { Component } = require('react') const { Component } = require('react')
const PropTypes = require('prop-types') const PropTypes = require('prop-types')
const connect = require('react-redux').connect const connect = require('react-redux').connect
const { Route, Switch, withRouter, matchPath } = require('react-router-dom') const { Route, Switch, withRouter } = require('react-router-dom')
const { compose } = require('recompose') const { compose } = require('recompose')
const h = require('react-hyperscript') const h = require('react-hyperscript')
const actions = require('./actions') const actions = require('./actions')
@ -83,15 +83,6 @@ class App extends Component {
) )
} }
renderAppHeader () {
const { location } = this.props
const isInitializing = matchPath(location.pathname, {
path: INITIALIZE_ROUTE, exact: false,
})
return isInitializing ? null : h(AppHeader)
}
render () { render () {
const { const {
isLoading, isLoading,
@ -128,7 +119,7 @@ class App extends Component {
// global modal // global modal
h(Modal, {}, []), h(Modal, {}, []),
this.renderAppHeader(), h(AppHeader),
// sidebar // sidebar
this.renderSidebar(), this.renderSidebar(),

@ -1,9 +1,13 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import classnames from 'classnames' import classnames from 'classnames'
import { matchPath } from 'react-router-dom'
const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../../../app/scripts/lib/enums') const {
const { DEFAULT_ROUTE, CONFIRM_TRANSACTION_ROUTE } = require('../../routes') ENVIRONMENT_TYPE_NOTIFICATION,
ENVIRONMENT_TYPE_POPUP,
} = require('../../../../app/scripts/lib/enums')
const { DEFAULT_ROUTE, INITIALIZE_ROUTE, CONFIRM_TRANSACTION_ROUTE } = require('../../routes')
const Identicon = require('../identicon') const Identicon = require('../identicon')
const NetworkIndicator = require('../network') const NetworkIndicator = require('../network')
@ -36,13 +40,23 @@ class AppHeader extends Component {
: hideNetworkDropdown() : hideNetworkDropdown()
} }
isConfirming () {
const { location } = this.props
return Boolean(matchPath(location.pathname, {
path: CONFIRM_TRANSACTION_ROUTE, exact: false,
}))
}
renderAccountMenu () { renderAccountMenu () {
const { isUnlocked, toggleAccountMenu, selectedAddress } = this.props const { isUnlocked, toggleAccountMenu, selectedAddress } = this.props
return isUnlocked && ( return isUnlocked && (
<div <div
className="account-menu__icon" className={classnames('account-menu__icon', {
onClick={toggleAccountMenu} 'account-menu__icon--disabled': this.isConfirming(),
})}
onClick={() => this.isConfirming() || toggleAccountMenu()}
> >
<Identicon <Identicon
address={selectedAddress} address={selectedAddress}
@ -52,6 +66,26 @@ class AppHeader extends Component {
) )
} }
hideAppHeader () {
const { location } = this.props
const isInitializing = Boolean(matchPath(location.pathname, {
path: INITIALIZE_ROUTE, exact: false,
}))
if (isInitializing) {
return true
}
if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_NOTIFICATION) {
return true
}
if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_POPUP && this.isConfirming()) {
return true
}
}
render () { render () {
const { const {
network, network,
@ -61,7 +95,7 @@ class AppHeader extends Component {
isUnlocked, isUnlocked,
} = this.props } = this.props
if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_NOTIFICATION) { if (this.hideAppHeader()) {
return null return null
} }

@ -12,7 +12,6 @@ const SimpleDropdown = require('../../dropdowns/simple-dropdown')
const ToggleButton = require('react-toggle-button') const ToggleButton = require('react-toggle-button')
const { REVEAL_SEED_ROUTE } = require('../../../routes') const { REVEAL_SEED_ROUTE } = require('../../../routes')
const locales = require('../../../../../app/_locales/index.json') const locales = require('../../../../../app/_locales/index.json')
const { OLD_UI_NETWORK_TYPE } = require('../../../../../app/scripts/controllers/network/enums')
const getInfuraCurrencyOptions = () => { const getInfuraCurrencyOptions = () => {
const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => { const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
@ -349,7 +348,6 @@ const mapDispatchToProps = dispatch => {
updateCurrentLocale: key => dispatch(actions.updateCurrentLocale(key)), updateCurrentLocale: key => dispatch(actions.updateCurrentLocale(key)),
setFeatureFlagToBeta: () => { setFeatureFlagToBeta: () => {
return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')) return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
.then(() => dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
}, },
showResetAccountConfirmationModal: () => { showResetAccountConfirmationModal: () => {
return dispatch(actions.showModal({ name: 'CONFIRM_RESET_ACCOUNT' })) return dispatch(actions.showModal({ name: 'CONFIRM_RESET_ACCOUNT' }))

@ -175,7 +175,6 @@ UnlockPage.propTypes = {
isUnlocked: PropTypes.bool, isUnlocked: PropTypes.bool,
t: PropTypes.func, t: PropTypes.func,
useOldInterface: PropTypes.func, useOldInterface: PropTypes.func,
setNetworkEndpoints: PropTypes.func,
} }
export default UnlockPage export default UnlockPage

@ -6,7 +6,6 @@ const {
tryUnlockMetamask, tryUnlockMetamask,
forgotPassword, forgotPassword,
markPasswordForgotten, markPasswordForgotten,
setNetworkEndpoints,
} = require('../../../actions') } = require('../../../actions')
import UnlockPage from './unlock-page.component' import UnlockPage from './unlock-page.component'
@ -23,7 +22,6 @@ const mapDispatchToProps = dispatch => {
forgotPassword: () => dispatch(forgotPassword()), forgotPassword: () => dispatch(forgotPassword()),
tryUnlockMetamask: password => dispatch(tryUnlockMetamask(password)), tryUnlockMetamask: password => dispatch(tryUnlockMetamask(password)),
markPasswordForgotten: () => dispatch(markPasswordForgotten()), markPasswordForgotten: () => dispatch(markPasswordForgotten()),
setNetworkEndpoints: type => dispatch(setNetworkEndpoints(type)),
} }
} }

@ -28,6 +28,10 @@ const currencies = require('currency-formatter/currencies')
const { MIN_GAS_PRICE_HEX } = require('../send/send-constants') const { MIN_GAS_PRICE_HEX } = require('../send/send-constants')
const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes') const { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
const {
ENVIRONMENT_TYPE_POPUP,
ENVIRONMENT_TYPE_NOTIFICATION,
} = require('../../../../app/scripts/lib/enums')
ConfirmSendEther.contextTypes = { ConfirmSendEther.contextTypes = {
t: PropTypes.func, t: PropTypes.func,
@ -293,6 +297,14 @@ ConfirmSendEther.prototype.editTransaction = function (txMeta) {
history.push(SEND_ROUTE) history.push(SEND_ROUTE)
} }
ConfirmSendEther.prototype.renderNetworkDisplay = function () {
const windowType = window.METAMASK_UI_TYPE
return (windowType === ENVIRONMENT_TYPE_NOTIFICATION || windowType === ENVIRONMENT_TYPE_POPUP)
? h(NetworkDisplay)
: null
}
ConfirmSendEther.prototype.render = function () { ConfirmSendEther.prototype.render = function () {
const { const {
currentCurrency, currentCurrency,
@ -358,7 +370,7 @@ ConfirmSendEther.prototype.render = function () {
visibility: !txMeta.lastGasPrice ? 'initial' : 'hidden', visibility: !txMeta.lastGasPrice ? 'initial' : 'hidden',
}, },
}, 'Edit'), }, 'Edit'),
window.METAMASK_UI_TYPE === 'notification' && h(NetworkDisplay), this.renderNetworkDisplay(),
]), ]),
h('.page-container__title', title), h('.page-container__title', title),
h('.page-container__subtitle', subtitle), h('.page-container__subtitle', subtitle),

@ -23,6 +23,10 @@
&__icon { &__icon {
margin-left: 20px; margin-left: 20px;
cursor: pointer; cursor: pointer;
&--disabled {
cursor: initial;
}
} }
&__header { &__header {

@ -82,10 +82,6 @@
display: flex; display: flex;
flex-flow: row nowrap; flex-flow: row nowrap;
align-items: center; align-items: center;
.identicon {
cursor: pointer;
}
} }
} }

@ -10,7 +10,6 @@ const getCaretCoordinates = require('textarea-caret')
const { RESTORE_VAULT_ROUTE, DEFAULT_ROUTE } = require('../routes') const { RESTORE_VAULT_ROUTE, DEFAULT_ROUTE } = require('../routes')
const { getEnvironmentType } = require('../../../app/scripts/lib/util') const { getEnvironmentType } = require('../../../app/scripts/lib/util')
const { ENVIRONMENT_TYPE_POPUP } = require('../../../app/scripts/lib/enums') const { ENVIRONMENT_TYPE_POPUP } = require('../../../app/scripts/lib/enums')
const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/controllers/network/enums')
class InitializeMenuScreen extends Component { class InitializeMenuScreen extends Component {
constructor (props) { constructor (props) {
@ -190,7 +189,6 @@ class InitializeMenuScreen extends Component {
showOldUI () { showOldUI () {
this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL')) this.props.dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
.then(() => this.props.dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
} }
} }

@ -6,8 +6,7 @@ const { HashRouter } = require('react-router-dom')
const App = require('./app') const App = require('./app')
const OldApp = require('../../old-ui/app/app') const OldApp = require('../../old-ui/app/app')
const { autoAddToBetaUI } = require('./selectors') const { autoAddToBetaUI } = require('./selectors')
const { setFeatureFlag, setNetworkEndpoints } = require('./actions') const { setFeatureFlag } = require('./actions')
const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/controllers/network/enums')
const I18nProvider = require('./i18n-provider') const I18nProvider = require('./i18n-provider')
function mapStateToProps (state) { function mapStateToProps (state) {
@ -24,11 +23,9 @@ function mapDispatchToProps (dispatch) {
return { return {
setFeatureFlagWithModal: () => { setFeatureFlagWithModal: () => {
return dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL')) return dispatch(setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
.then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
}, },
setFeatureFlagWithoutModal: () => { setFeatureFlagWithoutModal: () => {
return dispatch(setFeatureFlag('betaUI', true)) return dispatch(setFeatureFlag('betaUI', true))
.then(() => dispatch(setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
}, },
} }
} }

@ -5,11 +5,6 @@ const actions = require('./app/actions')
const configureStore = require('./app/store') const configureStore = require('./app/store')
const txHelper = require('./lib/tx-helper') const txHelper = require('./lib/tx-helper')
const { fetchLocale } = require('./i18n-helper') const { fetchLocale } = require('./i18n-helper')
const {
OLD_UI_NETWORK_TYPE,
BETA_UI_NETWORK_TYPE,
} = require('../app/scripts/controllers/network/enums')
const log = require('loglevel') const log = require('loglevel')
module.exports = launchMetamaskUi module.exports = launchMetamaskUi
@ -55,10 +50,6 @@ async function startApp (metamaskState, accountManager, opts) {
networkVersion: opts.networkVersion, 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 // if unconfirmed txs, start on txConf page
const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network) const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.unapprovedTypedMessages, metamaskState.network)
const numberOfUnapprivedTx = unapprovedTxsAll.length const numberOfUnapprivedTx = unapprovedTxsAll.length

Loading…
Cancel
Save