Changes behavior of `toJSON` to work as expected with `JSON.stringify`

- see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON%28%29_behavior
- Updates CONTRIBUTING with changes to Stardard Methods
- Aliases toJSON for toObject
- Removes all `fromJSON` methods, and many cases replaces with `fromObject`
- Constructors expect an object parsed via `JSON.parse` for JSON input
This commit is contained in:
Braydon Fuller 2015-08-12 17:37:28 -04:00
parent 79db9cc372
commit a50fccef4d
32 changed files with 166 additions and 424 deletions

View File

@ -85,16 +85,28 @@ var bufferUtil = require('./util/buffer');
#### G7 - Standard Methods #### G7 - Standard Methods
When possible, bitcore objects should have standard methods on an instance prototype: When possible, bitcore objects should have standard methods on an instance prototype:
* `toObject` - A plain JavaScript object that can be JSON stringified * `toObject/toJSON` - A plain JavaScript object that `JSON.stringify` can call
* `toJSON` - A JSON stringified object of the instance
* `toString` - A string representation of the instance * `toString` - A string representation of the instance
* `toBuffer` - A hex Buffer * `toBuffer` - A hex Buffer
These should have a matching static method that can be used for instantiation: These should have a matching static method that can be used for instantiation:
* `fromJSON` - Should handle both JSON from `toJSON` and plain JavaScript object from `toObject` * `fromObject` - Should be able to instatiate with the output from `toObject/toJSON`
* `fromString` - Should be able to instantiate with output from `toString` * `fromString` - Should be able to instantiate with output from `toString`
* `fromBuffer` - Should likewise be able to instantiate from output from `toBuffer` * `fromBuffer` - Should likewise be able to instantiate from output from `toBuffer`
`JSON.stringify` and `JSON.parse` are expected to be handled outside of the scope of Bitcore methods. For example, calling `JSON.stringify` on an Bitcore object will behave as expected and call `transaction.toJSON()` and then stringify it:
```javascript
var transactionString = JSON.stringify(transaction);
```
Likewise to instantiate a transaction from that string:
```javascript
var data = JSON.parse(transactionString);
var tx = new Transaction(data);
```
### Errors ### Errors
#### E1 - Use bitcore.Errors #### E1 - Use bitcore.Errors

View File

