const EventEmitter = require('events').EventEmitter const Wallet = require('ethereumjs-wallet') const ethUtil = require('ethereumjs-util') const type = 'Simple Key Pair' const sigUtil = require('../lib/sig-util') class SimpleKeyring extends EventEmitter { /* PUBLIC METHODS */ constructor (opts) { super() this.type = type this.opts = opts || {} this.wallets = [] } serialize () { return Promise.resolve(this.wallets.map(w => w.getPrivateKey().toString('hex'))) } deserialize (privateKeys = []) { return new Promise((resolve, reject) => { try { this.wallets = privateKeys.map((privateKey) => { const stripped = ethUtil.stripHexPrefix(privateKey) const buffer = new Buffer(stripped, 'hex') const wallet = Wallet.fromPrivateKey(buffer) return wallet }) } catch (e) { reject(e) } resolve() }) } addAccounts (n = 1) { var newWallets = [] for (var i = 0; i < n; i++) { newWallets.push(Wallet.generate()) } this.wallets = this.wallets.concat(newWallets) const hexWallets = newWallets.map(w => ethUtil.bufferToHex(w.getAddress())) return Promise.resolve(hexWallets) } getAccounts () { return Promise.resolve(this.wallets.map(w => ethUtil.bufferToHex(w.getAddress()))) } // 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 Promise.resolve(tx) } // For eth_sign, we need to sign transactions: signMessage (withAccount, msgHex) { const wallet = this._getWalletForAccount(withAccount) const privKey = wallet.getPrivateKey() const msgBuffer = ethUtil.toBuffer(msgHex) const msgHash = ethUtil.hashPersonalMessage(msgBuffer) const msgSig = ethUtil.ecsign(msgHash, privKey) const rawMsgSig = ethUtil.bufferToHex(sigUtil.concatSig(msgSig.v, msgSig.r, msgSig.s)) return Promise.resolve(rawMsgSig) } exportAccount (address) { const wallet = this._getWalletForAccount(address) return Promise.resolve(wallet.getPrivateKey().toString('hex')) } /* PRIVATE METHODS */ _getWalletForAccount (account) { let wallet = this.wallets.find(w => ethUtil.bufferToHex(w.getAddress()) === account) if (!wallet) throw new Error('Simple Keyring - Unable to find matching address.') return wallet } } SimpleKeyring.type = type module.exports = SimpleKeyring