Improved simple account generation

feature/default_network_editable
Dan Finlay 8 years ago
parent 55d56f77cf
commit 957b7a72b5
  1. 61
      app/scripts/keyring-controller.js
  2. 22
      app/scripts/keyrings/simple.js
  3. 2
      ui/app/actions.js

@ -16,7 +16,7 @@ module.exports = class KeyringController extends EventEmitter {
this.configManager = opts.configManager this.configManager = opts.configManager
this.ethStore = opts.ethStore this.ethStore = opts.ethStore
this.keyrings = [] this.keyrings = []
this.identities = {} // Essentially a nickname hash this.identities = {} // Essentially a name hash
} }
getState() { getState() {
@ -64,8 +64,7 @@ module.exports = class KeyringController extends EventEmitter {
.then((key) => { .then((key) => {
return this.unlockKeyrings(key) return this.unlockKeyrings(key)
}) })
.then((keyrings) => { .then(() => {
this.keyrings = keyrings
cb(null, this.getState()) cb(null, this.getState())
}) })
.catch((err) => { .catch((err) => {
@ -74,7 +73,7 @@ module.exports = class KeyringController extends EventEmitter {
} }
loadKey(password) { loadKey(password) {
const salt = this.configManager.getSalt() const salt = this.configManager.getSalt() || generateSalt()
return encryptor.keyFromPassword(password + salt) return encryptor.keyFromPassword(password + salt)
.then((key) => { .then((key) => {
this.key = key this.key = key
@ -89,9 +88,10 @@ module.exports = class KeyringController extends EventEmitter {
const accounts = keyring.addAccounts(1) const accounts = keyring.addAccounts(1)
accounts.forEach((account) => { accounts.forEach((account) => {
this.createBalanceAndNickname(account, i) this.loadBalanceAndNickname(account, i)
}) })
this.keyrings.push(keyring)
this.persistAllKeyrings() this.persistAllKeyrings()
.then(() => { .then(() => {
cb(this.getState()) cb(this.getState())
@ -102,28 +102,36 @@ module.exports = class KeyringController extends EventEmitter {
} }
// Takes an account address and an iterator representing // Takes an account address and an iterator representing
// the current number of nicknamed accounts. // the current number of named accounts.
createBalanceAndNickname(account, i) { loadBalanceAndNickname(account, i) {
this.ethStore.addAccount(ethUtil.addHexPrefix(account)) const address = ethUtil.addHexPrefix(account)
const oldNickname = this.configManager.nicknameForWallet(account) this.ethStore.addAccount(address)
const nickname = oldNickname || `Account ${++i}` const oldNickname = this.configManager.nicknameForWallet(address)
this.identities[account] = { const name = oldNickname || `Account ${++i}`
address: account, this.identities[address] = {
nickname, address,
name,
} }
this.saveAccountLabel(account, nickname) this.saveAccountLabel(address, name)
} }
saveAccountLabel (account, label, cb) { saveAccountLabel (account, label, cb) {
const address = ethUtil.addHexPrefix(account)
const configManager = this.configManager const configManager = this.configManager
configManager.setNicknameForWallet(account, label) configManager.setNicknameForWallet(address, label)
if (cb) { if (cb) {
cb(null, label) cb(null, label)
} }
} }
persistAllKeyrings() { persistAllKeyrings() {
const serialized = this.keyrings.map(k => k.serialize()) const serialized = this.keyrings.map((k) => {
return {
type: k.type,
// keyring.serialize() must return a JSON-encodable object.
data: k.serialize(),
}
})
return encryptor.encryptWithKey(this.key, serialized) return encryptor.encryptWithKey(this.key, serialized)
.then((encryptedString) => { .then((encryptedString) => {
this.configManager.setVault(encryptedString) this.configManager.setVault(encryptedString)
@ -138,15 +146,21 @@ module.exports = class KeyringController extends EventEmitter {
const encryptedVault = this.configManager.getVault() const encryptedVault = this.configManager.getVault()
return encryptor.decryptWithKey(key, encryptedVault) return encryptor.decryptWithKey(key, encryptedVault)
.then((vault) => { .then((vault) => {
this.keyrings = vault.map(this.restoreKeyring) this.keyrings = vault.map(this.restoreKeyring.bind(this, 0))
return this.keyrings return this.keyrings
}) })
} }
restoreKeyring(serialized) { restoreKeyring(serialized, i) {
const { type } = serialized const { type, data } = serialized
const Keyring = this.getKeyringClassForType(type) const Keyring = this.getKeyringClassForType(type)
const keyring = new Keyring(serialized) const keyring = new Keyring()
keyring.deserialize(data)
keyring.getAccounts().forEach((account) => {
this.loadBalanceAndNickname(account, i)
})
return keyring return keyring
} }
@ -162,7 +176,8 @@ module.exports = class KeyringController extends EventEmitter {
} }
getAccounts() { getAccounts() {
return this.keyrings.map(kr => kr.getAccounts()) const keyrings = this.keyrings || []
return keyrings.map(kr => kr.getAccounts())
.reduce((res, arr) => { .reduce((res, arr) => {
return res.concat(arr) return res.concat(arr)
}, []) }, [])
@ -207,8 +222,8 @@ module.exports = class KeyringController extends EventEmitter {
} }
function generateSalt (byteCount) { function generateSalt (byteCount = 32) {
var view = new Uint8Array(32) var view = new Uint8Array(byteCount)
global.crypto.getRandomValues(view) global.crypto.getRandomValues(view)
var b64encoded = btoa(String.fromCharCode.apply(null, view)) var b64encoded = btoa(String.fromCharCode.apply(null, view))
return b64encoded return b64encoded

@ -12,17 +12,19 @@ module.exports = class SimpleKeyring extends EventEmitter {
super() super()
this.type = type this.type = type
this.opts = opts || {} this.opts = opts || {}
const walletData = this.opts.wallets || [] this.wallets = []
this.wallets = walletData.map((w) => {
return Wallet.fromPrivateKey(w)
})
} }
serialize() { serialize() {
return { return this.wallets.map(w => w.getPrivateKey().toString('hex'))
type,
wallets: this.wallets.map(w => w.getPrivateKey()),
} }
deserialize(wallets = []) {
this.wallets = wallets.map((w) => {
var b = new Buffer(w, 'hex')
const wallet = Wallet.fromPrivateKey(b)
return wallet
})
} }
addAccounts(n = 1) { addAccounts(n = 1) {
@ -30,12 +32,12 @@ module.exports = class SimpleKeyring extends EventEmitter {
for (var i = 0; i < n; i++) { for (var i = 0; i < n; i++) {
newWallets.push(Wallet.generate()) newWallets.push(Wallet.generate())
} }
this.wallets.concat(newWallets) this.wallets = this.wallets.concat(newWallets)
return newWallets.map(w => w.getAddress()) return newWallets.map(w => w.getAddress().toString('hex'))
} }
getAccounts() { getAccounts() {
return this.wallets.map(w => w.getAddress()) return this.wallets.map(w => w.getAddress().toString('hex'))
} }
} }

@ -195,7 +195,7 @@ function addNewKeyring (type, opts) {
background.addNewKeyring(type, opts, (err, newState) => { background.addNewKeyring(type, opts, (err, newState) => {
dispatch(this.hideLoadingIndication()) dispatch(this.hideLoadingIndication())
if (err) { if (err) {
return dispatch(actions.showWarning(err.message)) return dispatch(actions.showWarning(err))
} }
dispatch(this.updateMetamaskState(newState)) dispatch(this.updateMetamaskState(newState))
dispatch(this.showAccountsPage()) dispatch(this.showAccountsPage())

Loading…
Cancel
Save