Comparing version 0.10.4 to 0.11.0
{ | ||
"name": "bitcore", | ||
"main": "./bitcore.min.js", | ||
"version": "0.10.4", | ||
"version": "0.11.0", | ||
"homepage": "http://bitcore.io", | ||
@@ -6,0 +6,0 @@ "authors": [ |
@@ -74,3 +74,3 @@ Contributing to Bitcore | ||
Name them in CamelCase, as they are namespaces. | ||
Name them in UpperCamelCase, as they are namespaces. | ||
@@ -77,0 +77,0 @@ DO: |
--- | ||
title: Browser Builds | ||
description: Guide to writing modules and optimizing browser bundles. | ||
description: Guide to using and writing modules and optimizing browser bundles. | ||
--- | ||
@@ -8,5 +8,73 @@ | ||
Bitcore and most official submodules work in the browser, thanks to [browserify](http://browserify.org/) (some modules are not fully compatible with web browsers). | ||
The easiest and recommended way to use them, is via [Bower](http://bower.io/), a browser package manager, and get the release bundles. | ||
For example, when building an app that uses `bitcore` and `bitcore-ecies`, you do: | ||
```sh | ||
bower install bitcore | ||
bower install bitcore-ecies | ||
``` | ||
You can also use a `bower.json` file to store the dependencies of your project: | ||
```json | ||
{ | ||
"name": "Your app name", | ||
"version": "0.0.1", | ||
"license": "MIT", | ||
"dependencies": { | ||
"bitcore-ecies": "^0.10.0", | ||
"bitcore": "^0.10.4" | ||
} | ||
} | ||
``` | ||
and run `bower install` to install the dependencies. | ||
After this, you can include the bundled release versions in your HTML file: | ||
```html | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<script src="bower_components/bitcore/bitcore.min.js"></script> | ||
<script src="bower_components/bitcore-ecies/bitcore-ecies.min.js"></script> | ||
</head> | ||
<body> | ||
<script type="text/javascript"> | ||
var bitcore = require('bitcore'); | ||
var ECIES = require('bitcore-ecies'); | ||
// etc... | ||
</script> | ||
</body> | ||
</html> | ||
``` | ||
## Building Custom Bundles | ||
If you want to use a specific version of a module, instead of a release version (not recommended), you must run browserify yourself. | ||
You can get a minified browser bundle by running the following on the project root folder. | ||
```sh | ||
browserify --require ./index.js:bitcore | uglifyjs > bitcore.min.js | ||
``` | ||
(for bitcore) | ||
```sh | ||
browserify --require ./index.js:bitcore-ecies --external bitcore | uglifyjs > bitcore-ecies.min.js | ||
``` | ||
(for a bitcore module, `bitcore-ecies` in the example) | ||
## Development of Modules | ||
*Note:* You probably don't want to use this method, but `bitcore-build`, as explained above. This is left here as documentation on what happens under the hood with `bitcore-build`. | ||
When developing a module that will depend on Bitcore, it's recommended to exclude Bitcore in the distributed browser bundle when using browserify and to use the `--external bitcore` parameter. It will produce a smaller browser bundle, as it will only include the JavaScript that is nessessary, and will depend on the Bitcore browser build which is better for distribution. | ||
## Tutorial | ||
### Building the Bundle Manually | ||
@@ -18,3 +86,2 @@ **Step 1**: Require Bitcore | ||
```javascript | ||
var bitcore = require('bitcore'); | ||
@@ -24,3 +91,2 @@ var PrivateKey = bitcore.PrivateKey; | ||
var Address = bitcore.Address; | ||
``` | ||
@@ -27,0 +93,0 @@ |
@@ -145,5 +145,3 @@ --- | ||
* `toString` or `uncheckedSerialize`: Returns an hexadecimal serialization of the transaction, in the [serialization format for bitcoin](https://bitcoin.org/en/developer-reference#raw-transaction-format). | ||
* `serialize`: Does a series of checks before serializing the transaction: | ||
- Check that the fee to be used is not very small or very large | ||
- Check for dust outputs | ||
* `serialize`: Does a series of checks before serializing the transaction | ||
* `inspect`: Returns a string with some information about the transaction (currently a string formated as `<Transaction 000...000>`, that only shows the serialized value of the transaction. | ||
@@ -153,2 +151,18 @@ * `toBuffer`: Serializes the transaction for sending over the wire in the bitcoin network | ||
## Serialization Checks | ||
When serializing, the bitcore library performs a series of checks. These can be disabled by providing an object to the `serialize` method with the checks that you'll like to skip. | ||
* `disableLargeFees` avoids checking that the fee is no more than `Transaction.FEE_PER_KB * Transaction.FEE_SECURITY_MARGIN * size_in_kb`. | ||
* `disableSmallFees` avoids checking that the fee is less than `Transaction.FEE_PER_KB * size_in_kb / Transaction.FEE_SECURITY_MARGIN`. | ||
* `disableIsFullySigned` does not check if all inputs are fully signed | ||
* `disableDustOutputs` does not check for dust outputs being generated | ||
* `disableMoreOutputThanInput` avoids checking that the sum of the output amounts is less than or equal to the sum of the amounts for the outputs being spent in the transaction | ||
These are the current default values in the bitcore library involved on these checks: | ||
* `Transaction.FEE_PER_KB`: `10000` (satoshis per kilobyte) | ||
* `Transaction.FEE_SECURITY_MARGIN`: `15` | ||
* `Transaction.DUST_AMOUNT`: `546` (satoshis) | ||
## Fee calculation | ||
@@ -155,0 +169,0 @@ |
@@ -33,3 +33,4 @@ var bitcore = module.exports; | ||
bitcore.Block = require('./lib/block'); | ||
bitcore.BlockHeader = require('./lib/blockheader'); | ||
bitcore.MerkleBlock = require('./lib/block/merkleblock'); | ||
bitcore.BlockHeader = require('./lib/block/blockheader'); | ||
bitcore.HDPrivateKey = require('./lib/hdprivatekey.js'); | ||
@@ -36,0 +37,0 @@ bitcore.HDPublicKey = require('./lib/hdpublickey.js'); |
@@ -39,4 +39,4 @@ 'use strict'; | ||
* @param {*} data - The encoded data in various formats | ||
* @param {Network|String|number} [network] - The network: 'livenet' or 'testnet' | ||
* @param {String} [type] - The type of address: 'script' or 'pubkey' | ||
* @param {Network|String|number=} network - The network: 'livenet' or 'testnet' | ||
* @param {string=} type - The type of address: 'script' or 'pubkey' | ||
* @returns {Address} A new valid and frozen instance of an Address | ||
@@ -90,4 +90,4 @@ * @constructor | ||
* @param {*} data - The encoded data in various formats | ||
* @param {Network|String|number} [network] - The network: 'livenet' or 'testnet' | ||
* @param {String} [type] - The type of address: 'script' or 'pubkey' | ||
* @param {Network|String|number=} network - The network: 'livenet' or 'testnet' | ||
* @param {string=} type - The type of address: 'script' or 'pubkey' | ||
* @returns {Object} An "info" object with "type", "network", and "hashBuffer" | ||
@@ -191,4 +191,4 @@ */ | ||
* @param {Buffer} buffer - An instance of a hex encoded address Buffer | ||
* @param {String} [network] - The network: 'livenet' or 'testnet' | ||
* @param {String} [type] - The type: 'pubkeyhash' or 'scripthash' | ||
* @param {string=} network - The network: 'livenet' or 'testnet' | ||
* @param {string=} type - The type: 'pubkeyhash' or 'scripthash' | ||
* @returns {Object} An object with keys: hashBuffer, network and type | ||
@@ -290,5 +290,5 @@ * @private | ||
* | ||
* @param {String} data | ||
* @param {String|Network} [network] - either a Network instance, 'livenet', or 'testnet' | ||
* @param {String} [type] - The type: 'pubkeyhash' or 'scripthash' | ||
* @param {string} data | ||
* @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet' | ||
* @param {string=} type - The type: 'pubkeyhash' or 'scripthash' | ||
* @returns {Object} An object with keys: hashBuffer, network and type | ||
@@ -359,4 +359,4 @@ * @private | ||
* @param {Buffer} buffer - An instance of buffer of the address | ||
* @param {String|Network} [network] - either a Network instance, 'livenet', or 'testnet' | ||
* @param {String} [type] - The type of address: 'script' or 'pubkey' | ||
* @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet' | ||
* @param {string=} type - The type of address: 'script' or 'pubkey' | ||
* @returns {Address} A new valid and frozen instance of an Address | ||
@@ -372,5 +372,5 @@ */ | ||
* | ||
* @param {String} str - An string of the bitcoin address | ||
* @param {String|Network} [network] - either a Network instance, 'livenet', or 'testnet' | ||
* @param {String} [type] - The type of address: 'script' or 'pubkey' | ||
* @param {string} str - An string of the bitcoin address | ||
* @param {String|Network=} network - either a Network instance, 'livenet', or 'testnet' | ||
* @param {string=} type - The type of address: 'script' or 'pubkey' | ||
* @returns {Address} A new valid and frozen instance of an Address | ||
@@ -386,3 +386,3 @@ */ | ||
* | ||
* @param {String} json - An JSON string or Object with keys: hash, network and type | ||
* @param {string} json - An JSON string or Object with keys: hash, network and type | ||
* @returns {Address} A new valid instance of an Address | ||
@@ -411,5 +411,5 @@ */ | ||
* | ||
* @param {String} data - The encoded data | ||
* @param {string} data - The encoded data | ||
* @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' | ||
* @param {String} type - The type of address: 'script' or 'pubkey' | ||
* @param {string} type - The type of address: 'script' or 'pubkey' | ||
* @returns {null|Error} The corresponding error message | ||
@@ -436,5 +436,5 @@ */ | ||
* | ||
* @param {String} data - The encoded data | ||
* @param {string} data - The encoded data | ||
* @param {String|Network} network - either a Network instance, 'livenet', or 'testnet' | ||
* @param {String} type - The type of address: 'script' or 'pubkey' | ||
* @param {string} type - The type of address: 'script' or 'pubkey' | ||
* @returns {boolean} The corresponding error message | ||
@@ -485,3 +485,3 @@ */ | ||
/** | ||
* @returns {String} A JSON representation of a plain object with the address information | ||
* @returns {string} A JSON representation of a plain object with the address information | ||
*/ | ||
@@ -495,3 +495,3 @@ Address.prototype.toJSON = function toJSON() { | ||
* | ||
* @returns {String} Bitcoin address | ||
* @returns {string} Bitcoin address | ||
*/ | ||
@@ -505,3 +505,3 @@ Address.prototype.toString = function() { | ||
* | ||
* @returns {String} Bitcoin address | ||
* @returns {string} Bitcoin address | ||
*/ | ||
@@ -508,0 +508,0 @@ Address.prototype.inspect = function() { |
@@ -64,2 +64,8 @@ 'use strict'; | ||
}, { | ||
name: 'InvalidOutputAmountSum', | ||
message: '{0}' | ||
}, { | ||
name: 'MissingSignatures', | ||
message: 'Some inputs have not been fully signed' | ||
}, { | ||
name: 'InvalidIndex', | ||
@@ -66,0 +72,0 @@ message: 'Invalid index: {0} is not between 0, {1}' |
@@ -407,2 +407,3 @@ 'use strict'; | ||
var network = Network.get(BufferUtil.integerFromBuffer(arg.version)); | ||
var xprivkey; | ||
@@ -412,3 +413,3 @@ xprivkey = Base58Check.encode(buffer.Buffer.concat(sequence)); | ||
var privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey)); | ||
var privateKey = new PrivateKey(BN.fromBuffer(arg.privateKey), network); | ||
var publicKey = privateKey.toPublicKey(); | ||
@@ -420,3 +421,3 @@ var size = HDPrivateKey.ParentFingerPrintSize; | ||
xprivkey: xprivkey, | ||
network: Network.get(BufferUtil.integerFromBuffer(arg.version)), | ||
network: network, | ||
depth: BufferUtil.integerFromSingleByteBuffer(arg.depth), | ||
@@ -423,0 +424,0 @@ privateKey: privateKey, |
@@ -321,2 +321,3 @@ 'use strict'; | ||
} | ||
var network = Network.get(BufferUtil.integerFromBuffer(arg.version)); | ||
@@ -327,3 +328,3 @@ var xpubkey; | ||
var publicKey = PublicKey.fromString(arg.publicKey); | ||
var publicKey = new PublicKey(arg.publicKey, {network: network}); | ||
var size = HDPublicKey.ParentFingerPrintSize; | ||
@@ -334,3 +335,3 @@ var fingerPrint = Hash.sha256ripemd160(publicKey.toBuffer()).slice(0, size); | ||
xpubkey: xpubkey, | ||
network: Network.get(BufferUtil.integerFromBuffer(arg.version)), | ||
network: network, | ||
depth: BufferUtil.integerFromSingleByteBuffer(arg.depth), | ||
@@ -337,0 +338,0 @@ publicKey: publicKey, |
@@ -48,4 +48,4 @@ 'use strict'; | ||
* @param {Object} data | ||
* @param {String} data.name - The name of the network | ||
* @param {String} data.alias - The aliased name of the network | ||
* @param {string} data.name - The name of the network | ||
* @param {string} data.alias - The aliased name of the network | ||
* @param {Number} data.pubkeyhash - The publickey hash prefix | ||
@@ -52,0 +52,0 @@ * @param {Number} data.privatekey - The privatekey prefix |
@@ -239,3 +239,3 @@ 'use strict'; | ||
* | ||
* @returns {String} Script opcode | ||
* @returns {string} Script opcode | ||
*/ | ||
@@ -242,0 +242,0 @@ Opcode.prototype.inspect = function() { |
@@ -32,3 +32,3 @@ 'use strict'; | ||
* @param {string} data - The encoded data in various formats | ||
* @param {Network|string} [network] - a {@link Network} object, or a string with the network name | ||
* @param {Network|string=} network - a {@link Network} object, or a string with the network name | ||
* @returns {PrivateKey} A new valid instance of an PrivateKey | ||
@@ -82,3 +82,3 @@ * @constructor | ||
* @param {*} data | ||
* @param {Network|string} [network] - a {@link Network} object, or a string with the network name | ||
* @param {Network|string=} network - a {@link Network} object, or a string with the network name | ||
* @return {Object} | ||
@@ -149,3 +149,3 @@ */ | ||
* @param {Buffer} buf - An WIF string | ||
* @param {Network|string} [network] - a {@link Network} object, or a string with the network name | ||
* @param {Network|string=} network - a {@link Network} object, or a string with the network name | ||
* @returns {Object} An object with keys: bn, network and compressed | ||
@@ -192,3 +192,3 @@ * @private | ||
* @param {Buffer} buf | ||
* @param {Network|string} [network] - a {@link Network} object, or a string with the network name | ||
* @param {Network|string=} network - a {@link Network} object, or a string with the network name | ||
* @returns {object} an Object with keys: bn, network, and compressed | ||
@@ -208,3 +208,3 @@ * @private | ||
* | ||
* @param {String} buf - An WIF string | ||
* @param {string} buf - An WIF string | ||
* @returns {Object} An object with keys: bn, network and compressed | ||
@@ -220,3 +220,3 @@ * @private | ||
* | ||
* @param {String} json - The JSON encoded private key string | ||
* @param {string} json - The JSON encoded private key string | ||
* @returns {PrivateKey} A new valid instance of PrivateKey | ||
@@ -247,3 +247,3 @@ */ | ||
* | ||
* @param {String} json - A JSON string or plain object | ||
* @param {string} json - A JSON string or plain object | ||
* @returns {Object} An object with keys: bn, network and compressed | ||
@@ -267,3 +267,3 @@ * @private | ||
* | ||
* @param {String} str - The WIF encoded private key string | ||
* @param {string} str - The WIF encoded private key string | ||
* @returns {PrivateKey} A new valid instance of PrivateKey | ||
@@ -278,3 +278,3 @@ */ | ||
* | ||
* @param {String} [network] - Either "livenet" or "testnet" | ||
* @param {string=} network - Either "livenet" or "testnet" | ||
* @returns {PrivateKey} A new valid instance of PrivateKey | ||
@@ -290,4 +290,4 @@ */ | ||
* | ||
* @param {String} data - The encoded data in various formats | ||
* @param {String} [network] - Either "livenet" or "testnet" | ||
* @param {string} data - The encoded data in various formats | ||
* @param {string=} network - Either "livenet" or "testnet" | ||
* @returns {null|Error} An error if exists | ||
@@ -310,7 +310,10 @@ */ | ||
* | ||
* @param {String} data - The encoded data in various formats | ||
* @param {String} [network] - Either "livenet" or "testnet" | ||
* @param {string} data - The encoded data in various formats | ||
* @param {string=} network - Either "livenet" or "testnet" | ||
* @returns {Boolean} If the private key is would be valid | ||
*/ | ||
PrivateKey.isValid = function(data, network){ | ||
if (!data) { | ||
return false; | ||
} | ||
return !PrivateKey.getValidationError(data, network); | ||
@@ -322,3 +325,3 @@ }; | ||
* | ||
* @returns {String} | ||
* @returns {string} | ||
*/ | ||
@@ -332,3 +335,3 @@ PrivateKey.prototype.toString = function() { | ||
* | ||
* @returns {String} A WIP representation of the private key | ||
* @returns {string} A WIP representation of the private key | ||
*/ | ||
@@ -384,8 +387,10 @@ PrivateKey.prototype.toWIF = function() { | ||
* Will return an address for the private key | ||
* @param {Network=} network - optional parameter specifying | ||
* the desired network for the address | ||
* | ||
* @returns {Address} An address generated from the private key | ||
*/ | ||
PrivateKey.prototype.toAddress = function() { | ||
PrivateKey.prototype.toAddress = function(network) { | ||
var pubkey = this.toPublicKey(); | ||
return Address.fromPublicKey(pubkey, this.network); | ||
return Address.fromPublicKey(pubkey, network || this.network); | ||
}; | ||
@@ -411,3 +416,3 @@ | ||
* | ||
* @returns {String} Private key | ||
* @returns {string} Private key | ||
*/ | ||
@@ -414,0 +419,0 @@ PrivateKey.prototype.inspect = function() { |
@@ -30,3 +30,3 @@ 'use strict'; | ||
* | ||
* @param {String} data - The encoded data in various formats | ||
* @param {string} data - The encoded data in various formats | ||
* @param {Object} extra - additional options | ||
@@ -74,4 +74,3 @@ * @param {Network=} extra.network - Which network should the address for this public key be for | ||
var info = { | ||
compressed: _.isUndefined(extra.compressed) || extra.compressed, | ||
network: _.isUndefined(extra.network) ? undefined : Network.get(extra.network) | ||
compressed: _.isUndefined(extra.compressed) || extra.compressed | ||
}; | ||
@@ -93,2 +92,5 @@ | ||
} | ||
if (!info.network) { | ||
info.network = _.isUndefined(extra.network) ? undefined : Network.get(extra.network); | ||
} | ||
return info; | ||
@@ -123,3 +125,3 @@ }; | ||
* | ||
* @param {*} param - value to test | ||
* @param {*} json - value to test | ||
* @returns {boolean} | ||
@@ -153,3 +155,3 @@ * @private | ||
* @param {Buffer} buf - An hex encoded buffer | ||
* @param {bool} [strict] - if set to false, will loosen some conditions | ||
* @param {bool=} strict - if set to false, will loosen some conditions | ||
* @returns {Object} An object with keys: point and compressed | ||
@@ -216,3 +218,3 @@ * @private | ||
* | ||
* @param {String} json - A JSON string | ||
* @param {string} json - A JSON string | ||
* @returns {PublicKey} A new valid instance of PublicKey | ||
@@ -229,3 +231,3 @@ */ | ||
* | ||
* @param {Buffer} buf - a JSON string or plain object | ||
* @param {String|Object} json - a JSON string or plain object | ||
* @returns {Object} An object with keys: point and compressed | ||
@@ -264,3 +266,3 @@ * @private | ||
* @param {Buffer} buf - A DER hex buffer | ||
* @param {bool} [strict] - if set to false, will loosen some conditions | ||
* @param {bool=} strict - if set to false, will loosen some conditions | ||
* @returns {PublicKey} A new valid instance of PublicKey | ||
@@ -295,4 +297,4 @@ */ | ||
* | ||
* @param {String} str - A DER hex string | ||
* @param {String} [encoding] - The type of string encoding | ||
* @param {string} str - A DER hex string | ||
* @param {String=} encoding - The type of string encoding | ||
* @returns {PublicKey} A new valid instance of PublicKey | ||
@@ -325,4 +327,3 @@ */ | ||
* | ||
* @param {String} data - The encoded data in various formats | ||
* @param {String} [compressed] - If the public key is compressed | ||
* @param {string} data - The encoded data in various formats | ||
* @returns {null|Error} An error if exists | ||
@@ -344,4 +345,3 @@ */ | ||
* | ||
* @param {String} data - The encoded data in various formats | ||
* @param {String} [compressed] - If the public key is compressed | ||
* @param {string} data - The encoded data in various formats | ||
* @returns {Boolean} If the public key would be valid | ||
@@ -364,2 +364,5 @@ */ | ||
/** | ||
* @returns {string} A JSON string of the PublicKey | ||
*/ | ||
PublicKey.prototype.toJSON = function toJSON() { | ||
@@ -412,2 +415,3 @@ return JSON.stringify(this.toObject()); | ||
* | ||
* @param {String|Network=} network - Which network should the address be for | ||
* @returns {Address} An address generated from the public key | ||
@@ -422,3 +426,3 @@ */ | ||
* | ||
* @returns {String} A DER hex encoded string | ||
* @returns {string} A DER hex encoded string | ||
*/ | ||
@@ -432,3 +436,3 @@ PublicKey.prototype.toString = function() { | ||
* | ||
* @returns {String} Public key | ||
* @returns {string} Public key | ||
*/ | ||
@@ -435,0 +439,0 @@ PublicKey.prototype.inspect = function() { |
@@ -40,3 +40,3 @@ 'use strict'; | ||
* @param {Script} scriptPubkey - the script's last part (corresponding to the tx output) | ||
* @param {Transaction} [tx] - the Transaction containing the scriptSig in one input (used | ||
* @param {Transaction=} tx - the Transaction containing the scriptSig in one input (used | ||
* to check signature validity for some opcodes like OP_CHECKSIG) | ||
@@ -43,0 +43,0 @@ * @param {number} nin - index of the transaction input containing the scriptSig verified. |
@@ -27,3 +27,3 @@ 'use strict'; | ||
* @constructor | ||
* @param {Object|string|Buffer} [from] optional data to populate script | ||
* @param {Object|string|Buffer=} from optional data to populate script | ||
*/ | ||
@@ -544,3 +544,3 @@ var Script = function Script(from) { | ||
* @param {number} threshold - amount of required signatures to spend the output | ||
* @param {Object} [opts] - Several options: | ||
* @param {Object=} opts - Several options: | ||
* - noSorting: defaults to false, if true, don't sort the given | ||
@@ -717,3 +717,3 @@ * public keys before creating the script | ||
/** | ||
* @param {Network} [network] | ||
* @param {Network=} network | ||
* @return {Address} the associated address for this script | ||
@@ -720,0 +720,0 @@ */ |
@@ -27,6 +27,2 @@ 'use strict'; | ||
var CURRENT_VERSION = 1; | ||
var DEFAULT_NLOCKTIME = 0; | ||
var DEFAULT_SEQNUMBER = 0xFFFFFFFF; | ||
/** | ||
@@ -66,2 +62,12 @@ * Represents a transaction, a set of inputs and outputs to change ownership of tokens | ||
var CURRENT_VERSION = 1; | ||
var DEFAULT_NLOCKTIME = 0; | ||
var DEFAULT_SEQNUMBER = 0xFFFFFFFF; | ||
// Minimum amount for an output for it not to be considered a dust output | ||
Transaction.DUST_AMOUNT = 546; | ||
// Margin of error to allow fees in the vecinity of the expected value but doesn't allow a big difference | ||
Transaction.FEE_SECURITY_MARGIN = 15; | ||
// max amount of satoshis in circulation | ||
@@ -76,2 +82,9 @@ Transaction.MAX_MONEY = 21000000 * 1e8; | ||
// Value used for fee estimation (satoshis per kilobyte) | ||
Transaction.FEE_PER_KB = 10000; | ||
// Safe upper bound for change address script size in bytes | ||
Transaction.CHANGE_OUTPUT_MAX_SIZE = 20 + 4 + 34 + 4; | ||
Transaction.MAXIMUM_EXTRA_SIZE = 4 + 9 + 9 + 4; | ||
/* Constructors and Serialization */ | ||
@@ -114,10 +127,17 @@ | ||
* | ||
* @param {boolean=} unsafe if true, skip testing for fees that are too high | ||
* @param {Object|boolean=} unsafe if true, skip all tests. if it's an object, | ||
* it's expected to contain a set of flags to skip certain tests: | ||
* * `disableAll`: disable all checks | ||
* * `disableSmallFees`: disable checking for fees that are too small | ||
* * `disableLargeFees`: disable checking for fees that are too large | ||
* * `disableNotFullySigned`: disable checking if all inputs are fully signed | ||
* * `disableDustOutputs`: disable checking if there are no outputs that are dust amounts | ||
* * `disableMoreOutputThanInput`: disable checking if the transaction spends more bitcoins than the sum of the input amounts | ||
* @return {string} | ||
*/ | ||
Transaction.prototype.serialize = function(unsafe) { | ||
if (unsafe) { | ||
if (true === unsafe || unsafe && unsafe.disableAll) { | ||
return this.uncheckedSerialize(); | ||
} else { | ||
return this.checkedSerialize(); | ||
return this.checkedSerialize(unsafe); | ||
} | ||
@@ -130,26 +150,67 @@ }; | ||
Transaction.prototype.checkedSerialize = function() { | ||
var feeError = this._validateFees(); | ||
/** | ||
* Retrieve a hexa string that can be used with bitcoind's CLI interface | ||
* (decoderawtransaction, sendrawtransaction) | ||
* | ||
* @param {Object} opts allows to skip certain tests. {@see Transaction#serialize} | ||
* @return {string} | ||
*/ | ||
Transaction.prototype.checkedSerialize = function(opts) { | ||
var serializationError = this.getSerializationError(opts); | ||
if (serializationError) { | ||
serializationError.message += ' Use Transaction#uncheckedSerialize if you want to skip security checks. ' + | ||
'See http://bitcore.io/guide/transaction.html#Serialization for more info.' | ||
throw serializationError; | ||
} | ||
return this.uncheckedSerialize(); | ||
}; | ||
/** | ||
* Retrieve a possible error that could appear when trying to serialize and broadcast this transaction | ||
* | ||
* @param {Object} opts allows to skip certain tests. {@see Transaction#serialize} | ||
* @return {bitcore.Error} | ||
*/ | ||
Transaction.prototype.getSerializationError = function(opts) { | ||
opts = opts || {}; | ||
var missingChange = this._missingChange(); | ||
if (feeError && missingChange) { | ||
throw new errors.Transaction.ChangeAddressMissing(); | ||
var feeIsTooLarge = this._isFeeTooLarge(); | ||
var feeIsTooSmall = this._isFeeTooSmall(); | ||
var isFullySigned = this.isFullySigned(); | ||
var hasDustOutputs = this._hasDustOutputs(); | ||
if (!opts.disableLargeFees && feeIsTooLarge) { | ||
if (missingChange) { | ||
return new errors.Transaction.ChangeAddressMissing('Fee is too large and no change address was provided'); | ||
} | ||
return new errors.Transaction.FeeError(feeIsTooLarge); | ||
} | ||
if (feeError && !missingChange) { | ||
throw new errors.Transaction.FeeError(feeError); | ||
if (!opts.disableSmallFees && feeIsTooSmall) { | ||
return new errors.Transaction.FeeError(feeIsTooSmall); | ||
} | ||
if (this._hasDustOutputs()) { | ||
throw new errors.Transaction.DustOutputs(); | ||
if (!opts.disableDustOutputs && this._hasDustOutputs()) { | ||
return new errors.Transaction.DustOutputs(); | ||
} | ||
return this.uncheckedSerialize(); | ||
if (!opts.disableIsFullySigned && !isFullySigned) { | ||
return new errors.Transaction.MissingSignatures(); | ||
} | ||
if (!opts.disableMoreOutputThanInput && this._getUnspentValue < 0) { | ||
return new errors.Transaction.InvalidOutputAmountSum(); | ||
} | ||
}; | ||
Transaction.FEE_SECURITY_MARGIN = 15; | ||
Transaction.prototype._isFeeTooLarge = function() { | ||
var fee = this._getUnspentValue(); | ||
var maximumFee = Math.floor(Transaction.FEE_SECURITY_MARGIN * this._estimateFee()); | ||
if (fee > maximumFee) { | ||
return 'Fee is too large: expected less than ' + maximumFee + ' but got ' + fee; | ||
} | ||
}; | ||
Transaction.prototype._validateFees = function() { | ||
if (this._getUnspentValue() > Transaction.FEE_SECURITY_MARGIN * this._estimateFee()) { | ||
return 'Fee is more than ' + Transaction.FEE_SECURITY_MARGIN + ' times the suggested amount'; | ||
Transaction.prototype._isFeeTooSmall = function() { | ||
var fee = this._getUnspentValue(); | ||
var minimumFee = Math.ceil(this._estimateFee() / Transaction.FEE_SECURITY_MARGIN); | ||
if (fee < minimumFee) { | ||
return 'Fee is too small: expected more than ' + minimumFee + ' but got ' + fee; | ||
} | ||
if (this._getUnspentValue() < this._estimateFee() / Transaction.FEE_SECURITY_MARGIN) { | ||
return 'Fee is less than ' + Transaction.FEE_SECURITY_MARGIN + ' times the suggested amount'; | ||
} | ||
}; | ||
@@ -161,4 +222,2 @@ | ||
Transaction.DUST_AMOUNT = 5460; | ||
Transaction.prototype._hasDustOutputs = function() { | ||
@@ -673,6 +732,2 @@ var index, output; | ||
Transaction.FEE_PER_KB = 10000; | ||
// Safe upper bound for change address script | ||
Transaction.CHANGE_OUTPUT_MAX_SIZE = 20 + 4 + 34 + 4; | ||
Transaction._estimateFee = function(size, amountAvailable) { | ||
@@ -686,4 +741,2 @@ var fee = Math.ceil(size / Transaction.FEE_PER_KB); | ||
Transaction.MAXIMUM_EXTRA_SIZE = 4 + 9 + 9 + 4; | ||
Transaction.prototype._estimateSize = function() { | ||
@@ -690,0 +743,0 @@ var result = Transaction.MAXIMUM_EXTRA_SIZE; |
@@ -213,3 +213,3 @@ 'use strict'; | ||
* | ||
* @returns {String} the value in satoshis | ||
* @returns {string} the value in satoshis | ||
*/ | ||
@@ -239,3 +239,3 @@ Unit.prototype.toString = function() { | ||
* | ||
* @returns {String} the value in satoshis | ||
* @returns {string} the value in satoshis | ||
*/ | ||
@@ -242,0 +242,0 @@ Unit.prototype.inspect = function() { |
@@ -29,3 +29,3 @@ 'use strict'; | ||
* @param {string|Object} data - A bitcoin URI string or an Object | ||
* @param {Array.<string>} [knownParams] - Required non-standard params | ||
* @param {Array.<string>=} knownParams - Required non-standard params | ||
* @throws {TypeError} Invalid bitcoin address | ||
@@ -62,3 +62,3 @@ * @throws {TypeError} Invalid amount | ||
* | ||
* @param {String} str - JSON string or object of the URI | ||
* @param {string} str - JSON string or object of the URI | ||
* @returns {URI} A new instance of a URI | ||
@@ -97,3 +97,3 @@ */ | ||
* @param {string|Object} data - A bitcoin URI string or an Object | ||
* @param {Array.<string>} [knownParams] - Required non-standard params | ||
* @param {Array.<string>=} knownParams - Required non-standard params | ||
* @returns {boolean} Result of uri validation | ||
@@ -169,3 +169,3 @@ */ | ||
* | ||
* @param {String} amount - Amount BTC string | ||
* @param {string} amount - Amount BTC string | ||
* @throws {TypeError} Invalid amount | ||
@@ -201,3 +201,3 @@ * @returns {Object} Amount represented in satoshis | ||
* | ||
* @returns {String} Bitcoin URI string | ||
* @returns {string} Bitcoin URI string | ||
*/ | ||
@@ -230,3 +230,3 @@ URI.prototype.toString = function() { | ||
* | ||
* @returns {String} Bitcoin URI | ||
* @returns {string} Bitcoin URI | ||
*/ | ||
@@ -233,0 +233,0 @@ URI.prototype.inspect = function() { |
{ | ||
"name": "bitcore", | ||
"version": "0.10.4", | ||
"version": "0.11.0", | ||
"description": "A pure and powerful JavaScript Bitcoin library.", | ||
@@ -5,0 +5,0 @@ "author": "BitPay <dev@bitpay.com>", |
@@ -87,4 +87,12 @@ Bitcore | ||
This will generate files named `browser/bitcore.js` and `browser/bitcore.min.js`. | ||
This will generate files named `bitcore.js` and `bitcore.min.js`. | ||
You can also use our pre-generated files, provided for each release along with a PGP signature by one of the project's main contributors. To get them, checkout a release commit (for example, https://github.com/bitpay/bitcore/commit/2670cd1ac5ec1742aae0599e1583c063415959ff for v0.10.4). | ||
To verify signatures, use the following PGP keys: | ||
- @maraoz: https://pgp.mit.edu/pks/lookup?op=get&search=0x64F3727BFE0B3196 | ||
- @eordano: https://pgp.mit.edu/pks/lookup?op=get&search=0x00BD4BAF1DEEAC20 | ||
- @yemel: https://pgp.mit.edu/pks/lookup?op=get&search=0xB4A468A6F14B6843 | ||
- @braydonf: https://pgp.mit.edu/pks/lookup?op=get&search=0x9BBF07CAC07A276D | ||
## Tests | ||
@@ -98,20 +106,5 @@ | ||
Run the NodeJS tests with mocha: | ||
You can also run just the NodeJS tests with `gulp test:node`, just the browser tests with `gulp test:browser` | ||
or create a test coverage report (you can open `coverage/lcov-report/index.html` to visualize it) with `gulp coverage`. | ||
```sh | ||
gulp test:node | ||
``` | ||
Run the browser tests with karma: | ||
```sh | ||
gulp test:browser | ||
``` | ||
Create a test coverage report (you can open `coverage/lcov-report/index.html` to visualize it): | ||
```sh | ||
gulp coverage | ||
``` | ||
## License | ||
@@ -118,0 +111,0 @@ |
@@ -11,2 +11,3 @@ 'use strict'; | ||
var buffer = require('buffer'); | ||
var Networks = bitcore.Networks; | ||
var BufferUtil = bitcore.util.buffer; | ||
@@ -89,13 +90,21 @@ var HDPrivateKey = bitcore.HDPrivateKey; | ||
}); | ||
it('allows the use of a copy constructor', function() { | ||
HDPrivateKey(HDPrivateKey(xprivkey)) | ||
.xprivkey.should.equal(xprivkey); | ||
}); | ||
}); | ||
describe('public key', function() { | ||
var testnetKey = new HDPrivateKey('tprv8ZgxMBicQKsPdEeU2KiGFnUgRGriMnQxrwrg6FWCBg4jeiidHRyCCdA357kfkZiGaXEapWZsGDKikeeEbvgXo3UmEdbEKNdQH9VXESmGuUK'); | ||
var livenetKey = new HDPrivateKey('xprv9s21ZrQH143K3e39bnn1vyS7YFa1EAJAFGDoeHaSBsgBxgAkTEXeSx7xLvhNQNJxJwhzziWcK3znUFKRPRwWBPkKZ8ijUBa5YYpYPQmeBDX'); | ||
it('matches the network', function() { | ||
testnetKey.publicKey.network.should.equal(Networks.testnet); | ||
livenetKey.publicKey.network.should.equal(Networks.livenet); | ||
}); | ||
}); | ||
it('inspect() displays correctly', function() { | ||
HDPrivateKey(xprivkey).inspect().should.equal('<HDPrivateKey: ' + xprivkey + '>'); | ||
}); | ||
it('allows the use of a copy constructor', function() { | ||
HDPrivateKey(HDPrivateKey(xprivkey)) | ||
.xprivkey.should.equal(xprivkey); | ||
}); | ||
it('fails when trying to derive with an invalid argument', function() { | ||
@@ -102,0 +111,0 @@ expectDerivationFail([], hdErrors.InvalidDerivationArgument); |
@@ -16,5 +16,7 @@ 'use strict'; | ||
var Base58Check = bitcore.encoding.Base58Check; | ||
var Networks = bitcore.Networks; | ||
var xprivkey = 'xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi'; | ||
var xpubkey = 'xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8'; | ||
var xpubkeyTestnet = 'tpubD6NzVbkrYhZ4WZaiWHz59q5EQ61bd6dUYfU4ggRWAtNAyyYRNWT6ktJ7UHJEXURvTfTfskFQmK7Ff4FRkiRN5wQH8nkGAb6aKB4Yyeqsw5m'; | ||
var json = '{"network":"livenet","depth":0,"fingerPrint":876747070,"parentFingerPrint":0,"childIndex":0,"chainCode":"873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508","publicKey":"0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2","checksum":-1421395167,"xpubkey":"xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8"}'; | ||
@@ -35,3 +37,3 @@ var derived_0_1_200000 = 'xpub6BqyndF6rkBNTV6LXwiY8Pco8aqctqq7tGEUdA8fmGDTnDJphn2fmxr3eM8Lm3m8TrNUsLbEjHvpa3adBU18YpEx4tp2Zp6nqax3mQkudhX'; | ||
if (!error instanceof errorType) { | ||
console.log('Adsasd', typeof error); | ||
console.log('Error', typeof error); | ||
} | ||
@@ -152,2 +154,10 @@ // expect(got).to.equal(true); | ||
it('publicKey property matches network', function() { | ||
var livenet = new HDPublicKey(xpubkey); | ||
var testnet = new HDPublicKey(xpubkeyTestnet); | ||
livenet.publicKey.network.should.equal(Networks.livenet); | ||
testnet.publicKey.network.should.equal(Networks.testnet); | ||
}); | ||
it('inspect() displays correctly', function() { | ||
@@ -154,0 +164,0 @@ var pubKey = new HDPublicKey(xpubkey); |
@@ -228,2 +228,8 @@ 'use strict'; | ||
it('creates network specific address', function() { | ||
var pk = PrivateKey.fromWIF('cR4qogdN9UxLZJXCNFNwDRRZNeLRWuds9TTSuLNweFVjiaE4gPaq'); | ||
pk.toAddress(Networks.livenet).network.name.should.equal(Networks.livenet.name); | ||
pk.toAddress(Networks.testnet).network.name.should.equal(Networks.testnet.name); | ||
}); | ||
}); | ||
@@ -265,2 +271,6 @@ | ||
it('should recognize that undefined is an invalid private key', function() { | ||
PrivateKey.isValid().should.equal(false); | ||
}); | ||
it('should validate as true', function() { | ||
@@ -267,0 +277,0 @@ var a = PrivateKey.isValid('L3T1s1TYP9oyhHpXgkyLoJFGniEgkv2Jhi138d7R2yJ9F4QdDU2m'); |
@@ -62,3 +62,4 @@ 'use strict'; | ||
it('serialize to Object roundtrip', function() { | ||
new Transaction(testTransaction.toObject()).uncheckedSerialize().should.equal(testTransaction.serialize()); | ||
new Transaction(testTransaction.toObject()).uncheckedSerialize() | ||
.should.equal(testTransaction.uncheckedSerialize()); | ||
}); | ||
@@ -325,3 +326,3 @@ | ||
.from(simpleUtxoWith1BTC) | ||
.to(toAddress, 1) | ||
.to(toAddress, 545) | ||
.change(changeAddress) | ||
@@ -333,2 +334,12 @@ .sign(privateKey); | ||
}); | ||
it('doesn\'t fail if a dust output is not dust', function() { | ||
var transaction = new Transaction() | ||
.from(simpleUtxoWith1BTC) | ||
.to(toAddress, 546) | ||
.change(changeAddress) | ||
.sign(privateKey); | ||
expect(function() { | ||
return transaction.serialize(); | ||
}).to.not.throw(errors.Transaction.DustOutputs); | ||
}); | ||
it('doesn\'t fail if a dust output is an op_return', function() { | ||
@@ -344,2 +355,59 @@ var transaction = new Transaction() | ||
}); | ||
describe('skipping checks', function() { | ||
var buildSkipTest = function(builder, check) { | ||
return function() { | ||
var transaction = new Transaction(); | ||
transaction.from(simpleUtxoWith1BTC) | ||
builder(transaction); | ||
var options = {}; | ||
options[check] = true; | ||
expect(function() { | ||
return transaction.serialize(options); | ||
}).not.to.throw(); | ||
expect(function() { | ||
return transaction.serialize(); | ||
}).to.throw(); | ||
}; | ||
}; | ||
it('can skip the check for too much fee', function() { | ||
buildSkipTest(function(transaction) { | ||
return transaction | ||
.fee(50000000) | ||
.change(changeAddress) | ||
.sign(privateKey); | ||
}, 'disableLargeFees'); | ||
}); | ||
it('can skip the check for a fee that is too small', function() { | ||
buildSkipTest(function(transaction) { | ||
return transaction | ||
.fee(1) | ||
.change(changeAddress) | ||
.sign(privateKey); | ||
}, 'disableSmallFees'); | ||
}); | ||
it('can skip the check that prevents dust outputs', function() { | ||
buildSkipTest(function(transaction) { | ||
return transaction | ||
.to(toAddress, 1000) | ||
.change(changeAddress) | ||
.sign(privateKey); | ||
}, 'disableDustOutputs'); | ||
}); | ||
it('can skip the check that prevents unsigned outputs', function() { | ||
buildSkipTest(function(transaction) { | ||
return transaction | ||
.to(toAddress, 10000) | ||
.change(changeAddress); | ||
}, 'disableIsFullySigned'); | ||
}); | ||
it('can skip the check that avoids spending more bitcoins than the inputs for a transaction', function() { | ||
buildSkipTest(function(transaction) { | ||
return transaction | ||
.to(toAddress, 10000000000) | ||
.change(changeAddress); | ||
}, 'disableMoreOutputThanInput'); | ||
}); | ||
}); | ||
}); | ||
@@ -346,0 +414,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1267256
134
21312
113