|
|
@ -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 |
|
|
|