Merge pull request #627 from yemel/feature/unit-util
Utility for unit conversion
This commit is contained in:
commit
1175c475a2
|
@ -0,0 +1,59 @@
|
|||
# Unit
|
||||
|
||||
Unit it's a utility for handling and converting bitcoins units. We strongly
|
||||
recommend you to always use satoshis to represent amount inside your application
|
||||
and only convert them to other units in the front-end.
|
||||
|
||||
The supported units are BTC, mBTC, bits and satoshis. The codes for each unit
|
||||
can be found as members of the Unit class.
|
||||
|
||||
```javascript
|
||||
var btcCode = Unit.BTC;
|
||||
var mbtcCode = Unit.mBTC;
|
||||
var bitsCode = Unit.bits;
|
||||
var satsCode = Unit.satoshis;
|
||||
```
|
||||
|
||||
There are two ways for creating a unit instance. You can instanciate the class
|
||||
using a value and a unit code; alternatively if the unit it's fixed you could
|
||||
you some of the static methods. Check some examples below:
|
||||
|
||||
```javascript
|
||||
var unit;
|
||||
var amount = 100;
|
||||
|
||||
// using a unit code
|
||||
var unitPreference = Unit.BTC;
|
||||
unit = new Unit(amount, unitPreference);
|
||||
|
||||
// using a known unit
|
||||
unit = Unit.fromBTC(amount);
|
||||
unit = Unit.fromMilis(amount);
|
||||
unit = Unit.fromBits(amount);
|
||||
unit = Unit.fromSatoshis(amount);
|
||||
```
|
||||
|
||||
Once you have a unit instance, you can check it's representantion in all the
|
||||
available units. For your convinience the classes expose three ways to acomplish
|
||||
this. Using the `.to(unitCode)` method, using a fixed unit like `.toSatoshis()`
|
||||
or by using the accessors.
|
||||
|
||||
```javascript
|
||||
var unit;
|
||||
|
||||
// using a unit code
|
||||
var unitPreference = Unit.BTC;
|
||||
value = Unit.fromSatoshis(amount).to(unitPreference);
|
||||
|
||||
// using a known unit
|
||||
value = Unit.fromBTC(amount).toBTC();
|
||||
value = Unit.fromBTC(amount).toMilis();
|
||||
value = Unit.fromBTC(amount).toBits();
|
||||
value = Unit.fromBTC(amount).toSatoshis();
|
||||
|
||||
// using accessors
|
||||
value = Unit.fromBTC(amount).BTC;
|
||||
value = Unit.fromBTC(amount).mBTC;
|
||||
value = Unit.fromBTC(amount).bits;
|
||||
value = Unit.fromBTC(amount).satoshis;
|
||||
```
|
1
index.js
1
index.js
|
@ -41,6 +41,7 @@ bitcore.Script = require('./lib/script');
|
|||
bitcore.Transaction = require('./lib/transaction');
|
||||
bitcore.Txin = require('./lib/txin');
|
||||
bitcore.Txout = require('./lib/txout');
|
||||
bitcore.Unit = require('./lib/unit');
|
||||
|
||||
|
||||
// dependencies, subject to change
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
*
|
||||
* Bitcore Unit
|
||||
*
|
||||
* Utility for handling and converting bitcoins units. The supported units are
|
||||
* BTC, mBTC, bits and satoshis. A unit instance can be created with an
|
||||
* amount and a unit code, or alternatively using static methods like {fromBTC}.
|
||||
* You can consult for different representation of a unit instance using it's
|
||||
* {to} method, the fixed unit methods like {toSatoshis} or alternatively using
|
||||
* the unit accessors.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* var sats = Unit.fromBTC(1.3).toSatoshis();
|
||||
* var mili = Unit.fromBits(1.3).to(Unit.mBTC);
|
||||
* var btc = new Unit(1.3, Unit.bits).BTC;
|
||||
*
|
||||
* @param {Number} amount - The amount to be represented
|
||||
* @param {String} code - The unit of the amount
|
||||
* @returns {Unit} A new instance of an Unit
|
||||
*/
|
||||
|
||||
function Unit(amount, code) {
|
||||
if (!(this instanceof Unit)) {
|
||||
return new Unit(amount, code);
|
||||
}
|
||||
|
||||
this._value = this._from(amount, code);
|
||||
|
||||
var self = this;
|
||||
var defineAccesor = function(key) {
|
||||
Object.defineProperty(self, key, {
|
||||
get: function() { return self.to(key); },
|
||||
enumerable: true,
|
||||
});
|
||||
};
|
||||
|
||||
Object.keys(UNITS).forEach(defineAccesor);
|
||||
};
|
||||
|
||||
var UNITS = {
|
||||
'BTC' : [1e8, 8],
|
||||
'mBTC' : [1e5, 5],
|
||||
'bits' : [1e2, 2],
|
||||
'satoshis' : [1, 0]
|
||||
};
|
||||
|
||||
Object.keys(UNITS).forEach(function(key) {
|
||||
Unit[key] = key;
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return a Unit instance created from an amount in BTC
|
||||
*
|
||||
* @param {Number} amount - The amount in BTC
|
||||
* @returns {Unit} A Unit instance
|
||||
*/
|
||||
Unit.fromBTC = function(amount) {
|
||||
return new Unit(amount, Unit.BTC);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return a Unit instance created from an amount in mBTC
|
||||
*
|
||||
* @param {Number} amount - The amount in mBTC
|
||||
* @returns {Unit} A Unit instance
|
||||
*/
|
||||
Unit.fromMilis = function(amount) {
|
||||
return new Unit(amount, Unit.mBTC);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return a Unit instance created from an amount in bits
|
||||
*
|
||||
* @param {Number} amount - The amount in bits
|
||||
* @returns {Unit} A Unit instance
|
||||
*/
|
||||
Unit.fromBits = function(amount) {
|
||||
return new Unit(amount, Unit.bits);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return a Unit instance created from an amount in satoshis
|
||||
*
|
||||
* @param {Number} amount - The amount in satoshis
|
||||
* @returns {Unit} A Unit instance
|
||||
*/
|
||||
Unit.fromSatoshis = function(amount) {
|
||||
return new Unit(amount, Unit.satoshis);
|
||||
};
|
||||
|
||||
Unit.prototype._from = function(amount, code) {
|
||||
if (!UNITS[code]) throw Error('Unknown unit code');
|
||||
|
||||
return parseInt((amount * UNITS[code][0]).toFixed());
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return the value represented in the specified unit
|
||||
*
|
||||
* @param {string} code - The unit code
|
||||
* @returns {Number} The converted value
|
||||
*/
|
||||
Unit.prototype.to = function(code) {
|
||||
if (!UNITS[code]) throw Error('Unknown unit code');
|
||||
|
||||
var value = this._value / UNITS[code][0];
|
||||
return parseFloat(value.toFixed(UNITS[code][1]));
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return the value represented in BTC
|
||||
*
|
||||
* @returns {Number} The value converted to BTC
|
||||
*/
|
||||
Unit.prototype.toBTC = function() {
|
||||
return this.to(Unit.BTC);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return the value represented in mBTC
|
||||
*
|
||||
* @returns {Number} The value converted to mBTC
|
||||
*/
|
||||
Unit.prototype.toMilis = function(code) {
|
||||
return this.to(Unit.mBTC);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return the value represented in bits
|
||||
*
|
||||
* @returns {Number} The value converted to bits
|
||||
*/
|
||||
Unit.prototype.toBits = function(code) {
|
||||
return this.to(Unit.bits);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return the value represented in satoshis
|
||||
*
|
||||
* @returns {Number} The value converted to satoshis
|
||||
*/
|
||||
Unit.prototype.toSatoshis = function() {
|
||||
return this.to(Unit.satoshis);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return a the string representation of the value in satoshis
|
||||
*
|
||||
* @returns {String} the value in satoshis
|
||||
*/
|
||||
Unit.prototype.toString = function() {
|
||||
return this.satoshis + ' satoshis';
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* Will return a string formatted for the console
|
||||
*
|
||||
* @returns {String} the value in satoshis
|
||||
*/
|
||||
Unit.prototype.inspect = function() {
|
||||
return '<Unit: ' + this.toString() + '>';
|
||||
};
|
||||
|
||||
module.exports = Unit;
|
|
@ -0,0 +1,132 @@
|
|||
'use strict';
|
||||
|
||||
var should = require('chai').should();
|
||||
var bitcore = require('..');
|
||||
var Unit = bitcore.Unit;
|
||||
|
||||
describe('Unit', function() {
|
||||
|
||||
it('should create an instance', function() {
|
||||
var unit;
|
||||
|
||||
unit = new Unit(1.2, 'BTC');
|
||||
should.exist(unit);
|
||||
|
||||
unit = Unit(1.2, 'BTC');
|
||||
should.exist(unit);
|
||||
});
|
||||
|
||||
it('should have property accesors', function() {
|
||||
var unit = new Unit(1.2, 'BTC');
|
||||
should.exist(unit.BTC);
|
||||
should.exist(unit.mBTC);
|
||||
should.exist(unit.bits);
|
||||
should.exist(unit.satoshis);
|
||||
});
|
||||
|
||||
it('should allow amount as string', function() {
|
||||
var unit;
|
||||
|
||||
unit = Unit.fromBTC('1.00001');
|
||||
unit.BTC.should.equal(1.00001);
|
||||
|
||||
unit = Unit.fromMilis('1.00001');
|
||||
unit.mBTC.should.equal(1.00001);
|
||||
|
||||
unit = Unit.fromBits('100');
|
||||
unit.bits.should.equal(100);
|
||||
|
||||
unit = Unit.fromSatoshis('8999');
|
||||
unit.satoshis.should.equal(8999);
|
||||
});
|
||||
|
||||
it('should have constructor helpers', function() {
|
||||
var unit;
|
||||
|
||||
unit = Unit.fromBTC(1.00001);
|
||||
unit.BTC.should.equal(1.00001);
|
||||
|
||||
unit = Unit.fromMilis(1.00001);
|
||||
unit.mBTC.should.equal(1.00001);
|
||||
|
||||
unit = Unit.fromBits(100);
|
||||
unit.bits.should.equal(100);
|
||||
|
||||
unit = Unit.fromSatoshis(8999);
|
||||
unit.satoshis.should.equal(8999);
|
||||
});
|
||||
|
||||
it('should convert to satoshis correctly', function() {
|
||||
var unit;
|
||||
|
||||
unit = Unit.fromBTC(1.3);
|
||||
unit.mBTC.should.equal(1300);
|
||||
unit.bits.should.equal(1300000);
|
||||
unit.satoshis.should.equal(130000000);
|
||||
|
||||
unit = Unit.fromMilis(1.3);
|
||||
unit.BTC.should.equal(0.0013);
|
||||
unit.bits.should.equal(1300);
|
||||
unit.satoshis.should.equal(130000);
|
||||
|
||||
unit = Unit.fromBits(1.3);
|
||||
unit.BTC.should.equal(0.0000013);
|
||||
unit.mBTC.should.equal(0.0013);
|
||||
unit.satoshis.should.equal(130);
|
||||
|
||||
unit = Unit.fromSatoshis(3);
|
||||
unit.BTC.should.equal(0.00000003);
|
||||
unit.mBTC.should.equal(0.00003);
|
||||
unit.bits.should.equal(0.03);
|
||||
});
|
||||
|
||||
it('should take in count floating point problems', function() {
|
||||
var unit = Unit.fromBTC(0.00000003);
|
||||
unit.mBTC.should.equal(0.00003);
|
||||
unit.bits.should.equal(0.03);
|
||||
unit.satoshis.should.equal(3);
|
||||
});
|
||||
|
||||
it('should expose unit codes', function() {
|
||||
should.exist(Unit.BTC);
|
||||
Unit.BTC.should.equal('BTC');
|
||||
|
||||
should.exist(Unit.mBTC);
|
||||
Unit.mBTC.should.equal('mBTC');
|
||||
|
||||
should.exist(Unit.bits);
|
||||
Unit.bits.should.equal('bits');
|
||||
|
||||
should.exist(Unit.satoshis);
|
||||
Unit.satoshis.should.equal('satoshis');
|
||||
});
|
||||
|
||||
it('should expose shorthand conversion methods', function() {
|
||||
var unit = new Unit(1.3, 'BTC');
|
||||
unit.toBTC().should.equal(unit.BTC);
|
||||
unit.toMilis().should.equal(unit.mBTC);
|
||||
unit.toBits().should.equal(unit.bits);
|
||||
unit.toSatoshis().should.equal(unit.satoshis);
|
||||
});
|
||||
|
||||
it('should expose a general conversion method', function() {
|
||||
var unit = new Unit(1.3, 'BTC');
|
||||
unit.to(Unit.BTC).should.equal(unit.BTC);
|
||||
unit.to(Unit.mBTC).should.equal(unit.mBTC);
|
||||
unit.to(Unit.bits).should.equal(unit.bits);
|
||||
unit.to(Unit.satoshis).should.equal(unit.satoshis);
|
||||
});
|
||||
|
||||
it('should have a toString method', function() {
|
||||
var unit = new Unit(1.3, 'BTC');
|
||||
should.exist(unit.toString);
|
||||
unit.toString().should.be.a('string');
|
||||
});
|
||||
|
||||
it('should have an inspect method', function() {
|
||||
var unit = new Unit(1.3, 'BTC');
|
||||
should.exist(unit.inspect);
|
||||
unit.inspect().should.be.a('string');
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in New Issue