bip32-utils
Advanced tools
Comparing version 0.10.1 to 0.10.2
@@ -10,7 +10,7 @@ var bitcoinjs = require('bitcoinjs-lib') | ||
Account.fromJSON = function (json, network) { | ||
Account.fromJSON = function (json, network, addressFunction) { | ||
var chains = json.map(function (j) { | ||
var node = bitcoinjs.HDNode.fromBase58(j.node, network) | ||
var chain = new Chain(node, j.k) | ||
var chain = new Chain(node, j.k, addressFunction) | ||
chain.map = j.map | ||
@@ -17,0 +17,0 @@ |
17
chain.js
@@ -1,2 +0,6 @@ | ||
function Chain (parent, k) { | ||
function DEFAULT_ADDRESS_FUNCTION (node) { | ||
return node.getAddress() | ||
} | ||
function Chain (parent, k, addressFunction) { | ||
k = k || 0 | ||
@@ -6,2 +10,3 @@ this.__parent = parent | ||
this.addresses = [] | ||
this.addressFunction = addressFunction || DEFAULT_ADDRESS_FUNCTION | ||
this.k = k | ||
@@ -12,3 +17,3 @@ this.map = {} | ||
Chain.prototype.__initialize = function () { | ||
var address = this.__parent.derive(this.k).getAddress() | ||
var address = this.addressFunction(this.__parent.derive(this.k)) | ||
this.map[address] = this.k | ||
@@ -19,6 +24,6 @@ this.addresses.push(address) | ||
Chain.prototype.clone = function () { | ||
var chain = new Chain(this.__parent, this.k) | ||
var chain = new Chain(this.__parent, this.k, this.addressFunction) | ||
for (var k in this.addresses) chain.addresses[k] = this.addresses[k] | ||
for (k in this.map) chain.map[k] = this.map[k] | ||
chain.addresses = this.addresses.concat() | ||
for (var s in this.map) chain.map[s] = this.map[s] | ||
@@ -58,3 +63,3 @@ return chain | ||
if (this.addresses.length === 0) this.__initialize() | ||
var address = this.__parent.derive(this.k + 1).getAddress() | ||
var address = this.addressFunction(this.__parent.derive(this.k + 1)) | ||
@@ -61,0 +66,0 @@ this.k += 1 |
{ | ||
"name": "bip32-utils", | ||
"version": "0.10.1", | ||
"version": "0.10.2", | ||
"description": "A set of utilities for working with BIP32.", | ||
@@ -36,2 +36,3 @@ "author": "Daniel Cousens", | ||
"bitcoinjs-lib": "^3.0.0", | ||
"keccak": "^1.3.0", | ||
"nyc": "*", | ||
@@ -43,3 +44,6 @@ "standard": "*", | ||
"bitcoinjs-lib": "^3.0.0" | ||
}, | ||
"engines": { | ||
"node": ">=4.0.0" | ||
} | ||
} |
@@ -5,8 +5,27 @@ var bitcoin = require('bitcoinjs-lib') | ||
var fixtures = require('./fixtures/chain') | ||
var createKeccakHash = require('keccak') | ||
function segwitAddr (node) { | ||
var hash = bitcoin.crypto.hash160(node.getPublicKeyBuffer()) | ||
var script = bitcoin.script.witnessPubKeyHash.output.encode(hash) | ||
return bitcoin.address.fromOutputScript(script) | ||
} | ||
function ethAddr (node) { | ||
return '0x' + createKeccakHash('keccak256') | ||
.update(node.getPublicKeyBuffer()) | ||
.digest().toString('hex') | ||
} | ||
var AF_MAPPING = { | ||
'eth': ethAddr, | ||
'segwit': segwitAddr | ||
} | ||
fixtures.forEach(function (f) { | ||
var node = bitcoin.HDNode.fromBase58(f.node) | ||
var addressFunction = AF_MAPPING[f.addressFunction] | ||
test('constructor', function (t) { | ||
var chain = new Chain(node) | ||
var chain = new Chain(node, null, addressFunction) | ||
@@ -16,6 +35,6 @@ t.plan(3) | ||
chain = new Chain(node, f.k) | ||
chain = new Chain(node, f.k, addressFunction) | ||
t.equal(chain.k, f.k, 'can start at a custom k value') | ||
chain = new Chain(node, f.k) | ||
chain = new Chain(node, f.k, addressFunction) | ||
t.equal(chain.addresses.length, 0, 'is lazy') | ||
@@ -25,6 +44,6 @@ }) | ||
test('clone', function (t) { | ||
var chain = new Chain(node) | ||
var chain = new Chain(node, null, addressFunction) | ||
var clone = chain.clone() | ||
t.plan(15) | ||
t.plan(17) | ||
@@ -40,2 +59,3 @@ // by reference | ||
t.same(chain.map, clone.map, 'k map is deep copied') | ||
t.same(chain.addressFunction, clone.addressFunction, 'address function is copied') | ||
@@ -57,15 +77,8 @@ for (var i = 0; i < 7; ++i) chain.next() | ||
t.same(chain.map, clone.map, 'k map is deep copied') | ||
t.same(chain.addressFunction, clone.addressFunction, 'address function is copied') | ||
}) | ||
test('get', function (t) { | ||
var chain = new Chain(node, f.k) | ||
chain.addresses = f.addresses | ||
t.plan(1) | ||
t.equal(chain.get(), f.addresses[f.addresses.length - 1], 'returns the last address') | ||
}) | ||
test('find/derive', function (t) { | ||
var neutered = node.neutered() | ||
var chain = new Chain(neutered, f.k) | ||
var chain = new Chain(neutered, f.k, addressFunction) | ||
@@ -83,15 +96,28 @@ t.plan(30) | ||
test('get', function (t) { | ||
var chain = new Chain(node, f.k, addressFunction) | ||
chain.addresses = f.addresses | ||
t.plan(1) | ||
t.equal(chain.get(), f.addresses[f.addresses.length - 1], 'returns the last address') | ||
}) | ||
test('next', function (t) { | ||
var chain = new Chain(node, f.k - f.addresses.length + 1) | ||
var first3 = f.addresses.slice(0, 3) | ||
var chain = new Chain(node, f.k - f.addresses.length + 1, addressFunction) | ||
t.plan(3) | ||
t.equal(chain.get(), first3[0], 'before next, get the first address') | ||
chain.next() | ||
t.equal(chain.get(), first3[1], 'after next, get returns next address') | ||
t.equal(chain.next(), first3[2], 'returns the next address') | ||
t.plan(f.addresses.length * 2 + 1) | ||
f.addresses.forEach(function (x, i) { | ||
t.equal(chain.get(), f.addresses[i], 'get returns the current address') | ||
if (f.addresses[i + 1]) { | ||
t.equal(chain.next(), f.addresses[i + 1], 'next returns the next address') | ||
} | ||
}) | ||
t.equal(chain.k, f.k, 'results in the the expected k value') | ||
t.same(chain.map, f.map, 'results in the expected address map') | ||
}) | ||
test('pop', function (t) { | ||
var chain = new Chain(node) | ||
var chain = new Chain(node, null, addressFunction) | ||
chain.next() | ||
@@ -98,0 +124,0 @@ chain.next() |
[ | ||
{ | ||
"addressFunction": "segwit", | ||
"addresses": [ | ||
"bc1q99vym3xh00dn659kd0ajj59hjrfzrqwxjtqxjz", | ||
"bc1qqv5dqszlqg33wjtn80xyneknq6atfg6w7f4upp", | ||
"bc1q8zzdyhujemc68kgexd7kqxq3cxgk0ac2nwze70", | ||
"bc1q9qfcjzp8qd2azktlgv4xmp9cvmnrkxa54k3ecr" | ||
], | ||
"k": 3, | ||
"map": { | ||
"bc1q99vym3xh00dn659kd0ajj59hjrfzrqwxjtqxjz": 0, | ||
"bc1qqv5dqszlqg33wjtn80xyneknq6atfg6w7f4upp": 1, | ||
"bc1q8zzdyhujemc68kgexd7kqxq3cxgk0ac2nwze70": 2, | ||
"bc1q9qfcjzp8qd2azktlgv4xmp9cvmnrkxa54k3ecr": 3 | ||
}, | ||
"node": "xprv9s21ZrQH143K2muoCkQq38JjsN4PGCovkjh7LVauc5cgRnkVoEtt1cDA5AjkFTBwfMwJrqw2JRWZk7YkvEQDFScF1BNJoz7CaPeqjkU1WYW" | ||
}, | ||
{ | ||
"addresses": [ | ||
"14mcVKY4W935C7M6rQaEUL3Vjc3bGjrh8s", | ||
@@ -37,3 +54,20 @@ "1HhvM4n8TwNZJfo1EWc3xeqzpoRYPQSbK", | ||
"node": "xprv9s21ZrQH143K2muoCkQq38JjsN4PGCovkjh7LVauc5cgRnkVoEtt1cDA5AjkFTBwfMwJrqw2JRWZk7YkvEQDFScF1BNJoz7CaPeqjkU1WYW" | ||
}, | ||
{ | ||
"addressFunction": "eth", | ||
"addresses": [ | ||
"0x8afb810bd34e0bef8be88959ef21ad618ce8c5eb31b960d4a2e142c109784f97", | ||
"0x4c8ee95d7d9cacab1db2599e34aa7b821948468272778b3a8ebce43ec15f93ed", | ||
"0xc43bd9d439085d86c6ae446ac0b995d928c73b454e3f208b4c586986cef7d568", | ||
"0x7421b47a0bf52fb9210722a82a2a7fda54fdd8ee9b860de201ad5aa9a37bf4d4" | ||
], | ||
"k": 3, | ||
"map": { | ||
"0x8afb810bd34e0bef8be88959ef21ad618ce8c5eb31b960d4a2e142c109784f97": 0, | ||
"0x4c8ee95d7d9cacab1db2599e34aa7b821948468272778b3a8ebce43ec15f93ed": 1, | ||
"0xc43bd9d439085d86c6ae446ac0b995d928c73b454e3f208b4c586986cef7d568": 2, | ||
"0x7421b47a0bf52fb9210722a82a2a7fda54fdd8ee9b860de201ad5aa9a37bf4d4": 3 | ||
}, | ||
"node": "xprv9s21ZrQH143K2muoCkQq38JjsN4PGCovkjh7LVauc5cgRnkVoEtt1cDA5AjkFTBwfMwJrqw2JRWZk7YkvEQDFScF1BNJoz7CaPeqjkU1WYW" | ||
} | ||
] |
Sorry, the diff of this file is not supported yet
51797
1055
5