@ -381,21 +381,18 @@ Address.fromString = function(str, network, type) {
}; };
/** /**
* Instantiate an address from JSON * Instantiate an address from an Object
* *
* @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 * @returns {Address} A new valid instance of an Address
*/ */
Address.fromJSON = function fromJSON(json) { Address.fromObject = function fromObject(obj) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
$.checkState( $.checkState(
JSUtil.isHexa(json.hash), JSUtil.isHexa(obj.hash),
'Unexpected hash property, "' + json.hash + '", expected to be hex.' 'Unexpected hash property, "' + obj.hash + '", expected to be hex.'
); );
var hashBuffer = new Buffer(json.hash, 'hex'); var hashBuffer = new Buffer(obj.hash, 'hex');
return new Address(hashBuffer, json.network, json.type); return new Address(hashBuffer, obj.network, obj.type);
}; };
/** /**
@ -470,7 +467,7 @@ Address.prototype.toBuffer = function() {
/** /**
* @returns {Object} A plain object with the address information * @returns {Object} A plain object with the address information
*/ */
Address.prototype.toObject = function toObject() { Address.prototype.toObject = Address.prototype.toJSON = function toObject() {
return { return {
hash: this.hashBuffer.toString('hex'), hash: this.hashBuffer.toString('hex'),
type: this.type, type: this.type,
@ -478,13 +475,6 @@ Address.prototype.toObject = function toObject() {
}; };
}; };
/**
* @returns {string} A JSON representation of a plain object with the address information
*/
Address.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Will return a the string representation of the address * Will return a the string representation of the address
* *

View File

@ -7,7 +7,6 @@ var BufferUtil = require('../util/buffer');
var BufferReader = require('../encoding/bufferreader'); var BufferReader = require('../encoding/bufferreader');
var BufferWriter = require('../encoding/bufferwriter'); var BufferWriter = require('../encoding/bufferwriter');
var Hash = require('../crypto/hash'); var Hash = require('../crypto/hash');
var JSUtil = require('../util/js');
var Transaction = require('../transaction'); var Transaction = require('../transaction');
var $ = require('../util/preconditions'); var $ = require('../util/preconditions');
@ -40,8 +39,6 @@ Block._from = function _from(arg) {
var info = {}; var info = {};
if (BufferUtil.isBuffer(arg)) { if (BufferUtil.isBuffer(arg)) {
info = Block._fromBufferReader(BufferReader(arg)); info = Block._fromBufferReader(BufferReader(arg));
} else if (JSUtil.isValidJSON(arg)) {
info = Block._fromJSON(arg);
} else if (_.isObject(arg)) { } else if (_.isObject(arg)) {
info = Block._fromObject(arg); info = Block._fromObject(arg);
} else { } else {
@ -50,17 +47,6 @@ Block._from = function _from(arg) {
return info; return info;
}; };
/**
* @param {String} - A JSON string
* @returns {Object} - An object representing block data
* @private
*/
Block._fromJSON = function _fromJSON(data) {
$.checkArgument(JSUtil.isValidJSON(data), 'data must be valid JSON');
data = JSON.parse(data);
return Block._fromObject(data);
};
/** /**
* @param {Object} - A plain JavaScript object * @param {Object} - A plain JavaScript object
* @returns {Object} - An object representing block data * @returns {Object} - An object representing block data
@ -72,7 +58,7 @@ Block._fromObject = function _fromObject(data) {
if (tx instanceof Transaction) { if (tx instanceof Transaction) {
transactions.push(tx); transactions.push(tx);
} else { } else {
transactions.push(Transaction().fromJSON(tx)); transactions.push(Transaction().fromObject(tx));
} }
}); });
var info = { var info = {
@ -82,15 +68,6 @@ Block._fromObject = function _fromObject(data) {
return info; return info;
}; };
/**
* @param {String} - A JSON string
* @returns {Block} - An instance of block
*/
Block.fromJSON = function fromJSON(json) {
var info = Block._fromJSON(json);
return new Block(info);
};
/** /**
* @param {Object} - A plain JavaScript object * @param {Object} - A plain JavaScript object
* @returns {Block} - An instance of block * @returns {Block} - An instance of block
@ -161,7 +138,7 @@ Block.fromRawBlock = function fromRawBlock(data) {
/** /**
* @returns {Object} - A plain object with the block properties * @returns {Object} - A plain object with the block properties
*/ */
Block.prototype.toObject = function toObject() { Block.prototype.toObject = Block.prototype.toJSON = function toObject() {
var transactions = []; var transactions = [];
this.transactions.forEach(function(tx) { this.transactions.forEach(function(tx) {
transactions.push(tx.toObject()); transactions.push(tx.toObject());
@ -172,13 +149,6 @@ Block.prototype.toObject = function toObject() {
}; };
}; };
/**
* @returns {string} - A JSON string
*/
Block.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* @returns {Buffer} - A buffer of the block * @returns {Buffer} - A buffer of the block
*/ */

View File

@ -50,8 +50,6 @@ BlockHeader._from = function _from(arg) {
var info = {}; var info = {};
if (BufferUtil.isBuffer(arg)) { if (BufferUtil.isBuffer(arg)) {
info = BlockHeader._fromBufferReader(BufferReader(arg)); info = BlockHeader._fromBufferReader(BufferReader(arg));
} else if (JSUtil.isValidJSON(arg)) {
info = BlockHeader._fromJSON(arg);
} else if (_.isObject(arg)) { } else if (_.isObject(arg)) {
info = BlockHeader._fromObject(arg); info = BlockHeader._fromObject(arg);
} else { } else {
@ -60,17 +58,6 @@ BlockHeader._from = function _from(arg) {
return info; return info;
}; };
/**
* @param {String} - A JSON string
* @returns {Object} - An object representing block header data
* @private
*/
BlockHeader._fromJSON = function _fromJSON(data) {
$.checkArgument(JSUtil.isValidJSON(data), 'data must be a valid JSON string');
data = JSON.parse(data);
return BlockHeader._fromObject(data);
};
/** /**
* @param {Object} - A JSON string * @param {Object} - A JSON string
* @returns {Object} - An object representing block header data * @returns {Object} - An object representing block header data
@ -99,15 +86,6 @@ BlockHeader._fromObject = function _fromObject(data) {
return info; return info;
}; };
/**
* @param {String} - A JSON string or object
* @returns {BlockHeader} - An instance of block header
*/
BlockHeader.fromJSON = function fromJSON(json) {
var info = BlockHeader._fromJSON(json);
return new BlockHeader(info);
};
/** /**
* @param {Object} - A plain JavaScript object * @param {Object} - A plain JavaScript object
* @returns {BlockHeader} - An instance of block header * @returns {BlockHeader} - An instance of block header
@ -177,7 +155,7 @@ BlockHeader.fromBufferReader = function fromBufferReader(br) {
/** /**
* @returns {Object} - A plain object of the BlockHeader * @returns {Object} - A plain object of the BlockHeader
*/ */
BlockHeader.prototype.toObject = function toObject() { BlockHeader.prototype.toObject = BlockHeader.prototype.toJSON = function toObject() {
return { return {
hash: this.hash, hash: this.hash,
version: this.version, version: this.version,
@ -189,13 +167,6 @@ BlockHeader.prototype.toObject = function toObject() {
}; };
}; };
/**
* @returns {string} - A JSON string
*/
BlockHeader.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* @returns {Buffer} - A Buffer of the BlockHeader * @returns {Buffer} - A Buffer of the BlockHeader
*/ */

View File

@ -28,14 +28,12 @@ function MerkleBlock(arg) {
var info = {}; var info = {};
if (BufferUtil.isBuffer(arg)) { if (BufferUtil.isBuffer(arg)) {
info = MerkleBlock._fromBufferReader(BufferReader(arg)); info = MerkleBlock._fromBufferReader(BufferReader(arg));
} else if (JSUtil.isValidJSON(arg)) {
info = MerkleBlock._fromJSON(arg);
} else if (_.isObject(arg)) { } else if (_.isObject(arg)) {
var header; var header;
if(arg.header instanceof BlockHeader) { if(arg.header instanceof BlockHeader) {
header = arg.header; header = arg.header;
} else { } else {
header = BlockHeader.fromJSON(JSON.stringify(arg.header)); header = BlockHeader.fromObject(arg.header);
} }
info = { info = {
/** /**
@ -84,14 +82,6 @@ MerkleBlock.fromBufferReader = function fromBufferReader(br) {
return new MerkleBlock(MerkleBlock._fromBufferReader(br)); return new MerkleBlock(MerkleBlock._fromBufferReader(br));
}; };
/**
* @param {String|Object} - A JSON String or Object
* @returns {MerkleBlock} - A MerkleBlock object
*/
MerkleBlock.fromJSON = function fromJSON(buf) {
return new MerkleBlock(MerkleBlock._fromJSON(buf));
};
/** /**
* @returns {Buffer} - A buffer of the block * @returns {Buffer} - A buffer of the block
*/ */
@ -123,7 +113,7 @@ MerkleBlock.prototype.toBufferWriter = function toBufferWriter(bw) {
/** /**
* @returns {Object} - A plain object with the MerkleBlock properties * @returns {Object} - A plain object with the MerkleBlock properties
*/ */
MerkleBlock.prototype.toObject = function toObject() { MerkleBlock.prototype.toObject = MerkleBlock.prototype.toJSON = function toObject() {
return { return {
header: this.header.toObject(), header: this.header.toObject(),
numTransactions: this.numTransactions, numTransactions: this.numTransactions,
@ -132,13 +122,6 @@ MerkleBlock.prototype.toObject = function toObject() {
}; };
}; };
/**
* @returns {String} - A JSON string of a MerkleBlock
*/
MerkleBlock.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Verify that the MerkleBlock is valid * Verify that the MerkleBlock is valid
* @returns {Boolean} - True/False whether this MerkleBlock is Valid * @returns {Boolean} - True/False whether this MerkleBlock is Valid
@ -279,21 +262,11 @@ MerkleBlock._fromBufferReader = function _fromBufferReader(br) {
}; };
/** /**
* @param {String|Object} - A JSON or String Object * @param {Object} - A plain JavaScript object
* @returns {Object} - An Object representing merkleblock data * @returns {Block} - An instance of block
* @private
*/ */
MerkleBlock._fromJSON = function _fromJSON(data) { MerkleBlock.fromObject = function fromObject(obj) {
if (JSUtil.isValidJSON(data)) { return new MerkleBlock(obj);
data = JSON.parse(data);
}
var info = {
header: BlockHeader.fromObject(data.header),
numTransactions: data.numTransactions,
hashes: data.hashes,
flags: data.flags,
};
return info;
}; };
module.exports = MerkleBlock; module.exports = MerkleBlock;

View File

@ -278,11 +278,6 @@ HDPrivateKey._validateNetwork = function(data, networkArg) {
return null; return null;
}; };
HDPrivateKey.fromJSON = function(arg) {
$.checkArgument(JSUtil.isValidJSON(arg), 'No valid JSON string was provided');
return new HDPrivateKey(arg);
};
HDPrivateKey.fromString = function(arg) { HDPrivateKey.fromString = function(arg) {
$.checkArgument(_.isString(arg), 'No valid string was provided'); $.checkArgument(_.isString(arg), 'No valid string was provided');
return new HDPrivateKey(arg); return new HDPrivateKey(arg);
@ -510,7 +505,7 @@ HDPrivateKey.prototype.inspect = function() {
* </ul> * </ul>
* @return {Object} * @return {Object}
*/ */
HDPrivateKey.prototype.toObject = function toObject() { HDPrivateKey.prototype.toObject = HDPrivateKey.prototype.toJSON = function toObject() {
return { return {
network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version), 'xprivkey').name, network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version), 'xprivkey').name,
depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth), depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth),
@ -524,15 +519,6 @@ HDPrivateKey.prototype.toObject = function toObject() {
}; };
}; };
/**
* Returns a JSON representation of the HDPrivateKey
*
* @return {string}
*/
HDPrivateKey.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Build a HDPrivateKey from a buffer * Build a HDPrivateKey from a buffer
* *

View File

@ -43,8 +43,6 @@ function HDPublicKey(arg) {
var error = HDPublicKey.getSerializedError(arg); var error = HDPublicKey.getSerializedError(arg);
if (!error) { if (!error) {
return this._buildFromSerialized(arg); return this._buildFromSerialized(arg);
} else if (JSUtil.isValidJSON(arg)) {
return this._buildFromJSON(arg);
} else if (BufferUtil.isBuffer(arg) && !HDPublicKey.getSerializedError(arg.toString())) { } else if (BufferUtil.isBuffer(arg) && !HDPublicKey.getSerializedError(arg.toString())) {
return this._buildFromSerialized(arg.toString()); return this._buildFromSerialized(arg.toString());
} else { } else {
@ -232,10 +230,6 @@ HDPublicKey._validateNetwork = function (data, networkArg) {
return null; return null;
}; };
HDPublicKey.prototype._buildFromJSON = function (arg) {
return this._buildFromObject(JSON.parse(arg));
};
HDPublicKey.prototype._buildFromPrivate = function (arg) { HDPublicKey.prototype._buildFromPrivate = function (arg) {
var args = _.clone(arg._buffers); var args = _.clone(arg._buffers);
var point = Point.getG().mul(BN.fromBuffer(args.privateKey)); var point = Point.getG().mul(BN.fromBuffer(args.privateKey));
@ -359,8 +353,8 @@ HDPublicKey._validateBufferArguments = function (arg) {
} }
}; };
HDPublicKey.fromJSON = function(arg) { HDPublicKey.fromString = function(arg) {
$.checkArgument(JSUtil.isValidJSON(arg), 'No valid JSON string was provided'); $.checkArgument(_.isString(arg), 'No valid string was provided');
return new HDPublicKey(arg); return new HDPublicKey(arg);
}; };
@ -369,11 +363,6 @@ HDPublicKey.fromObject = function(arg) {
return new HDPublicKey(arg); return new HDPublicKey(arg);
}; };
HDPublicKey.fromString = function(arg) {
$.checkArgument(_.isString(arg), 'No valid string was provided');
return new HDPublicKey(arg);
};
/** /**
* Returns the base58 checked representation of the public key * Returns the base58 checked representation of the public key
* @return {string} a string starting with "xpub..." in livenet * @return {string} a string starting with "xpub..." in livenet
@ -407,7 +396,7 @@ HDPublicKey.prototype.inspect = function() {
* <li> checksum: the base58 checksum of xpubkey * <li> checksum: the base58 checksum of xpubkey
* </ul> * </ul>
*/ */
HDPublicKey.prototype.toObject = function toObject() { HDPublicKey.prototype.toObject = HDPublicKey.prototype.toJSON = function toObject() {
return { return {
network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version)).name, network: Network.get(BufferUtil.integerFromBuffer(this._buffers.version)).name,
depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth), depth: BufferUtil.integerFromSingleByteBuffer(this._buffers.depth),
@ -421,14 +410,6 @@ HDPublicKey.prototype.toObject = function toObject() {
}; };
}; };
/**
* Serializes this object into a JSON string
* @return {string}
*/
HDPublicKey.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Create a HDPublicKey from a buffer argument * Create a HDPublicKey from a buffer argument
* *

View File

@ -9,6 +9,7 @@ var Networks = require('./networks');
var Point = require('./crypto/point'); var Point = require('./crypto/point');
var PublicKey = require('./publickey'); var PublicKey = require('./publickey');
var Random = require('./crypto/random'); var Random = require('./crypto/random');
var $ = require('./util/preconditions');
/** /**
* Instantiate a PrivateKey from a BN, Buffer and WIF. * Instantiate a PrivateKey from a BN, Buffer and WIF.
@ -33,7 +34,7 @@ var Random = require('./crypto/random');
* @returns {PrivateKey} A new valid instance of an PrivateKey * @returns {PrivateKey} A new valid instance of an PrivateKey
* @constructor * @constructor
*/ */
var PrivateKey = function PrivateKey(data, network) { function PrivateKey(data, network) {
/* jshint maxstatements: 20 */ /* jshint maxstatements: 20 */
/* jshint maxcomplexity: 8 */ /* jshint maxcomplexity: 8 */
@ -95,8 +96,8 @@ PrivateKey.prototype._classifyArguments = function(data, network) {
info.bn = data; info.bn = data;
} else if (data instanceof Buffer || data instanceof Uint8Array) { } else if (data instanceof Buffer || data instanceof Uint8Array) {
info = PrivateKey._transformBuffer(data, network); info = PrivateKey._transformBuffer(data, network);
} else if (PrivateKey._isJSON(data)){ } else if (data.bn && data.network){
info = PrivateKey._transformJSON(data); info = PrivateKey._transformObject(data);
} else if (!network && Networks.get(data)) { } else if (!network && Networks.get(data)) {
info.bn = PrivateKey._getRandomBN(); info.bn = PrivateKey._getRandomBN();
info.network = Networks.get(data); info.network = Networks.get(data);
@ -129,17 +130,6 @@ PrivateKey._getRandomBN = function(){
return bn; return bn;
}; };
/**
* Internal function to detect if a param is a JSON string or plain object
*
* @param {*} param - value to test
* @returns {boolean}
* @private
*/
PrivateKey._isJSON = function(json) {
return JSUtil.isValidJSON(json) || (json.bn && json.network);
};
/** /**
* Internal function to transform a WIF Buffer into a private key * Internal function to transform a WIF Buffer into a private key
* *
@ -206,20 +196,6 @@ PrivateKey._transformWIF = function(str, network) {
return PrivateKey._transformBuffer(Base58Check.decode(str), network); return PrivateKey._transformBuffer(Base58Check.decode(str), network);
}; };
/**
* Instantiate a PrivateKey from a JSON string
*
* @param {string} json - The JSON encoded private key string
* @returns {PrivateKey} A new valid instance of PrivateKey
*/
PrivateKey.fromJSON = function(json) {
if (!PrivateKey._isJSON(json)) {
throw new TypeError('Must be a valid JSON string or plain object');
}
return new PrivateKey(json);
};
/** /**
* Instantiate a PrivateKey from a Buffer with the DER or WIF representation * Instantiate a PrivateKey from a Buffer with the DER or WIF representation
* *
@ -239,10 +215,7 @@ PrivateKey.fromBuffer = function(arg, network) {
* @returns {Object} An object with keys: bn, network and compressed * @returns {Object} An object with keys: bn, network and compressed
* @private * @private
*/ */
PrivateKey._transformJSON = function(json) { PrivateKey._transformObject = function(json) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
var bn = new BN(json.bn, 'hex'); var bn = new BN(json.bn, 'hex');
var network = Networks.get(json.network); var network = Networks.get(json.network);
return { return {
@ -259,9 +232,20 @@ PrivateKey._transformJSON = function(json) {
* @returns {PrivateKey} A new valid instance of PrivateKey * @returns {PrivateKey} A new valid instance of PrivateKey
*/ */
PrivateKey.fromString = PrivateKey.fromWIF = function(str) { PrivateKey.fromString = PrivateKey.fromWIF = function(str) {
$.checkArgument(_.isString(str), 'First argument is expected to be a string.');
return new PrivateKey(str); return new PrivateKey(str);
}; };
/**
* Instantiate a PrivateKey from a plain JavaScript object
*
* @param {Object} obj - The output from privateKey.toObject()
*/
PrivateKey.fromObject = function(obj) {
$.checkArgument(_.isObject(obj), 'First argument is expected to be an object.');
return new PrivateKey(obj);
};
/** /**
* Instantiate a PrivateKey from random bytes * Instantiate a PrivateKey from random bytes
* *
@ -382,7 +366,7 @@ PrivateKey.prototype.toAddress = function(network) {
/** /**
* @returns {Object} A plain object representation * @returns {Object} A plain object representation
*/ */
PrivateKey.prototype.toObject = function toObject() { PrivateKey.prototype.toObject = PrivateKey.prototype.toJSON = function toObject() {
return { return {
bn: this.bn.toString('hex'), bn: this.bn.toString('hex'),
compressed: this.compressed, compressed: this.compressed,
@ -390,10 +374,6 @@ PrivateKey.prototype.toObject = function toObject() {
}; };
}; };
PrivateKey.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Will return a string formatted for the console * Will return a string formatted for the console
* *

View File

@ -33,7 +33,7 @@ var $ = require('./util/preconditions');
* @returns {PublicKey} A new valid instance of an PublicKey * @returns {PublicKey} A new valid instance of an PublicKey
* @constructor * @constructor
*/ */
var PublicKey = function PublicKey(data, extra) { function PublicKey(data, extra) {
if (!(this instanceof PublicKey)) { if (!(this instanceof PublicKey)) {
return new PublicKey(data, extra); return new PublicKey(data, extra);
@ -75,8 +75,8 @@ PublicKey.prototype._classifyArgs = function(data, extra) {
// detect type of data // detect type of data
if (data instanceof Point) { if (data instanceof Point) {
info.point = data; info.point = data;
} else if (PublicKey._isJSON(data)) { } else if (data.x && data.y) {
info = PublicKey._transformJSON(data); info = PublicKey._transformObject(data);
} else if (typeof(data) === 'string') { } else if (typeof(data) === 'string') {
info = PublicKey._transformDER(new Buffer(data, 'hex')); info = PublicKey._transformDER(new Buffer(data, 'hex'));
} else if (PublicKey._isBuffer(data)) { } else if (PublicKey._isBuffer(data)) {
@ -115,17 +115,6 @@ PublicKey._isBuffer = function(param) {
return (param instanceof Buffer) || (param instanceof Uint8Array); return (param instanceof Buffer) || (param instanceof Uint8Array);
}; };
/**
* Internal function to detect if a param is a JSON string or plain object
*
* @param {*} json - value to test
* @returns {boolean}
* @private
*/
PublicKey._isJSON = function(json) {
return !!(JSUtil.isValidJSON(json) || (json.x && json.y));
};
/** /**
* Internal function to transform a private key into a public key point * Internal function to transform a private key into a public key point
* *
@ -204,17 +193,6 @@ PublicKey._transformX = function(odd, x) {
return info; return info;
}; };
/**
* Instantiate a PublicKey from JSON
*
* @param {string} json - A JSON string
* @returns {PublicKey} A new valid instance of PublicKey
*/
PublicKey.fromJSON = function(json) {
$.checkArgument(PublicKey._isJSON(json), 'Must be a valid JSON string or plain object');
return new PublicKey(json);
};
/** /**
* Internal function to transform a JSON into a public key point * Internal function to transform a JSON into a public key point
* *
@ -222,10 +200,7 @@ PublicKey.fromJSON = function(json) {
* @returns {Object} An object with keys: point and compressed * @returns {Object} An object with keys: point and compressed
* @private * @private
*/ */
PublicKey._transformJSON = function(json) { PublicKey._transformObject = function(json) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
var x = new BN(json.x, 'hex'); var x = new BN(json.x, 'hex');
var y = new BN(json.y, 'hex'); var y = new BN(json.y, 'hex');
var point = new Point(x, y); var point = new Point(x, y);
@ -336,7 +311,7 @@ PublicKey.isValid = function(data) {
/** /**
* @returns {Object} A plain object of the PublicKey * @returns {Object} A plain object of the PublicKey
*/ */
PublicKey.prototype.toObject = function toObject() { PublicKey.prototype.toObject = PublicKey.prototype.toJSON = function toObject() {
return { return {
x: this.point.getX().toString('hex', 2), x: this.point.getX().toString('hex', 2),
y: this.point.getY().toString('hex', 2), y: this.point.getY().toString('hex', 2),
@ -344,13 +319,6 @@ PublicKey.prototype.toObject = function toObject() {
}; };
}; };
/**
* @returns {string} A JSON string of the PublicKey
*/
PublicKey.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Will output the PublicKey to a DER Buffer * Will output the PublicKey to a DER Buffer
* *

View File

@ -40,6 +40,12 @@ Object.defineProperty(Input.prototype, 'script', {
} }
}); });
Input.fromObject = function(obj) {
$.checkArgument(_.isObject(obj));
var input = new Input();
return input._fromObject(obj);
};
Input.prototype._fromObject = function(params) { Input.prototype._fromObject = function(params) {
var prevTxId; var prevTxId;
if (_.isString(params.prevTxId) && JSUtil.isHexa(params.prevTxId)) { if (_.isString(params.prevTxId) && JSUtil.isHexa(params.prevTxId)) {
@ -60,7 +66,7 @@ Input.prototype._fromObject = function(params) {
return this; return this;
}; };
Input.prototype.toObject = function toObject() { Input.prototype.toObject = Input.prototype.toJSON = function toObject() {
var obj = { var obj = {
prevTxId: this.prevTxId.toString('hex'), prevTxId: this.prevTxId.toString('hex'),
outputIndex: this.outputIndex, outputIndex: this.outputIndex,
@ -77,21 +83,6 @@ Input.prototype.toObject = function toObject() {
return obj; return obj;
}; };
Input.fromObject = function(obj) {
$.checkArgument(_.isObject(obj));
var input = new Input();
return input._fromObject(obj);
};
Input.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
Input.fromJSON = function(json) {
$.checkArgument(JSUtil.isValidJSON(json), 'Invalid JSON provided to Input.fromJSON');
return Input.fromObject(JSON.parse(json));
};
Input.fromBufferReader = function(br) { Input.fromBufferReader = function(br) {
var input = new Input(); var input = new Input();
input.prevTxId = br.readReverse(32); input.prevTxId = br.readReverse(32);
@ -153,7 +144,7 @@ Input.prototype.setScript = function(script) {
Input.prototype.getSignatures = function() { Input.prototype.getSignatures = function() {
throw new errors.AbstractMethodInvoked( throw new errors.AbstractMethodInvoked(
'Trying to sign unsupported output type (only P2PKH and P2SH multisig inputs are supported)' + 'Trying to sign unsupported output type (only P2PKH and P2SH multisig inputs are supported)' +
' for input: ' + this.toJSON() ' for input: ' + JSON.stringify(this)
); );
}; };

View File

@ -29,8 +29,6 @@ function Output(args) {
} }
this.setScript(script); this.setScript(script);
} }
} else if (JSUtil.isValidJSON(args)) {
return Output.fromJSON(args);
} else { } else {
throw new TypeError('Unrecognized argument for Output'); throw new TypeError('Unrecognized argument for Output');
} }
@ -91,7 +89,7 @@ Output.prototype.invalidSatoshis = function() {
return false; return false;
}; };
Output.prototype.toObject = function toObject() { Output.prototype.toObject = Output.prototype.toJSON = function toObject() {
var obj = { var obj = {
satoshis: this.satoshis satoshis: this.satoshis
}; };
@ -99,17 +97,8 @@ Output.prototype.toObject = function toObject() {
return obj; return obj;
}; };
Output.prototype.toJSON = function toJSON() { Output.fromObject = function(data) {
return JSON.stringify(this.toObject()); return new Output(data);
};
Output.fromJSON = function(data) {
$.checkArgument(JSUtil.isValidJSON(data), 'data must be valid JSON');
var json = JSON.parse(data);
return new Output({
satoshis: Number(json.satoshis),
script: new Script(json.script)
});
}; };
Output.prototype.setScriptFromBuffer = function(buffer) { Output.prototype.setScriptFromBuffer = function(buffer) {

View File

@ -24,11 +24,6 @@ function TransactionSignature(arg) {
if (arg instanceof TransactionSignature) { if (arg instanceof TransactionSignature) {
return arg; return arg;
} }
if (_.isString(arg)) {
if (JSUtil.isValidJSON(arg)) {
return TransactionSignature.fromJSON(arg);
}
}
if (_.isObject(arg)) { if (_.isObject(arg)) {
return this._fromObject(arg); return this._fromObject(arg);
} }
@ -70,7 +65,7 @@ TransactionSignature.prototype._checkObjectArgs = function(arg) {
* Serializes a transaction to a plain JS object * Serializes a transaction to a plain JS object
* @return {Object} * @return {Object}
*/ */
TransactionSignature.prototype.toObject = function() { TransactionSignature.prototype.toObject = TransactionSignature.prototype.toJSON = function toObject() {
return { return {
publicKey: this.publicKey.toString(), publicKey: this.publicKey.toString(),
prevTxId: this.prevTxId.toString('hex'), prevTxId: this.prevTxId.toString('hex'),
@ -81,23 +76,6 @@ TransactionSignature.prototype.toObject = function() {
}; };
}; };
/**
* Serializes a transaction to a JSON string
* @return {string}
*/
TransactionSignature.prototype.toJSON = function() {
return JSON.stringify(this.toObject());
};
/**
* Builds a TransactionSignature from a JSON string
* @param {string} json
* @return {TransactionSignature}
*/
TransactionSignature.fromJSON = function(json) {
return new TransactionSignature(JSON.parse(json));
};
/** /**
* Builds a TransactionSignature from an object * Builds a TransactionSignature from an object
* @param {Object} object * @param {Object} object

View File

@ -44,8 +44,6 @@ function Transaction(serialized) {
return Transaction.shallowCopy(serialized); return Transaction.shallowCopy(serialized);
} else if (JSUtil.isHexa(serialized)) { } else if (JSUtil.isHexa(serialized)) {
this.fromString(serialized); this.fromString(serialized);
} else if (JSUtil.isValidJSON(serialized)) {
this.fromJSON(serialized);
} else if (BufferUtil.isBuffer(serialized)) { } else if (BufferUtil.isBuffer(serialized)) {
this.fromBuffer(serialized); this.fromBuffer(serialized);
} else if (_.isObject(serialized)) { } else if (_.isObject(serialized)) {
@ -315,14 +313,7 @@ Transaction.prototype.fromBufferReader = function(reader) {
return this; return this;
}; };
Transaction.prototype.fromJSON = function(json) { Transaction.prototype.toObject = Transaction.prototype.toJSON = function toObject() {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
return this.fromObject(json);
};
Transaction.prototype.toObject = function toObject() {
var inputs = []; var inputs = [];
this.inputs.forEach(function(input) { this.inputs.forEach(function(input) {
inputs.push(input.toObject()); inputs.push(input.toObject());
@ -350,8 +341,9 @@ Transaction.prototype.toObject = function toObject() {
return obj; return obj;
}; };
Transaction.prototype.fromObject = function(arg) { Transaction.prototype.fromObject = function fromObject(arg) {
/* jshint maxstatements: 20 */ /* jshint maxstatements: 20 */
$.checkArgument(_.isObject(arg) || arg instanceof Transaction);
var self = this; var self = this;
var transaction; var transaction;
if (arg instanceof Transaction) { if (arg instanceof Transaction) {
@ -462,10 +454,6 @@ Transaction.prototype.getLockTime = function() {
return new Date(1000 * this.nLockTime); return new Date(1000 * this.nLockTime);
}; };
Transaction.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
Transaction.prototype.fromString = function(string) { Transaction.prototype.fromString = function(string) {
this.fromBuffer(new buffer.Buffer(string, 'hex')); this.fromBuffer(new buffer.Buffer(string, 'hex'));
}; };

View File

@ -75,30 +75,19 @@ UnspentOutput.prototype.toString = function() {
}; };
/** /**
* Deserialize an UnspentOutput from an object or JSON string * Deserialize an UnspentOutput from an object
* @param {object|string} data * @param {object|string} data
* @return UnspentOutput * @return UnspentOutput
*/ */
UnspentOutput.fromJSON = UnspentOutput.fromObject = function(data) { UnspentOutput.fromObject = function(data) {
if (JSUtil.isValidJSON(data)) {
data = JSON.parse(data);
}
return new UnspentOutput(data); return new UnspentOutput(data);
}; };
/**
* Retrieve a string representation of this object
* @return {string}
*/
UnspentOutput.prototype.toJSON = function() {
return JSON.stringify(this.toObject());
};
/** /**
* Returns a plain object (no prototype or methods) with the associated infor for this output * Returns a plain object (no prototype or methods) with the associated infor for this output
* @return {object} * @return {object}
*/ */
UnspentOutput.prototype.toObject = function() { UnspentOutput.prototype.toObject = UnspentOutput.prototype.toJSON = function toObject() {
return { return {
address: this.address ? this.address.toString() : undefined, address: this.address ? this.address.toString() : undefined,
txid: this.txId, txid: this.txId,

View File

@ -3,7 +3,7 @@
var _ = require('lodash'); var _ = require('lodash');
var errors = require('./errors'); var errors = require('./errors');
var JSUtil = require('./util/js'); var $ = require('./util/preconditions');
var UNITS = { var UNITS = {
'BTC' : [1e8, 8], 'BTC' : [1e8, 8],
@ -74,11 +74,9 @@ Object.keys(UNITS).forEach(function(key) {
* @param {String|Object} json - JSON with keys: amount and code * @param {String|Object} json - JSON with keys: amount and code
* @returns {Unit} A Unit instance * @returns {Unit} A Unit instance
*/ */
Unit.fromJSON = function fromJSON(json){ Unit.fromObject = function fromObject(data){
if (JSUtil.isValidJSON(json)) { $.checkArgument(_.isObject(data), 'Argument is expected to be an object');
json = JSON.parse(json); return new Unit(data.amount, data.code);
}
return new Unit(json.amount, json.code);
}; };
/** /**
@ -221,17 +219,13 @@ Unit.prototype.toString = function() {
* *
* @returns {Object} An object with the keys: amount and code * @returns {Object} An object with the keys: amount and code
*/ */
Unit.prototype.toObject = function toObject() { Unit.prototype.toObject = Unit.prototype.toJSON = function toObject() {
return { return {
amount: this.BTC, amount: this.BTC,
code: Unit.BTC code: Unit.BTC
}; };
}; };
Unit.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Returns a string formatted for the console * Returns a string formatted for the console
* *

View File

@ -5,7 +5,6 @@ var URL = require('url');
var Address = require('./address'); var Address = require('./address');
var Unit = require('./unit'); var Unit = require('./unit');
var JSUtil = require('./util/js');
/** /**
* Bitcore URI * Bitcore URI
@ -69,15 +68,12 @@ URI.fromString = function fromString(str) {
}; };
/** /**
* Instantiate a URI from JSON * Instantiate a URI from an Object
* *
* @param {String|Object} json - JSON string or object of the URI * @param {Object} data - object of the URI
* @returns {URI} A new instance of a URI * @returns {URI} A new instance of a URI
*/ */
URI.fromJSON = function fromJSON(json) { URI.fromObject = function fromObject(json) {
if (JSUtil.isValidJSON(json)) {
json = JSON.parse(json);
}
return new URI(json); return new URI(json);
}; };
@ -175,7 +171,7 @@ URI.prototype._parseAmount = function(amount) {
return Unit.fromBTC(amount).toSatoshis(); return Unit.fromBTC(amount).toSatoshis();
}; };
URI.prototype.toObject = function toObject() { URI.prototype.toObject = URI.prototype.toJSON = function toObject() {
var json = {}; var json = {};
for (var i = 0; i < URI.Members.length; i++) { for (var i = 0; i < URI.Members.length; i++) {
var m = URI.Members[i]; var m = URI.Members[i];
@ -187,10 +183,6 @@ URI.prototype.toObject = function toObject() {
return json; return json;
}; };
URI.prototype.toJSON = function toJSON() {
return JSON.stringify(this.toObject());
};
/** /**
* Will return a the string representation of the URI * Will return a the string representation of the URI
* *

View File

@ -445,18 +445,18 @@ describe('Address', function() {
}); });
describe('#json', function() { describe('#object', function() {
it('roundtrip to-from-to', function() { it('roundtrip to-from-to', function() {
var json = new Address(str).toJSON(); var obj = new Address(str).toObject();
var address = Address.fromJSON(json); var address = Address.fromObject(obj);
address.toString().should.equal(str); address.toString().should.equal(str);
}); });
it('checks that the string parameter is valid JSON', function() { it('will fail with invalid state', function() {
expect(function() { expect(function() {
return Address.fromJSON('¹'); return Address.fromObject('¹');
}).to.throw(); }).to.throw(bitcore.errors.InvalidState);
}); });
}); });

View File

@ -25,7 +25,7 @@ describe('Block', function() {
var bh = BlockHeader.fromBuffer(new Buffer(data.blockheaderhex, 'hex')); var bh = BlockHeader.fromBuffer(new Buffer(data.blockheaderhex, 'hex'));
var txs = []; var txs = [];
JSON.parse(dataJson).transactions.forEach(function(tx) { JSON.parse(dataJson).transactions.forEach(function(tx) {
txs.push(new Transaction().fromJSON(tx)); txs.push(new Transaction().fromObject(tx));
}); });
var json = dataJson; var json = dataJson;
@ -86,14 +86,13 @@ describe('Block', function() {
describe('#fromJSON', function() { describe('#fromJSON', function() {
it('should set these known values', function() { it('should set these known values', function() {
var block = Block.fromJSON(json); var block = Block.fromObject(JSON.parse(json));
should.exist(block.header); should.exist(block.header);
should.exist(block.transactions); should.exist(block.transactions);
}); });
it('should set these known values', function() { it('should set these known values', function() {
var block = new Block(JSON.parse(json));
var block = Block(json);
should.exist(block.header); should.exist(block.header);
should.exist(block.transactions); should.exist(block.transactions);
}); });
@ -103,8 +102,8 @@ describe('Block', function() {
describe('#toJSON', function() { describe('#toJSON', function() {
it('should recover these known values', function() { it('should recover these known values', function() {
var block = Block.fromJSON(json); var block = Block.fromObject(JSON.parse(json));
var b = JSON.parse(block.toJSON()); var b = block.toJSON();
should.exist(b.header); should.exist(b.header);
should.exist(b.transactions); should.exist(b.transactions);
}); });

View File

@ -79,17 +79,17 @@ describe('BlockHeader', function() {
}); });
describe('#fromJSON', function() { describe('#fromObject', function() {
it('should set all the variables', function() { it('should set all the variables', function() {
var bh = BlockHeader.fromJSON(JSON.stringify({ var bh = BlockHeader.fromObject({
version: version, version: version,
prevHash: prevblockidbuf.toString('hex'), prevHash: prevblockidbuf.toString('hex'),
merkleRoot: merklerootbuf.toString('hex'), merkleRoot: merklerootbuf.toString('hex'),
time: time, time: time,
bits: bits, bits: bits,
nonce: nonce nonce: nonce
})); });
should.exist(bh.version); should.exist(bh.version);
should.exist(bh.prevHash); should.exist(bh.prevHash);
should.exist(bh.merkleRoot); should.exist(bh.merkleRoot);
@ -103,7 +103,7 @@ describe('BlockHeader', function() {
describe('#toJSON', function() { describe('#toJSON', function() {
it('should set all the variables', function() { it('should set all the variables', function() {
var json = JSON.parse(bh.toJSON()); var json = bh.toJSON();
should.exist(json.version); should.exist(json.version);
should.exist(json.prevHash); should.exist(json.prevHash);
should.exist(json.merkleRoot); should.exist(json.merkleRoot);
@ -127,7 +127,7 @@ describe('BlockHeader', function() {
nonce: nonce nonce: nonce
}); });
var json = new BlockHeader(jsonString); var json = new BlockHeader(JSON.parse(jsonString));
should.exist(json.version); should.exist(json.version);
should.exist(json.prevHash); should.exist(json.prevHash);
should.exist(json.merkleRoot); should.exist(json.merkleRoot);

View File

@ -29,8 +29,8 @@ describe('MerkleBlock', function() {
}); });
it('should make a new merkleblock from JSON', function() { it('should make a new merkleblock from JSON', function() {
var b = MerkleBlock(blockJSON); var b = MerkleBlock(JSON.parse(blockJSON));
b.toJSON().should.equal(blockJSON); JSON.stringify(b).should.equal(blockJSON);
}); });
it('should not make an empty block', function() { it('should not make an empty block', function() {
@ -40,10 +40,10 @@ describe('MerkleBlock', function() {
}); });
}); });
describe('#fromJSON', function() { describe('#fromObject', function() {
it('should set these known values', function() { it('should set these known values', function() {
var block = MerkleBlock.fromJSON(blockJSON); var block = MerkleBlock.fromObject(JSON.parse(blockJSON));
should.exist(block.header); should.exist(block.header);
should.exist(block.numTransactions); should.exist(block.numTransactions);
should.exist(block.hashes); should.exist(block.hashes);
@ -51,7 +51,7 @@ describe('MerkleBlock', function() {
}); });
it('should set these known values', function() { it('should set these known values', function() {
var block = MerkleBlock(blockJSON); var block = MerkleBlock(JSON.parse(blockJSON));
should.exist(block.header); should.exist(block.header);
should.exist(block.numTransactions); should.exist(block.numTransactions);
should.exist(block.hashes); should.exist(block.hashes);
@ -60,7 +60,7 @@ describe('MerkleBlock', function() {
it('accepts an object as argument', function() { it('accepts an object as argument', function() {
var block = MerkleBlock(blockbuf); var block = MerkleBlock(blockbuf);
MerkleBlock.fromJSON(block.toObject()).should.exist(); MerkleBlock.fromObject(block.toObject()).should.exist();
}); });
}); });
@ -68,8 +68,8 @@ describe('MerkleBlock', function() {
describe('#toJSON', function() { describe('#toJSON', function() {
it('should recover these known values', function() { it('should recover these known values', function() {
var block = MerkleBlock.fromJSON(blockJSON); var block = new MerkleBlock(JSON.parse(blockJSON));
var b = JSON.parse(block.toJSON()); var b = JSON.parse(JSON.stringify(block));
should.exist(block.header); should.exist(block.header);
should.exist(block.numTransactions); should.exist(block.numTransactions);
should.exist(block.hashes); should.exist(block.hashes);
@ -128,14 +128,14 @@ describe('MerkleBlock', function() {
describe('#validMerkleTree', function() { describe('#validMerkleTree', function() {
it('should validate good merkleblocks', function() { it('should validate good merkleblocks', function() {
data.JSON.forEach(function(json) { data.JSON.forEach(function(data) {
var b = MerkleBlock(JSON.stringify(json)); var b = MerkleBlock(data);
b.validMerkleTree().should.equal(true); b.validMerkleTree().should.equal(true);
}); });
}); });
it('should not validate merkleblocks with too many hashes', function() { it('should not validate merkleblocks with too many hashes', function() {
var b = MerkleBlock(JSON.stringify(data.JSON[0])); var b = MerkleBlock(data.JSON[0]);
// Add too many hashes // Add too many hashes
var i = 0; var i = 0;
while(i <= b.numTransactions) { while(i <= b.numTransactions) {
@ -145,7 +145,7 @@ describe('MerkleBlock', function() {
}); });
it('should not validate merkleblocks with too few bit flags', function() { it('should not validate merkleblocks with too few bit flags', function() {
var b = MerkleBlock(blockJSON); var b = MerkleBlock(JSON.parse(blockJSON));
b.flags.pop(); b.flags.pop();
b.validMerkleTree().should.equal(false); b.validMerkleTree().should.equal(false);
}); });
@ -155,18 +155,18 @@ describe('MerkleBlock', function() {
describe('#hasTransaction', function() { describe('#hasTransaction', function() {
it('should find transactions via hash string', function() { it('should find transactions via hash string', function() {
var json = data.JSON[0]; var jsonData = data.JSON[0];
var txId = new Buffer(json.hashes[1],'hex').toString('hex'); var txId = new Buffer(jsonData.hashes[1],'hex').toString('hex');
var b = MerkleBlock(JSON.stringify(json)); var b = MerkleBlock(jsonData);
b.hasTransaction(txId).should.equal(true); b.hasTransaction(txId).should.equal(true);
b.hasTransaction(txId + 'abcd').should.equal(false); b.hasTransaction(txId + 'abcd').should.equal(false);
}); });
it('should find transactions via Transaction object', function() { it('should find transactions via Transaction object', function() {
var json = data.JSON[0]; var jsonData = data.JSON[0];
var txBuf = new Buffer(data.TXHEX[0][0],'hex'); var txBuf = new Buffer(data.TXHEX[0][0],'hex');
var tx = new Transaction().fromBuffer(txBuf); var tx = new Transaction().fromBuffer(txBuf);
var b = MerkleBlock(JSON.stringify(json)); var b = MerkleBlock(jsonData);
b.hasTransaction(tx).should.equal(true); b.hasTransaction(tx).should.equal(true);
}); });
@ -174,12 +174,12 @@ describe('MerkleBlock', function() {
// Reuse another transaction already in data/ dir // Reuse another transaction already in data/ dir
var serialized = transactionVector[0][7]; var serialized = transactionVector[0][7];
var tx = new Transaction().fromBuffer(new Buffer(serialized, 'hex')); var tx = new Transaction().fromBuffer(new Buffer(serialized, 'hex'));
var b = MerkleBlock(JSON.stringify(data.JSON[0])); var b = MerkleBlock(data.JSON[0]);
b.hasTransaction(tx).should.equal(false); b.hasTransaction(tx).should.equal(false);
}); });
it('should not match with merkle nodes', function() { it('should not match with merkle nodes', function() {
var b = MerkleBlock(JSON.stringify(data.JSON[0])); var b = MerkleBlock(data.JSON[0]);
var hashData = [ var hashData = [
['3612262624047ee87660be1a707519a443b1c1ce3d248cbfc6c15870f6c5daa2', false], ['3612262624047ee87660be1a707519a443b1c1ce3d248cbfc6c15870f6c5daa2', false],

View File

@ -27,13 +27,12 @@ describe('HDKeys building with static methods', function() {
expect(clazz[staticMethod].bind(null, argument)).to.throw(message); expect(clazz[staticMethod].bind(null, argument)).to.throw(message);
}; };
it(clazz.name + ' fromJSON checks that a valid JSON is provided', function() { it(clazz.name + ' fromJSON checks that a valid JSON is provided', function() {
var errorMessage = 'No valid JSON string was provided'; var errorMessage = 'Invalid Argument: No valid argument was provided';
var method = 'fromJSON'; var method = 'fromObject';
expectStaticMethodFail(method, undefined, errorMessage); expectStaticMethodFail(method, undefined, errorMessage);
expectStaticMethodFail(method, null, errorMessage); expectStaticMethodFail(method, null, errorMessage);
expectStaticMethodFail(method, 'invalid JSON', errorMessage); expectStaticMethodFail(method, 'invalid JSON', errorMessage);
expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage); expectStaticMethodFail(method, '{\'singlequotes\': true}', errorMessage);
expectStaticMethodFail(method, {}, errorMessage);
}); });
it(clazz.name + ' fromString checks that a string is provided', function() { it(clazz.name + ' fromString checks that a string is provided', function() {
var errorMessage = 'No valid string was provided'; var errorMessage = 'No valid string was provided';

View File

@ -294,12 +294,12 @@ describe('HDPrivate key interface', function() {
expect(BufferUtil.isBuffer(value)).to.equal(false); expect(BufferUtil.isBuffer(value)).to.equal(false);
}); });
}); });
it('roundtrips toJSON', function() { it('roundtrips toObject', function() {
expect(HDPrivateKey.fromJSON(new HDPrivateKey(xprivkey).toJSON()).xprivkey).to.equal(xprivkey); expect(HDPrivateKey.fromObject(new HDPrivateKey(xprivkey).toObject()).xprivkey).to.equal(xprivkey);
}); });
it('roundtrips to JSON and to Object', function() { it('roundtrips to JSON and to Object', function() {
var privkey = new HDPrivateKey(xprivkey); var privkey = new HDPrivateKey(xprivkey);
expect(HDPrivateKey.fromJSON(privkey.toJSON()).xprivkey).to.equal(xprivkey); expect(HDPrivateKey.fromObject(privkey.toJSON()).xprivkey).to.equal(xprivkey);
}); });
it('recovers state from JSON', function() { it('recovers state from JSON', function() {
new HDPrivateKey(JSON.stringify(plainObject)).xprivkey.should.equal(xprivkey); new HDPrivateKey(JSON.stringify(plainObject)).xprivkey.should.equal(xprivkey);

View File

@ -103,12 +103,12 @@ describe('HDPublicKey interface', function() {
}); });
it('can be generated from a json', function() { it('can be generated from a json', function() {
expect(new HDPublicKey(json).xpubkey).to.equal(xpubkey); expect(new HDPublicKey(JSON.parse(json)).xpubkey).to.equal(xpubkey);
}); });
it('can generate a json that has a particular structure', function() { it('can generate a json that has a particular structure', function() {
assert(_.isEqual( assert(_.isEqual(
new HDPublicKey(json).toJSON(), new HDPublicKey(JSON.parse(json)).toJSON(),
new HDPublicKey(xpubkey).toJSON() new HDPublicKey(xpubkey).toJSON()
)); ));
}); });
@ -187,10 +187,7 @@ describe('HDPublicKey interface', function() {
}; };
it('roundtrips to JSON and to Object', function() { it('roundtrips to JSON and to Object', function() {
var pubkey = new HDPublicKey(xpubkey); var pubkey = new HDPublicKey(xpubkey);
expect(HDPublicKey.fromJSON(pubkey.toJSON()).xpubkey).to.equal(xpubkey); expect(HDPublicKey.fromObject(pubkey.toJSON()).xpubkey).to.equal(xpubkey);
});
it('recovers state from JSON', function() {
new HDPublicKey(JSON.stringify(plainObject)).xpubkey.should.equal(xpubkey);
}); });
it('recovers state from Object', function() { it('recovers state from Object', function() {
new HDPublicKey(plainObject).xpubkey.should.equal(xpubkey); new HDPublicKey(plainObject).xpubkey.should.equal(xpubkey);

View File

@ -198,7 +198,7 @@ describe('PrivateKey', function() {
}); });
describe('#json', function() { describe('#json/object', function() {
it('should input/output json', function() { it('should input/output json', function() {
var json = JSON.stringify({ var json = JSON.stringify({
@ -206,24 +206,21 @@ describe('PrivateKey', function() {
compressed: false, compressed: false,
network: 'livenet' network: 'livenet'
}); });
PrivateKey.fromJSON(json).toJSON().should.deep.equal(json); var key = PrivateKey.fromObject(JSON.parse(json));
JSON.stringify(key).should.equal(json);
}); });
it('input json should correctly initialize network field', function() { it('input json should correctly initialize network field', function() {
['livenet', 'testnet', 'mainnet'].forEach(function (net) { ['livenet', 'testnet', 'mainnet'].forEach(function (net) {
var pk = PrivateKey.fromJSON(JSON.stringify({ var pk = PrivateKey.fromObject({
bn: '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a', bn: '96c132224121b509b7d0a16245e957d9192609c5637c6228311287b1be21627a',
compressed: false, compressed: false,
network: net network: net
})); });
pk.network.should.be.deep.equal(Networks.get(net)); pk.network.should.be.deep.equal(Networks.get(net));
}); });
}); });
it('an object with private key info can be also used as argument for "fromJSON"', function() {
expect(PrivateKey._isJSON({bn: true, network: true})).to.equal(true);
});
it('fails on invalid argument', function() { it('fails on invalid argument', function() {
expect(function() { expect(function() {
return PrivateKey.fromJSON('¹'); return PrivateKey.fromJSON('¹');
@ -232,7 +229,7 @@ describe('PrivateKey', function() {
it('also accepts an object as argument', function() { it('also accepts an object as argument', function() {
expect(function() { expect(function() {
return PrivateKey.fromJSON(new PrivateKey().toObject()); return PrivateKey.fromObject(new PrivateKey().toObject());
}).to.not.throw(); }).to.not.throw();
}); });
}); });

View File

@ -169,7 +169,7 @@ describe('PublicKey', function() {
}); });
}); });
describe('#json', function() { describe('#json/object', function() {
it('should input/ouput json', function() { it('should input/ouput json', function() {
var json = JSON.stringify({ var json = JSON.stringify({
@ -177,15 +177,16 @@ describe('PublicKey', function() {
y: '7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341', y: '7baad41d04514751e6851f5304fd243751703bed21b914f6be218c0fa354a341',
compressed: false compressed: false
}); });
PublicKey.fromJSON(json).toJSON().should.deep.equal(json); var pubkey = new PublicKey(JSON.parse(json));
JSON.stringify(pubkey).should.deep.equal(json);
}); });
it('fails if "y" is not provided', function() { it('fails if "y" is not provided', function() {
expect(function() { expect(function() {
return PublicKey.fromJSON('{"x": "1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a"}'); return new PublicKey({
x: '1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'
});
}).to.throw(); }).to.throw();
// coverage
PublicKey._isJSON({x: '1ff0fe0f7b15ffaa85ff9f4744d539139c252a49710fb053bb9f2b933173ff9a'}).should.equal(false);
}); });
it('fails if invalid JSON is provided', function() { it('fails if invalid JSON is provided', function() {

View File

@ -76,14 +76,15 @@ describe('Transaction.Input', function() {
input.toString(); input.toString();
}).to.throw('Need a script to create an input'); }).to.throw('Need a script to create an input');
}); });
it('fromJSON should work', function() { it('fromObject should work', function() {
var input = Input.fromJSON(coinbaseJSON); var jsonData = JSON.parse(coinbaseJSON);
var otherInput = Input.fromJSON(otherJSON); var input = Input.fromObject(jsonData);
should.exist(input); should.exist(input);
should.exist(otherInput); input.prevTxId.toString('hex').should.equal(jsonData.prevTxId);
input.outputIndex.should.equal(jsonData.outputIndex);
}); });
it('fromObject should work', function() { it('fromObject should work', function() {
var input = Input.fromJSON(coinbaseJSON); var input = Input.fromObject(JSON.parse(coinbaseJSON));
var obj = input.toObject(); var obj = input.toObject();
Input.fromObject(obj).should.deep.equal(input); Input.fromObject(obj).should.deep.equal(input);
obj.script = 42; obj.script = 42;

View File

@ -94,8 +94,8 @@ describe('Output', function() {
expectEqualOutputs(output, deserialized); expectEqualOutputs(output, deserialized);
}); });
it('can instantiate from JSON', function() { it('can instantiate from an object', function() {
var out = new Output(JSON.stringify(output.toObject())); var out = new Output(output.toObject());
should.exist(out); should.exist(out);
}); });
@ -161,9 +161,9 @@ describe('Output', function() {
}); });
it('roundtrips to/from JSON', function() { it('roundtrips to/from JSON', function() {
var json = output2.toJSON(); var json = JSON.stringify(output2);
var o3 = new Output(json); var o3 = new Output(JSON.parse(json));
o3.toJSON().should.equal(json); JSON.stringify(o3).should.equal(json);
}); });
it('setScript fails with invalid input', function() { it('setScript fails with invalid input', function() {

View File

@ -111,13 +111,14 @@ describe('TransactionSignature', function() {
it('can roundtrip to/from json', function() { it('can roundtrip to/from json', function() {
var signature = getSignatureFromTransaction(); var signature = getSignatureFromTransaction();
var serialized = signature.toObject(); var serialized = signature.toObject();
var json = signature.toJSON(); var json = JSON.stringify(signature);
expect(TransactionSignature(json).toObject()).to.deep.equal(serialized); expect(TransactionSignature(JSON.parse(json)).toObject()).to.deep.equal(serialized);
expect(TransactionSignature.fromJSON(json).toObject()).to.deep.equal(serialized); expect(TransactionSignature.fromObject(JSON.parse(json)).toObject()).to.deep.equal(serialized);
}); });
it('can parse a previously known json string', function() { it('can parse a previously known json string', function() {
expect(JSON.parse(TransactionSignature(testJSON).toJSON())).to.deep.equal(JSON.parse(testJSON)); var str = JSON.stringify(TransactionSignature(JSON.parse(testJSON)));
expect(JSON.parse(str)).to.deep.equal(JSON.parse(testJSON));
}); });
it('can deserialize a previously known object', function() { it('can deserialize a previously known object', function() {

View File

@ -578,7 +578,7 @@ describe('Transaction', function() {
it('serializes the `change` information', function() { it('serializes the `change` information', function() {
var transaction = new Transaction(); var transaction = new Transaction();
transaction.change(changeAddress); transaction.change(changeAddress);
expect(JSON.parse(transaction.toJSON()).changeScript).to.equal(Script.fromAddress(changeAddress).toString()); expect(transaction.toJSON().changeScript).to.equal(Script.fromAddress(changeAddress).toString());
expect(new Transaction(transaction.toJSON()).uncheckedSerialize()).to.equal(transaction.uncheckedSerialize()); expect(new Transaction(transaction.toJSON()).uncheckedSerialize()).to.equal(transaction.uncheckedSerialize());
}); });
it('serializes correctly p2sh multisig signed tx', function() { it('serializes correctly p2sh multisig signed tx', function() {
@ -759,7 +759,7 @@ describe('Transaction', function() {
it('handles unsupported utxo in tx object', function() { it('handles unsupported utxo in tx object', function() {
var transaction = new Transaction(); var transaction = new Transaction();
transaction.fromJSON.bind(transaction, unsupportedTxObj) transaction.fromObject.bind(transaction, JSON.parse(unsupportedTxObj))
.should.throw('Unsupported input script type: OP_1 OP_ADD OP_2 OP_EQUAL'); .should.throw('Unsupported input script type: OP_1 OP_ADD OP_2 OP_EQUAL');
}); });

View File

@ -84,16 +84,11 @@ describe('UnspentOutput', function() {
it('to/from JSON roundtrip', function() { it('to/from JSON roundtrip', function() {
var utxo = new UnspentOutput(sampleData2); var utxo = new UnspentOutput(sampleData2);
expect( var obj = UnspentOutput.fromObject(utxo.toJSON()).toObject();
JSON.parse( expect(obj).to.deep.equal(sampleData2);
UnspentOutput.fromJSON( var str = JSON.stringify(UnspentOutput.fromObject(obj));
UnspentOutput.fromObject( expect(JSON.parse(str)).to.deep.equal(sampleData2);
UnspentOutput.fromJSON( var str2 = JSON.stringify(new UnspentOutput(JSON.parse(str)));
utxo.toJSON() expect(JSON.parse(str2)).to.deep.equal(sampleData2);
).toObject()
).toJSON()
).toJSON()
)
).to.deep.equal(sampleData2);
}); });
}); });

View File

@ -157,8 +157,8 @@ describe('Unit', function() {
it('can be imported and exported from/to JSON', function() { it('can be imported and exported from/to JSON', function() {
var json = JSON.stringify({amount:1.3, code:'BTC'}); var json = JSON.stringify({amount:1.3, code:'BTC'});
var unit = Unit.fromJSON(json); var unit = Unit.fromObject(JSON.parse(json));
unit.toJSON().should.deep.equal(json); JSON.stringify(unit).should.deep.equal(json);
}); });
it('importing from invalid JSON fails quickly', function() { it('importing from invalid JSON fails quickly', function() {

View File

@ -183,7 +183,7 @@ describe('URI', function() {
label: 'myLabel', label: 'myLabel',
other: 'xD' other: 'xD'
}); });
URI.fromJSON(json).toJSON().should.deep.equal(json); JSON.stringify(URI.fromObject(JSON.parse(json))).should.equal(json);
}); });
it('should support numeric amounts', function() { it('should support numeric amounts', function() {