diff options
author | Dan Finlay <dan@danfinlay.com> | 2016-10-21 07:44:31 +0800 |
---|---|---|
committer | Dan Finlay <dan@danfinlay.com> | 2016-10-21 07:45:58 +0800 |
commit | 55d56f77cf42a9c4e80768fd7e4a9bb6f0485606 (patch) | |
tree | 188e95248f865459b5a816ea51f889145f43d92b | |
parent | 351c8e2086e043ee66e42f653dcb2b446dd88808 (diff) | |
download | tangerine-wallet-browser-55d56f77cf42a9c4e80768fd7e4a9bb6f0485606.tar tangerine-wallet-browser-55d56f77cf42a9c4e80768fd7e4a9bb6f0485606.tar.gz tangerine-wallet-browser-55d56f77cf42a9c4e80768fd7e4a9bb6f0485606.tar.bz2 tangerine-wallet-browser-55d56f77cf42a9c4e80768fd7e4a9bb6f0485606.tar.lz tangerine-wallet-browser-55d56f77cf42a9c4e80768fd7e4a9bb6f0485606.tar.xz tangerine-wallet-browser-55d56f77cf42a9c4e80768fd7e4a9bb6f0485606.tar.zst tangerine-wallet-browser-55d56f77cf42a9c4e80768fd7e4a9bb6f0485606.zip |
Began adding first basic keyring
-rw-r--r-- | app/scripts/keyring-controller.js | 111 | ||||
-rw-r--r-- | app/scripts/keyrings/simple.js | 41 | ||||
-rw-r--r-- | app/scripts/lib/idStore.js | 1 | ||||
-rw-r--r-- | app/scripts/metamask-controller.js | 2 | ||||
-rw-r--r-- | package.json | 1 | ||||
-rw-r--r-- | ui/app/accounts/index.js | 6 | ||||
-rw-r--r-- | ui/app/actions.js | 16 | ||||
-rw-r--r-- | ui/app/app.js | 1 |
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'}) |