mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-27 12:56:01 +01:00
4cf1b606e4
Now old vaults are recognized as an "Initialized" MetaMask instance. Upon logging in, when fetching the initial password-derived key, if there is no new-style vault, but there is an old style vault, it is migrated to the new format before proceeding through the usual unlocking steps.
94 lines
2.3 KiB
JavaScript
94 lines
2.3 KiB
JavaScript
const EventEmitter = require('events').EventEmitter
|
|
const hdkey = require('ethereumjs-wallet/hdkey')
|
|
const bip39 = require('bip39')
|
|
const ethUtil = require('ethereumjs-util')
|
|
const type = 'HD Key Tree'
|
|
const sigUtil = require('../lib/sig-util')
|
|
|
|
const hdPathString = `m/44'/60'/0'/0`
|
|
|
|
module.exports = class HdKeyring extends EventEmitter {
|
|
|
|
static type() {
|
|
return type
|
|
}
|
|
|
|
constructor(opts = {}) {
|
|
super()
|
|
this.type = type
|
|
this.deserialize(opts)
|
|
}
|
|
|
|
deserialize(opts = {}) {
|
|
this.opts = opts || {}
|
|
this.wallets = []
|
|
this.mnemonic = null
|
|
this.root = null
|
|
|
|
if ('mnemonic' in opts) {
|
|
this.initFromMnemonic(opts.mnemonic)
|
|
}
|
|
|
|
if ('n' in opts) {
|
|
this.addAccounts(opts.n)
|
|
}
|
|
}
|
|
|
|
initFromMnemonic(mnemonic) {
|
|
this.mnemonic = mnemonic
|
|
const seed = bip39.mnemonicToSeed(mnemonic)
|
|
this.hdWallet = hdkey.fromMasterSeed(seed)
|
|
this.root = this.hdWallet.derivePath(hdPathString)
|
|
}
|
|
|
|
serialize() {
|
|
return {
|
|
mnemonic: this.mnemonic,
|
|
n: this.wallets.length,
|
|
}
|
|
}
|
|
|
|
addAccounts(n = 1) {
|
|
if (!this.root) {
|
|
this.initFromMnemonic(bip39.generateMnemonic())
|
|
}
|
|
|
|
const oldLen = this.wallets.length
|
|
const newWallets = []
|
|
for (let i = oldLen; i < n + oldLen; i++) {
|
|
const child = this.root.deriveChild(i)
|
|
const wallet = child.getWallet()
|
|
newWallets.push(wallet)
|
|
this.wallets.push(wallet)
|
|
}
|
|
return newWallets.map(w => w.getAddress().toString('hex'))
|
|
}
|
|
|
|
getAccounts() {
|
|
return this.wallets.map(w => w.getAddress().toString('hex'))
|
|
}
|
|
|
|
// tx is an instance of the ethereumjs-transaction class.
|
|
signTransaction(address, tx) {
|
|
const wallet = this.getWalletForAccount(address)
|
|
var privKey = wallet.getPrivateKey()
|
|
tx.sign(privKey)
|
|
return tx
|
|
}
|
|
|
|
// For eth_sign, we need to sign transactions:
|
|
signMessage(withAccount, data) {
|
|
const wallet = this.getWalletForAccount(withAccount)
|
|
const message = ethUtil.removeHexPrefix(data)
|
|
var privKey = wallet.getPrivateKey()
|
|
var msgSig = ethUtil.ecsign(new Buffer(message, 'hex'), privKey)
|
|
var rawMsgSig = ethUtil.bufferToHex(sigUtil.concatSig(msgSig.v, msgSig.r, msgSig.s))
|
|
return rawMsgSig
|
|
}
|
|
|
|
getWalletForAccount(account) {
|
|
return this.wallets.find(w => w.getAddress().toString('hex') === account)
|
|
}
|
|
|
|
}
|