Merge pull request #750 from eordano/test/publicWIF

Add `network` property to PublicKey
This commit is contained in:
Braydon Fuller 2014-12-15 18:02:03 -05:00
commit 6f37520a58
2 changed files with 42 additions and 22 deletions

View File

@ -1,9 +1,11 @@
'use strict'; 'use strict';
var _ = require('lodash');
var Address = require('./address'); var Address = require('./address');
var BN = require('./crypto/bn'); var BN = require('./crypto/bn');
var Point = require('./crypto/point'); var Point = require('./crypto/point');
var JSUtil = require('./util/js'); var JSUtil = require('./util/js');
var Network = require('./networks');
/** /**
* Instantiate a PublicKey from a 'PrivateKey', 'Point', 'string', 'Buffer'. * Instantiate a PublicKey from a 'PrivateKey', 'Point', 'string', 'Buffer'.
@ -20,15 +22,17 @@ var JSUtil = require('./util/js');
* var imported = PublicKey.fromString(exported); * var imported = PublicKey.fromString(exported);
* *
* @param {String} data - The encoded data in various formats * @param {String} data - The encoded data in various formats
* @param {Object} extra - additional options
* @param {Network=} extra.network - Which network should the address for this public key be for
* @param {String=} extra.compressed - If the public key is compressed
* @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) { var PublicKey = function PublicKey(data, extra) {
if (!(this instanceof PublicKey)) { if (!(this instanceof PublicKey)) {
return new PublicKey(data); return new PublicKey(data, extra);
} }
if (!data) { if (!data) {
throw new TypeError('First argument is required, please include public key data.'); throw new TypeError('First argument is required, please include public key data.');
} }
@ -36,9 +40,11 @@ var PublicKey = function PublicKey(data) {
// Return copy, but as it's an immutable object, return same argument // Return copy, but as it's an immutable object, return same argument
return data; return data;
} }
extra = extra || {};
var info = { var info = {
compressed: true compressed: _.isUndefined(extra.compressed) || extra.compressed,
network: _.isUndefined(extra.network) ? undefined : Network.get(extra.network)
}; };
// detect type of data // detect type of data
@ -69,9 +75,9 @@ var PublicKey = function PublicKey(data) {
value: info.compressed value: info.compressed
}); });
Object.defineProperty(this, 'address', { Object.defineProperty(this, 'network', {
configurable: false, configurable: false,
get: this.toAddress.bind(this) value: info.network
}); });
return this; return this;
@ -126,6 +132,7 @@ PublicKey._transformPrivateKey = function(privkey) {
} }
info.point = Point.getG().mul(privkey.bn); info.point = Point.getG().mul(privkey.bn);
info.compressed = privkey.compressed; info.compressed = privkey.compressed;
info.network = privkey.network;
return info; return info;
}; };
@ -217,11 +224,8 @@ PublicKey._transformJSON = function(json) {
} }
var x = BN(json.x, 'hex'); var x = BN(json.x, 'hex');
var y = BN(json.y, 'hex'); var y = BN(json.y, 'hex');
var point = new Point(x, y);
return { return new PublicKey(point, {compressed: json.compressed});
point: Point(x, y),
compressed: json.compressed
};
}; };
/** /**
@ -234,7 +238,8 @@ PublicKey.fromPrivateKey = function(privkey) {
if (!PublicKey._isPrivateKey(privkey)) { if (!PublicKey._isPrivateKey(privkey)) {
throw new TypeError('Must be an instance of PrivateKey'); throw new TypeError('Must be an instance of PrivateKey');
} }
return new PublicKey(privkey); var info = PublicKey._transformPrivateKey(privkey);
return new PublicKey(info.point, {compressed: info.compressed, network: info.network});
}; };
/** /**
@ -247,24 +252,26 @@ PublicKey.fromDER = PublicKey.fromBuffer = function(buf) {
if (!PublicKey._isBuffer(buf)) { if (!PublicKey._isBuffer(buf)) {
throw new TypeError('Must be a hex buffer of DER encoded public key'); throw new TypeError('Must be a hex buffer of DER encoded public key');
} }
return new PublicKey(buf); var info = PublicKey._transformDER(buf);
return new PublicKey(info.point, {compressed: info.compressed});
}; };
/** /**
* Instantiate a PublicKey from a Point * Instantiate a PublicKey from a Point
* *
* @param {Point} point - A Point instance * @param {Point} point - A Point instance
* @param {boolean=true} compressed - whether to store this public key as compressed format
* @returns {PublicKey} A new valid instance of PublicKey * @returns {PublicKey} A new valid instance of PublicKey
*/ */
PublicKey.fromPoint = function(point){ PublicKey.fromPoint = function(point, compressed){
if (!(point instanceof Point)) { if (!(point instanceof Point)) {
throw new TypeError('First argument must be an instance of Point.'); throw new TypeError('First argument must be an instance of Point.');
} }
return new PublicKey(point); return new PublicKey(point, {compressed: compressed});
}; };
/** /**
* Instantiate a PublicKey from a DER Buffer * Instantiate a PublicKey from a DER hex encoded string
* *
* @param {String} str - A DER hex string * @param {String} str - A DER hex string
* @param {String} [encoding] - The type of string encoding * @param {String} [encoding] - The type of string encoding
@ -272,7 +279,8 @@ PublicKey.fromPoint = function(point){
*/ */
PublicKey.fromString = function(str, encoding) { PublicKey.fromString = function(str, encoding) {
var buf = new Buffer(str, encoding || 'hex'); var buf = new Buffer(str, encoding || 'hex');
return new PublicKey(buf); var info = PublicKey._transformDER(buf);
return new PublicKey(info.point, {compressed: info.compressed});
}; };
/** /**
@ -284,7 +292,7 @@ PublicKey.fromString = function(str, encoding) {
*/ */
PublicKey.fromX = function(odd, x) { PublicKey.fromX = function(odd, x) {
var info = PublicKey._transformX(odd, x); var info = PublicKey._transformX(odd, x);
return new PublicKey(info.point); return new PublicKey(info.point, {compressed: info.compressed});
}; };
/** /**
@ -363,7 +371,7 @@ PublicKey.prototype.toBuffer = PublicKey.prototype.toDER = function() {
* @returns {Address} An address generated from the public key * @returns {Address} An address generated from the public key
*/ */
PublicKey.prototype.toAddress = function(network) { PublicKey.prototype.toAddress = function(network) {
return Address.fromPublicKey(this, network); return Address.fromPublicKey(this, network || this.network);
}; };
/** /**
@ -372,7 +380,8 @@ PublicKey.prototype.toAddress = function(network) {
* @returns {String} A DER hex encoded string * @returns {String} A DER hex encoded string
*/ */
PublicKey.prototype.toString = function() { PublicKey.prototype.toString = function() {
return this.toDER().toString('hex'); var compressed = _.isUndefined(this.compressed) || this.compressed;
return this.toDER(compressed).toString('hex');
}; };
/** /**
@ -381,8 +390,9 @@ PublicKey.prototype.toString = function() {
* @returns {String} Public key * @returns {String} Public key
*/ */
PublicKey.prototype.inspect = function() { PublicKey.prototype.inspect = function() {
var uncompressed = !this.compressed ? ', uncompressed' : ''; return '<PublicKey: ' + this.toString() +
return '<PublicKey: ' + this.toString() + uncompressed + '>'; (this.compressed ? '' : ', uncompressed') +
(this.network ? this.network.name : '') + '>';
}; };
module.exports = PublicKey; module.exports = PublicKey;

View File

@ -303,4 +303,14 @@ describe('PrivateKey', function() {
}); });
it('creates an address as expected from WIF, livenet', function() {
var privkey = new PrivateKey('5J2NYGstJg7aJQEqNwYp4enG5BSfFdKXVTtBLvHicnRGD5kjxi6')
privkey.publicKey.toAddress().toString().should.equal('135bwugFCmhmNU3SeCsJeTqvo5ViymgwZ9');
});
it('creates an address as expected from WIF, testnet', function() {
var privkey = new PrivateKey('92VYMmwFLXRwXn5688edGxYYgMFsc3fUXYhGp17WocQhU6zG1kd')
privkey.publicKey.toAddress().toString().should.equal('moiAvLUw16qgrwhFGo1eDnXHC2wPMYiv7Y');
});
}); });