mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge branch 'develop' into testing
This commit is contained in:
commit
770379c3da
@ -13,20 +13,6 @@ const RINKEBY_DISPLAY_NAME = 'Rinkeby'
|
||||
const KOVAN_DISPLAY_NAME = 'Kovan'
|
||||
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 = {
|
||||
ROPSTEN,
|
||||
@ -41,16 +27,4 @@ module.exports = {
|
||||
RINKEBY_DISPLAY_NAME,
|
||||
KOVAN_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,
|
||||
KOVAN,
|
||||
MAINNET,
|
||||
OLD_UI_NETWORK_TYPE,
|
||||
DEFAULT_NETWORK,
|
||||
LOCALHOST,
|
||||
} = require('./enums')
|
||||
const { getNetworkEndpoints } = require('./util')
|
||||
const LOCALHOST_RPC_URL = 'http://localhost:8545'
|
||||
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 {
|
||||
|
||||
constructor (config) {
|
||||
constructor (opts = {}) {
|
||||
super()
|
||||
|
||||
this._networkEndpointVersion = OLD_UI_NETWORK_TYPE
|
||||
this._networkEndpoints = getNetworkEndpoints(OLD_UI_NETWORK_TYPE)
|
||||
this._defaultRpc = this._networkEndpoints[DEFAULT_NETWORK]
|
||||
|
||||
config.provider.rpcTarget = this.getRpcAddressForType(config.provider.type, config.provider)
|
||||
// parse options
|
||||
const providerConfig = opts.provider || defaultProviderConfig
|
||||
// create stores
|
||||
this.providerStore = new ObservableStore(providerConfig)
|
||||
this.networkStore = new ObservableStore('loading')
|
||||
this.providerStore = new ObservableStore(config.provider)
|
||||
this.store = new ComposedStore({ provider: this.providerStore, network: this.networkStore })
|
||||
// create event emitter proxy
|
||||
this._proxy = createEventEmitterProxy()
|
||||
|
||||
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) {
|
||||
this._baseProviderParams = _providerParams
|
||||
const { type, rpcTarget } = this.providerStore.getState()
|
||||
// map rpcTarget to rpcUrl
|
||||
const opts = {
|
||||
type,
|
||||
rpcUrl: rpcTarget,
|
||||
}
|
||||
this._configureProvider(opts)
|
||||
this._configureProvider({ type, rpcTarget })
|
||||
this._proxy.on('block', this._logBlock.bind(this))
|
||||
this._proxy.on('error', this.verifyNetwork.bind(this))
|
||||
this.ethQuery = new EthQuery(this._proxy)
|
||||
@ -96,45 +84,27 @@ module.exports = class NetworkController extends EventEmitter {
|
||||
})
|
||||
}
|
||||
|
||||
setRpcTarget (rpcUrl) {
|
||||
this.providerStore.updateState({
|
||||
setRpcTarget (rpcTarget) {
|
||||
const providerConfig = {
|
||||
type: 'rpc',
|
||||
rpcTarget: rpcUrl,
|
||||
})
|
||||
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
|
||||
rpcTarget,
|
||||
}
|
||||
this.providerStore.updateState(providerConfig)
|
||||
this._switchNetwork(providerConfig)
|
||||
}
|
||||
|
||||
const rpcTarget = this.getRpcAddressForType(type)
|
||||
assert(rpcTarget, `NetworkController - unknown rpc address for type "${type}"`)
|
||||
this.providerStore.updateState({ type, rpcTarget })
|
||||
this._switchNetwork({ type })
|
||||
async setProviderType (type) {
|
||||
assert.notEqual(type, 'rpc', `NetworkController - cannot call "setProviderType" with type 'rpc'. use "setRpcTarget"`)
|
||||
assert(INFURA_PROVIDER_TYPES.includes(type) || type === LOCALHOST, `NetworkController - Unknown rpc type "${type}"`)
|
||||
const providerConfig = { type }
|
||||
this.providerStore.updateState(providerConfig)
|
||||
this._switchNetwork(providerConfig)
|
||||
}
|
||||
|
||||
getProviderConfig () {
|
||||
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
|
||||
//
|
||||
@ -146,32 +116,27 @@ module.exports = class NetworkController extends EventEmitter {
|
||||
}
|
||||
|
||||
_configureProvider (opts) {
|
||||
// type-based rpc endpoints
|
||||
const { type } = opts
|
||||
if (type) {
|
||||
// type-based infura rpc endpoints
|
||||
const isInfura = INFURA_PROVIDER_TYPES.includes(type)
|
||||
opts.rpcUrl = this.getRpcAddressForType(type)
|
||||
if (isInfura) {
|
||||
this._configureInfuraProvider(opts)
|
||||
// other type-based rpc endpoints
|
||||
} else {
|
||||
this._configureStandardProvider(opts)
|
||||
}
|
||||
const { type, rpcTarget } = opts
|
||||
// infura type-based endpoints
|
||||
const isInfura = INFURA_PROVIDER_TYPES.includes(type)
|
||||
if (isInfura) {
|
||||
this._configureInfuraProvider(opts)
|
||||
// other type-based rpc endpoints
|
||||
} else if (type === LOCALHOST) {
|
||||
this._configureStandardProvider({ rpcUrl: LOCALHOST_RPC_URL })
|
||||
// url-based rpc endpoints
|
||||
} else if (type === 'rpc'){
|
||||
this._configureStandardProvider({ rpcUrl: rpcTarget })
|
||||
} else {
|
||||
this._configureStandardProvider(opts)
|
||||
throw new Error(`NetworkController - _configureProvider - unknown type "${type}"`)
|
||||
}
|
||||
}
|
||||
|
||||
_configureInfuraProvider (opts) {
|
||||
log.info('_configureInfuraProvider', opts)
|
||||
const infuraProvider = createInfuraProvider({
|
||||
network: opts.type,
|
||||
})
|
||||
_configureInfuraProvider ({ type }) {
|
||||
log.info('_configureInfuraProvider', type)
|
||||
const infuraProvider = createInfuraProvider({ network: type })
|
||||
const infuraSubprovider = new SubproviderFromProvider(infuraProvider)
|
||||
const providerParams = extend(this._baseProviderParams, {
|
||||
rpcUrl: opts.rpcUrl,
|
||||
engineParams: {
|
||||
pollingInterval: 8000,
|
||||
blockTrackerProvider: infuraProvider,
|
||||
|
@ -3,7 +3,6 @@ const {
|
||||
RINKEBY,
|
||||
KOVAN,
|
||||
MAINNET,
|
||||
LOCALHOST,
|
||||
ROPSTEN_CODE,
|
||||
RINKEYBY_CODE,
|
||||
KOVAN_CODE,
|
||||
@ -11,17 +10,6 @@ const {
|
||||
RINKEBY_DISPLAY_NAME,
|
||||
KOVAN_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')
|
||||
|
||||
const networkToNameMap = {
|
||||
@ -34,32 +22,8 @@ const networkToNameMap = {
|
||||
[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 getNetworkEndpoints = (networkType = OLD_UI_NETWORK_TYPE) => {
|
||||
return {
|
||||
...networkEndpointsMap[networkType],
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getNetworkDisplayName,
|
||||
getNetworkEndpoints,
|
||||
}
|
||||
|
@ -25,26 +25,31 @@ function migrateFromSnapshotsToDiffs (longHistory) {
|
||||
}
|
||||
|
||||
/**
|
||||
generates an array of history objects sense the previous state.
|
||||
The object has the keys opp(the operation preformed),
|
||||
path(the key and if a nested object then each key will be seperated with a `/`)
|
||||
value
|
||||
with the first entry having the note
|
||||
Generates an array of history objects sense the previous state.
|
||||
The object has the keys
|
||||
op (the operation performed),
|
||||
path (the key and if a nested object then each key will be seperated with a `/`)
|
||||
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 newState {object} - the update object
|
||||
@param note {string} - a optional note for the state change
|
||||
@reurns {array}
|
||||
@returns {array}
|
||||
*/
|
||||
function generateHistoryEntry (previousState, newState, note) {
|
||||
const entry = jsonDiffer.compare(previousState, newState)
|
||||
// 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
|
||||
}
|
||||
|
||||
/**
|
||||
Recovers previous txMeta state obj
|
||||
@return {object}
|
||||
@returns {object}
|
||||
*/
|
||||
function replayHistory (_shortHistory) {
|
||||
const shortHistory = clone(_shortHistory)
|
||||
|
@ -158,7 +158,7 @@ class TransactionStateManager extends EventEmitter {
|
||||
/**
|
||||
updates the txMeta in the list and adds a history entry
|
||||
@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) {
|
||||
// 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
|
||||
@ -14,11 +10,6 @@ const { DEFAULT_NETWORK, MAINNET } = require('./controllers/network/enums')
|
||||
*/
|
||||
const initialState = {
|
||||
config: {},
|
||||
NetworkController: {
|
||||
provider: {
|
||||
type: (METAMASK_DEBUG || env === 'test') ? DEFAULT_NETWORK : MAINNET,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = initialState
|
||||
|
@ -25,7 +25,7 @@ function setupRaven(opts) {
|
||||
const report = opts.data
|
||||
try {
|
||||
// handle error-like non-error exceptions
|
||||
nonErrorException(report)
|
||||
rewriteErrorLikeExceptions(report)
|
||||
// simplify certain complex error messages (e.g. Ethjs)
|
||||
simplifyErrorMessages(report)
|
||||
// modify report urls
|
||||
@ -42,27 +42,35 @@ function setupRaven(opts) {
|
||||
return Raven
|
||||
}
|
||||
|
||||
function nonErrorException(report) {
|
||||
// handle errors that lost their error-ness in serialization
|
||||
if (report.message.includes('Non-Error exception captured with keys: message')) {
|
||||
if (!(report.extra && report.extra.__serialized__)) return
|
||||
report.message = `Non-Error Exception: ${report.extra.__serialized__.message}`
|
||||
}
|
||||
function rewriteErrorLikeExceptions(report) {
|
||||
// handle errors that lost their error-ness in serialization (e.g. dnode)
|
||||
rewriteErrorMessages(report, (errorMessage) => {
|
||||
if (!errorMessage.includes('Non-Error exception captured with keys:')) return errorMessage
|
||||
if (!(report.extra && report.extra.__serialized__ && report.extra.__serialized__.message)) return errorMessage
|
||||
return `Non-Error Exception: ${report.extra.__serialized__.message}`
|
||||
})
|
||||
}
|
||||
|
||||
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) {
|
||||
report.exception.values.forEach(item => {
|
||||
let errorMessage = 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
|
||||
item.value = rewriteFn(item.value)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -355,7 +355,6 @@ 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),
|
||||
|
||||
|
96
docs/send-screen-QA-checklist.md
Normal file
96
docs/send-screen-QA-checklist.md
Normal file
@ -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 RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
|
||||
const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
|
||||
const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/controllers/network/enums')
|
||||
|
||||
module.exports = connect(mapStateToProps)(App)
|
||||
|
||||
@ -409,7 +408,6 @@ App.prototype.renderDropdown = function () {
|
||||
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
|
||||
onClick: () => {
|
||||
this.props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
|
||||
.then(() => this.props.dispatch(actions.setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
|
||||
},
|
||||
}, 'Try Beta!'),
|
||||
])
|
||||
@ -472,7 +470,6 @@ App.prototype.renderPrimary = function () {
|
||||
onClick: () => {
|
||||
global.platform.openExtensionInBrowser()
|
||||
props.dispatch(actions.setFeatureFlag('betaUI', true, 'BETA_UI_NOTIFICATION_MODAL'))
|
||||
.then(() => props.dispatch(actions.setNetworkEndpoints(BETA_UI_NETWORK_TYPE)))
|
||||
},
|
||||
style: {
|
||||
fontSize: '0.8em',
|
||||
|
@ -3,17 +3,15 @@ const nock = require('nock')
|
||||
const NetworkController = require('../../app/scripts/controllers/network')
|
||||
const {
|
||||
getNetworkDisplayName,
|
||||
getNetworkEndpoints,
|
||||
} = require('../../app/scripts/controllers/network/util')
|
||||
|
||||
const { createTestProviderTools } = require('../stub/provider')
|
||||
const providerResultStub = {}
|
||||
const provider = createTestProviderTools({ scaffold: providerResultStub }).provider
|
||||
|
||||
describe('# Network Controller', function () {
|
||||
let networkController
|
||||
const noop = () => {}
|
||||
const networkControllerProviderInit = {
|
||||
const networkControllerProviderConfig = {
|
||||
getAccounts: noop,
|
||||
}
|
||||
|
||||
@ -24,11 +22,9 @@ describe('# Network Controller', function () {
|
||||
.post('/metamask')
|
||||
.reply(200)
|
||||
|
||||
networkController = new NetworkController({
|
||||
provider,
|
||||
})
|
||||
networkController = new NetworkController()
|
||||
|
||||
networkController.initializeProvider(networkControllerProviderInit, provider)
|
||||
networkController.initializeProvider(networkControllerProviderConfig)
|
||||
})
|
||||
|
||||
afterEach(function () {
|
||||
@ -38,7 +34,7 @@ describe('# Network Controller', function () {
|
||||
describe('network', function () {
|
||||
describe('#provider', function () {
|
||||
it('provider should be updatable without reassignment', function () {
|
||||
networkController.initializeProvider(networkControllerProviderInit, provider)
|
||||
networkController.initializeProvider(networkControllerProviderConfig)
|
||||
const proxy = networkController._proxy
|
||||
proxy.setTarget({ test: true, on: () => {} })
|
||||
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 () {
|
||||
it('should update provider.type', function () {
|
||||
networkController.setProviderType('mainnet')
|
||||
@ -76,16 +66,11 @@ describe('# Network Controller', function () {
|
||||
const loading = networkController.isNetworkLoading()
|
||||
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', () => {
|
||||
const tests = [
|
||||
{
|
||||
@ -114,9 +99,4 @@ describe('# Network utils', () => {
|
||||
|
||||
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 clone = require('clone')
|
||||
const txStateHistoryHelper = require('../../app/scripts/controllers/transactions/lib/tx-state-history-helper')
|
||||
const testVault = require('../data/v17-long-history.json')
|
||||
|
||||
describe('deepCloneFromTxMeta', function () {
|
||||
it('should clone deep', function () {
|
||||
const input = {
|
||||
foo: {
|
||||
bar: {
|
||||
bam: 'baz'
|
||||
describe ('Transaction state history helper', function () {
|
||||
|
||||
describe('#snapshotFromTxMeta', function () {
|
||||
it('should clone deep', function () {
|
||||
const input = {
|
||||
foo: {
|
||||
bar: {
|
||||
bam: 'baz'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const output = txStateHistoryHelper.snapshotFromTxMeta(input)
|
||||
assert('foo' in output, 'has a foo key')
|
||||
assert('bar' in output.foo, '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')
|
||||
const output = txStateHistoryHelper.snapshotFromTxMeta(input)
|
||||
assert('foo' in output, 'has a foo key')
|
||||
assert('bar' in output.foo, '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')
|
||||
})
|
||||
|
||||
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 () {
|
||||
const input = { foo: 'bar', history: 'remembered' }
|
||||
const output = txStateHistoryHelper.snapshotFromTxMeta(input)
|
||||
assert(typeof output.history, 'undefined', 'should remove history')
|
||||
describe('#migrateFromSnapshotsToDiffs', 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')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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')
|
||||
// modify value and updateTx
|
||||
updatedTx.txParams.gasPrice = desiredGasPrice
|
||||
const before = new Date().getTime()
|
||||
txStateManager.updateTx(updatedTx)
|
||||
const after = new Date().getTime()
|
||||
// check updated value
|
||||
const result = txStateManager.getTx('1')
|
||||
assert.equal(result.txParams.gasPrice, desiredGasPrice, 'gas price updated')
|
||||
// validate history was updated
|
||||
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 }
|
||||
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',
|
||||
|
||||
// Network
|
||||
setNetworkEndpoints,
|
||||
updateNetworkEndpointType,
|
||||
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) {
|
||||
return {
|
||||
type: actions.UPDATE_NETWORK_ENDPOINT_TYPE,
|
||||
|
@ -1,7 +1,7 @@
|
||||
const { Component } = require('react')
|
||||
const PropTypes = require('prop-types')
|
||||
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 h = require('react-hyperscript')
|
||||
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 () {
|
||||
const {
|
||||
isLoading,
|
||||
@ -128,7 +119,7 @@ class App extends Component {
|
||||
// global modal
|
||||
h(Modal, {}, []),
|
||||
|
||||
this.renderAppHeader(),
|
||||
h(AppHeader),
|
||||
|
||||
// sidebar
|
||||
this.renderSidebar(),
|
||||
|
@ -1,9 +1,13 @@
|
||||
import React, { Component } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
import { matchPath } from 'react-router-dom'
|
||||
|
||||
const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../../../app/scripts/lib/enums')
|
||||
const { DEFAULT_ROUTE, CONFIRM_TRANSACTION_ROUTE } = require('../../routes')
|
||||
const {
|
||||
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 NetworkIndicator = require('../network')
|
||||
|
||||
@ -36,13 +40,23 @@ class AppHeader extends Component {
|
||||
: hideNetworkDropdown()
|
||||
}
|
||||
|
||||
isConfirming () {
|
||||
const { location } = this.props
|
||||
|
||||
return Boolean(matchPath(location.pathname, {
|
||||
path: CONFIRM_TRANSACTION_ROUTE, exact: false,
|
||||
}))
|
||||
}
|
||||
|
||||
renderAccountMenu () {
|
||||
const { isUnlocked, toggleAccountMenu, selectedAddress } = this.props
|
||||
|
||||
return isUnlocked && (
|
||||
<div
|
||||
className="account-menu__icon"
|
||||
onClick={toggleAccountMenu}
|
||||
className={classnames('account-menu__icon', {
|
||||
'account-menu__icon--disabled': this.isConfirming(),
|
||||
})}
|
||||
onClick={() => this.isConfirming() || toggleAccountMenu()}
|
||||
>
|
||||
<Identicon
|
||||
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 () {
|
||||
const {
|
||||
network,
|
||||
@ -61,7 +95,7 @@ class AppHeader extends Component {
|
||||
isUnlocked,
|
||||
} = this.props
|
||||
|
||||
if (window.METAMASK_UI_TYPE === ENVIRONMENT_TYPE_NOTIFICATION) {
|
||||
if (this.hideAppHeader()) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,6 @@ const SimpleDropdown = require('../../dropdowns/simple-dropdown')
|
||||
const ToggleButton = require('react-toggle-button')
|
||||
const { REVEAL_SEED_ROUTE } = require('../../../routes')
|
||||
const locales = require('../../../../../app/_locales/index.json')
|
||||
const { OLD_UI_NETWORK_TYPE } = require('../../../../../app/scripts/controllers/network/enums')
|
||||
|
||||
const getInfuraCurrencyOptions = () => {
|
||||
const sortedCurrencies = infuraCurrencies.objects.sort((a, b) => {
|
||||
@ -349,7 +348,6 @@ const mapDispatchToProps = dispatch => {
|
||||
updateCurrentLocale: key => dispatch(actions.updateCurrentLocale(key)),
|
||||
setFeatureFlagToBeta: () => {
|
||||
return dispatch(actions.setFeatureFlag('betaUI', false, 'OLD_UI_NOTIFICATION_MODAL'))
|
||||
.then(() => dispatch(actions.setNetworkEndpoints(OLD_UI_NETWORK_TYPE)))
|
||||
},
|
||||
showResetAccountConfirmationModal: () => {
|
||||
return dispatch(actions.showModal({ name: 'CONFIRM_RESET_ACCOUNT' }))
|
||||
|
@ -175,7 +175,6 @@ UnlockPage.propTypes = {
|
||||
isUnlocked: PropTypes.bool,
|
||||
t: PropTypes.func,
|
||||
useOldInterface: PropTypes.func,
|
||||
setNetworkEndpoints: PropTypes.func,
|
||||
}
|
||||
|
||||
export default UnlockPage
|
||||
|
@ -6,7 +6,6 @@ const {
|
||||
tryUnlockMetamask,
|
||||
forgotPassword,
|
||||
markPasswordForgotten,
|
||||
setNetworkEndpoints,
|
||||
} = require('../../../actions')
|
||||
|
||||
import UnlockPage from './unlock-page.component'
|
||||
@ -23,7 +22,6 @@ const mapDispatchToProps = dispatch => {
|
||||
forgotPassword: () => dispatch(forgotPassword()),
|
||||
tryUnlockMetamask: password => dispatch(tryUnlockMetamask(password)),
|
||||
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 { SEND_ROUTE, DEFAULT_ROUTE } = require('../../routes')
|
||||
const {
|
||||
ENVIRONMENT_TYPE_POPUP,
|
||||
ENVIRONMENT_TYPE_NOTIFICATION,
|
||||
} = require('../../../../app/scripts/lib/enums')
|
||||
|
||||
ConfirmSendEther.contextTypes = {
|
||||
t: PropTypes.func,
|
||||
@ -293,6 +297,14 @@ ConfirmSendEther.prototype.editTransaction = function (txMeta) {
|
||||
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 () {
|
||||
const {
|
||||
currentCurrency,
|
||||
@ -358,7 +370,7 @@ ConfirmSendEther.prototype.render = function () {
|
||||
visibility: !txMeta.lastGasPrice ? 'initial' : 'hidden',
|
||||
},
|
||||
}, 'Edit'),
|
||||
window.METAMASK_UI_TYPE === 'notification' && h(NetworkDisplay),
|
||||
this.renderNetworkDisplay(),
|
||||
]),
|
||||
h('.page-container__title', title),
|
||||
h('.page-container__subtitle', subtitle),
|
||||
|
@ -23,6 +23,10 @@
|
||||
&__icon {
|
||||
margin-left: 20px;
|
||||
cursor: pointer;
|
||||
|
||||
&--disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
|
||||
&__header {
|
||||
|
@ -82,10 +82,6 @@
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
|
||||
.identicon {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@ const getCaretCoordinates = require('textarea-caret')
|
||||
const { RESTORE_VAULT_ROUTE, DEFAULT_ROUTE } = require('../routes')
|
||||
const { getEnvironmentType } = require('../../../app/scripts/lib/util')
|
||||
const { ENVIRONMENT_TYPE_POPUP } = require('../../../app/scripts/lib/enums')
|
||||
const { OLD_UI_NETWORK_TYPE } = require('../../../app/scripts/controllers/network/enums')
|
||||
|
||||
class InitializeMenuScreen extends Component {
|
||||
constructor (props) {
|
||||
@ -190,7 +189,6 @@ class InitializeMenuScreen extends Component {
|
||||
|
||||
showOldUI () {
|
||||
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 OldApp = require('../../old-ui/app/app')
|
||||
const { autoAddToBetaUI } = require('./selectors')
|
||||
const { setFeatureFlag, setNetworkEndpoints } = require('./actions')
|
||||
const { BETA_UI_NETWORK_TYPE } = require('../../app/scripts/controllers/network/enums')
|
||||
const { setFeatureFlag } = require('./actions')
|
||||
const I18nProvider = require('./i18n-provider')
|
||||
|
||||
function mapStateToProps (state) {
|
||||
@ -24,11 +23,9 @@ function mapDispatchToProps (dispatch) {
|
||||
return {
|
||||
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)))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,6 @@ const actions = require('./app/actions')
|
||||
const configureStore = require('./app/store')
|
||||
const txHelper = require('./lib/tx-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')
|
||||
|
||||
module.exports = launchMetamaskUi
|
||||
@ -55,10 +50,6 @@ async 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
|
||||
|
Loading…
Reference in New Issue
Block a user