From 3ef60e0391b2637351c8c9aad2e1cbbdd06a1245 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Mon, 23 Jun 2014 09:55:31 -0700 Subject: [PATCH 1/9] [TASK] add npm-debug to gitignore --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 870069a7..ce6e3338 100644 --- a/.gitignore +++ b/.gitignore @@ -45,4 +45,7 @@ test/config.js /coverage # Ignore IntelliJ files -.idea \ No newline at end of file +.idea + +# Ignore npm-debug +npm-debug.log \ No newline at end of file From 9527d6ed224face3d99083da24d09057d92c3dc6 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Mon, 23 Jun 2014 09:55:53 -0700 Subject: [PATCH 2/9] [TEST] add test for demurred currency Amount parsing --- test/amount-test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/amount-test.js b/test/amount-test.js index 93ab0093..01ef6275 100644 --- a/test/amount-test.js +++ b/test/amount-test.js @@ -117,6 +117,12 @@ describe('Amount', function() { assert.strictEqual(typeof Amount.from_json('x').to_text(true), 'number'); assert(isNaN(Amount.from_json('x').to_text(true))); }); + it('parse dem', function() { + assert.strictEqual(Amount.from_json('10/015841551A748AD2C1F76FF6ECB0CCCD00000000/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_text_full(), '10/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); + }); + it('parse dem', function() { + assert.strictEqual(Amount.from_json('10/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_text_full(), '10/XAU (-0.5%pa)/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh'); + }); it('Parse 800/USD/mtgox', function () { assert.strictEqual('800/USD/'+config.accounts['mtgox'].account, Amount.from_json('800/USD/mtgox').to_text_full()); }); From a573465e41073480e52e40ab22c6cf9dcf7e1437 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Mon, 23 Jun 2014 14:48:54 -0700 Subject: [PATCH 3/9] [FEATURE] Currency: add option force hex in json format provide the `force_hex` flag in the options object in a `to_json` or `json_rewrite` call --- src/js/ripple/currency.js | 6 ++++-- test/currency-test.js | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/js/ripple/currency.js b/src/js/ripple/currency.js index e5b27fd7..e2521510 100644 --- a/src/js/ripple/currency.js +++ b/src/js/ripple/currency.js @@ -313,16 +313,18 @@ Currency.prototype.to_json = function(opts) { return 'XRP'; } + var opts = opts || {}; + var currency; var fullName = opts && opts.full_name ? " - " + opts.full_name : ""; // Any currency with standard properties and a valid code can be abbreviated // in the JSON wire format as the three character code. - if (/^[A-Z0-9]{3}$/.test(this._iso_code) && !this.has_interest()) { + if (!opts.force_hex && /^[A-Z0-9]{3}$/.test(this._iso_code) && !this.has_interest()) { currency = this._iso_code + fullName; // If there is interest, append the annual interest to the full currency name - } else if (this.has_interest()) { + } else if (!opts.force_hex && this.has_interest()) { var decimals = opts ? opts.decimals : undefined; currency = this._iso_code + fullName + " (" + this.get_interest_percentage_at(this._interest_start + 3600 * 24 * 365, decimals) + "%pa)"; } else { diff --git a/test/currency-test.js b/test/currency-test.js index 65fc7879..e742017c 100644 --- a/test/currency-test.js +++ b/test/currency-test.js @@ -37,6 +37,22 @@ describe('Currency', function() { assert(!r.is_valid()); assert.strictEqual('XRP', r.to_json()); }); + it('from_json("XAU").to_json() hex', function() { + var r = currency.from_json("XAU"); + assert.strictEqual('0000000000000000000000005841550000000000', r.to_json({force_hex: true})); + }); + it('from_json("XAU (0.5%pa").to_json() hex', function() { + var r = currency.from_json("XAU (0.5%pa)"); + assert.strictEqual('015841550000000041F78E0A28CBF19200000000', r.to_json({force_hex: true})); + }); + it('json_rewrite("015841550000000041F78E0A28CBF19200000000").to_json() hex', function() { + var r = currency.json_rewrite('015841550000000041F78E0A28CBF19200000000'); + assert.strictEqual('XAU (0.5%pa)', r); + }); + it('json_rewrite("015841550000000041F78E0A28CBF19200000000") hex', function() { + var r = currency.json_rewrite('015841550000000041F78E0A28CBF19200000000', {force_hex: true}); + assert.strictEqual('015841550000000041F78E0A28CBF19200000000', r); + }); }); describe('from_human', function() { From fa9305626bb7b4eb72e1a46994257964619f4d02 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Mon, 23 Jun 2014 14:49:48 -0700 Subject: [PATCH 4/9] [FIX] force hex for orderbook requests interest bearing currencies would be sent down malformed `XAU (0.5%pa)` when rippled would be expecting either hex or iso --- src/js/ripple/remote.js | 4 ++-- src/js/ripple/request.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/js/ripple/remote.js b/src/js/ripple/remote.js index 5e20a78b..76f21771 100644 --- a/src/js/ripple/remote.js +++ b/src/js/ripple/remote.js @@ -1436,7 +1436,7 @@ Remote.prototype.requestBookOffers = function(gets, pays, taker, callback) { var request = new Request(this, 'book_offers'); request.message.taker_gets = { - currency: Currency.json_rewrite(gets.currency) + currency: Currency.json_rewrite(gets.currency, {force_hex:true}) }; if (request.message.taker_gets.currency !== 'XRP') { @@ -1444,7 +1444,7 @@ Remote.prototype.requestBookOffers = function(gets, pays, taker, callback) { } request.message.taker_pays = { - currency: Currency.json_rewrite(pays.currency) + currency: Currency.json_rewrite(pays.currency, {force_hex:true}) }; if (request.message.taker_pays.currency !== 'XRP') { diff --git a/src/js/ripple/request.js b/src/js/ripple/request.js index 617a3cd8..d058b3c9 100644 --- a/src/js/ripple/request.js +++ b/src/js/ripple/request.js @@ -340,7 +340,7 @@ Request.prototype.addBook = function(book, snapshot) { } var obj = json[side] = { - currency: Currency.json_rewrite(book[side].currency) + currency: Currency.json_rewrite(book[side].currency, {force_hex: true}) }; if (obj.currency !== 'XRP') { From e0bcf193403204609b8cf99cd60361932399ca1f Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Tue, 24 Jun 2014 10:48:12 -0700 Subject: [PATCH 5/9] [FIX] value parsing for amount/currency order pairs e.g. `100000 USD` and `USD 100000` should have the same result --- src/js/ripple/amount.js | 4 ++-- test/amount-test.js | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/js/ripple/amount.js b/src/js/ripple/amount.js index 0e4f33d7..f3b9f697 100644 --- a/src/js/ripple/amount.js +++ b/src/js/ripple/amount.js @@ -617,8 +617,8 @@ Amount.prototype.parse_human = function(j, opts) { var m = String(j).match(Amount.human_RE); if (m) { - var currency = m[1] || m[5] || 'XRP'; - var integer = m[3] || '0'; + var currency = m[5] || m[1] || 'XRP'; + var integer = m[5] && m[1] ? m[1] + '' + m[3] : (m[3] || '0'); var fraction = m[4] || ''; var precision = null; diff --git a/test/amount-test.js b/test/amount-test.js index 01ef6275..9d5c040a 100644 --- a/test/amount-test.js +++ b/test/amount-test.js @@ -26,6 +26,24 @@ describe('Amount', function() { it('0.1 USD', function() { assert.strictEqual(Amount.from_human("0.1 USD").to_text_full(), '0.1/USD/NaN'); }); + it('10000 USD', function() { + assert.strictEqual(Amount.from_human("10000 USD").to_text_full(), '10000/USD/NaN'); + }); + it('USD 10000', function() { + assert.strictEqual(Amount.from_human("USD 10000").to_text_full(), '10000/USD/NaN'); + }); + it('12345.6789 XAU', function() { + assert.strictEqual(Amount.from_human("12345.6789 XAU").to_text_full(), '12345.6789/XAU/NaN'); + }); + it('XAU 12345.6789', function() { + assert.strictEqual(Amount.from_human("XAU 12345.6789").to_text_full(), '12345.6789/XAU/NaN'); + }); + it('101 12345.6789', function() { + assert.strictEqual(Amount.from_human("101 12345.6789").to_text_full(), '12345.6789/101/NaN'); + }); + it('12345.6789 101', function() { + assert.strictEqual(Amount.from_human("12345.6789 101").to_text_full(), '12345.6789/101/NaN'); + }); }); describe('from_json', function() { it('1 XRP', function() { From a47eef32835252b4df2fa68b5dcba3ced90f259c Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Tue, 24 Jun 2014 11:55:33 -0700 Subject: [PATCH 6/9] [TEST] add full_name null case test --- test/currency-test.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/currency-test.js b/test/currency-test.js index e742017c..c0df3295 100644 --- a/test/currency-test.js +++ b/test/currency-test.js @@ -114,6 +114,14 @@ describe('Currency', function() { it('to_human with full_name "XRP - Ripples"', function() { assert.strictEqual('XRP - Ripples', currency.from_json('XRP').to_human({full_name:'Ripples'})); }); + it('to_human human "TIM" without full_name', function() { + var cur = currency.from_json("TIM"); + assert.strictEqual(cur.to_human(), "TIM"); + }); + it('to_human "TIM" with null full_name', function() { + var cur = currency.from_json("TIM"); + assert.strictEqual(cur.to_human({full_name: null}), "TIM"); + }); }); describe('from_hex', function() { From b6f0aa3914df388f912d08eb0e3b7b06d73e6918 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Tue, 24 Jun 2014 11:58:11 -0700 Subject: [PATCH 7/9] [TEST] modify order book test to support hex values --- test/request-test.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/test/request-test.js b/test/request-test.js index 5dbf927e..87cc5059 100644 --- a/test/request-test.js +++ b/test/request-test.js @@ -3,6 +3,7 @@ var utils = require('./testutils'); var Request = utils.load_module('request').Request; var Remote = utils.load_module('remote').Remote; var Server = utils.load_module('server').Server; +var Currency = utils.load_module('currency').Currency; function makeServer(url) { var server = new Server(new process.EventEmitter(), url); @@ -554,6 +555,9 @@ describe('Request', function() { request.books(books); + books[0]['taker_gets'].currency = Currency.from_json('EUR').to_hex(); + books[0]['taker_pays'].currency = Currency.from_json('USD').to_hex(); + assert.deepEqual(request.message.books, books); }); @@ -577,11 +581,11 @@ describe('Request', function() { assert.deepEqual(request.message.books, [ { 'taker_gets': { - 'currency': 'CNY', + 'currency': Currency.from_json('CNY').to_hex(), 'issuer': 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }, 'taker_pays': { - 'currency': 'USD', + 'currency': Currency.from_json('USD').to_hex(), 'issuer': 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' } } @@ -605,11 +609,11 @@ describe('Request', function() { assert.deepEqual(request.message.books, [ { 'taker_gets': { - 'currency': 'EUR', + 'currency': '0000000000000000000000004555520000000000', // EUR hex 'issuer': 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }, 'taker_pays': { - 'currency': 'USD', + 'currency': '0000000000000000000000005553440000000000', // USD hex 'issuer': 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' } }, @@ -662,11 +666,11 @@ describe('Request', function() { assert.deepEqual(request.message.books, [{ 'taker_gets': { - 'currency': 'EUR', + 'currency': Currency.from_json('EUR').to_hex(), 'issuer': 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }, 'taker_pays': { - 'currency': 'USD', + 'currency': Currency.from_json('USD').to_hex(), 'issuer': 'rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B' }, 'snapshot': true, From a0ba289848ed9e936f9f33c097df8586083a27b3 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Tue, 24 Jun 2014 16:33:05 -0700 Subject: [PATCH 8/9] [FEATURE] use Currency object and hex format in orderbook instead of checking the value of the currency string, create a Currency object and work with that the json format going to rippled will contain the hex value of the currency --- src/js/ripple/orderbook.js | 26 ++++++++++++++------------ src/js/ripple/remote.js | 6 +++--- src/js/ripple/request.js | 2 +- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/js/ripple/orderbook.js b/src/js/ripple/orderbook.js index 0799f697..99d30cee 100644 --- a/src/js/ripple/orderbook.js +++ b/src/js/ripple/orderbook.js @@ -21,9 +21,9 @@ function OrderBook(remote, currency_gets, issuer_gets, currency_pays, issuer_pay var self = this; this._remote = remote; - this._currency_gets = currency_gets; + this._currency_gets = Currency.from_json(currency_gets); this._issuer_gets = issuer_gets; - this._currency_pays = currency_pays; + this._currency_pays = Currency.from_json(currency_pays); this._issuer_pays = issuer_pays; this._subs = 0; this._key = key; @@ -132,18 +132,18 @@ OrderBook.prototype._prepareSubscribe = function (request) { OrderBook.prototype.to_json = function () { var json = { taker_gets: { - currency: this._currency_gets + currency: this._currency_gets.to_hex() }, taker_pays: { - currency: this._currency_pays + currency: this._currency_pays.to_hex() } }; - if (this._currency_gets !== 'XRP') { + if (!this._currency_gets.is_native()) { json.taker_gets.issuer = this._issuer_gets; } - if (this._currency_pays !== 'XRP') { + if (!this._currency_pays.is_native()) { json.taker_pays.issuer = this._issuer_pays; } @@ -159,17 +159,19 @@ OrderBook.prototype.to_json = function () { OrderBook.prototype.is_valid = function () { // XXX Should check for same currency (non-native) && same issuer return ( - Currency.is_valid(this._currency_pays) && - (this._currency_pays === 'XRP' || UInt160.is_valid(this._issuer_pays)) && - Currency.is_valid(this._currency_gets) && - (this._currency_gets === 'XRP' || UInt160.is_valid(this._issuer_gets)) && - !(this._currency_pays === 'XRP' && this._currency_gets === 'XRP') + this._currency_pays && this._currency_pays.is_valid() && + (this._currency_pays.is_native() || UInt160.is_valid(this._issuer_pays)) && + + this._currency_gets && this._currency_gets.is_valid() && + (this._currency_gets.is_native() || UInt160.is_valid(this._issuer_gets)) && + + !(this._currency_pays.is_native() && this._currency_gets.is_native()) ); }; OrderBook.prototype.trade = function(type) { var tradeStr = '0' - + ((this['_currency_' + type] === 'XRP') ? '' : '/' + + ((Currency.from_json(this['_currency_' + type]).is_native()) ? '' : '/' + this['_currency_' + type ] + '/' + this['_issuer_' + type]); return Amount.from_json(tradeStr); diff --git a/src/js/ripple/remote.js b/src/js/ripple/remote.js index 76f21771..eed4d4ef 100644 --- a/src/js/ripple/remote.js +++ b/src/js/ripple/remote.js @@ -1439,7 +1439,7 @@ Remote.prototype.requestBookOffers = function(gets, pays, taker, callback) { currency: Currency.json_rewrite(gets.currency, {force_hex:true}) }; - if (request.message.taker_gets.currency !== 'XRP') { + if (!Currency.from_json(request.message.taker_gets.currency).is_native()) { request.message.taker_gets.issuer = UInt160.json_rewrite(gets.issuer); } @@ -1447,7 +1447,7 @@ Remote.prototype.requestBookOffers = function(gets, pays, taker, callback) { currency: Currency.json_rewrite(pays.currency, {force_hex:true}) }; - if (request.message.taker_pays.currency !== 'XRP') { + if (!Currency.from_json(request.message.taker_pays.currency).is_native()) { request.message.taker_pays.issuer = UInt160.json_rewrite(pays.issuer); } @@ -1757,7 +1757,7 @@ Remote.prototype.createPathFind = function(src_account, dst_account, dst_amount, }; Remote.prepareTrade = function(currency, issuer) { - return currency + (currency === 'XRP' ? '' : ('/' + issuer)); + return currency + (Currency.from_json(currency).is_native() ? '' : ('/' + issuer)); }; /** diff --git a/src/js/ripple/request.js b/src/js/ripple/request.js index d058b3c9..7e20ec64 100644 --- a/src/js/ripple/request.js +++ b/src/js/ripple/request.js @@ -343,7 +343,7 @@ Request.prototype.addBook = function(book, snapshot) { currency: Currency.json_rewrite(book[side].currency, {force_hex: true}) }; - if (obj.currency !== 'XRP') { + if (!Currency.from_json(obj.currency).is_native()) { obj.issuer = UInt160.json_rewrite(book[side].issuer); } } From 5fe1ebdd4522938d234c6ac9890d6fdeb385bc68 Mon Sep 17 00:00:00 2001 From: Geert Weening Date: Tue, 24 Jun 2014 16:35:12 -0700 Subject: [PATCH 9/9] [TEST] add test to verify HEX_ZERO is native currency --- test/currency-test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/currency-test.js b/test/currency-test.js index c0df3295..d03aa201 100644 --- a/test/currency-test.js +++ b/test/currency-test.js @@ -27,6 +27,12 @@ describe('Currency', function() { assert(r.is_native()); assert.strictEqual('XRP', r.to_json()); }); + it('from_json("0000000000000000000000000000000000000000").to_json() == "XRP"', function() { + var r = currency.from_json('0000000000000000000000000000000000000000'); + assert(r.is_valid()); + assert(r.is_native()); + assert.strictEqual('XRP', r.to_json()); + }); it('from_json("111").to_human()', function() { var r = currency.from_json("111"); assert(r.is_valid());