Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,20 @@ Contributing to Bitcore

We're working hard to make *bitcore* the most powerful JavaScript library for working with bitcoin. Our goal is to have *bitcore* be a library that can be used by anyone interested in bitcoin, and to level expertise differences with great design and documentation.

## Community

If there are any questions, etc., please feel to ask in one of the community channels:

- https://labs.bitpay.com/c/bitcore (Support Forum)
- https://gitter.im/bitpay/bitcore (Development Chat)

## Quick Checklist

Make sure:
Ideally, please make sure to run:

* `gulp test` passes all the tests (We run tests against Node.js v0.10, v0.12, io.js, and modern browsers)
* `gulp coverage` covers 100% of the branches of your code (See `coverage/lcov-report/index.html` for details)
* `gulp lint` doesn't complain about your changes
* `gulp test` passes all the tests
* `gulp coverage` covers 100% of the branches of your code

## Design Guidelines

Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "bitcore",
"main": "./bitcore.min.js",
"version": "0.12.15",
"version": "0.13.0",
"homepage": "http://bitcore.io",
"authors": [
"BitPay, Inc."
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Bitcore v0.12
# Bitcore v0.13

## Principles

Expand Down
2 changes: 1 addition & 1 deletion lib/crypto/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Hash.ripemd160 = function(buf) {

// Node.js crypto ripemd160 hashes are not supported in a browser
// We'll replace with a (slower) version that does.
if (global.window) {
if (process.browser) {
Hash.ripemd160 = function(buf) {
$.checkArgument(BufferUtil.isBuffer(buf));
var hash = (new hashjs.ripemd160()).update(buf).digest();
Expand Down
3 changes: 3 additions & 0 deletions lib/errors/spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ module.exports = [{
}, {
name: 'InvalidPath',
message: 'Invalid derivation path, it should look like: "m/1/100", got "{0}"'
}, {
name: 'InvalidIndexCantDeriveHardened',
message: 'Invalid argument: creating a hardened path requires an HDPrivateKey'
}, {
name: 'MustSupplyArgument',
message: 'Must supply an argument to create a HDPublicKey'
Expand Down
28 changes: 14 additions & 14 deletions lib/hdpublickey.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,18 +108,18 @@ HDPublicKey.isValidPath = function(arg) {
*
* @param {string|number} arg
*/
HDPublicKey.prototype.derive = function (arg) {
HDPublicKey.prototype.derive = function(arg, hardened) {
if (_.isNumber(arg)) {
return this._deriveWithNumber(arg);
return this._deriveWithNumber(arg, hardened);
} else if (_.isString(arg)) {
return this._deriveFromString(arg);
} else {
throw new hdErrors.InvalidDerivationArgument(arg);
}
};

HDPublicKey.prototype._deriveWithNumber = function (index) {
if (index >= HDPublicKey.Hardened) {
HDPublicKey.prototype._deriveWithNumber = function(index, hardened) {
if (index >= HDPublicKey.Hardened || hardened) {
throw new hdErrors.InvalidIndexCantDeriveHardened();
}
if (index < 0) {
Expand Down Expand Up @@ -150,7 +150,7 @@ HDPublicKey.prototype._deriveWithNumber = function (index) {
return derived;
};

HDPublicKey.prototype._deriveFromString = function (path) {
HDPublicKey.prototype._deriveFromString = function(path) {
/* jshint maxcomplexity: 8 */
if (_.contains(path, "'")) {
throw new hdErrors.InvalidIndexCantDeriveHardened();
Expand All @@ -175,7 +175,7 @@ HDPublicKey.prototype._deriveFromString = function (path) {
* network provided matches the network serialized.
* @return {boolean}
*/
HDPublicKey.isValidSerialized = function (data, network) {
HDPublicKey.isValidSerialized = function(data, network) {
return _.isNull(HDPublicKey.getSerializedError(data, network));
};

Expand All @@ -188,7 +188,7 @@ HDPublicKey.isValidSerialized = function (data, network) {
* network provided matches the network serialized.
* @return {errors|null}
*/
HDPublicKey.getSerializedError = function (data, network) {
HDPublicKey.getSerializedError = function(data, network) {
/* jshint maxcomplexity: 10 */
/* jshint maxstatements: 20 */
if (!(_.isString(data) || BufferUtil.isBuffer(data))) {
Expand All @@ -203,7 +203,7 @@ HDPublicKey.getSerializedError = function (data, network) {
return new errors.InvalidB58Checksum(data);
}
if (data.length !== HDPublicKey.DataSize) {
return new errors.InvalidLength(data);
return new hdErrors.InvalidLength(data);
}
if (!_.isUndefined(network)) {
var error = HDPublicKey._validateNetwork(data, network);
Expand All @@ -218,7 +218,7 @@ HDPublicKey.getSerializedError = function (data, network) {
return null;
};

HDPublicKey._validateNetwork = function (data, networkArg) {
HDPublicKey._validateNetwork = function(data, networkArg) {
var network = Network.get(networkArg);
if (!network) {
return new errors.InvalidNetworkArgument(networkArg);
Expand All @@ -241,7 +241,7 @@ HDPublicKey.prototype._buildFromPrivate = function (arg) {
return this._buildFromBuffers(args);
};

HDPublicKey.prototype._buildFromObject = function (arg) {
HDPublicKey.prototype._buildFromObject = function(arg) {
/* jshint maxcomplexity: 10 */
// TODO: Type validation
var buffers = {
Expand All @@ -257,7 +257,7 @@ HDPublicKey.prototype._buildFromObject = function (arg) {
return this._buildFromBuffers(buffers);
};

HDPublicKey.prototype._buildFromSerialized = function (arg) {
HDPublicKey.prototype._buildFromSerialized = function(arg) {
var decoded = Base58Check.decode(arg);
var buffers = {
version: decoded.slice(HDPublicKey.VersionStart, HDPublicKey.VersionEnd),
Expand Down Expand Up @@ -289,7 +289,7 @@ HDPublicKey.prototype._buildFromSerialized = function (arg) {
* representation
* @return {HDPublicKey} this
*/
HDPublicKey.prototype._buildFromBuffers = function (arg) {
HDPublicKey.prototype._buildFromBuffers = function(arg) {
/* jshint maxcomplexity: 8 */
/* jshint maxstatements: 20 */

Expand Down Expand Up @@ -333,7 +333,7 @@ HDPublicKey.prototype._buildFromBuffers = function (arg) {
return this;
};

HDPublicKey._validateBufferArguments = function (arg) {
HDPublicKey._validateBufferArguments = function(arg) {
var checkBuffer = function(name, size) {
var buff = arg[name];
assert(BufferUtil.isBuffer(buff), name + ' argument is not a buffer, it\'s ' + typeof buff);
Expand Down Expand Up @@ -367,7 +367,7 @@ HDPublicKey.fromObject = function(arg) {
* Returns the base58 checked representation of the public key
* @return {string} a string starting with "xpub..." in livenet
*/
HDPublicKey.prototype.toString = function () {
HDPublicKey.prototype.toString = function() {
return this.xpubkey;
};

Expand Down
2 changes: 2 additions & 0 deletions lib/transaction/input/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var Output = require('../output');


var DEFAULT_SEQNUMBER = 0xFFFFFFFF;
var DEFAULT_LOCKTIME_SEQNUMBER = 0x00000000;

function Input(params) {
if (!(this instanceof Input)) {
Expand All @@ -24,6 +25,7 @@ function Input(params) {
}

Input.DEFAULT_SEQNUMBER = DEFAULT_SEQNUMBER;
Input.DEFAULT_LOCKTIME_SEQNUMBER = DEFAULT_LOCKTIME_SEQNUMBER;

Object.defineProperty(Input.prototype, 'script', {
configurable: false,
Expand Down
11 changes: 11 additions & 0 deletions lib/transaction/transaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,11 @@ Transaction.prototype.lockUntilDate = function(time) {
if (_.isDate(time)) {
time = time.getTime() / 1000;
}

for (var i = 0; i < this.inputs.length; i++) {
this.inputs[i].sequenceNumber = Input.DEFAULT_LOCKTIME_SEQNUMBER;
}

this.nLockTime = time;
return this;
};
Expand All @@ -433,6 +438,12 @@ Transaction.prototype.lockUntilBlockHeight = function(height) {
if (height < 0) {
throw new errors.Transaction.NLockTimeOutOfRange();
}

for (var i = 0; i < this.inputs.length; i++) {
this.inputs[i].sequenceNumber = Input.DEFAULT_LOCKTIME_SEQNUMBER;
}


this.nLockTime = height;
return this;
};
Expand Down
8 changes: 4 additions & 4 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bitcore",
"version": "0.12.15",
"version": "0.13.0",
"description": "A pure and powerful JavaScript Bitcoin library.",
"author": "BitPay <dev@bitpay.com>",
"main": "index.js",
Expand Down Expand Up @@ -84,7 +84,7 @@
"elliptic": "=3.0.3",
"hash.js": "=1.0.2",
"inherits": "=2.0.1",
"lodash": "=2.4.1",
"lodash": "=3.10.1",
"sha512": "=0.0.1"
},
"devDependencies": {
Expand Down
91 changes: 44 additions & 47 deletions test/hdpublickey.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,22 @@ var derived_0_1_200000 = 'xpub6BqyndF6rkBNTV6LXwiY8Pco8aqctqq7tGEUdA8fmGDTnDJphn
describe('HDPublicKey interface', function() {

var expectFail = function(func, errorType) {
var got = null;
var error = null;
try {
(function() {
func();
} catch (e) {
error = e;
got = e instanceof errorType;
}
if (!error instanceof errorType) {
console.log('Error', typeof error);
}
// expect(got).to.equal(true);
}).should.throw(errorType);
};

var expectDerivationFail = function(argument, error) {
return expectFail(function() {
(function() {
var pubkey = new HDPublicKey(xpubkey);
xpubkey.derive(argument);
}, error);
pubkey.derive(argument);
}).should.throw(error);
};

var expectFailBuilding = function(argument, error) {
return expectFail(function() {
(function() {
return new HDPublicKey(argument);
}, error);
}).should.throw(error);
};

describe('creation formats', function() {
Expand Down Expand Up @@ -225,55 +216,61 @@ describe('HDPublicKey interface', function() {

it('doesn\'t allow other parameters like m\' or M\' or "s"', function() {
/* jshint quotmark: double */
expectDerivationFail("m'", hdErrors.InvalidDerivationArgument);
expectDerivationFail("M'", hdErrors.InvalidDerivationArgument);
expectDerivationFail("1", hdErrors.InvalidDerivationArgument);
expectDerivationFail("S", hdErrors.InvalidDerivationArgument);
expectDerivationFail("m'", hdErrors.InvalidIndexCantDeriveHardened);
expectDerivationFail("M'", hdErrors.InvalidIndexCantDeriveHardened);
expectDerivationFail("1", hdErrors.InvalidPath);
expectDerivationFail("S", hdErrors.InvalidPath);
});

it('can\'t derive hardened keys', function() {
expectFail(function() {
return new HDPublicKey(xpubkey).derive(HDPublicKey.Hardened);
}, hdErrors.InvalidDerivationArgument);
}, hdErrors.InvalidIndexCantDeriveHardened);
});

it('validates correct paths', function() {
var valid;
it('can\'t derive hardened keys via second argument', function() {
expectFail(function() {
return new HDPublicKey(xpubkey).derive(5, true);
}, hdErrors.InvalidIndexCantDeriveHardened);
});

valid = HDPublicKey.isValidPath('m/123/12');
valid.should.equal(true);
it('validates correct paths', function() {
var valid;

valid = HDPublicKey.isValidPath('m');
valid.should.equal(true);
valid = HDPublicKey.isValidPath('m/123/12');
valid.should.equal(true);

valid = HDPublicKey.isValidPath(123);
valid.should.equal(true);
});
valid = HDPublicKey.isValidPath('m');
valid.should.equal(true);

it('rejects illegal paths', function() {
var valid;
valid = HDPublicKey.isValidPath(123);
valid.should.equal(true);
});

valid = HDPublicKey.isValidPath('m/-1/12');
valid.should.equal(false);
it('rejects illegal paths', function() {
var valid;

valid = HDPublicKey.isValidPath("m/0'/12");
valid.should.equal(false);
valid = HDPublicKey.isValidPath('m/-1/12');
valid.should.equal(false);

valid = HDPublicKey.isValidPath("m/8000000000/12");
valid.should.equal(false);
valid = HDPublicKey.isValidPath("m/0'/12");
valid.should.equal(false);

valid = HDPublicKey.isValidPath('bad path');
valid.should.equal(false);
valid = HDPublicKey.isValidPath("m/8000000000/12");
valid.should.equal(false);

valid = HDPublicKey.isValidPath(-1);
valid.should.equal(false);
valid = HDPublicKey.isValidPath('bad path');
valid.should.equal(false);

valid = HDPublicKey.isValidPath(8000000000);
valid.should.equal(false);
valid = HDPublicKey.isValidPath(-1);
valid.should.equal(false);

valid = HDPublicKey.isValidPath(HDPublicKey.Hardened);
valid.should.equal(false);
});
valid = HDPublicKey.isValidPath(8000000000);
valid.should.equal(false);

valid = HDPublicKey.isValidPath(HDPublicKey.Hardened);
valid.should.equal(false);
});

it('should use the cache', function() {
var pubkey = new HDPublicKey(xpubkey);
Expand Down
Loading