Repository: bitcoinjs/bitcoinjs-lib
Pull request #536 (2016-02-05 03:44:03)

Adding function to decide if HDNode is private
It's a very simple function that probably isn't that important, but can help someone.

If you like this idea, I will add some tests for that

dcousens: Nice!

Maybe `isNeutered`?
That way it is consistent with the `neutered()` interface?
dcousens: Also, are you up to add some tests? :+1: 
runn1ng: Hm. On one hand, it makes sense, because it's consistent, on the other hand I just wouldn't guess from the name what it means.

I will look more into the travis failures (seems like style issue... that's what I get for editing code in github GUI :))
dcousens: ![why not both?](https://i.ytimg.com/vi/vqgSO8_cRio/hqdefault.jpg)

I wouldn't be opposed to having both then I guess?  Its just more to maintain and think about.
I'm just wanting to be consistent, especially since `isPrivate` is equally vague,  at least the `isNeutered` introduces less context.

@fanatid thoughts?
dcousens: In any case @runn1ng,  please add tests in lieu of the bike shed. 
fanatid: Since `HDNode` already has [neutered](https://github.com/bitcoinjs/bitcoinjs-lib/blob/daafb9794e60a7329c7d5825fceab71e17f6f0a7/src/hdnode.js#L147), `isNeutered` is better.
runn1ng: I have renamed the function and removed the semicolon. Now I am adding tests

Patch:
diff --git a/src/hdnode.js b/src/hdnode.js
index 80ae630c..ff97d467 100644
--- a/src/hdnode.js
+++ b/src/hdnode.js
@@ -170,7 +170,7 @@ HDNode.prototype.toBase58 = function (__isPrivate) {
 
   // Version
   var network = this.keyPair.network
-  var version = this.keyPair.d ? network.bip32.private : network.bip32.public
+  var version = (!this.isNeutered()) ? network.bip32.private : network.bip32.public
   var buffer = new Buffer(78)
 
   // 4 bytes: version bytes
@@ -190,7 +190,7 @@ HDNode.prototype.toBase58 = function (__isPrivate) {
   this.chainCode.copy(buffer, 13)
 
   // 33 bytes: the public key or private key data
-  if (this.keyPair.d) {
+  if (!this.isNeutered()) {
     // 0x00 + k for private keys
     buffer.writeUInt8(0, 45)
     this.keyPair.d.toBuffer(32).copy(buffer, 46)
@@ -211,7 +211,7 @@ HDNode.prototype.derive = function (index) {
 
   // Hardened child
   if (isHardened) {
-    if (!this.keyPair.d) throw new TypeError('Could not derive hardened child key')
+    if (this.isNeutered()) throw new TypeError('Could not derive hardened child key')
 
     // data = 0x00 || ser256(kpar) || ser32(index)
     data[0] = 0x00
@@ -239,7 +239,7 @@ HDNode.prototype.derive = function (index) {
 
   // Private parent key -> private child key
   var derivedKeyPair
-  if (this.keyPair.d) {
+  if (!this.isNeutered()) {
     // ki = parse256(IL) + kpar (mod n)
     var ki = pIL.add(this.keyPair.d).mod(curve.n)
 
@@ -281,6 +281,12 @@ HDNode.prototype.deriveHardened = function (index) {
   return this.derive(index + HDNode.HIGHEST_BIT)
 }
 
+// Private === not neutered
+// Public === neutered
+HDNode.prototype.isNeutered = function () {
+  return !(this.keyPair.d)
+}
+
 HDNode.prototype.toString = HDNode.prototype.toBase58
 
 module.exports = HDNode


Test patch:
diff --git a/test/hdnode.js b/test/hdnode.js
index afa98873..e8f3184a 100644
--- a/test/hdnode.js
+++ b/test/hdnode.js
@@ -192,6 +192,7 @@ describe('HDNode', function () {
 
         assert.strictEqual(hd.toBase58(), f.master.base58)
         assert.strictEqual(hd.keyPair.network, network)
+        assert.strictEqual(hd.isNeutered(), true)
       })
     })
 
@@ -202,6 +203,7 @@ describe('HDNode', function () {
 
         assert.strictEqual(hd.toBase58(), f.master.base58Priv)
         assert.strictEqual(hd.keyPair.network, network)
+        assert.strictEqual(hd.isNeutered(), false)
       })
     })
 
@@ -240,7 +242,7 @@ describe('HDNode', function () {
     var f = fixtures.valid[0]
 
     it('strips all private information', function () {
-      var hd = HDNode.fromBase58(f.master.base58, NETWORKS_LIST)
+      var hd = HDNode.fromBase58(f.master.base58Priv, NETWORKS_LIST)
       var hdn = hd.neutered()
 
       assert.strictEqual(hdn.keyPair.d, undefined)
@@ -248,6 +250,8 @@ describe('HDNode', function () {
       assert.strictEqual(hdn.chainCode, hd.chainCode)
       assert.strictEqual(hdn.depth, hd.depth)
       assert.strictEqual(hdn.index, hd.index)
+      assert.strictEqual(hdn.isNeutered(), true)
+      assert.strictEqual(hd.isNeutered(), false)
     })
   })