mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-15 01:55:48 +00:00
Compare commits
15 Commits
v0.8.1-rc3
...
v0.8.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eeba86f9c5 | ||
|
|
e0d68e60ec | ||
|
|
254248486b | ||
|
|
1b57cc6d35 | ||
|
|
77234f256d | ||
|
|
795d31d2db | ||
|
|
f3f10fd9bd | ||
|
|
7100b4be8d | ||
|
|
b1a7200d1b | ||
|
|
5d8bb541c6 | ||
|
|
b51c59b23a | ||
|
|
2cd434e861 | ||
|
|
1599eb9629 | ||
|
|
8ef7481858 | ||
|
|
344d478b3f |
16
HISTORY.md
16
HISTORY.md
@@ -1,3 +1,18 @@
|
||||
##0.8.2
|
||||
|
||||
+ Currency: Allow mixed letters and numbers in currencies
|
||||
|
||||
+ Deprecate account_tx map/reduce/filter
|
||||
|
||||
+ Fix: correct requestLedger arguments
|
||||
|
||||
+ Fix: missing subscription on error events for some server methods
|
||||
|
||||
+ Fix: orderbook reset on reconnect
|
||||
|
||||
+ Fix: ripple-lib crashing. Add potential missing error handlers
|
||||
|
||||
|
||||
##0.8.1
|
||||
|
||||
+ Wallet: Add Wallet class that generates wallets
|
||||
@@ -10,6 +25,7 @@
|
||||
|
||||
+ Fix undefined fee states when connecting to a rippled that is syncing
|
||||
|
||||
|
||||
##0.8.0
|
||||
|
||||
+ Orderbook: Added tracking of offer funds for determining when offers are not funded
|
||||
|
||||
@@ -111,14 +111,14 @@ See the [wiki](https://ripple.com/wiki/JSON_Messages#subscribe) for details on s
|
||||
//handle ledger
|
||||
});
|
||||
|
||||
remote.on('transaction', function onTransacstion(transaction) {
|
||||
request.on('transaction', function onTransacstion(transaction) {
|
||||
//handle transaction
|
||||
});
|
||||
|
||||
remote.request(function(err) {
|
||||
request.request(function(err) {
|
||||
if (err) {
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
@@ -186,14 +186,7 @@ var Amount = require('ripple-lib').Amount;
|
||||
|
||||
var MY_ADDRESS = 'rrrMyAddress';
|
||||
var MY_SECRET = 'secret';
|
||||
|
||||
var BUY_AMOUNT = Amount.from_human('100XRP');
|
||||
var SELL_AMOUNT = Amount.from_human('1USD');
|
||||
|
||||
// EXPIRATION must be a Date object, leave undefined to submit offer that won't expire
|
||||
var now = new Date();
|
||||
var tomorrow = new Date(now.getTime() + (24 * 60 * 60 * 1000));
|
||||
var EXPIRATION = tomorrow;
|
||||
var GATEWAY = 'rrrGateWay';
|
||||
|
||||
var remote = new Remote({ /* Remote options */ });
|
||||
|
||||
@@ -201,10 +194,9 @@ remote.connect(function() {
|
||||
remote.setSecret(MY_ADDRESS, MY_SECRET);
|
||||
|
||||
var transaction = remote.createTransaction('OfferCreate', {
|
||||
account: MY_ADDRESS,
|
||||
buy: BUY_AMOUNT,
|
||||
sell: SELL_AMOUNT,
|
||||
expiration: EXPIRATION
|
||||
account: MY_ADDRESS,
|
||||
taker_pays: '1',
|
||||
taker_gets: '1/USD/' + GATEWAY
|
||||
});
|
||||
|
||||
transaction.submit(function(err, res) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ripple-lib",
|
||||
"version": "0.8.1-rc3",
|
||||
"version": "0.8.2",
|
||||
"description": "Ripple JavaScript client library",
|
||||
"files": [
|
||||
"src/js/*",
|
||||
|
||||
@@ -50,7 +50,7 @@ Currency.HEX_CURRENCY_BAD = '0000000000000000000000005852500000000000';
|
||||
* \s*$ // end with any amount of whitespace
|
||||
*
|
||||
*/
|
||||
Currency.prototype.human_RE = /^\s*([a-zA-Z]{3}|[0-9]{3})(\s*-\s*[- \w]+)?(\s*\(-?\d+\.?\d*%pa\))?\s*$/;
|
||||
Currency.prototype.human_RE = /^\s*([a-zA-Z0-9]{3})(\s*-\s*[- \w]+)?(\s*\(-?\d+\.?\d*%pa\))?\s*$/;
|
||||
|
||||
Currency.from_json = function(j, shouldInterpretXrpAsIou) {
|
||||
if (j instanceof this) {
|
||||
|
||||
@@ -78,19 +78,20 @@ function OrderBook(remote, getsC, getsI, paysC, paysI, key) {
|
||||
});
|
||||
|
||||
this.on('unsubscribe', function() {
|
||||
self._ownerFunds = { };
|
||||
self.resetCache();
|
||||
self._remote.removeListener('transaction', updateFundedAmounts);
|
||||
self._remote.removeListener('transaction', updateTransferRate);
|
||||
});
|
||||
|
||||
this._remote.on('prepare_subscribe', function() {
|
||||
this._remote.once('prepare_subscribe', function() {
|
||||
self.subscribe();
|
||||
});
|
||||
|
||||
this._remote.on('disconnect', function() {
|
||||
self._ownerFunds = { };
|
||||
self._offerCounts = { };
|
||||
self._synchronized = false;
|
||||
self.resetCache();
|
||||
self._remote.once('prepare_subscribe', function() {
|
||||
self.subscribe();
|
||||
});
|
||||
});
|
||||
|
||||
function updateFundedAmounts(message) {
|
||||
@@ -195,6 +196,16 @@ OrderBook.prototype.unsubscribe = function() {
|
||||
this.emit('unsubscribe');
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset cached owner funds, offer counts
|
||||
*/
|
||||
|
||||
OrderBook.prototype.resetCache = function() {
|
||||
this._ownerFunds = { };
|
||||
this._offerCounts = { };
|
||||
this._synchronized = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check that the funds for offer owner have been cached
|
||||
*
|
||||
@@ -695,6 +706,9 @@ OrderBook.prototype.requestOffers = function(callback) {
|
||||
log.info('requested offers', self._key, 'offers: ' + res.offers.length);
|
||||
}
|
||||
|
||||
// Reset offers
|
||||
self._offers = [ ];
|
||||
|
||||
for (var i=0, l=res.offers.length; i<l; i++) {
|
||||
var offer = res.offers[i];
|
||||
var fundedAmount;
|
||||
|
||||
@@ -615,16 +615,16 @@ Remote.prototype._handleMessage = function(message, server) {
|
||||
|
||||
switch (message.type) {
|
||||
case 'ledgerClosed':
|
||||
this._handleLedgerClosed(message);
|
||||
this._handleLedgerClosed(message, server);
|
||||
break;
|
||||
case 'serverStatus':
|
||||
this._handleServerStatus(message);
|
||||
this._handleServerStatus(message, server);
|
||||
break;
|
||||
case 'transaction':
|
||||
this._handleTransaction(message);
|
||||
this._handleTransaction(message, server);
|
||||
break;
|
||||
case 'path_find':
|
||||
this._handlePathFind(message);
|
||||
this._handlePathFind(message, server);
|
||||
break;
|
||||
default:
|
||||
if (this.trace) {
|
||||
@@ -640,7 +640,7 @@ Remote.prototype._handleMessage = function(message, server) {
|
||||
* @param {Object} message
|
||||
*/
|
||||
|
||||
Remote.prototype._handleLedgerClosed = function(message) {
|
||||
Remote.prototype._handleLedgerClosed = function(message, server) {
|
||||
var self = this;
|
||||
|
||||
// XXX If not trusted, need to verify we consider ledger closed.
|
||||
@@ -659,11 +659,11 @@ Remote.prototype._handleLedgerClosed = function(message) {
|
||||
this._ledger_current_index = message.ledger_index + 1;
|
||||
|
||||
if (this.isConnected()) {
|
||||
this.emit('ledger_closed', message);
|
||||
this.emit('ledger_closed', message, server);
|
||||
} else {
|
||||
this.once('connect', function() {
|
||||
// Delay until server is 'online'
|
||||
self.emit('ledger_closed', message);
|
||||
self.emit('ledger_closed', message, server);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -675,8 +675,8 @@ Remote.prototype._handleLedgerClosed = function(message) {
|
||||
* @param {Object} message
|
||||
*/
|
||||
|
||||
Remote.prototype._handleServerStatus = function(message) {
|
||||
this.emit('server_status', message);
|
||||
Remote.prototype._handleServerStatus = function(message, server) {
|
||||
this.emit('server_status', message, server);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -685,7 +685,7 @@ Remote.prototype._handleServerStatus = function(message) {
|
||||
* @param {Object} message
|
||||
*/
|
||||
|
||||
Remote.prototype._handleTransaction = function(message) {
|
||||
Remote.prototype._handleTransaction = function(message, server) {
|
||||
var self = this;
|
||||
|
||||
// XXX If not trusted, need proof.
|
||||
@@ -732,8 +732,8 @@ Remote.prototype._handleTransaction = function(message) {
|
||||
});
|
||||
}
|
||||
|
||||
this.emit('transaction', message);
|
||||
this.emit('transaction_all', message);
|
||||
this.emit('transaction', message, server);
|
||||
this.emit('transaction_all', message, server);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -742,7 +742,7 @@ Remote.prototype._handleTransaction = function(message) {
|
||||
* @param {Object} message
|
||||
*/
|
||||
|
||||
Remote.prototype._handlePathFind = function(message) {
|
||||
Remote.prototype._handlePathFind = function(message, server) {
|
||||
var self = this;
|
||||
|
||||
// Pass the event to the currently open PathFind object
|
||||
@@ -750,7 +750,7 @@ Remote.prototype._handlePathFind = function(message) {
|
||||
this._cur_path_find.notify_update(message);
|
||||
}
|
||||
|
||||
this.emit('path_find_all', message);
|
||||
this.emit('path_find_all', message, server);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -929,20 +929,19 @@ Remote.prototype.requestServerInfo = function(callback) {
|
||||
* @return {Request} request
|
||||
*/
|
||||
|
||||
Remote.prototype.requestLedger = function(ledger, options, callback) {
|
||||
Remote.prototype.requestLedger = function(options, callback) {
|
||||
// XXX This is a bad command. Some variants don't scale.
|
||||
// XXX Require the server to be trusted.
|
||||
//utils.assert(this.trusted);
|
||||
|
||||
var request = new Request(this, 'ledger');
|
||||
|
||||
if (ledger) {
|
||||
// DEPRECATED: use .ledger_hash() or .ledger_index()
|
||||
//console.log('request_ledger: ledger parameter is deprecated');
|
||||
request.message.ledger = ledger;
|
||||
}
|
||||
|
||||
switch (typeof options) {
|
||||
case 'undefined': break;
|
||||
case 'function':
|
||||
callback = options;
|
||||
break;
|
||||
|
||||
case 'object':
|
||||
Object.keys(options).forEach(function(o) {
|
||||
switch (o) {
|
||||
@@ -950,23 +949,16 @@ Remote.prototype.requestLedger = function(ledger, options, callback) {
|
||||
case 'expand':
|
||||
case 'transactions':
|
||||
case 'accounts':
|
||||
case 'ledger_index':
|
||||
case 'ledger_hash':
|
||||
request.message[o] = true;
|
||||
break;
|
||||
}
|
||||
}, options);
|
||||
break;
|
||||
|
||||
case 'function':
|
||||
callback = options;
|
||||
options = void(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
//DEPRECATED
|
||||
if (this.trace) {
|
||||
log.info('request_ledger: full parameter is deprecated');
|
||||
}
|
||||
request.message.full = true;
|
||||
request.ledgerSelect(options);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1337,6 +1329,10 @@ Remote.prototype.requestAccountTx = function(options, callback) {
|
||||
options.ledger_index_max = options.max_ledger;
|
||||
}
|
||||
|
||||
if (options.binary && options.parseBinary === void(0)) {
|
||||
options.parseBinary = true;
|
||||
}
|
||||
|
||||
Object.keys(options).forEach(function(o) {
|
||||
switch (o) {
|
||||
case 'account':
|
||||
@@ -1356,101 +1352,32 @@ Remote.prototype.requestAccountTx = function(options, callback) {
|
||||
}
|
||||
}, options);
|
||||
|
||||
function propertiesFilter(obj, transaction) {
|
||||
var properties = Object.keys(obj);
|
||||
return function(transaction) {
|
||||
var result = properties.every(function(property) {
|
||||
return transaction.tx[property] === obj[property];
|
||||
});
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
function parseBinaryTransaction(transaction) {
|
||||
var tx = { validated: transaction.validated };
|
||||
tx.meta = new SerializedObject(transaction.meta).to_json();
|
||||
tx.tx = new SerializedObject(transaction.tx_blob).to_json();
|
||||
tx.tx.ledger_index = transaction.ledger_index;
|
||||
tx.tx.hash = Transaction.from_json(tx.tx).hash();
|
||||
return tx;
|
||||
};
|
||||
|
||||
function accountTxFilter(fn) {
|
||||
if (typeof fn !== 'function') {
|
||||
throw new Error('Missing filter function');
|
||||
request.once('success', function(res) {
|
||||
if (options.parseBinary) {
|
||||
res.transactions = res.transactions.map(Remote.parseBinaryTransaction);
|
||||
}
|
||||
request.emit('transactions', res);
|
||||
});
|
||||
|
||||
var self = this;
|
||||
|
||||
function filterHandler() {
|
||||
var listeners = self.listeners('success');
|
||||
|
||||
self.removeAllListeners('success');
|
||||
|
||||
self.once('success', function(res) {
|
||||
if (options.parseBinary) {
|
||||
res.transactions = res.transactions.map(parseBinaryTransaction);
|
||||
}
|
||||
|
||||
if (fn !== Boolean) {
|
||||
res.transactions = res.transactions.filter(fn);
|
||||
}
|
||||
|
||||
if (typeof options.map === 'function') {
|
||||
res.transactions = res.transactions.map(options.map);
|
||||
}
|
||||
|
||||
if (typeof options.reduce === 'function') {
|
||||
res.transactions = res.transactions.reduce(options.reduce);
|
||||
}
|
||||
|
||||
if (typeof options.pluck === 'string') {
|
||||
res = res[options.pluck];
|
||||
}
|
||||
|
||||
listeners.forEach(function(listener) {
|
||||
listener.call(self, res);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
this.once('request', filterHandler);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
request.filter = accountTxFilter;
|
||||
|
||||
if (typeof options.parseBinary !== 'boolean') {
|
||||
options.parseBinary = true;
|
||||
}
|
||||
|
||||
if (options.binary || (options.map || options.reduce)) {
|
||||
options.filter = options.filter || Boolean;
|
||||
}
|
||||
|
||||
if (options.filter) {
|
||||
switch (options.filter) {
|
||||
case 'inbound':
|
||||
request.filter(propertiesFilter({ Destination: options.account }));
|
||||
break;
|
||||
case 'outbound':
|
||||
request.filter(propertiesFilter({ Account: options.account }));
|
||||
break;
|
||||
default:
|
||||
if (typeof options.filter === 'object') {
|
||||
options.filter = propertiesFilter(options.filter);
|
||||
}
|
||||
|
||||
request.filter(options.filter);
|
||||
}
|
||||
}
|
||||
|
||||
request.callback(callback);
|
||||
request.callback(callback, 'transactions');
|
||||
|
||||
return request;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Object} transaction
|
||||
* @return {Transaction}
|
||||
*/
|
||||
|
||||
Remote.parseBinaryTransaction = function(transaction) {
|
||||
var tx = { validated: transaction.validated };
|
||||
tx.meta = new SerializedObject(transaction.meta).to_json();
|
||||
tx.tx = new SerializedObject(transaction.tx_blob).to_json();
|
||||
tx.tx.ledger_index = transaction.ledger_index;
|
||||
tx.tx.hash = Transaction.from_json(tx.tx).hash();
|
||||
return tx;
|
||||
};
|
||||
|
||||
/**
|
||||
* Request the overall transaction history.
|
||||
*
|
||||
@@ -1589,10 +1516,14 @@ Remote.prototype.requestSubmit = function(callback) {
|
||||
* @api private
|
||||
*/
|
||||
|
||||
Remote.prototype._serverPrepareSubscribe = function(callback) {
|
||||
Remote.prototype._serverPrepareSubscribe = function(server, callback) {
|
||||
var self = this;
|
||||
var feeds = [ 'ledger', 'server' ];
|
||||
|
||||
if (typeof server === 'function') {
|
||||
callback = server;
|
||||
}
|
||||
|
||||
if (this._transaction_subs) {
|
||||
feeds.push('transactions');
|
||||
}
|
||||
@@ -1613,11 +1544,17 @@ Remote.prototype._serverPrepareSubscribe = function(callback) {
|
||||
self.emit('random', utils.hexToArray(message.random));
|
||||
}
|
||||
|
||||
self._handleLedgerClosed(message);
|
||||
self._handleLedgerClosed(message, server);
|
||||
|
||||
self.emit('subscribed');
|
||||
};
|
||||
|
||||
request.on('error', function(err) {
|
||||
if (self.trace) {
|
||||
log.info('Initial server subscribe failed', err);
|
||||
}
|
||||
});
|
||||
|
||||
request.once('success', serverSubscribed);
|
||||
|
||||
self.emit('prepare_subscribe', request);
|
||||
@@ -2261,7 +2198,7 @@ Remote.prototype.createTransaction = function(type, options) {
|
||||
*/
|
||||
|
||||
Remote.prototype.feeTx = function(units) {
|
||||
var server = this._getServer();
|
||||
var server = this.getServer();
|
||||
|
||||
if (!server) {
|
||||
throw new Error('No connected servers');
|
||||
@@ -2280,7 +2217,7 @@ Remote.prototype.feeTx = function(units) {
|
||||
*/
|
||||
|
||||
Remote.prototype.feeTxUnit = function() {
|
||||
var server = this._getServer();
|
||||
var server = this.getServer();
|
||||
|
||||
if (!server) {
|
||||
throw new Error('No connected servers');
|
||||
@@ -2299,7 +2236,7 @@ Remote.prototype.feeTxUnit = function() {
|
||||
*/
|
||||
|
||||
Remote.prototype.reserve = function(owner_count) {
|
||||
var server = this._getServer();
|
||||
var server = this.getServer();
|
||||
|
||||
if (!server) {
|
||||
throw new Error('No connected servers');
|
||||
|
||||
@@ -134,7 +134,9 @@ function Server(remote, opts) {
|
||||
}
|
||||
});
|
||||
|
||||
self._request(self._remote.requestServerInfo());
|
||||
var serverInfoRequest = self._remote.requestServerInfo();
|
||||
serverInfoRequest.on('error', function() { });
|
||||
self._request(serverInfoRequest);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -407,7 +409,7 @@ Server.prototype.connect = function() {
|
||||
if (ws === self._ws) {
|
||||
self.emit('socket_open');
|
||||
// Subscribe to events
|
||||
self._request(self._remote._serverPrepareSubscribe());
|
||||
self._request(self._remote._serverPrepareSubscribe(self));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -292,7 +292,7 @@ describe('Amount', function() {
|
||||
assert.strictEqual('0/111/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', Amount.from_json('0/111/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_text_full());
|
||||
});
|
||||
it('Parse 0.0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', function () {
|
||||
assert.strictEqual('0/XRP/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', Amount.from_json('0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_text_full());
|
||||
assert.strictEqual('0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', Amount.from_json('0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_text_full());
|
||||
});
|
||||
it('Parse native 0 human', function () {
|
||||
assert.strictEqual('0/XRP', Amount.from_json('0').to_human_full());
|
||||
@@ -337,7 +337,7 @@ describe('Amount', function() {
|
||||
assert.strictEqual('0/111/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', Amount.from_json('0/111/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_human_full());
|
||||
});
|
||||
it('Parse 0.0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh human', function () {
|
||||
assert.strictEqual('0/XRP/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', Amount.from_json('0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_human_full());
|
||||
assert.strictEqual('0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh', Amount.from_json('0/12D/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh').to_human_full());
|
||||
});
|
||||
});
|
||||
describe('Amount to_json', function() {
|
||||
|
||||
@@ -40,8 +40,8 @@ describe('Currency', function() {
|
||||
});
|
||||
it('from_json("1D2").to_human()', function() {
|
||||
var r = currency.from_json("1D2");
|
||||
assert(!r.is_valid());
|
||||
assert.strictEqual('XRP', r.to_json());
|
||||
assert(r.is_valid());
|
||||
assert.strictEqual('1D2', r.to_json());
|
||||
});
|
||||
it('from_json("XAU").to_json() hex', function() {
|
||||
var r = currency.from_json("XAU");
|
||||
|
||||
@@ -1546,7 +1546,7 @@ describe('OrderBook', function() {
|
||||
]
|
||||
|
||||
|
||||
book.once('model', function(model) {
|
||||
book.on('model', function(model) {
|
||||
assert.deepEqual(model, expected);
|
||||
assert.strictEqual(book._synchronized, true);
|
||||
done();
|
||||
|
||||
Reference in New Issue
Block a user