eth-hd-keyring
Advanced tools
Comparing version 2.0.0 to 2.1.0
51
index.js
const EventEmitter = require('events').EventEmitter | ||
const hdkey = require('ethereumjs-wallet/hdkey') | ||
const Wallet = require('ethereumjs-wallet') | ||
const bip39 = require('bip39') | ||
@@ -73,4 +74,4 @@ const ethUtil = require('ethereumjs-util') | ||
// tx is an instance of the ethereumjs-transaction class. | ||
signTransaction (address, tx) { | ||
const wallet = this._getWalletForAccount(address) | ||
signTransaction (address, tx, opts = {}) { | ||
const wallet = this._getWalletForAccount(address, opts) | ||
var privKey = wallet.getPrivateKey() | ||
@@ -83,4 +84,4 @@ tx.sign(privKey) | ||
// hd | ||
signMessage (withAccount, data) { | ||
const wallet = this._getWalletForAccount(withAccount) | ||
signMessage (withAccount, data, opts = {}) { | ||
const wallet = this._getWalletForAccount(withAccount, opts) | ||
const message = ethUtil.stripHexPrefix(data) | ||
@@ -94,4 +95,4 @@ var privKey = wallet.getPrivateKey() | ||
// For personal_sign, we need to prefix the message: | ||
signPersonalMessage (withAccount, msgHex) { | ||
const wallet = this._getWalletForAccount(withAccount) | ||
signPersonalMessage (withAccount, msgHex, opts = {}) { | ||
const wallet = this._getWalletForAccount(withAccount, opts) | ||
const privKey = ethUtil.stripHexPrefix(wallet.getPrivateKey()) | ||
@@ -104,4 +105,4 @@ const privKeyBuffer = new Buffer(privKey, 'hex') | ||
// personal_signTypedData, signs data along with the schema | ||
signTypedData (withAccount, typedData) { | ||
const wallet = this._getWalletForAccount(withAccount) | ||
signTypedData (withAccount, typedData, opts = {}) { | ||
const wallet = this._getWalletForAccount(withAccount, opts) | ||
const privKey = ethUtil.toBuffer(wallet.getPrivateKey()) | ||
@@ -113,4 +114,4 @@ const signature = sigUtil.signTypedData(privKey, { data: typedData }) | ||
// For eth_sign, we need to sign transactions: | ||
newGethSignMessage (withAccount, msgHex) { | ||
const wallet = this._getWalletForAccount(withAccount) | ||
newGethSignMessage (withAccount, msgHex, opts = {}) { | ||
const wallet = this._getWalletForAccount(withAccount, opts) | ||
const privKey = wallet.getPrivateKey() | ||
@@ -124,2 +125,17 @@ const msgBuffer = ethUtil.toBuffer(msgHex) | ||
// returns an app key | ||
getAppKeyAddress (address, origin) { | ||
return new Promise((resolve, reject) => { | ||
try { | ||
const wallet = this._getWalletForAccount(address, { | ||
withAppKeyOrigin: origin, | ||
}) | ||
const appKeyAddress = sigUtil.normalize(wallet.getAddress().toString('hex')) | ||
return resolve(appKeyAddress) | ||
} catch (e) { | ||
return reject(e) | ||
} | ||
}) | ||
} | ||
exportAccount (address) { | ||
@@ -141,5 +157,6 @@ const wallet = this._getWalletForAccount(address) | ||
_getWalletForAccount (account) { | ||
_getWalletForAccount (account, opts = {}) { | ||
const targetAddress = sigUtil.normalize(account) | ||
return this.wallets.find((w) => { | ||
let wallet = this.wallets.find((w) => { | ||
const address = sigUtil.normalize(w.getAddress().toString('hex')) | ||
@@ -149,2 +166,12 @@ return ((address === targetAddress) || | ||
}) | ||
if (opts.withAppKeyOrigin) { | ||
const privKey = wallet.getPrivateKey() | ||
const appKeyOriginBuffer = Buffer.from(opts.withAppKeyOrigin, 'utf8') | ||
const appKeyBuffer = Buffer.concat([privKey, appKeyOriginBuffer]) | ||
const appKeyPrivKey = ethUtil.keccak(appKeyBuffer, 256) | ||
wallet = Wallet.fromPrivateKey(appKeyPrivKey) | ||
} | ||
return wallet | ||
} | ||
@@ -151,0 +178,0 @@ } |
{ | ||
"name": "eth-hd-keyring", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "A simple standard interface for a seed phrase generated set of Ethereum accounts.", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -5,3 +5,5 @@ const assert = require('assert') | ||
const sigUtil = require('eth-sig-util') | ||
const ethUtil = require('ethereumjs-util') | ||
// Sample account: | ||
@@ -269,2 +271,118 @@ const privKeyHex = 'b8a9c05beeedb25df85f8d641538cbffedf67216048de9c678ee26260eb91952' | ||
}) | ||
describe('getAppKeyAddress', function () { | ||
it('should return a public address custom to the provided app key origin', async function () { | ||
const address = firstAcct | ||
keyring = new HdKeyring({ | ||
mnemonic: sampleMnemonic, | ||
numberOfAccounts: 1, | ||
}) | ||
const appKeyAddress = await keyring.getAppKeyAddress(address, 'someapp.origin.io') | ||
assert.notEqual(address, appKeyAddress) | ||
assert(ethUtil.isValidAddress(appKeyAddress)) | ||
const accounts = await keyring.getAccounts() | ||
assert.equal(accounts[0], firstAcct) | ||
}) | ||
it('should return different addresses when provided different app key origins', async function () { | ||
keyring = new HdKeyring({ | ||
mnemonic: sampleMnemonic, | ||
numberOfAccounts: 1, | ||
}) | ||
const address = firstAcct | ||
const appKeyAddress1 = await keyring.getAppKeyAddress(address, 'someapp.origin.io') | ||
assert(ethUtil.isValidAddress(appKeyAddress1)) | ||
const appKeyAddress2 = await keyring.getAppKeyAddress(address, 'anotherapp.origin.io') | ||
assert(ethUtil.isValidAddress(appKeyAddress2)) | ||
assert.notEqual(appKeyAddress1, appKeyAddress2) | ||
}) | ||
it('should return the same address when called multiple times with the same params', async function () { | ||
keyring = new HdKeyring({ | ||
mnemonic: sampleMnemonic, | ||
numberOfAccounts: 1, | ||
}) | ||
const address = firstAcct | ||
const appKeyAddress1 = await keyring.getAppKeyAddress(address, 'someapp.origin.io') | ||
assert(ethUtil.isValidAddress(appKeyAddress1)) | ||
const appKeyAddress2 = await keyring.getAppKeyAddress(address, 'someapp.origin.io') | ||
assert(ethUtil.isValidAddress(appKeyAddress2)) | ||
assert.equal(appKeyAddress1, appKeyAddress2) | ||
}) | ||
}) | ||
describe('signing methods withAppKeyOrigin option', function () { | ||
it('should signPersonalMessage with the expected key when passed a withAppKeyOrigin', function (done) { | ||
const address = firstAcct | ||
const message = '0x68656c6c6f20776f726c64' | ||
const privateKeyBuffer = Buffer.from('8e82d2d74c50e5c8460f771d38a560ebe1151a9134c65a7e92b28ad0cfae7151', 'hex') | ||
const expectedSig = sigUtil.personalSign(privateKeyBuffer, { data: message }) | ||
keyring.deserialize({ | ||
mnemonic: sampleMnemonic, | ||
numberOfAccounts: 1, | ||
}) | ||
.then(() => { | ||
return keyring.signPersonalMessage(address, message, { | ||
withAppKeyOrigin: 'someapp.origin.io', | ||
}) | ||
}) | ||
.then((sig) => { | ||
assert.equal(sig, expectedSig, 'signed with app key') | ||
done() | ||
}) | ||
.catch((reason) => { | ||
assert(!reason, reason.message) | ||
done() | ||
}) | ||
}) | ||
it('should signTypedData with the expected key when passed a withAppKeyOrigin', function (done) { | ||
const address = firstAcct | ||
const typedData = { | ||
types: { | ||
EIP712Domain: [] | ||
}, | ||
domain: {}, | ||
primaryType: 'EIP712Domain', | ||
message: {} | ||
} | ||
const privateKeyBuffer = Buffer.from('8e82d2d74c50e5c8460f771d38a560ebe1151a9134c65a7e92b28ad0cfae7151', 'hex') | ||
const expectedSig = sigUtil.signTypedData(privateKeyBuffer, { data: typedData }) | ||
keyring.deserialize({ | ||
mnemonic: sampleMnemonic, | ||
numberOfAccounts: 1 | ||
}).then(() => { | ||
return keyring.signTypedData(address, typedData, { | ||
withAppKeyOrigin: 'someapp.origin.io', | ||
}) | ||
}) | ||
.then((sig) => { | ||
assert.equal(sig, expectedSig, 'signed with app key') | ||
done() | ||
}) | ||
.catch((reason) => { | ||
assert(!reason, reason.message) | ||
done() | ||
}) | ||
}) | ||
}) | ||
}) |
21666
6
472