1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Convert to bip44 hdTrees

Added initial test just to verify we can recover the accounts we generate in this way.

Still need to add compliance test to make sure this interoperates with testrpc's new mnemonic flag.
This commit is contained in:
Dan Finlay 2016-03-25 12:41:18 -07:00
parent da31f4daed
commit 37fd45e5b7
3 changed files with 70 additions and 24 deletions

View File

@ -1,6 +1,7 @@
const EventEmitter = require('events').EventEmitter const EventEmitter = require('events').EventEmitter
const inherits = require('util').inherits const inherits = require('util').inherits
const Transaction = require('ethereumjs-tx') const Transaction = require('ethereumjs-tx')
const Lightwallet = require('eth-lightwallet')
const LightwalletKeyStore = require('eth-lightwallet').keystore const LightwalletKeyStore = require('eth-lightwallet').keystore
const LightwalletSigner = require('eth-lightwallet').signing const LightwalletSigner = require('eth-lightwallet').signing
const async = require('async') const async = require('async')
@ -14,23 +15,24 @@ module.exports = IdentityStore
inherits(IdentityStore, EventEmitter) inherits(IdentityStore, EventEmitter)
function IdentityStore(ethStore) { function IdentityStore(ethStore) {
const self = this EventEmitter.call(this)
EventEmitter.call(self)
// we just use the ethStore to auto-add accounts // we just use the ethStore to auto-add accounts
self._ethStore = ethStore this._ethStore = ethStore
// lightwallet key store // lightwallet key store
self._keyStore = null this._keyStore = null
// lightwallet wrapper // lightwallet wrapper
self._idmgmt = null this._idmgmt = null
self._currentState = { this.hdPathString = "m/44'/60'/0'/0"
this._currentState = {
selectedAddress: null, selectedAddress: null,
identities: {}, identities: {},
unconfTxs: {}, unconfTxs: {},
} }
// not part of serilized metamask state - only kept in memory // not part of serilized metamask state - only kept in memory
self._unconfTxCbs = {} this._unconfTxCbs = {}
} }
// //
@ -122,7 +124,6 @@ IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, cb){
status: 'unconfirmed', status: 'unconfirmed',
} }
self._currentState.unconfTxs[txId] = txData self._currentState.unconfTxs[txId] = txData
console.log('addUnconfirmedTransaction:', txData)
// keep the cb around for after approval (requires user interaction) // keep the cb around for after approval (requires user interaction)
self._unconfTxCbs[txId] = cb self._unconfTxCbs[txId] = cb
@ -201,7 +202,7 @@ IdentityStore.prototype._loadIdentities = function(){
const self = this const self = this
if (!self._isUnlocked()) throw new Error('not unlocked') if (!self._isUnlocked()) throw new Error('not unlocked')
// get addresses and normalize address hexString // get addresses and normalize address hexString
var addresses = self._keyStore.getAddresses().map(function(address){ return '0x'+address }) var addresses = self._keyStore.getAddresses(this.hdPathString).map(function(address){ return '0x'+address })
addresses.forEach(function(address){ addresses.forEach(function(address){
// // add to ethStore // // add to ethStore
self._ethStore.addAccount(address) self._ethStore.addAccount(address)
@ -257,7 +258,7 @@ IdentityStore.prototype._createIdmgmt = function(password, seed, entropy, cb){
IdentityStore.prototype._restoreFromSeed = function(keyStore, seed, derivedKey) { IdentityStore.prototype._restoreFromSeed = function(keyStore, seed, derivedKey) {
keyStore = new LightwalletKeyStore(seed, derivedKey) keyStore = new LightwalletKeyStore(seed, derivedKey)
keyStore.generateNewAddress(derivedKey, 3) keyStore.generateNewAddress(derivedKey, 3, hdPathString)
window.localStorage['lightwallet'] = keyStore.serialize() window.localStorage['lightwallet'] = keyStore.serialize()
console.log('restored from seed. saved to keystore localStorage') console.log('restored from seed. saved to keystore localStorage')
} }
@ -268,19 +269,20 @@ IdentityStore.prototype._loadFromLocalStorage = function(serializedKeystore, der
IdentityStore.prototype._createFirstWallet = function(entropy, derivedKey) { IdentityStore.prototype._createFirstWallet = function(entropy, derivedKey) {
var secretSeed = LightwalletKeyStore.generateRandomSeed(entropy) var secretSeed = LightwalletKeyStore.generateRandomSeed(entropy)
var keyStore = new LightwalletKeyStore(secretSeed, derivedKey) var keyStore = new LightwalletKeyStore(secretSeed, derivedKey, this.hdPathString)
keyStore.generateNewAddress(derivedKey, 3) keyStore.generateNewAddress(derivedKey, 3, this.hdPathString)
window.localStorage['lightwallet'] = keyStore.serialize() window.localStorage['lightwallet'] = keyStore.serialize()
console.log('saved to keystore localStorage') console.log('saved to keystore localStorage')
return keyStore return keyStore
} }
function IdManagement( opts = { keyStore: null, derivedKey: null } ) { function IdManagement( opts = { keyStore: null, derivedKey: null, hdPathString: null } ) {
this.keyStore = opts.keyStore this.keyStore = opts.keyStore
this.derivedKey = opts.derivedKey this.derivedKey = opts.derivedKey
this.hdPathString = opts.hdPathString
this.getAddresses = function(){ this.getAddresses = function(){
return keyStore.getAddresses().map(function(address){ return '0x'+address }) return keyStore.getAddresses(this.hdPathString).map(function(address){ return '0x'+address })
} }
this.signTx = function(txParams){ this.signTx = function(txParams){

View File

@ -5,11 +5,11 @@
"private": true, "private": true,
"scripts": { "scripts": {
"start": "gulp dev", "start": "gulp dev",
"test": "mocha --compilers js:babel-register" "test": "mocha --compilers js:babel-register",
"watch": "mocha watch --compilers js:babel-register"
}, },
"dependencies": { "dependencies": {
"async": "^1.5.2", "async": "^1.5.2",
"bip39": "^2.2.0",
"clone": "^1.0.2", "clone": "^1.0.2",
"dnode": "^1.2.2", "dnode": "^1.2.2",
"end-of-stream": "^1.1.0", "end-of-stream": "^1.1.0",
@ -39,8 +39,11 @@
"gulp-sourcemaps": "^1.6.0", "gulp-sourcemaps": "^1.6.0",
"gulp-util": "^3.0.7", "gulp-util": "^3.0.7",
"gulp-watch": "^4.3.5", "gulp-watch": "^4.3.5",
"jsdom": "^8.1.0",
"jshint-stylish": "~0.1.5", "jshint-stylish": "~0.1.5",
"lodash.assign": "^4.0.6", "lodash.assign": "^4.0.6",
"mocha": "^2.4.5",
"mocha-jsdom": "^1.1.0",
"tape": "^4.5.1", "tape": "^4.5.1",
"vinyl-buffer": "^1.0.0", "vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0", "vinyl-source-stream": "^1.1.0",

View File

@ -1,11 +1,52 @@
var assert = require('assert'); var assert = require('assert')
var idStore = require('../app/scripts/lib/idStore') var IdentityStore = require('../app/scripts/lib/idStore')
var jsdom = require('mocha-jsdom')
jsdom()
describe('IdentityStore', function() { describe('IdentityStore', function() {
describe('#_createFirstWallet', function () {
it('should return the expected keystore', function () {
assert.equal(1,1) describe('#createNewVault', function () {
}); let idStore
}); let password = 'password123'
}); let entropy = 'entripppppyy duuude'
let seedWords
let accounts = []
let originalKeystore
before(function(done) {
window.localStorage = {} // Hacking localStorage support into JSDom
idStore = new IdentityStore({
addAccount(acct) { accounts.push(acct) },
})
idStore.createNewVault(password, entropy, (err, seeds) => {
seedWords = seeds
originalKeystore = idStore._idmgmt.keyStore
done()
})
})
describe('#recoverFromSeed', function() {
before(function() {
window.localStorage = {} // Hacking localStorage support into JSDom
accounts = []
idStore = new IdentityStore({
addAccount(acct) { accounts.push(acct) },
})
})
it('should return the expected keystore', function () {
idStore.recoverFromSeed(password, seedWords, (err) => {
assert.ifError(err)
let newKeystore = idStore._idmgmt.keyStore
assert.equal(newKeystore, originalKeystore)
})
})
})
})
})