mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-22 17:33:23 +01:00
Began adding first basic keyring
This commit is contained in:
parent
351c8e2086
commit
55d56f77cf
@ -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()
|
||||
}
|
||||
|
41
app/scripts/keyrings/simple.js
Normal file
41
app/scripts/keyrings/simple.js
Normal file
@ -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())
|
||||
}
|
||||
|
||||
}
|
@ -114,7 +114,6 @@ IdentityStore.prototype.getState = function () {
|
||||
conversionRate: configManager.getConversionRate(),
|
||||
conversionDate: configManager.getConversionDate(),
|
||||
gasMultiplier: configManager.getGasMultiplier(),
|
||||
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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 () {
|
||||
|
@ -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,
|
||||
|
@ -405,7 +405,6 @@ App.prototype.renderPrimary = function () {
|
||||
|
||||
// show current view
|
||||
switch (props.currentView.name) {
|
||||
|
||||
case 'createVault':
|
||||
return h(CreateVaultScreen, {key: 'createVault'})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user