diff --git a/src/core/IOUValue.js b/src/core/IOUValue.js index 3ae3e242..f8c61ead 100644 --- a/src/core/IOUValue.js +++ b/src/core/IOUValue.js @@ -3,6 +3,7 @@ 'use strict'; const Value = require('./value').Value; +const XRPValue = require('./XRPValue').XRPValue; const GlobalBigNumber = require('bignumber.js'); const BigNumber = GlobalBigNumber.another({ ROUNDING_MODE: GlobalBigNumber.ROUND_HALF_UP, @@ -11,33 +12,44 @@ const BigNumber = GlobalBigNumber.another({ class IOUValue extends Value { - constructor(value: string | BigNumber) { - super(value); + constructor(value: string | BigNumber, roundingMode: ?number = null, + base: ?number = null) { + + super(new BigNumber(value, base).toDigits(16, roundingMode)); } - multiplyByXRP(multiplicand: {_value: BigNumber, _bi_xns_unit: number}) { - const constant = new BigNumber((multiplicand._bi_xns_unit).toString()); - const value = new BigNumber(multiplicand._value); - multiplicand._value = (value).times(constant); + multiply(multiplicand: Value) { + if (multiplicand instanceof XRPValue) { + return super.multiply( + new IOUValue( + multiplicand._value.times(multiplicand.rippleUnits))); + } return super.multiply(multiplicand); } - divideByXRP(divisor: {_value: BigNumber, _bi_xns_unit: number}) { - const constant = new BigNumber((divisor._bi_xns_unit).toString()); - const value = new BigNumber(divisor._value); - divisor._value = (value).times(constant); + divide(divisor: Value) { + if (divisor instanceof XRPValue) { + return super.divide( + new IOUValue(divisor._value.times(divisor.rippleUnits))); + } return super.divide(divisor); } + negate() { + return new IOUValue(this._value.neg()); + } + _canonicalize(value) { + if (value.isNaN()) { + throw new Error('Invalid result'); + } return new IOUValue(value.toPrecision(16)); } equals(comparator) { return (comparator instanceof IOUValue) - && this._value.equals(comparator.value); + && this._value.equals(comparator._value); } - } exports.IOUValue = IOUValue; diff --git a/src/core/XRPValue.js b/src/core/XRPValue.js index f68ec198..286fce39 100644 --- a/src/core/XRPValue.js +++ b/src/core/XRPValue.js @@ -1,3 +1,5 @@ +/* @flow */ + 'use strict'; const GlobalBigNumber = require('bignumber.js'); @@ -10,20 +12,48 @@ const Value = require('./value').Value; class XRPValue extends Value { - constructor(value, bi_xns_unit) { + constructor(value: string | BigNumber) { super(value); - this._bi_xns_unit = bi_xns_unit; + this.rippleUnits = new BigNumber(1e6); + if (this._value.dp() > 6) { + throw new Error( + 'Value has more than 6 digits of precision past the decimal point, ' + + 'an IOUValue may be being cast to an XRPValue' + ); + } + } + + multiply(multiplicand: Value) { + if (multiplicand instanceof XRPValue) { + return super.multiply( + new XRPValue(multiplicand._value.times(multiplicand.rippleUnits))); + } + return super.multiply(multiplicand); + } + + divide(divisor: Value) { + if (divisor instanceof XRPValue) { + return super.divide( + new XRPValue(divisor._value.times(divisor.rippleUnits))); + } + return super.divide(divisor); + } + + negate() { + return new XRPValue(this._value.neg()); } _canonicalize(value) { + if (value.isNaN()) { + throw new Error('Invalid result'); + } return new XRPValue(value.round(6, BigNumber.ROUND_DOWN)); } equals(comparator) { return (comparator instanceof XRPValue) - && this._value.equals(comparator.value); + && this._value.equals(comparator._value); } - } exports.XRPValue = XRPValue; diff --git a/src/core/amount.js b/src/core/amount.js index 5797feb2..6caec5ce 100644 --- a/src/core/amount.js +++ b/src/core/amount.js @@ -13,17 +13,13 @@ const Value = require('./value').Value; const IOUValue = require('./IOUValue').IOUValue; const XRPValue = require('./XRPValue').XRPValue; - -function inverse(number) { - return new IOUValue(number).invert()._value; -} - -function Amount() { +function Amount(value = new XRPValue(NaN)) { // Json format: // integer : XRP // { 'value' : ..., 'currency' : ..., 'issuer' : ...} + assert(value instanceof Value); - this._value = new Value(NaN)._value; + this._value = value; this._is_native = true; // Default to XRP. Only valid if value is not NaN. this._currency = new Currency(); this._issuer = new UInt160(); @@ -41,19 +37,11 @@ const consts = { xns_precision: 6, // bi_ prefix refers to "big integer" - // TODO: we shouldn't expose our BigNumber library publicly - bi_5: new Value(5)._value, - bi_7: new Value(7)._value, - bi_10: new Value(10)._value, - bi_1e14: new Value(1e14)._value, - bi_1e16: new Value(1e16)._value, - bi_1e17: new Value(1e17)._value, - bi_1e32: new Value(1e32)._value, - bi_man_max_value: new Value('9999999999999999')._value, - bi_man_min_value: new Value(1e15)._value, - bi_xns_max: new Value(1e17)._value, - bi_xns_min: new Value(-1e17)._value, - bi_xns_unit: new Value(1e6)._value, + // man refers to mantissa + bi_man_max_value: '9999999999999999', + bi_man_min_value: Number(1e15).toString(), + bi_xns_max: Number(1e17).toString(), + bi_xns_min: Number(-1e17).toString(), cMinOffset: -96, cMaxOffset: 80, @@ -65,9 +53,11 @@ const consts = { min_value: '-1000000000000000e-96' }; -const MAX_XRP_VALUE = new Value(1e11)._value; -const MAX_IOU_VALUE = new Value(consts.max_value)._value; -const MIN_IOU_VALUE = new Value(consts.min_value)._value.abs(); +const MAX_XRP_VALUE = new XRPValue(1e11); +const MAX_IOU_VALUE = new IOUValue(consts.max_value); +const MIN_IOU_VALUE = new IOUValue(consts.min_value).abs(); + +const bi_xns_unit = new IOUValue(1e6); // Add constants to Amount class extend(Amount, consts); @@ -111,21 +101,15 @@ Amount.is_valid_full = function(j) { Amount.NaN = function() { const result = new Amount(); - result._value = new Value(NaN)._value; // should have no effect + result._value = new IOUValue(NaN); // should have no effect return result; // but let's be careful }; // be sure that _is_native is set properly BEFORE calling _set_value -Amount.prototype._set_value = function(value, roundingMode) { - assert(value instanceof Object); +Amount.prototype._set_value = function(value: Value) { - this._value = this._value = value.isZero() && value.isNegative() ? - value.negated()._value : value._value; - if (!this._value) { - this._value = value.isZero() && value.isNegative() ? - value.negated() : value; - } - this.canonicalize(roundingMode); + this._value = value.isZero() && value.isNegative() ? + value.negate() : value; this._check_limits(); }; @@ -133,8 +117,7 @@ Amount.prototype._set_value = function(value, roundingMode) { // Returns a new value which is the absolute value of this. Amount.prototype.abs = function() { - const val = (new IOUValue(this._value)).abs(); - return this._copy(val); + return this._copy(this._value.abs()); }; @@ -142,12 +125,10 @@ Amount.prototype.add = function(addend) { const addendAmount = Amount.from_json(addend); if (!this.is_comparable(addendAmount)) { - return new Amount(NaN); + return new Amount(); } - const thisValue = new IOUValue(this._value); - const addendValue = new IOUValue(addendAmount._value); - return this._copy(thisValue.add(addendValue)); + return this._copy(this._value.add(addendAmount._value)); }; @@ -160,17 +141,8 @@ Amount.prototype.subtract = function(subtrahend) { Amount.prototype.multiply = function(multiplicand) { const multiplicandAmount = Amount.from_json(multiplicand); - const thisValue = new IOUValue(this._value); - let multiplyBy; - - if (multiplicandAmount.is_native()) { - multiplyBy = new XRPValue(multiplicandAmount._value, Amount.bi_xns_unit); - return this._copy(thisValue.multiplyByXRP(multiplyBy)._value); - } - - multiplyBy = new IOUValue(multiplicandAmount._value); - return this._copy(thisValue.multiply(multiplyBy)); + return this._copy(this._value.multiply(multiplicandAmount._value)); }; @@ -180,17 +152,8 @@ Amount.prototype.scale = function(scaleFactor) { Amount.prototype.divide = function(divisor) { const divisorAmount = Amount.from_json(divisor); - const thisValue = new IOUValue(this._value); - let divideBy; - - if (divisorAmount.is_native()) { - divideBy = new XRPValue(divisorAmount._value, Amount.bi_xns_unit); - return this._copy(thisValue.divideByXRP(divideBy)._value); - } - - divideBy = new IOUValue(divisorAmount._value); - return this._copy(thisValue.divide(divideBy)); + return this._copy(this._value.divide(divisorAmount._value)); }; /** @@ -248,7 +211,7 @@ Amount.prototype.ratio_human = function(denom, opts) { // // To compensate, we multiply the numerator by 10^xns_precision. if (denominator._is_native) { - numerator._set_value(numerator.multiply(Amount.bi_xns_unit)); + numerator._set_value(numerator.multiply(bi_xns_unit)); } return numerator.divide(denominator); @@ -268,20 +231,20 @@ Amount.prototype.ratio_human = function(denom, opts) { * * @see Amount#ratio_human * - * @param {Amount} fac The second factor of the product. + * @param {Amount} factor The second factor of the product. * @param {Object} opts Options for the calculation. * @param {Date|Number} opts.reference_date Date based on which * demurrage/interest should be applied. Can be given as JavaScript Date or int * for Ripple epoch. * @return {Amount} The product. Unit will be the same as the first factor. */ -Amount.prototype.product_human = function(fac, options = {}) { +Amount.prototype.product_human = function(factor, options = {}) { - let factor = Amount.from_json(fac); + let fac = Amount.from_json(factor); // If either operand is NaN, the result is NaN. - if (!this.is_valid() || !factor.is_valid()) { - return new Amount(NaN); + if (!this.is_valid() || !fac.is_valid()) { + return new Amount(); } // Apply interest/demurrage @@ -289,17 +252,17 @@ Amount.prototype.product_human = function(fac, options = {}) { // We only need to apply it to the second factor, because the currency unit of // the first factor will carry over into the result. if (options.reference_date) { - factor = factor.applyInterest(options.reference_date); + fac = fac.applyInterest(options.reference_date); } - const product = this.multiply(factor); + const product = this.multiply(fac); // Special case: The second factor is a native (XRP) amount expressed as base // units (1 XRP = 10^xns_precision base units). // // See also Amount#ratio_human. - if (factor._is_native) { - const quotient = product.divide(Amount.bi_xns_unit.toString()); + if (fac._is_native) { + const quotient = product.divide(bi_xns_unit.toString()); product._set_value(quotient._value); } @@ -313,7 +276,7 @@ Amount.prototype.product_human = function(fac, options = {}) { * @private */ Amount.prototype._invert = function() { - this._set_value(inverse(this._value)); + this._set_value(this._value.invert()); return this; }; @@ -328,7 +291,7 @@ Amount.prototype.invert = function() { }; /** - * Canonicalize amount value + * Canonicalize amount value is now taken care of in the Value classes * * Mirrors rippled's internal Amount representation * From https://github.com/ripple/rippled/blob/develop/src/ripple/data @@ -357,19 +320,6 @@ Amount.prototype.invert = function() { * bigger than supported */ -Amount.prototype.canonicalize = function(roundingMode) { - if (typeof this._value === 'undefined') { - throw new Error('undefined value'); - } - if (this._is_native) { - this._value = this._value.round(6, Value.getBNRoundDown()); - } else if (roundingMode) { - this._value = new Value(this._value.toPrecision(16, roundingMode))._value; - } else { - this._value = new Value(this._value.toPrecision(16))._value; - } -}; - Amount.prototype._check_limits = function() { if (!Amount.strict_mode) { return this; @@ -377,7 +327,7 @@ Amount.prototype._check_limits = function() { if (this._value.isNaN() || this._value.isZero()) { return this; } - const absval = this._value.absoluteValue(); + const absval = this._value.abs(); if (this._is_native) { if (absval.greaterThan(MAX_XRP_VALUE)) { throw new Error('Exceeding max value of ' + MAX_XRP_VALUE.toString()); @@ -406,7 +356,7 @@ Amount.prototype._copy = function(value) { Amount.prototype.compareTo = function(to) { const toAmount = Amount.from_json(to); if (!this.is_comparable(toAmount)) { - return new Amount(NaN); + return new Amount(); } return this._value.comparedTo(toAmount._value); }; @@ -414,7 +364,7 @@ Amount.prototype.compareTo = function(to) { // Make d a copy of this. Returns d. // Modification of objects internally refered to is not allowed. Amount.prototype.copyTo = function(d, negate) { - d._value = negate ? this._value.negated() : this._value; + d._value = negate ? this._value.negate() : this._value; d._is_native = this._is_native; d._currency = this._currency; d._issuer = this._issuer; @@ -525,7 +475,7 @@ Amount.prototype.parse_human = function(j, options) { value = words[0].slice(0, -3); currency = words[0].slice(-3); if (!(isNumber(value) && currency.match(currency_RE))) { - return new Amount(NaN); + return new Amount(); } } } else if (words.length === 2) { @@ -539,22 +489,25 @@ Amount.prototype.parse_human = function(j, options) { value = words[0]; currency = words[1]; } else { - return new Amount(NaN); + return new Amount(); } } else { - return new Amount(NaN); + return new Amount(); } currency = currency.toUpperCase(); this.set_currency(currency); this._is_native = (currency === 'XRP'); - this._set_value(new Value(value)._value); + const newValue = + (this._is_native ? new XRPValue(value) : + new IOUValue(value)); + this._set_value(newValue); // Apply interest/demurrage if (opts.reference_date && this._currency.has_interest()) { const interest = this._currency.get_interest_at(opts.reference_date); this._set_value( - new IOUValue(this._value).divide(new Value(interest.toString()))); + this._value.divide(new IOUValue(interest.toString()))); } return this; @@ -608,11 +561,9 @@ function(quality, counterCurrency, counterIssuer, opts) { const mantissa_hex = quality.substring(quality.length - 14); const offset_hex = quality.substring( quality.length - 16, quality.length - 14); - const mantissa = new Value(mantissa_hex, 16)._value; + const mantissa = new IOUValue(mantissa_hex, null, 16); const offset = parseInt(offset_hex, 16) - 100; - const valueStr = mantissa.toString() + 'e' + offset.toString(); - const value = new Value(valueStr)._value; this._currency = Currency.from_json(counterCurrency); this._issuer = UInt160.from_json(counterIssuer); this._is_native = this._currency.is_native(); @@ -634,9 +585,9 @@ function(quality, counterCurrency, counterIssuer, opts) { quality as stored : 5 USD / 3000000 drops inverted : 3000000 drops / 5 USD */ - const adjusted = options.inverse ? inverse(value) : value; - let nativeAdjusted = this._is_native ? - new XRPValue(adjusted, Amount.bi_xns_unit) : new IOUValue(adjusted); + const valueStr = mantissa.toString() + 'e' + offset.toString(); + let nativeAdjusted = new IOUValue(valueStr); + nativeAdjusted = options.inverse ? nativeAdjusted.invert() : nativeAdjusted; if (!options.xrp_as_drops) { // `In a currency exchange, the exchange rate is quoted as the units of the @@ -647,22 +598,26 @@ function(quality, counterCurrency, counterIssuer, opts) { if (this._is_native) { // pay:$price drops get:1 X // pay:($price / 1,000,000) XRP get:1 X - nativeAdjusted = nativeAdjusted.divide(new Value(Amount.bi_xns_unit)); + nativeAdjusted = nativeAdjusted.divide(bi_xns_unit); } else if (baseCurrency.is_valid() && baseCurrency.is_native()) { // pay:$price X get:1 drop // pay:($price * 1,000,000) X get:1 XRP - nativeAdjusted = nativeAdjusted.multiply(new Value(Amount.bi_xns_unit)); + nativeAdjusted = nativeAdjusted.multiply(bi_xns_unit); } } - this._set_value(nativeAdjusted); + if (this._is_native) { + this._set_value( + new XRPValue(nativeAdjusted.round(6, Value.getBNRoundDown()))); + } else { + this._set_value(nativeAdjusted); + } if (options.reference_date && baseCurrency.is_valid() && baseCurrency.has_interest()) { const interest = baseCurrency.get_interest_at(options.reference_date); this._set_value( - new IOUValue(this._value).divide(new Value(interest.toString()))); + this._value.divide(new IOUValue(interest.toString()))); } - return this; }; @@ -670,7 +625,7 @@ Amount.prototype.parse_number = function(n) { this._is_native = false; this._currency = Currency.from_json(1); this._issuer = UInt160.from_json(1); - this._set_value(new Value(n)._value); + this._set_value(new IOUValue(n)); return this; }; @@ -721,7 +676,7 @@ Amount.prototype.parse_json = function(j) { break; default: - this._set_value(new Value(NaN)._value); + this._set_value(new IOUValue(NaN)); } return this; @@ -736,11 +691,11 @@ Amount.prototype.parse_native = function(j) { if (j.indexOf('.') >= 0) { throw new Error('Native amounts must be specified in integer drops'); } - const value = new XRPValue(j, Amount.bi_xns_unit); + const value = new XRPValue(j); this._is_native = true; - this._set_value(value.divide(new Value(Amount.bi_xns_unit))); + this._set_value(value.divide(bi_xns_unit)); } else { - this._set_value(new Value(NaN)._value); + this._set_value(new IOUValue(NaN)); } return this; @@ -750,7 +705,8 @@ Amount.prototype.parse_native = function(j) { // Requires _currency to be set! Amount.prototype.parse_value = function(j) { this._is_native = false; - this._set_value(new Value(j)._value, Value.getBNRoundDown()); + const newValue = new IOUValue(j, Value.getBNRoundDown()); + this._set_value(newValue); return this; }; @@ -781,14 +737,14 @@ Amount.prototype.to_text = function() { } if (this._is_native) { - return new XRPValue(this._value).multiply( - new Value(Amount.bi_xns_unit))._value.toString(); + return this._value.multiply(bi_xns_unit).toString(); } // not native - const offset = this._value.e - 15; + const offset = this._value.getExponent() - 15; const sign = this._value.isNegative() ? '-' : ''; - const mantissa = utils.getMantissaDecimalString(this._value.absoluteValue()); + const mantissa = utils.getMantissa16FromString( + this._value.abs().toString()); if (offset !== 0 && (offset < -25 || offset > -4)) { // Use e notation. // XXX Clamp output. @@ -825,7 +781,7 @@ Amount.prototype.applyInterest = function(referenceDate) { } const interest = this._currency.get_interest_at(referenceDate); return this._copy( - new IOUValue(this._value).multiply(new Value(interest.toString()))); + this._value.multiply(new IOUValue(interest.toString()))); }; /** @@ -1005,7 +961,7 @@ Amount.prototype.not_equals_why = function(d, ignore_issuer) { } const type = this._is_native ? 'XRP' : 'Non-XRP'; - if (!this._value.isZero() && this._value.negated().equals(d._value)) { + if (!this._value.isZero() && this._value.negate().equals(d._value)) { return type + ' sign differs.'; } if (!this._value.equals(d._value)) { diff --git a/src/core/orderbook.js b/src/core/orderbook.js index 59725ec1..0e173e3f 100644 --- a/src/core/orderbook.js +++ b/src/core/orderbook.js @@ -451,8 +451,7 @@ OrderBook.prototype.applyTransferRate = function(balance) { const adjustedBalance = (new IOUValue(balance)) .divide(new IOUValue(this._issuerTransferRate)) - .multiply(new IOUValue(OrderBook.DEFAULT_TRANSFER_RATE)) - ._value.toString(); + .multiply(new IOUValue(OrderBook.DEFAULT_TRANSFER_RATE)).toString(); return adjustedBalance; }; diff --git a/src/core/orderbookutils.js b/src/core/orderbookutils.js index 9eaf668a..34705dcc 100644 --- a/src/core/orderbookutils.js +++ b/src/core/orderbookutils.js @@ -32,12 +32,7 @@ function createAmount(value, currency, counterparty) { */ function getCurrencyFromOffer(offer) { - let currency = offer.TakerPays.currency; - - if (!currency) { - currency = offer.TakerGets.currency; - } - return currency; + return offer.TakerPays.currency || offer.TakerGets.currency; } /** @@ -47,12 +42,7 @@ function getCurrencyFromOffer(offer) { */ function getIssuerFromOffer(offer) { - let issuer = offer.TakerPays.issuer; - - if (!issuer) { - issuer = offer.TakerGets.issuer; - } - return issuer; + return offer.TakerPays.issuer || offer.TakerGets.issuer; } /** diff --git a/src/core/utils.js b/src/core/utils.js index e8fe8f3c..2d9de2fa 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -1,8 +1,9 @@ 'use strict'; -function getMantissaDecimalString(bignum) { - let mantissa = bignum.toPrecision(16) - .replace(/\./, '') // remove decimal point +// returns the mantissa from the passed in string, +// adding zeros until it has 16 sd +function getMantissa16FromString(decimalString) { + let mantissa = decimalString.replace(/\./, '') // remove decimal point .replace(/e.*/, '') // remove scientific notation .replace(/^0*/, ''); // remove leading zeroes while (mantissa.length < 16) { @@ -11,6 +12,10 @@ function getMantissaDecimalString(bignum) { return mantissa; } +function getMantissaDecimalString(bignum) { + return getMantissa16FromString(bignum.toPrecision(16)); +} + function trace(comment, func) { return function() { console.log('%s: %s', trace, arguments.toString); @@ -156,6 +161,7 @@ exports.arrayUnique = arrayUnique; exports.toTimestamp = toTimestamp; exports.fromTimestamp = fromTimestamp; exports.getMantissaDecimalString = getMantissaDecimalString; +exports.getMantissa16FromString = getMantissa16FromString; exports.sjcl = require('sjcl-extended'); diff --git a/src/core/value.js b/src/core/value.js index 7e7e2869..eea11495 100644 --- a/src/core/value.js +++ b/src/core/value.js @@ -9,10 +9,16 @@ const BigNumber = GlobalBigNumber.another({ DECIMAL_PLACES: 40 }); +const assert = require('assert'); + class Value { - constructor(value: string | BigNumber, base: number) { - this._value = new BigNumber(value, base); + constructor(value: string | BigNumber) { + if (this.constructor === 'Value') { + throw new Error( + 'Cannot instantiate Value directly, it is an abstract base class'); + } + this._value = new BigNumber(value); } static getBNRoundDown() { @@ -25,35 +31,23 @@ class Value { } add(addend: Value) { + assert(this.constructor === addend.constructor); const result = this._value.plus(addend._value); return this._canonicalize(result); } subtract(subtrahend: Value) { + assert(this.constructor === subtrahend.constructor); const result = this._value.minus(subtrahend._value); return this._canonicalize(result); } multiply(multiplicand: Value) { - const val = this._value; - const mult = multiplicand._value; - const result = (val).times(mult); + const result = this._value.times(multiplicand._value); return this._canonicalize(result); } - scale(scaleFactor: Value) { - const result = this._value.times(scaleFactor._value); - return this._canonicalize(result); - - } - divide(divisor: Value) { - if (this._value.isNaN()) { - throw new Error('Invalid dividend'); - } - if (divisor.isNaN()) { - throw new Error('Invalid divisor'); - } if (divisor.isZero()) { throw new Error('divide by zero'); } @@ -66,6 +60,19 @@ class Value { return this._canonicalize(result); } + round(decimalPlaces: number, roundingMode: number) { + const result = this._value.round(decimalPlaces, roundingMode); + return this._canonicalize(result); + } + + toFixed(decimalPlaces: number, roundingMode: number) { + return this._value.toFixed(decimalPlaces, roundingMode); + } + + getExponent() { + return this._value.e; + } + isNaN() { return this._value.isNaN(); } @@ -78,8 +85,23 @@ class Value { return this._value.isNegative(); } - negated() { - return this._value.neg(); + toString() { + return this._value.toString(); + } + + greaterThan(comparator: Value) { + assert(this.constructor === comparator.constructor); + return this._value.greaterThan(comparator._value); + } + + lessThan(comparator: Value) { + assert(this.constructor === comparator.constructor); + return this._value.lessThan(comparator._value); + } + + comparedTo(comparator: Value) { + assert(this.constructor === comparator.constructor); + return this._value.comparedTo(comparator._value); } } diff --git a/test/amount-test.js b/test/amount-test.js index 72339c40..3deec477 100644 --- a/test/amount-test.js +++ b/test/amount-test.js @@ -1186,19 +1186,19 @@ describe('Amount', function() { describe('amount limits', function() { it('max JSON wire limite', function() { - assert.strictEqual(Amount.bi_xns_max.toString(), '100000000000000000'); + assert.strictEqual(Amount.bi_xns_max, '100000000000000000'); }); it('max JSON wire limite', function() { - assert.strictEqual(Amount.bi_xns_min.toString(), '-100000000000000000'); + assert.strictEqual(Amount.bi_xns_min, '-100000000000000000'); }); it('max mantissa value', function() { - assert.strictEqual(Amount.bi_man_max_value.toString(), '9999999999999999'); + assert.strictEqual(Amount.bi_man_max_value, '9999999999999999'); }); it('min mantissa value', function() { - assert.strictEqual(Amount.bi_man_min_value.toString(), '1000000000000000'); + assert.strictEqual(Amount.bi_man_min_value, '1000000000000000'); }); it('from_json minimum XRP', function() {