Add from/to Fiat methods to Unit class
This commit is contained in:
parent
6e88efbe51
commit
e7839d9ba2
|
@ -40,6 +40,9 @@ module.exports = [{
|
||||||
errors: [{
|
errors: [{
|
||||||
'name': 'UnknownCode',
|
'name': 'UnknownCode',
|
||||||
'message': format('Unrecognized unit code: {0}')
|
'message': format('Unrecognized unit code: {0}')
|
||||||
|
},{
|
||||||
|
'name': 'InvalidRate',
|
||||||
|
'message': format('Invalid exchange rate: {0}')
|
||||||
}]
|
}]
|
||||||
}, {
|
}, {
|
||||||
name: 'Transaction',
|
name: 'Transaction',
|
||||||
|
|
54
lib/unit.js
54
lib/unit.js
|
@ -1,5 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
|
||||||
var errors = require('./errors');
|
var errors = require('./errors');
|
||||||
var JSUtil = require('./util/js');
|
var JSUtil = require('./util/js');
|
||||||
|
|
||||||
|
@ -15,19 +17,23 @@ var UNITS = {
|
||||||
* Utility for handling and converting bitcoins units. The supported units are
|
* Utility for handling and converting bitcoins units. The supported units are
|
||||||
* BTC, mBTC, bits (also named uBTC) and satoshis. A unit instance can be created with an
|
* BTC, mBTC, bits (also named uBTC) and satoshis. A unit instance can be created with an
|
||||||
* amount and a unit code, or alternatively using static methods like {fromBTC}.
|
* amount and a unit code, or alternatively using static methods like {fromBTC}.
|
||||||
|
* It also allows to be created from a fiat amount and the exchange rate, or
|
||||||
|
* alternatively using the {fromFiat} static method.
|
||||||
* You can consult for different representation of a unit instance using it's
|
* You can consult for different representation of a unit instance using it's
|
||||||
* {to} method, the fixed unit methods like {toSatoshis} or alternatively using
|
* {to} method, the fixed unit methods like {toSatoshis} or alternatively using
|
||||||
* the unit accessors.
|
* the unit accessors. It also can be converted to a fiat amount by providing the
|
||||||
|
* corresponding BTC/fiat exchange rate.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```javascript
|
* ```javascript
|
||||||
* var sats = Unit.fromBTC(1.3).toSatoshis();
|
* var sats = Unit.fromBTC(1.3).toSatoshis();
|
||||||
* var mili = Unit.fromBits(1.3).to(Unit.mBTC);
|
* var mili = Unit.fromBits(1.3).to(Unit.mBTC);
|
||||||
|
* var bits = Unit.fromFiat(1.3, 350).bits;
|
||||||
* var btc = new Unit(1.3, Unit.bits).BTC;
|
* var btc = new Unit(1.3, Unit.bits).BTC;
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param {Number} amount - The amount to be represented
|
* @param {Number} amount - The amount to be represented
|
||||||
* @param {String} code - The unit of the amount
|
* @param {String|Number} code - The unit of the amount or the exchange rate
|
||||||
* @returns {Unit} A new instance of an Unit
|
* @returns {Unit} A new instance of an Unit
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
|
@ -36,8 +42,14 @@ function Unit(amount, code) {
|
||||||
return new Unit(amount, code);
|
return new Unit(amount, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._amount = amount;
|
// convert fiat to BTC
|
||||||
this._code = code;
|
if (_.isNumber(code)) {
|
||||||
|
if (code <= 0) {
|
||||||
|
throw new errors.Unit.InvalidRate(code);
|
||||||
|
}
|
||||||
|
amount = amount / code;
|
||||||
|
code = Unit.BTC;
|
||||||
|
}
|
||||||
|
|
||||||
this._value = this._from(amount, code);
|
this._value = this._from(amount, code);
|
||||||
|
|
||||||
|
@ -109,6 +121,17 @@ Unit.fromSatoshis = function(amount) {
|
||||||
return new Unit(amount, Unit.satoshis);
|
return new Unit(amount, Unit.satoshis);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a Unit instance created from a fiat amount and exchange rate.
|
||||||
|
*
|
||||||
|
* @param {Number} amount - The amount in fiat
|
||||||
|
* @param {Number} rate - The exchange rate BTC/fiat
|
||||||
|
* @returns {Unit} A Unit instance
|
||||||
|
*/
|
||||||
|
Unit.fromFiat = function(amount, rate) {
|
||||||
|
return new Unit(amount, rate);
|
||||||
|
};
|
||||||
|
|
||||||
Unit.prototype._from = function(amount, code) {
|
Unit.prototype._from = function(amount, code) {
|
||||||
if (!UNITS[code]) {
|
if (!UNITS[code]) {
|
||||||
throw new errors.Unit.UnknownCode(code);
|
throw new errors.Unit.UnknownCode(code);
|
||||||
|
@ -119,10 +142,17 @@ Unit.prototype._from = function(amount, code) {
|
||||||
/**
|
/**
|
||||||
* Returns the value represented in the specified unit
|
* Returns the value represented in the specified unit
|
||||||
*
|
*
|
||||||
* @param {string} code - The unit code
|
* @param {String|Number} code - The unit code or exchange rate
|
||||||
* @returns {Number} The converted value
|
* @returns {Number} The converted value
|
||||||
*/
|
*/
|
||||||
Unit.prototype.to = function(code) {
|
Unit.prototype.to = function(code) {
|
||||||
|
if (_.isNumber(code)) {
|
||||||
|
if (code <= 0) {
|
||||||
|
throw new errors.Unit.InvalidRate(code);
|
||||||
|
}
|
||||||
|
return parseFloat((this.BTC * code).toFixed(2));
|
||||||
|
}
|
||||||
|
|
||||||
if (!UNITS[code]) {
|
if (!UNITS[code]) {
|
||||||
throw new errors.Unit.UnknownCode(code);
|
throw new errors.Unit.UnknownCode(code);
|
||||||
}
|
}
|
||||||
|
@ -167,6 +197,16 @@ Unit.prototype.toSatoshis = function() {
|
||||||
return this.to(Unit.satoshis);
|
return this.to(Unit.satoshis);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value represented in fiat
|
||||||
|
*
|
||||||
|
* @param {string} rate - The exchange rate between BTC/currency
|
||||||
|
* @returns {Number} The value converted to satoshis
|
||||||
|
*/
|
||||||
|
Unit.prototype.toFiat = function(rate) {
|
||||||
|
return this.to(rate);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a the string representation of the value in satoshis
|
* Returns a the string representation of the value in satoshis
|
||||||
*
|
*
|
||||||
|
@ -183,8 +223,8 @@ Unit.prototype.toString = function() {
|
||||||
*/
|
*/
|
||||||
Unit.prototype.toObject = function toObject() {
|
Unit.prototype.toObject = function toObject() {
|
||||||
return {
|
return {
|
||||||
amount: this._amount,
|
amount: this.BTC,
|
||||||
code: this._code
|
code: Unit.BTC
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
34
test/unit.js
34
test/unit.js
|
@ -15,10 +15,20 @@ describe('Unit', function() {
|
||||||
}).to.not.throw();
|
}).to.not.throw();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can be created from a number and exchange rate', function() {
|
||||||
|
expect(function() {
|
||||||
|
return new Unit(1.2, 350);
|
||||||
|
}).to.not.throw();
|
||||||
|
});
|
||||||
|
|
||||||
it('no "new" is required for creating an instance', function() {
|
it('no "new" is required for creating an instance', function() {
|
||||||
expect(function() {
|
expect(function() {
|
||||||
return Unit(1.2, 'BTC');
|
return Unit(1.2, 'BTC');
|
||||||
}).to.not.throw();
|
}).to.not.throw();
|
||||||
|
|
||||||
|
expect(function() {
|
||||||
|
return Unit(1.2, 350);
|
||||||
|
}).to.not.throw();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has property accesors "BTC", "mBTC", "uBTC", "bits", and "satoshis"', function() {
|
it('has property accesors "BTC", "mBTC", "uBTC", "bits", and "satoshis"', function() {
|
||||||
|
@ -44,6 +54,9 @@ describe('Unit', function() {
|
||||||
|
|
||||||
unit = Unit.fromSatoshis('8999');
|
unit = Unit.fromSatoshis('8999');
|
||||||
unit.satoshis.should.equal(8999);
|
unit.satoshis.should.equal(8999);
|
||||||
|
|
||||||
|
unit = Unit.fromFiat('43', 350);
|
||||||
|
unit.BTC.should.equal(0.12285714);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have constructor helpers', function() {
|
it('should have constructor helpers', function() {
|
||||||
|
@ -60,6 +73,9 @@ describe('Unit', function() {
|
||||||
|
|
||||||
unit = Unit.fromSatoshis(8999);
|
unit = Unit.fromSatoshis(8999);
|
||||||
unit.satoshis.should.equal(8999);
|
unit.satoshis.should.equal(8999);
|
||||||
|
|
||||||
|
unit = Unit.fromFiat(43, 350);
|
||||||
|
unit.BTC.should.equal(0.12285714);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('converts to satoshis correctly', function() {
|
it('converts to satoshis correctly', function() {
|
||||||
|
@ -124,6 +140,15 @@ describe('Unit', function() {
|
||||||
unit.toSatoshis().should.equal(unit.satoshis);
|
unit.toSatoshis().should.equal(unit.satoshis);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can convert to fiat', function() {
|
||||||
|
var unit = new Unit(1.3, 350);
|
||||||
|
unit.toFiat(350).should.equal(1.3);
|
||||||
|
unit.to(350).should.equal(1.3);
|
||||||
|
|
||||||
|
unit = Unit.fromBTC(0.0123);
|
||||||
|
unit.toFiat(10).should.equal(0.12);
|
||||||
|
});
|
||||||
|
|
||||||
it('toString works as expected', function() {
|
it('toString works as expected', function() {
|
||||||
var unit = new Unit(1.3, 'BTC');
|
var unit = new Unit(1.3, 'BTC');
|
||||||
should.exist(unit.toString);
|
should.exist(unit.toString);
|
||||||
|
@ -156,4 +181,13 @@ describe('Unit', function() {
|
||||||
}).to.throw(errors.Unit.UnknownCode);
|
}).to.throw(errors.Unit.UnknownCode);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('fails when the exchange rate is invalid', function() {
|
||||||
|
expect(function() {
|
||||||
|
return new Unit(100, -123);
|
||||||
|
}).to.throw(errors.Unit.InvalidRate);
|
||||||
|
expect(function() {
|
||||||
|
return new Unit(100, 'BTC').toFiat(-123);
|
||||||
|
}).to.throw(errors.Unit.InvalidRate);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue