mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Merge pull request #69 from MetaMask/ImproveVaultManagement
Improve vault management
This commit is contained in:
commit
1ff518a94e
1
app/images/loading.svg
Normal file
1
app/images/loading.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg width='120px' height='120px' xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid" class="uil-default"><rect x="0" y="0" width="100" height="100" fill="none" class="bk"></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(0 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(40 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.1111111111111111s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(80 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.2222222222222222s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(120 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.3333333333333333s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(160 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.4444444444444444s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(200 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.5555555555555556s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(240 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.6666666666666666s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(280 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.7777777777777778s' repeatCount='indefinite'/></rect><rect x='46' y='39' width='8' height='22' rx='5' ry='5' fill='#ffae29' transform='rotate(320 50 50) translate(0 -20)'> <animate attributeName='opacity' from='1' to='0' dur='1s' begin='0.8888888888888888s' repeatCount='indefinite'/></rect></svg>
|
After Width: | Height: | Size: 2.3 KiB |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "__MSG_appName__",
|
"name": "__MSG_appName__",
|
||||||
"version": "0.14.0",
|
"version": "0.15.0",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"description": "__MSG_appDescription__",
|
"description": "__MSG_appDescription__",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
@ -121,10 +121,11 @@ function linkDnode(stream){
|
|||||||
approveTransaction: idStore.approveTransaction.bind(idStore),
|
approveTransaction: idStore.approveTransaction.bind(idStore),
|
||||||
cancelTransaction: idStore.cancelTransaction.bind(idStore),
|
cancelTransaction: idStore.cancelTransaction.bind(idStore),
|
||||||
setLocked: idStore.setLocked.bind(idStore),
|
setLocked: idStore.setLocked.bind(idStore),
|
||||||
|
clearSeedWordCache: idStore.clearSeedWordCache.bind(idStore),
|
||||||
})
|
})
|
||||||
stream.pipe(connection).pipe(stream)
|
stream.pipe(connection).pipe(stream)
|
||||||
connection.on('remote', function(remote){
|
connection.on('remote', function(remote){
|
||||||
|
|
||||||
// push updates to popup
|
// push updates to popup
|
||||||
ethStore.on('update', sendUpdate)
|
ethStore.on('update', sendUpdate)
|
||||||
idStore.on('update', sendUpdate)
|
idStore.on('update', sendUpdate)
|
||||||
@ -208,4 +209,4 @@ function jsonStringifyStream(){
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function noop(){}
|
function noop(){}
|
||||||
|
@ -37,22 +37,22 @@ function IdentityStore(ethStore) {
|
|||||||
// public
|
// public
|
||||||
//
|
//
|
||||||
|
|
||||||
IdentityStore.prototype.createNewVault = function(password, cb){
|
IdentityStore.prototype.createNewVault = function(password, entropy, cb){
|
||||||
const self = this
|
delete this._keyStore
|
||||||
delete self._keyStore
|
|
||||||
delete window.localStorage['lightwallet']
|
delete window.localStorage['lightwallet']
|
||||||
var keyStore = self._createIdmgmt(password, null, function(err){
|
this._createIdmgmt(password, null, entropy, (err) => {
|
||||||
if (err) return cb(err)
|
if (err) return cb(err)
|
||||||
var seedWords = self._idmgmt.getSeed()
|
var seedWords = this._idmgmt.getSeed()
|
||||||
self._loadIdentities()
|
this._cacheSeedWordsUntilConfirmed(seedWords)
|
||||||
self._didUpdate()
|
this._loadIdentities()
|
||||||
|
this._didUpdate()
|
||||||
cb(null, seedWords)
|
cb(null, seedWords)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityStore.prototype.recoverFromSeed = function(password, seed, cb){
|
IdentityStore.prototype.recoverFromSeed = function(password, seed, cb){
|
||||||
const self = this
|
const self = this
|
||||||
self._createIdmgmt(password, seed, function(err){
|
self._createIdmgmt(password, seed, null, function(err){
|
||||||
if (err) return cb(err)
|
if (err) return cb(err)
|
||||||
self._loadIdentities()
|
self._loadIdentities()
|
||||||
self._didUpdate()
|
self._didUpdate()
|
||||||
@ -65,12 +65,18 @@ IdentityStore.prototype.setStore = function(store){
|
|||||||
self._ethStore = store
|
self._ethStore = store
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdentityStore.prototype.clearSeedWordCache = function(cb) {
|
||||||
|
delete window.localStorage['seedWords']
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
|
||||||
IdentityStore.prototype.getState = function(){
|
IdentityStore.prototype.getState = function(){
|
||||||
const self = this
|
const self = this
|
||||||
|
const cachedSeeds = window.localStorage['seedWords']
|
||||||
return clone(extend(self._currentState, {
|
return clone(extend(self._currentState, {
|
||||||
isInitialized: !!window.localStorage['lightwallet'],
|
isInitialized: !!window.localStorage['lightwallet'] && !cachedSeeds,
|
||||||
isUnlocked: self._isUnlocked(),
|
isUnlocked: self._isUnlocked(),
|
||||||
|
seedWords: cachedSeeds,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,10 +91,11 @@ IdentityStore.prototype.setSelectedAddress = function(address){
|
|||||||
self._didUpdate()
|
self._didUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityStore.prototype.setLocked = function(){
|
IdentityStore.prototype.setLocked = function(cb){
|
||||||
const self = this
|
const self = this
|
||||||
delete self._keyStore
|
delete self._keyStore
|
||||||
delete self._idmgmt
|
delete self._idmgmt
|
||||||
|
cb()
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityStore.prototype.submitPassword = function(password, cb){
|
IdentityStore.prototype.submitPassword = function(password, cb){
|
||||||
@ -185,6 +192,10 @@ IdentityStore.prototype._isUnlocked = function(){
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdentityStore.prototype._cacheSeedWordsUntilConfirmed = function(seedWords) {
|
||||||
|
window.localStorage['seedWords'] = seedWords
|
||||||
|
}
|
||||||
|
|
||||||
// load identities from keyStoreet
|
// load identities from keyStoreet
|
||||||
IdentityStore.prototype._loadIdentities = function(){
|
IdentityStore.prototype._loadIdentities = function(){
|
||||||
const self = this
|
const self = this
|
||||||
@ -211,59 +222,86 @@ IdentityStore.prototype._loadIdentities = function(){
|
|||||||
|
|
||||||
IdentityStore.prototype._tryPassword = function(password, cb){
|
IdentityStore.prototype._tryPassword = function(password, cb){
|
||||||
const self = this
|
const self = this
|
||||||
self._createIdmgmt(password, null, cb)
|
self._createIdmgmt(password, null, null, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
IdentityStore.prototype._createIdmgmt = function(password, seed, cb){
|
IdentityStore.prototype._createIdmgmt = function(password, seed, entropy, cb){
|
||||||
const self = this
|
|
||||||
var keyStore = null
|
var keyStore = null
|
||||||
LightwalletKeyStore.deriveKeyFromPassword(password, function(err, derrivedKey){
|
LightwalletKeyStore.deriveKeyFromPassword(password, (err, derivedKey) => {
|
||||||
if (err) return cb(err)
|
if (err) return cb(err)
|
||||||
var serializedKeystore = window.localStorage['lightwallet']
|
var serializedKeystore = window.localStorage['lightwallet']
|
||||||
// recovering from seed
|
|
||||||
if (seed) {
|
if (seed) {
|
||||||
keyStore = new LightwalletKeyStore(seed, derrivedKey)
|
this._restoreFromSeed(keyStore, seed, derivedKey)
|
||||||
keyStore.generateNewAddress(derrivedKey, 3)
|
|
||||||
window.localStorage['lightwallet'] = keyStore.serialize()
|
|
||||||
console.log('saved to keystore localStorage')
|
|
||||||
// returning user, recovering from localStorage
|
// returning user, recovering from localStorage
|
||||||
} else if (serializedKeystore) {
|
} else if (serializedKeystore) {
|
||||||
keyStore = LightwalletKeyStore.deserialize(serializedKeystore)
|
keyStore = this._loadFromLocalStorage(serializedKeystore, derivedKey, cb)
|
||||||
var isCorrect = keyStore.isDerivedKeyCorrect(derrivedKey)
|
var isCorrect = keyStore.isDerivedKeyCorrect(derivedKey)
|
||||||
if (!isCorrect) return cb(new Error('Lightwallet - password incorrect'))
|
if (!isCorrect) return cb(new Error('Lightwallet - password incorrect'))
|
||||||
// first time here
|
|
||||||
|
// first time here
|
||||||
} else {
|
} else {
|
||||||
var secretSeed = LightwalletKeyStore.generateRandomSeed()
|
keyStore = this._createFirstWallet(entropy, derivedKey)
|
||||||
keyStore = new LightwalletKeyStore(secretSeed, derrivedKey)
|
|
||||||
keyStore.generateNewAddress(derrivedKey, 3)
|
|
||||||
window.localStorage['lightwallet'] = keyStore.serialize()
|
|
||||||
console.log('saved to keystore localStorage')
|
|
||||||
}
|
|
||||||
self._keyStore = keyStore
|
|
||||||
self._idmgmt = {
|
|
||||||
getAddresses: function(){
|
|
||||||
return keyStore.getAddresses().map(function(address){ return '0x'+address })
|
|
||||||
},
|
|
||||||
signTx: function(txParams){
|
|
||||||
// normalize values
|
|
||||||
txParams.to = ethUtil.addHexPrefix(txParams.to)
|
|
||||||
txParams.from = ethUtil.addHexPrefix(txParams.from)
|
|
||||||
txParams.value = ethUtil.addHexPrefix(txParams.value)
|
|
||||||
txParams.data = ethUtil.addHexPrefix(txParams.data)
|
|
||||||
txParams.gasLimit = ethUtil.addHexPrefix(txParams.gasLimit || txParams.gas)
|
|
||||||
txParams.nonce = ethUtil.addHexPrefix(txParams.nonce)
|
|
||||||
var tx = new Transaction(txParams)
|
|
||||||
var rawTx = '0x'+tx.serialize().toString('hex')
|
|
||||||
return '0x'+LightwalletSigner.signTx(keyStore, derrivedKey, rawTx, txParams.from)
|
|
||||||
},
|
|
||||||
getSeed: function(){
|
|
||||||
return keyStore.getSeed(derrivedKey)
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._keyStore = keyStore
|
||||||
|
this._idmgmt = new IdManagement({
|
||||||
|
keyStore: keyStore,
|
||||||
|
derivedKey: derivedKey,
|
||||||
|
})
|
||||||
|
|
||||||
cb()
|
cb()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IdentityStore.prototype._restoreFromSeed = function(keyStore, seed, derivedKey) {
|
||||||
|
keyStore = new LightwalletKeyStore(seed, derivedKey)
|
||||||
|
keyStore.generateNewAddress(derivedKey, 3)
|
||||||
|
window.localStorage['lightwallet'] = keyStore.serialize()
|
||||||
|
console.log('restored from seed. saved to keystore localStorage')
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentityStore.prototype._loadFromLocalStorage = function(serializedKeystore, derivedKey) {
|
||||||
|
return LightwalletKeyStore.deserialize(serializedKeystore)
|
||||||
|
}
|
||||||
|
|
||||||
|
IdentityStore.prototype._createFirstWallet = function(entropy, derivedKey) {
|
||||||
|
var secretSeed = LightwalletKeyStore.generateRandomSeed(entropy)
|
||||||
|
var keyStore = new LightwalletKeyStore(secretSeed, derivedKey)
|
||||||
|
keyStore.generateNewAddress(derivedKey, 3)
|
||||||
|
window.localStorage['lightwallet'] = keyStore.serialize()
|
||||||
|
console.log('saved to keystore localStorage')
|
||||||
|
return keyStore
|
||||||
|
}
|
||||||
|
|
||||||
|
function IdManagement( opts = { keyStore: null, derivedKey: null } ) {
|
||||||
|
this.keyStore = opts.keyStore
|
||||||
|
this.derivedKey = opts.derivedKey
|
||||||
|
|
||||||
|
this.getAddresses = function(){
|
||||||
|
return keyStore.getAddresses().map(function(address){ return '0x'+address })
|
||||||
|
}
|
||||||
|
|
||||||
|
this.signTx = function(txParams){
|
||||||
|
// normalize values
|
||||||
|
txParams.to = ethUtil.addHexPrefix(txParams.to)
|
||||||
|
txParams.from = ethUtil.addHexPrefix(txParams.from)
|
||||||
|
txParams.value = ethUtil.addHexPrefix(txParams.value)
|
||||||
|
txParams.data = ethUtil.addHexPrefix(txParams.data)
|
||||||
|
txParams.gasLimit = ethUtil.addHexPrefix(txParams.gasLimit || txParams.gas)
|
||||||
|
txParams.nonce = ethUtil.addHexPrefix(txParams.nonce)
|
||||||
|
var tx = new Transaction(txParams)
|
||||||
|
var rawTx = '0x'+tx.serialize().toString('hex')
|
||||||
|
return '0x'+LightwalletSigner.signTx(this.keyStore, this.derivedKey, rawTx, txParams.from)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getSeed = function(){
|
||||||
|
return this.keyStore.getSeed(this.derivedKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// util
|
// util
|
||||||
|
|
||||||
function noop(){}
|
function noop(){}
|
||||||
|
Loading…
Reference in New Issue
Block a user