Skip to content

Commit

Permalink
Update getBalances to use getTrustlines
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Clark committed Jun 24, 2015
1 parent d2df75d commit 47a87f3
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 285 deletions.
3 changes: 2 additions & 1 deletion src/api/common/index.js
Expand Up @@ -10,5 +10,6 @@ module.exports = {
dropsToXrp: utils.dropsToXrp,
xrpToDrops: utils.xrpToDrops,
toRippledAmount: utils.toRippledAmount,
wrapCatch: utils.wrapCatch
wrapCatch: utils.wrapCatch,
composeAsync: utils.composeAsync
};
13 changes: 12 additions & 1 deletion src/api/common/utils.js
Expand Up @@ -31,9 +31,20 @@ function wrapCatch(asyncFunction: () => void): () => void {
};
}

function composeAsync(wrapper, callback) {
return function(error, data) {
if (error) {
callback(error);
return;
}
callback(null, wrapper(data));
};
}

module.exports = {
dropsToXrp,
xrpToDrops,
toRippledAmount,
wrapCatch
wrapCatch,
composeAsync
};
183 changes: 31 additions & 152 deletions src/api/ledger/balances.js
@@ -1,164 +1,43 @@
/* globals Promise: true */
/* eslint-disable valid-jsdoc */
'use strict';
const _ = require('lodash');
const async = require('async');
const utils = require('./utils');
const getTrustlines = require('./trustlines').getTrustlines;
const validate = utils.common.validate;
const composeAsync = utils.common.composeAsync;
const dropsToXrp = utils.common.dropsToXrp;

const DefaultPageLimit = 200;
function getXRPBalance(remote, address, ledgerVersion, callback) {
remote.requestAccountInfo({account: address, ledger: ledgerVersion},
composeAsync((data) => dropsToXrp(data.account_data.Balance), callback));
}

function parseBalanceAmount(trustline) {
return {
currency: trustline.specification.currency,
counterparty: trustline.specification.counterparty,
value: trustline.state.balance
};
}

function formatBalances(balances) {
const xrpBalance = {
currency: 'XRP',
value: balances[0]
};
return [xrpBalance].concat(balances[1].map(parseBalanceAmount));
}

/**
* Request the balances for a given account
*
* Notes:
* In order to use paging, you must provide at least ledger as a query
* parameter. Additionally, any limit lower than 10 will be bumped up to 10.
*
* @url
* @param {RippleAddress} request.params.account
* - account to retrieve balances for
*
* @query
* @param {String ISO 4217 Currency Code} [request.query.currency]
* - only request balances with given currency
* @param {RippleAddress} [request.query.counterparty]
* - only request balances with given counterparty
* @param {String} [request.query.marker] - start position in response paging
* @param {Number String} [request.query.limit] - max results per response
* @param {Number String} [request.query.ledger] - identifier
*
*/
function getBalances(account, options, callback) {
validate.address(account);
validate.options(options);

const self = this;

const currencyRE = new RegExp(options.currency ?
('^' + options.currency.toUpperCase() + '$') : /./);

function getXRPBalance() {
const promise = new Promise(function(resolve, reject) {
const accountInfoRequest = self.remote.requestAccountInfo({
account: account,
ledger: utils.parseLedger(options.ledger)
});

const lines = [];
accountInfoRequest.once('error', reject);
accountInfoRequest.once('success', function(result) {
lines.push({
value: utils.common.dropsToXrp(result.account_data.Balance),
currency: 'XRP',
counterparty: ''
});

result.lines = lines;
resolve(result);
});

accountInfoRequest.request();
});

return promise;
}

function getLineBalances(prevResult) {
const isAggregate = options.limit === undefined;
if (prevResult && (!isAggregate || !prevResult.marker)) {
return Promise.resolve(prevResult);
}

const promise = new Promise(function(resolve, reject) {
let accountLinesRequest;
let marker;
let ledger;
let limit;

if (prevResult) {
marker = prevResult.marker;
limit = prevResult.limit;
ledger = prevResult.ledger_index;
} else {
marker = options.marker;
limit = options.limit || DefaultPageLimit;
ledger = utils.parseLedger(options.ledger);
}

accountLinesRequest = self.remote.requestAccountLines({
account: account,
marker: marker,
limit: limit,
ledger: ledger
});

if (options.counterparty) {
accountLinesRequest.message.peer = options.counterparty;
}

accountLinesRequest.once('error', reject);
accountLinesRequest.once('success', function(nextResult) {
const lines = [];
nextResult.lines.forEach(function(line) {
if (options.frozen && !line.freeze) {
return;
}

if (currencyRE.test(line.currency)) {
lines.push({
value: line.balance,
currency: line.currency,
counterparty: line.account
});
}
});

nextResult.lines = prevResult ? prevResult.lines.concat(lines) : lines;
resolve(nextResult);
});
accountLinesRequest.request();
});

return promise.then(getLineBalances);
}

function getAccountBalances() {
if (options.counterparty || options.frozen) {
return getLineBalances();
}

if (options.currency) {
if (options.currency === 'XRP') {
return getXRPBalance();
}
return getLineBalances();
}

return Promise.all([getXRPBalance(), getLineBalances()])
.then(function(values) {
const xrpBalance = values[0].lines[0];
const lineBalances = values[1];
lineBalances.lines.unshift(xrpBalance);
return Promise.resolve(lineBalances);
});
}

function respondWithBalances(result) {
let balances = {};

if (result.marker) {
balances.marker = result.marker;
}

balances.limit = result.limit;
balances.ledger = result.ledger_index;
balances.balances = result.lines;

callback(null, balances);
}

getAccountBalances()
.then(respondWithBalances)
.catch(callback);
const ledgerVersion = options.ledgerVersion
|| this.remote.getLedgerSequence();
async.parallel([
_.partial(getXRPBalance, this.remote, account, ledgerVersion),
_.partial(getTrustlines.bind(this), account, options)
], composeAsync(formatBalances, callback));
}

module.exports.getBalances = getBalances;

0 comments on commit 47a87f3

Please sign in to comment.