aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/scripts/keyring-controller.js111
-rw-r--r--app/scripts/keyrings/simple.js41
-rw-r--r--app/scripts/lib/idStore.js1
-rw-r--r--app/scripts/metamask-controller.js2
-rw-r--r--package.json1
-rw-r--r--ui/app/accounts/index.js6
-rw-r--r--ui/app/actions.js16
-rw-r--r--ui/app/app.js1
8 files changed, 166 insertions, 13 deletions
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index d25dddba1..86d61b22b 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -1,7 +1,13 @@
const EventEmitter = require('events').EventEmitter
const encryptor = require('./lib/encryptor')
const messageManager = require('./lib/message-manager')
+const ethUtil = require('ethereumjs-util')
+// Keyrings:
+const SimpleKeyring = require('./keyrings/simple')
+const keyringTypes = [
+ SimpleKeyring,
+]
module.exports = class KeyringController extends EventEmitter {
@@ -9,14 +15,15 @@ module.exports = class KeyringController extends EventEmitter {
super()
this.configManager = opts.configManager
this.ethStore = opts.ethStore
- this.keyChains = []
+ this.keyrings = []
+ this.identities = {} // Essentially a nickname hash
}
getState() {
return {
isInitialized: !!this.configManager.getVault(),
isUnlocked: !!this.key,
- isConfirmed: true, // this.configManager.getConfirmed(),
+ isConfirmed: true, // AUDIT this.configManager.getConfirmed(),
isEthConfirmed: this.configManager.getShouldntShowWarning(),
unconfTxs: this.configManager.unconfirmedTxs(),
transactions: this.configManager.getTxList(),
@@ -27,6 +34,8 @@ module.exports = class KeyringController extends EventEmitter {
currentFiat: this.configManager.getCurrentFiat(),
conversionRate: this.configManager.getConversionRate(),
conversionDate: this.configManager.getConversionDate(),
+ keyringTypes: keyringTypes.map((krt) => krt.type()),
+ identities: this.identities,
}
}
@@ -39,7 +48,7 @@ module.exports = class KeyringController extends EventEmitter {
this.configManager.setSalt(salt)
this.loadKey(password)
.then((key) => {
- return encryptor.encryptWithKey(key, {})
+ return encryptor.encryptWithKey(key, [])
})
.then((encryptedString) => {
this.configManager.setVault(encryptedString)
@@ -53,6 +62,10 @@ module.exports = class KeyringController extends EventEmitter {
submitPassword(password, cb) {
this.loadKey(password)
.then((key) => {
+ return this.unlockKeyrings(key)
+ })
+ .then((keyrings) => {
+ this.keyrings = keyrings
cb(null, this.getState())
})
.catch((err) => {
@@ -69,8 +82,94 @@ module.exports = class KeyringController extends EventEmitter {
})
}
+ addNewKeyring(type, opts, cb) {
+ const i = this.getAccounts().length
+ const Keyring = this.getKeyringClassForType(type)
+ const keyring = new Keyring(opts)
+ const accounts = keyring.addAccounts(1)
+
+ accounts.forEach((account) => {
+ this.createBalanceAndNickname(account, i)
+ })
+
+ this.persistAllKeyrings()
+ .then(() => {
+ cb(this.getState())
+ })
+ .catch((reason) => {
+ cb(reason)
+ })
+ }
+
+ // Takes an account address and an iterator representing
+ // the current number of nicknamed accounts.
+ createBalanceAndNickname(account, i) {
+ this.ethStore.addAccount(ethUtil.addHexPrefix(account))
+ const oldNickname = this.configManager.nicknameForWallet(account)
+ const nickname = oldNickname || `Account ${++i}`
+ this.identities[account] = {
+ address: account,
+ nickname,
+ }
+ this.saveAccountLabel(account, nickname)
+ }
+
+ saveAccountLabel (account, label, cb) {
+ const configManager = this.configManager
+ configManager.setNicknameForWallet(account, label)
+ if (cb) {
+ cb(null, label)
+ }
+ }
+
+ persistAllKeyrings() {
+ const serialized = this.keyrings.map(k => k.serialize())
+ return encryptor.encryptWithKey(this.key, serialized)
+ .then((encryptedString) => {
+ this.configManager.setVault(encryptedString)
+ return true
+ })
+ .catch((reason) => {
+ console.error('Failed to persist keyrings.', reason)
+ })
+ }
+
+ unlockKeyrings(key) {
+ const encryptedVault = this.configManager.getVault()
+ return encryptor.decryptWithKey(key, encryptedVault)
+ .then((vault) => {
+ this.keyrings = vault.map(this.restoreKeyring)
+ return this.keyrings
+ })
+ }
+
+ restoreKeyring(serialized) {
+ const { type } = serialized
+ const Keyring = this.getKeyringClassForType(type)
+ const keyring = new Keyring(serialized)
+ return keyring
+ }
+
+ getKeyringClassForType(type) {
+ const Keyring = keyringTypes.reduce((res, kr) => {
+ if (kr.type() === type) {
+ return kr
+ } else {
+ return res
+ }
+ })
+ return Keyring
+ }
+
+ getAccounts() {
+ return this.keyrings.map(kr => kr.getAccounts())
+ .reduce((res, arr) => {
+ return res.concat(arr)
+ }, [])
+ }
+
setSelectedAddress(address, cb) {
- this.selectedAddress = address
+ this.configManager.setSelectedAccount(address)
cb(null, address)
}
@@ -102,10 +201,6 @@ module.exports = class KeyringController extends EventEmitter {
cb(null, '0xPrivateKey')
}
- saveAccountLabel(account, label, cb) {
- cb(/* null, label */)
- }
-
tryPassword(password, cb) {
cb()
}
diff --git a/app/scripts/keyrings/simple.js b/app/scripts/keyrings/simple.js
new file mode 100644
index 000000000..3eda9b8f9
--- /dev/null
+++ b/app/scripts/keyrings/simple.js
@@ -0,0 +1,41 @@
+const EventEmitter = require('events').EventEmitter
+const Wallet = require('ethereumjs-wallet')
+const type = 'Simple Key Pair'
+
+module.exports = class SimpleKeyring extends EventEmitter {
+
+ static type() {
+ return type
+ }
+
+ constructor(opts) {
+ super()
+ this.type = type
+ this.opts = opts || {}
+ const walletData = this.opts.wallets || []
+ this.wallets = walletData.map((w) => {
+ return Wallet.fromPrivateKey(w)
+ })
+ }
+
+ serialize() {
+ return {
+ type,
+ wallets: this.wallets.map(w => w.getPrivateKey()),
+ }
+ }
+
+ addAccounts(n = 1) {
+ var newWallets = []
+ for (var i = 0; i < n; i++) {
+ newWallets.push(Wallet.generate())
+ }
+ this.wallets.concat(newWallets)
+ return newWallets.map(w => w.getAddress())
+ }
+
+ getAccounts() {
+ return this.wallets.map(w => w.getAddress())
+ }
+
+}
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index 9d0ca7f19..416b65b85 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -114,7 +114,6 @@ IdentityStore.prototype.getState = function () {
conversionRate: configManager.getConversionRate(),
conversionDate: configManager.getConversionDate(),
gasMultiplier: configManager.getGasMultiplier(),
-
}))
}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 92551d633..0d12931f6 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -61,6 +61,7 @@ module.exports = class MetamaskController {
// forward directly to idStore
createNewVault: idStore.createNewVault.bind(idStore),
+ addNewKeyring: idStore.addNewKeyring.bind(idStore),
submitPassword: idStore.submitPassword.bind(idStore),
setSelectedAddress: idStore.setSelectedAddress.bind(idStore),
approveTransaction: idStore.approveTransaction.bind(idStore),
@@ -183,6 +184,7 @@ module.exports = class MetamaskController {
})
this.idStore.on('update', function (state) {
storeSetFromObj(publicConfigStore, idStoreToPublic(state))
+ this.sendUpdate()
})
// idStore substate
diff --git a/package.json b/package.json
index 70ca1c7d4..bb472a8fe 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
"eth-store": "^1.1.0",
"ethereumjs-tx": "^1.0.0",
"ethereumjs-util": "^4.4.0",
+ "ethereumjs-wallet": "^0.6.0",
"express": "^4.14.0",
"gulp-eslint": "^2.0.0",
"hat": "0.0.3",
diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js
index 7551c498e..92054f24d 100644
--- a/ui/app/accounts/index.js
+++ b/ui/app/accounts/index.js
@@ -87,7 +87,7 @@ AccountsScreen.prototype.render = function () {
h('div.footer.hover-white.pointer', {
key: 'reveal-account-bar',
onClick: () => {
- this.onRevealAccount()
+ this.addNewKeyring()
},
style: {
display: 'flex',
@@ -146,8 +146,8 @@ AccountsScreen.prototype.onShowDetail = function (address, event) {
this.props.dispatch(actions.showAccountDetail(address))
}
-AccountsScreen.prototype.onRevealAccount = function () {
- this.props.dispatch(actions.revealAccount())
+AccountsScreen.prototype.addNewKeyring = function () {
+ this.props.dispatch(actions.addNewKeyring('Simple Key Pair'))
}
AccountsScreen.prototype.goHome = function () {
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 230ffee78..e49cac4b4 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -25,6 +25,7 @@ var actions = {
showInitializeMenu: showInitializeMenu,
createNewVault: createNewVault,
createNewVaultInProgress: createNewVaultInProgress,
+ addNewKeyring: addNewKeyring,
showNewVaultSeed: showNewVaultSeed,
showInfoPage: showInfoPage,
// unlock screen
@@ -136,6 +137,7 @@ var actions = {
SHOW_NEW_KEYCHAIN: 'SHOW_NEW_KEYCHAIN',
showNewKeychain: showNewKeychain,
+
}
module.exports = actions
@@ -187,6 +189,20 @@ function createNewVault (password, entropy) {
}
}
+function addNewKeyring (type, opts) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ background.addNewKeyring(type, opts, (err, newState) => {
+ dispatch(this.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.showWarning(err.message))
+ }
+ dispatch(this.updateMetamaskState(newState))
+ dispatch(this.showAccountsPage())
+ })
+ }
+}
+
function showInfoPage () {
return {
type: actions.SHOW_INFO_PAGE,
diff --git a/ui/app/app.js b/ui/app/app.js
index fb9b16a3a..3ceae0027 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -405,7 +405,6 @@ App.prototype.renderPrimary = function () {
// show current view
switch (props.currentView.name) {
-
case 'createVault':
return h(CreateVaultScreen, {key: 'createVault'})