Bitcoinjs-lib: How to generate a seed, retrieve its 12-word phrase, and generate private keys & addresses from it?

Created on 10 May 2016  路  12Comments  路  Source: bitcoinjs/bitcoinjs-lib

I haven't had much luck digging around for an answer to this. What I'm trying to accomplish:

  1. Generate a random seed
  2. Get a 12-word phrase from said seed
  3. Generate X private keys (and public addresses) from the seed

A nod in the right direction would be appreciated!

how to / question / docs

Most helpful comment

1 & 2:

var bip39 = require('bip39') // npm i -S bip39
var crypto = require('crypto')

// what you describe as 'seed'
var  randomBytes = crypto.randomBytes(16) // 128 bits is enough

// your 12 word phrase
var mnemonic = bip39.entropyToMnemonic(randomBytes.toString('hex')) 

// what is accurately described as the wallet seed
var seed = bip39.mnemonicToSeed(mnemonic) // you'll use this in #3 below

3:

var bitcoin = require('bitcoinjs-lib') // npm i -S bitcoinjs-lib

var bitcoinNetwork = bitcoin.networks.bitcoin
var hdMaster = bitcoin.HDNode.fromSeedBuffer(seed, bitcoinNetwork) // seed from above

var key1 = hdMaster.derivePath('m/0')
var key2 = hdMaster.derivePath('m/1')

console.log(key1.keyPair.toWIF())
console.log(key2.keyPair.toWIF())

.... should do it. May be a typo or incorrect parameter here or there. I strongly encourage you to read the BIP32 spec and learn about the paths and what hardened keys are.

All 12 comments

1 & 2:

var bip39 = require('bip39') // npm i -S bip39
var crypto = require('crypto')

// what you describe as 'seed'
var  randomBytes = crypto.randomBytes(16) // 128 bits is enough

// your 12 word phrase
var mnemonic = bip39.entropyToMnemonic(randomBytes.toString('hex')) 

// what is accurately described as the wallet seed
var seed = bip39.mnemonicToSeed(mnemonic) // you'll use this in #3 below

3:

var bitcoin = require('bitcoinjs-lib') // npm i -S bitcoinjs-lib

var bitcoinNetwork = bitcoin.networks.bitcoin
var hdMaster = bitcoin.HDNode.fromSeedBuffer(seed, bitcoinNetwork) // seed from above

var key1 = hdMaster.derivePath('m/0')
var key2 = hdMaster.derivePath('m/1')

console.log(key1.keyPair.toWIF())
console.log(key2.keyPair.toWIF())

.... should do it. May be a typo or incorrect parameter here or there. I strongly encourage you to read the BIP32 spec and learn about the paths and what hardened keys are.

This line:

var hdMaster = bitcoin.HDNodeFromSeedBuffer(seed, bitcoinNetwork) // seed from above

should be:

var hdMaster = bitcoin.HDNode.fromSeedBuffer(seed, bitcoinNetwork) // seed from above

And hdMaster.derivePath throws an error.. I can't seem to figure that one out. It says it's not a function. I don't see derivePath anywhere else.

And thank you! I would've never been able to figure all that out, as there isn't much in the way of documentation. Not to mention I also don't fully understand how this works under the hood.

as there isn't much in the way of documentation.

Yeah, we've been meaning to address that. It's really tough with our limited resources and how the fast the entire Bitcoin and JavaScript ecosystems move. I know it's not a good answer... but the best we have at this moment is to ask questions and to look at the tests. Overall, we realize that it's a shitty solution.

Yeah, but it's open source, and I understand most devs are busy with jobs & other obligations. Nothing pressing going on here! At some point I'd like to build a wallet app in React Native. I'm not really that impressed with the current selection of wallets (for iOS) at the moment.

@ffxsam @jprichardson derivePath was added recently, and hasn't yet been released.
It is part of the 2.3.0 milestone.

@ffxsam in the mean time, you can use .derive(0) and .derive(1).

We'll add some more integration tests to show these examples...

Sorry for commenting here - my question is related to the derivepath and I figured better put it in one place rather than opening a new issue.

Is there a way to derive change addresses as per the BIP32 path using the current release version (2.2.0)? Looking at hdnode.js, I can't find any way to generate a change address. Is this up to the wallet software then to separate change addresses from external addresses?

I think it has something to do with chainCode but I can't really fathom how to use it. Any suggestions will be greatly appreciated!

Note that in the examples above
bitcoin.HDNode.fromSeedBuffer
is now,
bitcoin.bip32.fromSeed

This solves UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'toWIF' of undefined:

console.log(key1.toWIF())
console.log(key2.toWIF())

console.log(key1.keyPair.toWIF())
should be
console.log(key1.toWIF())

Was this page helpful?
0 / 5 - 0 ratings

Related issues

namnv04 picture namnv04  路  3Comments

coingeek picture coingeek  路  4Comments

yakitorifoodie picture yakitorifoodie  路  3Comments

ghost picture ghost  路  3Comments

prahaladbelavadi picture prahaladbelavadi  路  3Comments