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
|
||||
|
||||
- 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.
|
||||
|
||||
## 3.11.0 2017-10-11
|
||||
|
@ -5,7 +5,9 @@ const BN = require('ethereumjs-util').BN
|
||||
class BalanceController {
|
||||
|
||||
constructor (opts = {}) {
|
||||
this._validateParams(opts)
|
||||
const { address, accountTracker, txController, blockTracker } = opts
|
||||
|
||||
this.address = address
|
||||
this.accountTracker = accountTracker
|
||||
this.txController = txController
|
||||
@ -65,6 +67,14 @@ class BalanceController {
|
||||
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
|
||||
|
@ -20,23 +20,34 @@ class ComputedbalancesController {
|
||||
}
|
||||
|
||||
updateAllBalances () {
|
||||
for (let address in this.accountTracker.store.getState().accounts) {
|
||||
Object.keys(this.balances).forEach((balance) => {
|
||||
const address = balance.address
|
||||
this.balances[address].updateBalance()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
_initBalanceUpdating () {
|
||||
const store = this.accountTracker.store.getState()
|
||||
this.addAnyAccountsFromStore(store)
|
||||
this.accountTracker.store.subscribe(this.addAnyAccountsFromStore.bind(this))
|
||||
this.syncAllAccountsFromStore(store)
|
||||
this.accountTracker.store.subscribe(this.syncAllAccountsFromStore.bind(this))
|
||||
}
|
||||
|
||||
addAnyAccountsFromStore(store) {
|
||||
const balances = store.accounts
|
||||
syncAllAccountsFromStore(store) {
|
||||
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) {
|
||||
this.trackAddressIfNotAlready(address)
|
||||
}
|
||||
|
||||
// Unfollow old ones
|
||||
balances.forEach(({ address }) => {
|
||||
if (!upstream.includes(address)) {
|
||||
delete this.balances[address]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
trackAddressIfNotAlready (address) {
|
||||
|
@ -38,6 +38,29 @@ class AccountTracker extends EventEmitter {
|
||||
// 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) {
|
||||
const accounts = this.store.getState().accounts
|
||||
accounts[address] = {}
|
||||
|
@ -1,6 +1,5 @@
|
||||
const EventEmitter = require('events')
|
||||
const extend = require('xtend')
|
||||
const promiseToCallback = require('promise-to-callback')
|
||||
const pump = require('pump')
|
||||
const Dnode = require('dnode')
|
||||
const ObservableStore = require('obs-store')
|
||||
@ -96,25 +95,20 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
// key mgmt
|
||||
this.keyringController = new KeyringController({
|
||||
initState: initState.KeyringController,
|
||||
accountTracker: this.accountTracker,
|
||||
getNetwork: this.networkController.getNetworkState.bind(this.networkController),
|
||||
encryptor: opts.encryptor || undefined,
|
||||
})
|
||||
|
||||
// If only one account exists, make sure it is selected.
|
||||
this.keyringController.store.subscribe((state) => {
|
||||
const addresses = Object.keys(state.walletNicknames || {})
|
||||
this.keyringController.memStore.subscribe((state) => {
|
||||
const addresses = state.keyrings.reduce((res, keyring) => {
|
||||
return res.concat(keyring.accounts)
|
||||
}, [])
|
||||
if (addresses.length === 1) {
|
||||
const address = addresses[0]
|
||||
this.preferencesController.setSelectedAddress(address)
|
||||
}
|
||||
})
|
||||
this.keyringController.on('newAccount', (address) => {
|
||||
this.preferencesController.setSelectedAddress(address)
|
||||
this.accountTracker.addAccount(address)
|
||||
})
|
||||
this.keyringController.on('removedAccount', (address) => {
|
||||
this.accountTracker.removeAccount(address)
|
||||
this.accountTracker.syncWithAddresses(addresses)
|
||||
})
|
||||
|
||||
// address book controller
|
||||
@ -329,13 +323,13 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
createShapeShiftTx: this.createShapeShiftTx.bind(this),
|
||||
|
||||
// primary HD keyring management
|
||||
addNewAccount: this.addNewAccount.bind(this),
|
||||
addNewAccount: nodeify(this.addNewAccount, this),
|
||||
placeSeedWords: this.placeSeedWords.bind(this),
|
||||
clearSeedWordCache: this.clearSeedWordCache.bind(this),
|
||||
importAccountWithStrategy: this.importAccountWithStrategy.bind(this),
|
||||
|
||||
// vault management
|
||||
submitPassword: this.submitPassword.bind(this),
|
||||
submitPassword: nodeify(keyringController.submitPassword, keyringController),
|
||||
|
||||
// network management
|
||||
setProviderType: nodeify(networkController.setProviderType, networkController),
|
||||
@ -351,8 +345,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
|
||||
// KeyringController
|
||||
setLocked: nodeify(keyringController.setLocked, keyringController),
|
||||
createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain, keyringController),
|
||||
createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore, keyringController),
|
||||
createNewVaultAndKeychain: nodeify(this.createNewVaultAndKeychain, this),
|
||||
createNewVaultAndRestore: nodeify(this.createNewVaultAndRestore, this),
|
||||
addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController),
|
||||
saveAccountLabel: nodeify(keyringController.saveAccountLabel, keyringController),
|
||||
exportAccount: nodeify(keyringController.exportAccount, keyringController),
|
||||
@ -473,20 +467,43 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||
// Vault Management
|
||||
//
|
||||
|
||||
submitPassword (password, cb) {
|
||||
return this.keyringController.submitPassword(password)
|
||||
.then((newState) => { cb(null, newState) })
|
||||
.catch((reason) => { cb(reason) })
|
||||
async createNewVaultAndKeychain (password, cb) {
|
||||
const vault = await this.keyringController.createNewVaultAndKeychain(password)
|
||||
this.selectFirstIdentity(vault)
|
||||
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
|
||||
//
|
||||
|
||||
addNewAccount (cb) {
|
||||
async addNewAccount (cb) {
|
||||
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
|
||||
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.
|
||||
|
@ -134,7 +134,7 @@
|
||||
"redux-logger": "^3.0.6",
|
||||
"redux-thunk": "^2.2.0",
|
||||
"request-promise": "^4.2.1",
|
||||
"sandwich-expando": "^1.0.5",
|
||||
"sandwich-expando": "^1.1.3",
|
||||
"semaphore": "^1.0.5",
|
||||
"sw-stream": "^2.0.0",
|
||||
"textarea-caret": "^3.0.1",
|
||||
|
@ -43,7 +43,12 @@ function rootReducer (state, action) {
|
||||
|
||||
window.logState = function () {
|
||||
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
|
||||
let stateString = JSON.stringify(state, removeSeedWords, 2)
|
||||
return stateString
|
||||
|
Loading…
Reference in New Issue
Block a user