improve utils: primarily toBTC and fromBTC.

This commit is contained in:
Christopher Jeffrey 2015-12-21 15:06:57 -08:00
parent 500f079632
commit a7ea69f48a
2 changed files with 115 additions and 36 deletions

View File

@ -141,6 +141,10 @@ utils.fromBase58 = function fromBase58(str) {
return z.concat(res.toArray());
};
utils.isBase58 = function isBase58(msg) {
return typeof msg === 'string' && /^[1-9a-zA-Z]+$/.test(msg);
};
utils.ripemd160 = function ripemd160(data, enc) {
return hash.ripemd160().update(data, enc).digest();
};
@ -372,6 +376,10 @@ function toHex(msg) {
utils.toHex = toHex;
utils.isHex = function isHex(msg) {
return typeof msg === 'string' && /^[0-9a-f]+$/i.test(msg);
};
function binaryInsert(list, item, compare, search) {
var start = 0;
var end = list.length;
@ -544,16 +552,16 @@ utils.toBTC = function toBTC(satoshi, strict) {
var m = new bn(10000000).mul(new bn(10));
var lo;
if (typeof satoshi === 'string' && /^\d+(?:\.\d+)?$/.test(satoshi)) {
satoshi = new bn(satoshi, 10);
} else if (typeof satoshi === 'number') {
// XXX Dangerous precision - do not use for any real txes
if (!strict)
satoshi = new bn(Math.floor(+satoshi || 0).toString(16), 16);
}
if (utils.isBTC(satoshi))
return utils.isBTC(satoshi);
if (!(satoshi instanceof bn))
throw new Error('could not calculate btc');
if (!strict && utils.isFinite(satoshi))
satoshi = new bn(Math.floor(satoshi) + '', 10);
satoshi = utils.isSatoshi(satoshi);
if (!satoshi)
throw new Error('Could not calculate BTC');
lo = satoshi.mod(m);
@ -563,36 +571,85 @@ utils.toBTC = function toBTC(satoshi, strict) {
lo = '0' + lo;
lo = '.' + lo;
} else {
lo = '';
lo = '.0';
}
return satoshi.div(m).toString(10) + lo.replace(/0+$/, '');
lo = lo.replace(/0+$/, '');
if (lo === '.')
lo += '0';
return satoshi.div(m).toString(10) + lo;
};
utils.fromBTC = function fromBTC(btc, strict) {
var m = new bn(10000000).mul(new bn(10));
var satoshi, parts;
var satoshi, parts, hi, lo;
if (typeof btc === 'string' && /^\d+(?:\.\d+)?$/.test(btc)) {
parts = btc.split('.');
parts[0] = parts[0] || '0';
parts[1] = parts[1] || '0';
while (parts[1].length < 8)
parts[1] += '0';
parts[0] = parts[0].replace(/^0+/, '');
satoshi = new bn(parts[0] + parts[1], 10);
} else if (typeof btc === 'number') {
// XXX Dangerous precision - do not use for any real txes
if (!strict)
satoshi = new bn(+btc || 0);
if (utils.isSatoshi(btc))
return utils.isSatoshi(btc);
if (!strict && utils.isFinite(btc)) {
btc = btc + '';
if (utils.isInt(btc))
btc += '.0';
}
if (!(satoshi instanceof bn))
throw new Error('could not calculate satoshis');
btc = utils.isBTC(btc);
satoshi.imuln(m);
if (!btc)
throw new Error('Could not calculate satoshis');
return satoshi;
parts = btc.split('.');
hi = parts[0] || '0';
lo = parts[1] || '0';
while (lo.length < 8)
lo += '0';
satoshi = (hi + lo).replace(/^0+/, '');
return new bn(satoshi, 10);
};
utils.isInt = function isInt(val) {
return typeof val === 'string' && /^\d+$/.test(val);
};
utils.isFloat = function isFloat(val) {
return typeof val === 'string' && /^\d+\.\d+$/.test(val);
};
utils.isFinite = function _isFinite(val) {
return typeof val === 'number' && isFinite(val);
};
utils.isSatoshi = function isSatoshi(val) {
if (val instanceof bn)
return val;
if (utils.isInt(val))
return new bn(val, 10);
if (utils.isHex(val))
return new bn(val, 'hex');
if (Array.isArray(val))
return new bn(val);
return false;
};
utils.isBTC = function isBTC(val) {
if (utils.isFloat(val))
return val;
// For user input strings. Might cause overlap
// with isSatoshi if not used carefully.
// if (utils.isInt(val))
// return val;
return false;
};
utils.toFloat = function toFloat(val) {
if (utils.isFloat(val))
return val;
if (utils.isInt(val))
return val + '.0';
throw new Error('Could not convert ' + val + ' to float');
};
utils.isIP = function isIP(ip) {
@ -608,18 +665,27 @@ utils.isIP = function isIP(ip) {
return 0;
};
utils.isHex = function isHex(msg) {
return typeof msg === 'string' && /^[0-9a-f]+$/i.test(msg);
utils.isArrayLike = function isArrayLike(msg) {
return msg
&& !Array.isArray(msg)
&& typeof msg === 'object'
&& typeof msg.length === 'number';
};
utils.toKeyArray = function toKeyArray(msg) {
if (typeof msg !== 'string')
if (Array.isArray(msg))
return msg;
if (utils.isArrayLike(msg))
return Array.prototype.slice.call(msg);
if (utils.isHex(msg))
return utils.toArray(msg, 'hex');
return utils.fromBase58(msg);
if (utils.isBase58(msg))
return utils.fromBase58(msg);
throw new Error('Cannot ensure array');
};
utils.inspect = function inspect(obj) {

View File

@ -23,9 +23,22 @@ describe('Utils', function() {
it('should convert satoshi to btc', function() {
var btc = bcoin.utils.toBTC(new bn(5460));
assert.equal(btc, '0.0000546');
var btc = bcoin.utils.toBTC(new bn(54678).mul(new bn(1000000)));
btc = bcoin.utils.toBTC(new bn(54678).mul(new bn(1000000)));
assert.equal(btc, '546.78');
var btc = bcoin.utils.toBTC(new bn(5460).mul(new bn(10000000)));
assert.equal(btc, '546');
btc = bcoin.utils.toBTC(new bn(5460).mul(new bn(10000000)));
assert.equal(btc, '546.0');
btc = bcoin.utils.toBTC(new bn(5460).mul(new bn(10000000)).toArray());
assert.equal(btc, '546.0');
btc = bcoin.utils.toBTC(new bn(5460).mul(new bn(10000000)).toString('hex'));
assert.equal(btc, '546.0');
});
it('should convert btc to satoshi', function() {
var btc = bcoin.utils.fromBTC('0.0000546');
assert(btc.cmp(new bn(5460)) === 0);
btc = bcoin.utils.fromBTC('546.78');
assert(btc.cmp(new bn(54678).mul(new bn(1000000))) === 0);
btc = bcoin.utils.fromBTC('546.0');
assert(btc.cmp(new bn(5460).mul(new bn(10000000))) === 0);
});
});