mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #2389 from MetaMask/i2348-SelectAccountOnNewVault
Select first account on create or restore vault
This commit is contained in:
commit
e3a7da961d
@ -3,6 +3,7 @@
|
|||||||
## Current Master
|
## Current Master
|
||||||
|
|
||||||
- Fix bug where web3 API was sometimes injected after the page loaded.
|
- Fix bug where web3 API was sometimes injected after the page loaded.
|
||||||
|
- Fix bug where first account was sometimes not selected correctly after creating or restoring a vault.
|
||||||
- Fix bug where imported accounts could not use new eth_signTypedData method.
|
- Fix bug where imported accounts could not use new eth_signTypedData method.
|
||||||
|
|
||||||
## 3.11.0 2017-10-11
|
## 3.11.0 2017-10-11
|
||||||
|
@ -5,7 +5,9 @@ const BN = require('ethereumjs-util').BN
|
|||||||
class BalanceController {
|
class BalanceController {
|
||||||
|
|
||||||
constructor (opts = {}) {
|
constructor (opts = {}) {
|
||||||
|
this._validateParams(opts)
|
||||||
const { address, accountTracker, txController, blockTracker } = opts
|
const { address, accountTracker, txController, blockTracker } = opts
|
||||||
|
|
||||||
this.address = address
|
this.address = address
|
||||||
this.accountTracker = accountTracker
|
this.accountTracker = accountTracker
|
||||||
this.txController = txController
|
this.txController = txController
|
||||||
@ -65,6 +67,14 @@ class BalanceController {
|
|||||||
return pending
|
return pending
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_validateParams (opts) {
|
||||||
|
const { address, accountTracker, txController, blockTracker } = opts
|
||||||
|
if (!address || !accountTracker || !txController || !blockTracker) {
|
||||||
|
const error = 'Cannot construct a balance checker without address, accountTracker, txController, and blockTracker.'
|
||||||
|
throw new Error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = BalanceController
|
module.exports = BalanceController
|
||||||
|
@ -20,23 +20,34 @@ class ComputedbalancesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateAllBalances () {
|
updateAllBalances () {
|
||||||
for (let address in this.accountTracker.store.getState().accounts) {
|
Object.keys(this.balances).forEach((balance) => {
|
||||||
|
const address = balance.address
|
||||||
this.balances[address].updateBalance()
|
this.balances[address].updateBalance()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_initBalanceUpdating () {
|
_initBalanceUpdating () {
|
||||||
const store = this.accountTracker.store.getState()
|
const store = this.accountTracker.store.getState()
|
||||||
this.addAnyAccountsFromStore(store)
|
this.syncAllAccountsFromStore(store)
|
||||||
this.accountTracker.store.subscribe(this.addAnyAccountsFromStore.bind(this))
|
this.accountTracker.store.subscribe(this.syncAllAccountsFromStore.bind(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
addAnyAccountsFromStore(store) {
|
syncAllAccountsFromStore(store) {
|
||||||
const balances = store.accounts
|
const upstream = Object.keys(store.accounts)
|
||||||
|
const balances = Object.keys(this.balances)
|
||||||
|
.map(address => this.balances[address])
|
||||||
|
|
||||||
|
// Follow new addresses
|
||||||
for (let address in balances) {
|
for (let address in balances) {
|
||||||
this.trackAddressIfNotAlready(address)
|
this.trackAddressIfNotAlready(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unfollow old ones
|
||||||
|
balances.forEach(({ address }) => {
|
||||||
|
if (!upstream.includes(address)) {
|
||||||
|
delete this.balances[address]
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
trackAddressIfNotAlready (address) {
|
trackAddressIfNotAlready (address) {
|
||||||
|
@ -38,6 +38,29 @@ class AccountTracker extends EventEmitter {
|
|||||||
// public
|
// public
|
||||||
//
|
//
|
||||||
|
|
||||||
|
syncWithAddresses (addresses) {
|
||||||
|
const accounts = this.store.getState().accounts
|
||||||
|
const locals = Object.keys(accounts)
|
||||||
|
|
||||||
|
const toAdd = []
|
||||||
|
addresses.forEach((upstream) => {
|
||||||
|
if (!locals.includes(upstream)) {
|
||||||
|
toAdd.push(upstream)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const toRemove = []
|
||||||
|
locals.forEach((local) => {
|
||||||
|
if (!addresses.includes(local)) {
|
||||||
|
toRemove.push(local)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
toAdd.forEach(upstream => this.addAccount(upstream))
|
||||||
|
toRemove.forEach(local => this.removeAccount(local))
|
||||||
|
this._updateAccounts()
|
||||||
|
}
|
||||||
|
|
||||||
addAccount (address) {
|
addAccount (address) {
|
||||||
const accounts = this.store.getState().accounts
|
const accounts = this.store.getState().accounts
|
||||||
accounts[address] = {}
|
accounts[address] = {}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
const EventEmitter = require('events')
|
const EventEmitter = require('events')
|
||||||
const extend = require('xtend')
|
const extend = require('xtend')
|
||||||
const promiseToCallback = require('promise-to-callback')
|
|
||||||
const pump = require('pump')
|
const pump = require('pump')
|
||||||
const Dnode = require('dnode')
|
const Dnode = require('dnode')
|
||||||
const ObservableStore = require('obs-store')
|
const ObservableStore = require('obs-store')
|
||||||
@ -96,25 +95,20 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
// key mgmt
|
// key mgmt
|
||||||
this.keyringController = new KeyringController({
|
this.keyringController = new KeyringController({
|
||||||
initState: initState.KeyringController,
|
initState: initState.KeyringController,
|
||||||
accountTracker: this.accountTracker,
|
|
||||||
getNetwork: this.networkController.getNetworkState.bind(this.networkController),
|
getNetwork: this.networkController.getNetworkState.bind(this.networkController),
|
||||||
encryptor: opts.encryptor || undefined,
|
encryptor: opts.encryptor || undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
// If only one account exists, make sure it is selected.
|
// If only one account exists, make sure it is selected.
|
||||||
this.keyringController.store.subscribe((state) => {
|
this.keyringController.memStore.subscribe((state) => {
|
||||||
const addresses = Object.keys(state.walletNicknames || {})
|
const addresses = state.keyrings.reduce((res, keyring) => {
|
||||||
|
return res.concat(keyring.accounts)
|
||||||
|
}, [])
|
||||||
if (addresses.length === 1) {
|
if (addresses.length === 1) {
|
||||||
const address = addresses[0]
|
const address = addresses[0]
|
||||||
this.preferencesController.setSelectedAddress(address)
|
this.preferencesController.setSelectedAddress(address)
|
||||||
}
|
}
|
||||||
})
|
this.accountTracker.syncWithAddresses(addresses)
|
||||||
this.keyringController.on('newAccount', (address) => {
|
|
||||||
this.preferencesController.setSelectedAddress(address)
|
|
||||||
this.accountTracker.addAccount(address)
|
|
||||||
})
|
|
||||||
this.keyringController.on('removedAccount', (address) => {
|
|
||||||
this.accountTracker.removeAccount(address)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// address book controller
|
// address book controller
|
||||||
@ -329,13 +323,13 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
createShapeShiftTx: this.createShapeShiftTx.bind(this),
|
createShapeShiftTx: this.createShapeShiftTx.bind(this),
|
||||||
|
|
||||||
// primary HD keyring management
|
// primary HD keyring management
|
||||||
addNewAccount: this.addNewAccount.bind(this),
|
addNewAccount: nodeify(this.addNewAccount, this),
|
||||||
placeSeedWords: this.placeSeedWords.bind(this),
|
placeSeedWords: this.placeSeedWords.bind(this),
|
||||||
clearSeedWordCache: this.clearSeedWordCache.bind(this),
|
clearSeedWordCache: this.clearSeedWordCache.bind(this),
|
||||||
importAccountWithStrategy: this.importAccountWithStrategy.bind(this),
|
importAccountWithStrategy: this.importAccountWithStrategy.bind(this),
|
||||||
|
|
||||||
// vault management
|
// vault management
|
||||||
submitPassword: this.submitPassword.bind(this),
|
submitPassword: nodeify(keyringController.submitPassword, keyringController),
|
||||||
|
|
||||||
// network management
|
// network management
|
||||||
setProviderType: nodeify(networkController.setProviderType, networkController),
|
setProviderType: nodeify(networkController.setProviderType, networkController),
|
||||||
@ -351,8 +345,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
|
|
||||||
// KeyringController
|
// KeyringController
|
||||||
setLocked: nodeify(keyringController.setLocked, keyringController),
|
setLocked: nodeify(keyringController.setLocked, keyringController),
|
||||||
createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain, keyringController),
|
createNewVaultAndKeychain: nodeify(this.createNewVaultAndKeychain, this),
|
||||||
createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore, keyringController),
|
createNewVaultAndRestore: nodeify(this.createNewVaultAndRestore, this),
|
||||||
addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController),
|
addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController),
|
||||||
saveAccountLabel: nodeify(keyringController.saveAccountLabel, keyringController),
|
saveAccountLabel: nodeify(keyringController.saveAccountLabel, keyringController),
|
||||||
exportAccount: nodeify(keyringController.exportAccount, keyringController),
|
exportAccount: nodeify(keyringController.exportAccount, keyringController),
|
||||||
@ -473,20 +467,43 @@ module.exports = class MetamaskController extends EventEmitter {
|
|||||||
// Vault Management
|
// Vault Management
|
||||||
//
|
//
|
||||||
|
|
||||||
submitPassword (password, cb) {
|
async createNewVaultAndKeychain (password, cb) {
|
||||||
return this.keyringController.submitPassword(password)
|
const vault = await this.keyringController.createNewVaultAndKeychain(password)
|
||||||
.then((newState) => { cb(null, newState) })
|
this.selectFirstIdentity(vault)
|
||||||
.catch((reason) => { cb(reason) })
|
return vault
|
||||||
|
}
|
||||||
|
|
||||||
|
async createNewVaultAndRestore (password, seed, cb) {
|
||||||
|
const vault = await this.keyringController.createNewVaultAndRestore(password, seed)
|
||||||
|
this.selectFirstIdentity(vault)
|
||||||
|
return vault
|
||||||
|
}
|
||||||
|
|
||||||
|
selectFirstIdentity (vault) {
|
||||||
|
const { identities } = vault
|
||||||
|
const address = Object.keys(identities)[0]
|
||||||
|
this.preferencesController.setSelectedAddress(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Opinionated Keyring Management
|
// Opinionated Keyring Management
|
||||||
//
|
//
|
||||||
|
|
||||||
addNewAccount (cb) {
|
async addNewAccount (cb) {
|
||||||
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
|
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
|
||||||
if (!primaryKeyring) return cb(new Error('MetamaskController - No HD Key Tree found'))
|
if (!primaryKeyring) return cb(new Error('MetamaskController - No HD Key Tree found'))
|
||||||
promiseToCallback(this.keyringController.addNewAccount(primaryKeyring))(cb)
|
const keyringController = this.keyringController
|
||||||
|
const oldAccounts = await keyringController.getAccounts()
|
||||||
|
const keyState = await keyringController.addNewAccount(primaryKeyring)
|
||||||
|
const newAccounts = await keyringController.getAccounts()
|
||||||
|
|
||||||
|
newAccounts.forEach((address) => {
|
||||||
|
if (!oldAccounts.includes(address)) {
|
||||||
|
this.preferencesController.setSelectedAddress(address)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return keyState
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds the current vault's seed words to the UI's state tree.
|
// Adds the current vault's seed words to the UI's state tree.
|
||||||
|
@ -134,7 +134,7 @@
|
|||||||
"redux-logger": "^3.0.6",
|
"redux-logger": "^3.0.6",
|
||||||
"redux-thunk": "^2.2.0",
|
"redux-thunk": "^2.2.0",
|
||||||
"request-promise": "^4.2.1",
|
"request-promise": "^4.2.1",
|
||||||
"sandwich-expando": "^1.0.5",
|
"sandwich-expando": "^1.1.3",
|
||||||
"semaphore": "^1.0.5",
|
"semaphore": "^1.0.5",
|
||||||
"sw-stream": "^2.0.0",
|
"sw-stream": "^2.0.0",
|
||||||
"textarea-caret": "^3.0.1",
|
"textarea-caret": "^3.0.1",
|
||||||
|
@ -43,7 +43,12 @@ function rootReducer (state, action) {
|
|||||||
|
|
||||||
window.logState = function () {
|
window.logState = function () {
|
||||||
let state = window.METAMASK_CACHED_LOG_STATE
|
let state = window.METAMASK_CACHED_LOG_STATE
|
||||||
const version = global.platform.getVersion()
|
let version
|
||||||
|
try {
|
||||||
|
version = global.platform.getVersion()
|
||||||
|
} catch (e) {
|
||||||
|
version = 'unable to load version.'
|
||||||
|
}
|
||||||
state.version = version
|
state.version = version
|
||||||
let stateString = JSON.stringify(state, removeSeedWords, 2)
|
let stateString = JSON.stringify(state, removeSeedWords, 2)
|
||||||
return stateString
|
return stateString
|
||||||
|
Loading…
Reference in New Issue
Block a user