Support importing BIP32 xpub/xpriv

This commit is contained in:
Alex Beregszaszi 2016-03-23 12:15:44 +00:00
parent ecbf109a71
commit f72c9679c1
4 changed files with 36 additions and 0 deletions

View File

@ -23,7 +23,9 @@ Constructors:
* `generate([icap])` - create an instance based on a new random key (setting `icap` to true will generate an address suitable for the `ICAP Direct mode`)
* `fromPrivateKey(input)` - create an instance based on a raw private key
* `fromExtendedPrivateKey(input)` - create an instance based on a BIP32 xprv
* `fromPublicKey(input)` - create an instance based on a public key (certain methods will not be available)
* `fromExtendedPublicKey(input)` - create an instance based on a BIP32 xpub
* `fromV1(input, password)` - import a wallet (Version 1 of the Ethereum wallet format)
* `fromV3(input, password, [nonStrict])` - import a wallet (Version 3 of the Ethereum wallet format). Set `nonStrict` true to accept files with mixed-caps.
* `fromEthSale(input, password)` - import an Ethereum Pre Sale wallet

View File

@ -2,6 +2,8 @@ var ethUtil = require('ethereumjs-util')
var crypto = require('crypto')
var scryptsy = require('scrypt.js')
var uuid = require('uuid')
var secp256k1 = require('secp256k1')
var bs58check = require('bs58check')
function assert (val, msg) {
if (!val) {
@ -163,10 +165,25 @@ Wallet.fromPublicKey = function (pub) {
return new Wallet(null, pub)
}
Wallet.fromExtendedPublicKey = function (pub) {
assert(pub.slice(0, 4) === 'xpub', 'Not an extended public key')
pub = bs58check.decode(pub).slice(45)
// Convert to an Ethereum public key
pub = secp256k1.publicKeyConvert(pub, false).slice(1)
return Wallet.fromPublicKey(pub)
}
Wallet.fromPrivateKey = function (priv) {
return new Wallet(priv)
}
Wallet.fromExtendedPrivateKey = function (priv) {
assert(priv.slice(0, 4) === 'xprv', 'Not an extended private key')
var tmp = bs58check.decode(priv)
assert(tmp[45] === 0, 'Invalid extended private key')
return Wallet.fromPrivateKey(tmp.slice(46))
}
// https://github.com/ethereum/go-ethereum/wiki/Passphrase-protected-key-store-spec
Wallet.fromV1 = function (input, password) {
assert(typeof password === 'string')

View File

@ -25,8 +25,10 @@
"homepage": "https://github.com/axic/ethereumjs-wallet",
"dependencies": {
"aes-js": "^0.2.3",
"bs58check": "^1.0.8",
"ethereumjs-util": "^4.3.0",
"scrypt.js": "^0.1.0",
"secp256k1": "^3.0.1",
"uuid": "^2.0.1",
"utf8": "^2.1.1"
},

View File

@ -73,6 +73,21 @@ describe('public key only wallet', function () {
})
})
describe('.fromExtendedPrivateKey()', function () {
it('should work', function () {
var xprv = 'xprv9s21ZrQH143K4KqQx9Zrf1eN8EaPQVFxM2Ast8mdHn7GKiDWzNEyNdduJhWXToy8MpkGcKjxeFWd8oBSvsz4PCYamxR7TX49pSpp3bmHVAY'
assert.equal(Wallet.fromExtendedPrivateKey(xprv).getAddressString(), '0xb800bf5435f67c7ee7d83c3a863269969a57c57c')
})
})
describe('.fromExtendedPublicKey()', function () {
it('should work', function () {
var xpub = 'xpub661MyMwAqRbcGout4B6s29b6gGQsowyoiF6UgXBEr7eFCWYfXuZDvRxP9zEh1Kwq3TLqDQMbkbaRpSnoC28oWvjLeshoQz1StZ9YHM1EpcJ'
assert.equal(Wallet.fromExtendedPublicKey(xpub).getAddressString(), '0xb800bf5435f67c7ee7d83c3a863269969a57c57c')
})
})
describe('.generate()', function () {
it('should generate an account', function () {
assert.equal(Wallet.generate().getPrivateKey().length, 32)