From 9f31b31af8250d2dd0278ca953ec4be593cb1cee Mon Sep 17 00:00:00 2001 From: Josh Harvey Date: Sun, 27 Mar 2016 18:33:21 +0200 Subject: [PATCH] updated some files to standard formatting --- lib/plugins.js | 534 ++++++++++++++++++++++++------------------------- lib/routes.js | 226 ++++++++++----------- 2 files changed, 375 insertions(+), 385 deletions(-) diff --git a/lib/plugins.js b/lib/plugins.js index cdc3b0e3..104e14cf 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -1,52 +1,53 @@ -'use strict'; +'use strict' -var _ = require('lodash'); -var async = require('async'); -var logger = require('./logger'); +var _ = require('lodash') +var async = require('async') +var BigNumber = require('bignumber.js') +var logger = require('./logger') +var argv = require('minimist')(process.argv.slice(2)) -var argv = require('minimist')(process.argv.slice(2)); +var tradeInterval = null -var SATOSHI_FACTOR = 1e8; -var POLLING_RATE = 60 * 1000; // poll each minute -var REAP_RATE = 2 * 1000; -var PENDING_TIMEOUT = 70 * 1000; +var SATOSHI_FACTOR = 1e8 +var POLLING_RATE = 60 * 1000 // poll each minute +var REAP_RATE = 2 * 1000 +var PENDING_TIMEOUT = 70 * 1000 -if (argv.timeout) PENDING_TIMEOUT = argv.timeout / 1000; +if (argv.timeout) PENDING_TIMEOUT = argv.timeout / 1000 // TODO: might have to update this if user is allowed to extend monitoring time -var DEPOSIT_TIMEOUT = 130 * 1000; +var DEPOSIT_TIMEOUT = 130 * 1000 -var db = null; +var db = null -var cryptoCoins = null; +var cryptoCoins = null -var tickerPlugins = {}; -var traderPlugin = null; -var walletPlugins = {}; -var idVerifierPlugin = null; -var infoPlugin = null; +var tickerPlugins = {} +var traderPlugin = null +var walletPlugins = {} +var idVerifierPlugin = null +var infoPlugin = null -var currentlyUsedPlugins = {}; +var currentlyUsedPlugins = {} -var cachedConfig = null; -var deviceCurrency = 'USD'; +var cachedConfig = null +var deviceCurrency = 'USD' -var lastBalances = {}; -var lastRates = {}; +var lastBalances = {} +var lastRates = {} -var tradesQueue = []; +var tradesQueue = [] // that's basically a constructor -exports.init = function init(databaseHandle) { +exports.init = function init (databaseHandle) { if (!databaseHandle) { - throw new Error('\'db\' is required'); + throw new Error('\'db\' is required') } - db = databaseHandle; -}; - -function loadPlugin(name, config) { + db = databaseHandle +} +function loadPlugin (name, config) { // plugins definitions var moduleMethods = { ticker: ['ticker'], @@ -54,94 +55,95 @@ function loadPlugin(name, config) { wallet: ['balance', 'sendBitcoins', 'newAddress'], idVerifier: ['verifyUser', 'verifyTransaction'], info: ['checkAddress'] - }; + } - var plugin = null; + var plugin = null // each used plugin MUST be installed try { - plugin = require('lamassu-' + name); + plugin = require('lamassu-' + name) } catch (_) { throw new Error(name + ' module is not installed. ' + - 'Try running \'npm install --save lamassu-' + name + '\' first'); + 'Try running \'npm install --save lamassu-' + name + '\' first') } // each plugin MUST implement those if (typeof plugin.SUPPORTED_MODULES !== 'undefined') { - if (plugin.SUPPORTED_MODULES === 'string') - plugin.SUPPORTED_MODULES = [plugin.SUPPORTED_MODULES]; + if (plugin.SUPPORTED_MODULES === 'string') { + plugin.SUPPORTED_MODULES = [plugin.SUPPORTED_MODULES] + } } - if (!(plugin.SUPPORTED_MODULES instanceof Array)) + if (!(plugin.SUPPORTED_MODULES instanceof Array)) { throw new Error('\'' + name + '\' fails to implement *required* ' + - '\'SUPPORTED_MODULES\' constant'); + '\'SUPPORTED_MODULES\' constant') + } - plugin.SUPPORTED_MODULES.forEach(function(moduleName) { - moduleMethods[moduleName].forEach(function(methodName) { + plugin.SUPPORTED_MODULES.forEach(function (moduleName) { + moduleMethods[moduleName].forEach(function (methodName) { if (typeof plugin[methodName] !== 'function') { throw new Error('\'' + name + '\' declares \'' + moduleName + - '\', but fails to implement \'' + methodName + '\' method'); + '\', but fails to implement \'' + methodName + '\' method') } - }); - }); + }) + }) // each plugin SHOULD implement those - if (typeof plugin.NAME === 'undefined') + if (typeof plugin.NAME === 'undefined') { logger.warn(new Error('\'' + name + - '\' fails to implement *recommended* \'NAME\' field')); + '\' fails to implement *recommended* \'NAME\' field')) + } if (typeof plugin.config !== 'function') { logger.warn(new Error('\'' + name + - '\' fails to implement *recommended* \'config\' method')); - plugin.config = function() {}; + '\' fails to implement *recommended* \'config\' method')) + plugin.config = function () {} } else if (config !== null) { - plugin.config(config); // only when plugin supports it, and config is passed + plugin.config(config) // only when plugin supports it, and config is passed } - return plugin; + return plugin } -function loadOrConfigPlugin(pluginHandle, pluginType, cryptoCoin, currency, +function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCoin, currency, onChangeCallback) { - if (!cryptoCoin) cryptoCoin = 'any' var currentName = cryptoCoin === 'any' || cryptoCoin === 'BTC' ? cachedConfig.exchanges.plugins.current[pluginType] : cachedConfig.exchanges.plugins.current[cryptoCoin][pluginType] - var pluginChanged = currentlyUsedPlugins[cryptoCoin][pluginType] !== currentName; + var pluginChanged = currentlyUsedPlugins[cryptoCoin][pluginType] !== currentName - if (!currentName) pluginHandle = null; + if (!currentName) pluginHandle = null else { // some plugins may be disabled var pluginConfig = cachedConfig.exchanges.plugins.settings[currentName] || - {}; + {} - if (currency) pluginConfig.currency = currency; + if (currency) pluginConfig.currency = currency - if (pluginHandle && !pluginChanged) pluginHandle.config(pluginConfig); + if (pluginHandle && !pluginChanged) pluginHandle.config(pluginConfig) else { - pluginHandle = loadPlugin(currentName, pluginConfig); - currentlyUsedPlugins[cryptoCoin] ||= {} + pluginHandle = loadPlugin(currentName, pluginConfig) + currentlyUsedPlugins[cryptoCoin] = currentlyUsedPlugins[cryptoCoin] || {} currentlyUsedPlugins[cryptoCoin][pluginType] = currentName logger.debug('[%s] plugin(%s) loaded: %s', cryptoCoin, pluginType, pluginHandle.NAME || - currentName); + currentName) } } - if (typeof onChangeCallback === 'function') - onChangeCallback(pluginHandle, currency); + if (typeof onChangeCallback === 'function') onChangeCallback(pluginHandle, currency) - return pluginHandle; + return pluginHandle } -exports.configure = function configure(config) { +exports.configure = function configure (config) { if (config.exchanges.settings.lowBalanceMargin < 1) { - throw new Error('\'settings.lowBalanceMargin\' has to be >= 1'); + throw new Error('\'settings.lowBalanceMargin\' has to be >= 1') } - cachedConfig = config; - deviceCurrency = config.exchanges.settings.currency; - cryptoCoins = config.exchanges.settings.coins || ['BTC']; + cachedConfig = config + deviceCurrency = config.exchanges.settings.currency + cryptoCoins = config.exchanges.settings.coins || ['BTC'] cryptoCoins.forEach(function (cryptoCoin) { // TICKER [required] configure (or load) @@ -150,11 +152,11 @@ exports.configure = function configure(config) { 'ticker', cryptoCoin, deviceCurrency, // device currency - function onTickerChange(newTicker) { - tickerPlugins[cryptoCoin] = newTicker; - pollRate(cryptoCoin); + function onTickerChange (newTicker) { + tickerPlugins[cryptoCoin] = newTicker + pollRate(cryptoCoin) } - ); + ) // WALLET [required] configure (or load) loadOrConfigPlugin( @@ -162,11 +164,11 @@ exports.configure = function configure(config) { 'transfer', cryptoCoin, null, - function onWalletChange(newWallet) { - walletPlugins[cryptoCoin] = newWallet; - pollBalance(cryptoCoin); + function onWalletChange (newWallet) { + walletPlugins[cryptoCoin] = newWallet + pollBalance(cryptoCoin) } - ); + ) }) // TRADER [optional] configure (or load) @@ -175,33 +177,33 @@ exports.configure = function configure(config) { 'trade', null, null, - function onTraderChange(newTrader) { - traderPlugin = newTrader; - if (newTrader === null) stopTrader(); - else startTrader(); + function onTraderChange (newTrader) { + traderPlugin = newTrader + if (newTrader === null) stopTrader() + else startTrader() } - ); + ) // ID VERIFIER [optional] configure (or load) idVerifierPlugin = loadOrConfigPlugin( idVerifierPlugin, 'idVerifier' - ); + ) infoPlugin = loadOrConfigPlugin( infoPlugin, 'info' - ); -}; -exports.getConfig = function getConfig() { - return cachedConfig; -}; + ) +} +exports.getConfig = function getConfig () { + return cachedConfig +} -exports.logEvent = function event(session, rawEvent) { - db.recordDeviceEvent(session, rawEvent); -}; +exports.logEvent = function event (session, rawEvent) { + db.recordDeviceEvent(session, rawEvent) +} -function buildCartridges(cartridges, virtualCartridges, rec) { +function buildCartridges (cartridges, virtualCartridges, rec) { return { cartridges: [ { @@ -215,110 +217,107 @@ function buildCartridges(cartridges, virtualCartridges, rec) { ], virtualCartridges: virtualCartridges, id: rec.id - }; + } } -exports.pollQueries = function pollQueries(session, cb) { - var cartridges = cachedConfig.exchanges.settings.cartridges; - if (!cartridges) return cb(null, {}); - var virtualCartridges = cachedConfig.exchanges.settings.virtualCartridges; +exports.pollQueries = function pollQueries (session, cb) { + var cartridges = cachedConfig.exchanges.settings.cartridges + if (!cartridges) return cb(null, {}) + var virtualCartridges = cachedConfig.exchanges.settings.virtualCartridges - db.cartridgeCounts(session, function(err, result) { - if (err) return cb(err); + db.cartridgeCounts(session, function (err, result) { + if (err) return cb(err) return cb(null, { cartridges: buildCartridges(cartridges, virtualCartridges, result) - }); - }); -}; - -function _sendCoins(toAddress, cryptoUnits, cryptoCoin, cb) { - var walletPlugin = walletPlugins[cryptoCoin] - var transactionFee = cachedConfig.exchanges.settings.transactionFee; - if (cryptoCoin === 'BTC') - walletPlugin.sendBitcoins(toAddress, cryptoUnits, transactionFee, cb); - else - walletPlugin.sendCoins(toAddress, cryptoUnits, cryptoCoin, transactionFee, cb); + }) + }) } -function executeTx(session, tx, authority, cb) { - db.addOutgoingTx(session, tx, function(err, toSend) { - if (err) return cb(err); - var cryptoUnitsToSend = toSend.cryptoUnits; - if (cryptoUnitsToSend === 0) - return cb(null, {statusCode: 204, txId: tx.txId, txHash: null}); +function _sendCoins (toAddress, cryptoUnits, cryptoCoin, cb) { + var walletPlugin = walletPlugins[cryptoCoin] + var transactionFee = cachedConfig.exchanges.settings.transactionFee + if (cryptoCoin === 'BTC') { + walletPlugin.sendBitcoins(toAddress, cryptoUnits, transactionFee, cb) + } else { + walletPlugin.sendCoins(toAddress, cryptoUnits, cryptoCoin, transactionFee, cb) + } +} - _sendCoins(tx.toAddress, cryptoUnitsToSend, function(_err, txHash) { - var fee = null; // Need to fill this out in plugins - if (_err) toSend = {cryptoUnits: new BigNumber(0), fiat: 0}; - db.sentCoins(session, tx, authority, toSend, fee, _err, txHash); +function executeTx (session, tx, authority, cb) { + db.addOutgoingTx(session, tx, function (err, toSend) { + if (err) return cb(err) + var cryptoUnitsToSend = toSend.cryptoUnits + if (cryptoUnitsToSend === 0) { + return cb(null, {statusCode: 204, txId: tx.txId, txHash: null}) + } - if (_err) return cb(_err); + _sendCoins(tx.toAddress, cryptoUnitsToSend, function (_err, txHash) { + var fee = null // Need to fill this out in plugins + if (_err) toSend = {cryptoUnits: new BigNumber(0), fiat: 0} + db.sentCoins(session, tx, authority, toSend, fee, _err, txHash) - var cryptoCoin = tx.coin - ? tx.coin.unitCode - : 'BTC' + if (_err) return cb(_err) - pollBalance('BTC'); + pollBalance('BTC') cb(null, { statusCode: 201, // Created txHash: txHash, txId: tx.txId - }); - }); - }); + }) + }) + }) } -function reapOutgoingTx(session, tx) { - executeTx(session, tx, 'timeout', function(err) { - if (err) logger.error(err); - }); +function reapOutgoingTx (session, tx) { + executeTx(session, tx, 'timeout', function (err) { + if (err) logger.error(err) + }) } -function reapTx(row) { - var session = {fingerprint: row.device_fingerprint, id: row.session_id}; +function reapTx (row) { + var session = {fingerprint: row.device_fingerprint, id: row.session_id} var tx = { fiat: 0, satoshis: row.satoshis, toAddress: row.to_address, currencyCode: row.currency_code, incoming: row.incoming - }; - if (!row.incoming) reapOutgoingTx(session, tx); + } + if (!row.incoming) reapOutgoingTx(session, tx) } -function reapTxs() { - db.removeOldPending(DEPOSIT_TIMEOUT); +function reapTxs () { + db.removeOldPending(DEPOSIT_TIMEOUT) // NOTE: No harm in processing old pending tx, we don't need to wait for // removeOldPending to complete. - db.pendingTxs(PENDING_TIMEOUT, function(err, results) { - if (err) return logger.warn(err); - var rows = results.rows; - var rowCount = rows.length; + db.pendingTxs(PENDING_TIMEOUT, function (err, results) { + if (err) return logger.warn(err) + var rows = results.rows + var rowCount = rows.length for (var i = 0; i < rowCount; i++) { - var row = rows[i]; - reapTx(row); + var row = rows[i] + reapTx(row) } - }); + }) } // TODO: Run these in parallel and return success -exports.trade = function trade(session, rawTrade, cb) { - +exports.trade = function trade (session, rawTrade, cb) { // TODO: move this to DB, too // add bill to trader queue (if trader is enabled) if (traderPlugin) { tradesQueue.push({ currency: rawTrade.currency, satoshis: rawTrade.satoshis - }); + }) } if (!rawTrade.toAddress) { - var newRawTrade = _.cloneDeep(rawTrade); - newRawTrade.toAddress = 'remit'; - return db.recordBill(session, newRawTrade, cb); + var newRawTrade = _.cloneDeep(rawTrade) + newRawTrade.toAddress = 'remit' + return db.recordBill(session, newRawTrade, cb) } var tx = { @@ -327,23 +326,23 @@ exports.trade = function trade(session, rawTrade, cb) { satoshis: 0, toAddress: rawTrade.toAddress, currencyCode: rawTrade.currency - }; + } async.parallel([ async.apply(db.addOutgoingPending, session, tx.currencyCode, tx.toAddress), async.apply(db.recordBill, session, rawTrade) - ], cb); -}; + ], cb) +} -exports.sendCoins = function sendCoins(session, rawTx, cb) { - executeTx(session, rawTx, 'machine', cb); -}; +exports.sendCoins = function sendCoins (session, rawTx, cb) { + executeTx(session, rawTx, 'machine', cb) +} -exports.cashOut = function cashOut(session, tx, cb) { +exports.cashOut = function cashOut (session, tx, cb) { var tmpInfo = { label: 'TX ' + Date.now(), account: 'deposit' - }; + } var cryptoCoin = tx.coin ? tx.coin.unitCode @@ -351,61 +350,61 @@ exports.cashOut = function cashOut(session, tx, cb) { var walletPlugin = walletPlugins[cryptoCoin] - walletPlugin.newAddress(tmpInfo, function(err, address) { - if (err) return cb(err); + walletPlugin.newAddress(tmpInfo, function (err, address) { + if (err) return cb(err) - var newTx = _.clone(tx); - newTx.toAddress = address; - db.addInitialIncoming(session, newTx, function(_err) { - cb(_err, address); - }); - }); -}; + var newTx = _.clone(tx) + newTx.toAddress = address + db.addInitialIncoming(session, newTx, function (_err) { + cb(_err, address) + }) + }) +} -exports.dispenseAck = function dispenseAck(session, rec) { - db.addDispense(session, rec.tx, rec.cartridges); -}; +exports.dispenseAck = function dispenseAck (session, rec) { + db.addDispense(session, rec.tx, rec.cartridges) +} -exports.fiatBalance = function fiatBalance(cryptoCoin) { - var rawRate = exports.getDeviceRate(cryptoCoin).rates.ask; - var commission = cachedConfig.exchanges.settings.commission; +exports.fiatBalance = function fiatBalance (cryptoCoin) { + var rawRate = exports.getDeviceRate(cryptoCoin).rates.ask + var commission = cachedConfig.exchanges.settings.commission var lastBalance = lastBalances[cryptoCoin] - if (!rawRate || !lastBalance) return null; + if (!rawRate || !lastBalance) return null // The rate is actually our commission times real rate. - var rate = commission * rawRate; + var rate = commission * rawRate // `lowBalanceMargin` is our safety net. It's a number > 1, and we divide // all our balances by it to provide a safety margin. - var lowBalanceMargin = cachedConfig.exchanges.settings.lowBalanceMargin; + var lowBalanceMargin = cachedConfig.exchanges.settings.lowBalanceMargin // `balance.transferBalance` is the balance of our transfer account (the one // we use to send Bitcoins to clients) in satoshis. - var transferBalance = lastBalance.transferBalance; + var transferBalance = lastBalance.transferBalance - var fiatTransferBalance = (transferBalance * rate) / lowBalanceMargin; + var fiatTransferBalance = (transferBalance * rate) / lowBalanceMargin - return fiatTransferBalance; -}; + return fiatTransferBalance +} /* * Polling livecycle */ -exports.startPolling = function startPolling() { - executeTrades(); +exports.startPolling = function startPolling () { + executeTrades() cryptoCoins.forEach(function (coin) { - setInterval(async.apply(pollBalance, coin), POLLING_RATE); - setInterval(async.apply(pollRate, coin), POLLING_RATE); - }); + setInterval(async.apply(pollBalance, coin), POLLING_RATE) + setInterval(async.apply(pollRate, coin), POLLING_RATE) + }) - setInterval(reapTxs, REAP_RATE); + setInterval(reapTxs, REAP_RATE) - startTrader(); -}; + startTrader() +} -function startTrader() { +function startTrader () { // Always start trading, even if we don't have a trade exchange configured, // since configuration can always change in `Trader#configure`. // `Trader#executeTrades` returns early if we don't have a trade exchange @@ -414,144 +413,133 @@ function startTrader() { tradeInterval = setInterval( executeTrades, cachedConfig.exchanges.settings.tradeInterval - ); + ) } } -function stopTrader() { +function stopTrader () { if (tradeInterval) { - clearInterval(tradeInterval); - tradeInterval = null; - tradesQueue = []; + clearInterval(tradeInterval) + tradeInterval = null + tradesQueue = [] } } -function pollBalance(cryptoCoin, cb) { - logger.debug('[%s] collecting balance', cryptoCoin); +function pollBalance (cryptoCoin, cb) { + logger.debug('[%s] collecting balance', cryptoCoin) var walletPlugin = walletPlugins[cryptoCoin] - var jobs = { - transferBalance: walletPlugin.balance - }; - walletPlugin.balance(function(err, balance) { + walletPlugin.balance(function (err, balance) { if (err) { - logger.error(err); - return cb && cb(err); + logger.error(err) + return cb && cb(err) } - logger.debug('[%s] Balance update:', cryptoCoin, balance); - balance.timestamp = Date.now(); - lastBalances[cryptoCoin] = balance; + logger.debug('[%s] Balance update:', cryptoCoin, balance) + balance.timestamp = Date.now() + lastBalances[cryptoCoin] = balance - return cb && cb(null, lastBalances); - }); + return cb && cb(null, lastBalances) + }) } -function pollRates (cb) { - var polls = cryptoCoins.map(function (cryptoCoin) { - async.apply(pollRate, cryptoCoin) - }); +function pollRate (cryptoCoin, cb) { + logger.debug('[%s] polling for rates (%s)', cryptoCoin, tickerPlugin.NAME) + var tickerPlugin = tickerPlugins[cryptoCoin] - async.parallel(polls, cb); -} - -function pollRate(cryptoCoin, cb) { - logger.debug('[%s] polling for rates (%s)', cryptoCoin, tickerPlugin.NAME); - var tickerPlugin = tickerPlugins[cryptoCoin]; - - tickerPlugin.ticker(deviceCurrency, function(err, resRates) { + tickerPlugin.ticker(deviceCurrency, function (err, resRates) { if (err) { - logger.error(err); - return cb && cb(err); + logger.error(err) + return cb && cb(err) } - logger.debug('got rates: %j', resRates); - resRates.timestamp = new Date(); - lastRates[cryptoCoin] = resRates; + logger.debug('got rates: %j', resRates) + resRates.timestamp = new Date() + lastRates[cryptoCoin] = resRates - return cb && cb(null, lastRates); - }); + return cb && cb(null, lastRates) + }) } /* * Getters | Helpers */ -exports.getDeviceRate = function getDeviceRate(cryptoCoin) { - if (!lastRates[cryptoCoin]) return null; +exports.getDeviceRate = function getDeviceRate (cryptoCoin) { + if (!lastRates[cryptoCoin]) return null var lastRate = lastRates[cryptoCoin] - if (!lastRate) return null; + if (!lastRate) return null - return lastRate[deviceCurrency]; -}; + return lastRate[deviceCurrency] +} -exports.getBalance = function getBalance(cryptoCoin) { +exports.getBalance = function getBalance (cryptoCoin) { var lastBalance = lastBalances[cryptoCoin] - if (!lastBalance) return null; + if (!lastBalance) return null - return lastBalance.transferBalance; -}; + return lastBalance.transferBalance +} /* * Trader functions */ -function purchase(trade, cb) { - traderPlugin.purchase(trade.satoshis, null, function(err) { - if (err) return cb(err); - pollBalance('BTC'); - if (typeof cb === 'function') cb(); - }); +function purchase (trade, cb) { + traderPlugin.purchase(trade.satoshis, null, function (err) { + if (err) return cb(err) + pollBalance('BTC') + if (typeof cb === 'function') cb() + }) } -function consolidateTrades() { +function consolidateTrades () { // NOTE: value in satoshis stays the same no matter the currency var consolidatedTrade = { currency: deviceCurrency, - satoshis: tradesQueue.reduce(function(prev, current) { - return prev + current.satoshis; + satoshis: tradesQueue.reduce(function (prev, current) { + return prev + current.satoshis }, 0) - }; - - tradesQueue = []; - - logger.debug('consolidated: ', JSON.stringify(consolidatedTrade)); - return consolidatedTrade; -} - -function executeTrades() { - if (!traderPlugin) return; - - logger.debug('checking for trades'); - - var trade = consolidateTrades(); - - if (trade.satoshis === 0) { - logger.debug('rejecting 0 trade'); - return; } - logger.debug('making a trade: %d', trade.satoshis / SATOSHI_FACTOR); - purchase(trade, function(err) { + tradesQueue = [] + + logger.debug('consolidated: ', JSON.stringify(consolidatedTrade)) + return consolidatedTrade +} + +function executeTrades () { + if (!traderPlugin) return + + logger.debug('checking for trades') + + var trade = consolidateTrades() + + if (trade.satoshis === 0) { + logger.debug('rejecting 0 trade') + return + } + + logger.debug('making a trade: %d', trade.satoshis / SATOSHI_FACTOR) + purchase(trade, function (err) { if (err) { - tradesQueue.push(trade); - if (err.name !== 'orderTooSmall') logger.error(err); + tradesQueue.push(trade) + if (err.name !== 'orderTooSmall') logger.error(err) } - }); + }) } /* * ID Verifier functions */ -exports.verifyUser = function verifyUser(data, cb) { - idVerifierPlugin.verifyUser(data, cb); -}; +exports.verifyUser = function verifyUser (data, cb) { + idVerifierPlugin.verifyUser(data, cb) +} -exports.verifyTx = function verifyTx(data, cb) { - idVerifierPlugin.verifyTransaction(data, cb); -}; +exports.verifyTx = function verifyTx (data, cb) { + idVerifierPlugin.verifyTransaction(data, cb) +} exports.getCryptoCoins = function getCryptoCoins () { - return cryptoCoins; + return cryptoCoins } diff --git a/lib/routes.js b/lib/routes.js index f937a609..8f21d706 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -1,29 +1,32 @@ -'use strict'; +'use strict' -var logger = require('./logger'); +var logger = require('./logger') -var mock = false; +var mock = false -var plugins; -var lamassuConfig; +var plugins +var lamassuConfig module.exports = { init: init, getFingerprint: getFingerprint -}; +} // Make sure these are higher than polling interval // or there will be a lot of errors -var STALE_TICKER = 180000; -var STALE_BALANCE = 180000; +var STALE_TICKER = 180000 +var STALE_BALANCE = 180000 var pids = {} var reboots = {} function buildRates () { - var cryptoCoins = plugins.getCryptoCoins(); - var cashInCommission = settings.commission; - var cashOutCommission = settings.fiatCommission || cashInCommission; + var cryptoCoins = plugins.getCryptoCoins() + var config = plugins.getConfig() + var settings = config.exchanges.settings + + var cashInCommission = settings.commission + var cashOutCommission = settings.fiatCommission || cashInCommission var rates = {} cryptoCoins.forEach(function (coin) { @@ -38,7 +41,7 @@ function buildRates () { } function buildBalances () { - var cryptoCoins = plugins.getCryptoCoins(); + var cryptoCoins = plugins.getCryptoCoins() var balances = {} cryptoCoins.forEach(function (coin) { @@ -46,20 +49,19 @@ function buildBalances () { balances[coin] = balance }) - return balance - + return balances } -function poll(req, res) { +function poll (req, res) { var fingerprint = getFingerprint(req) var pid = req.query.pid pids[fingerprint] = {pid: pid, ts: Date.now()} - logger.debug('poll request from: %s', fingerprint); + logger.debug('poll request from: %s', fingerprint) - var rateRec = plugins.getDeviceRate(); - var balanceRec = plugins.getBalance(); + var rateRec = plugins.getDeviceRate() + var balanceRec = plugins.getBalance() var rates = buildRates() var balances = buildBalances() @@ -67,39 +69,38 @@ function poll(req, res) { // `rateRec` and `balanceRec` are both objects, so there's no danger // of misinterpreting rate or balance === 0 as 'Server initializing'. if (!rateRec || !balanceRec) { - return res.json({err: 'Server initializing'}); + return res.json({err: 'Server initializing'}) } - var now = Date.now(); + var now = Date.now() if (now - rateRec.timestamp > STALE_TICKER) { - return res.json({err: 'Stale ticker'}); + return res.json({err: 'Stale ticker'}) } if (now - balanceRec.timestamp > STALE_BALANCE) { - return res.json({err: 'Stale balance'}); + return res.json({err: 'Stale balance'}) } - var rate = rateRec.rates.ask; - var fiatRate = rateRec.rates.bid || rate; + var rate = rateRec.rates.ask + var fiatRate = rateRec.rates.bid || rate - if (rate === null) return res.json({err: 'No rate available'}); - if (!fiatRate) - logger.warn('No bid rate, using ask rate'); + if (rate === null) return res.json({err: 'No rate available'}) + if (!fiatRate) logger.warn('No bid rate, using ask rate') - var fiatBalance = plugins.fiatBalance(); + var fiatBalance = plugins.fiatBalance() if (fiatBalance === null) { - logger.warn('No balance available.'); - return res.json({err: 'No balance available'}); + logger.warn('No balance available.') + return res.json({err: 'No balance available'}) } - var config = plugins.getConfig(); - var settings = config.exchanges.settings; - var complianceSettings = settings.compliance; - var fiatCommission = settings.fiatCommission || settings.commission; + var config = plugins.getConfig() + var settings = config.exchanges.settings + var complianceSettings = settings.compliance + var fiatCommission = settings.fiatCommission || settings.commission - plugins.pollQueries(session(req), function(err, results) { - if (err) return logger.error(err); - var cartridges = results.cartridges; + plugins.pollQueries(session(req), function (err, results) { + if (err) return logger.error(err) + var cartridges = results.cartridges var reboot = reboots[fingerprint] === pid @@ -112,30 +113,31 @@ function poll(req, res) { txLimit: parseInt(complianceSettings.maximum.limit, 10), idVerificationEnabled: complianceSettings.idVerificationEnabled, cartridges: cartridges, - twoWayMode: cartridges ? true : false, + twoWayMode: !!cartridges, zeroConfLimit: settings.zeroConfLimit, fiatTxLimit: settings.fiatTxLimit, reboot: reboot, rates: rates, balances: balances - }; + } - if (response.idVerificationEnabled) - response.idVerificationLimit = complianceSettings.idVerificationLimit; + if (response.idVerificationEnabled) { + response.idVerificationLimit = complianceSettings.idVerificationLimit + } - res.json(response); - }); + res.json(response) + }) } -function trade(req, res) { - plugins.trade(session(req), req.body, function(err) { - var statusCode = err ? 500 : 201; - res.json(statusCode, {err: err}); - }); +function trade (req, res) { + plugins.trade(session(req), req.body, function (err) { + var statusCode = err ? 500 : 201 + res.json(statusCode, {err: err}) + }) } -function send(req, res) { - plugins.sendCoins(session(req), req.body, function(err, status) { +function send (req, res) { + plugins.sendCoins(session(req), req.body, function (err, status) { // TODO: use status.statusCode here after confirming machine compatibility // FIX: (joshm) set txHash to status.txId instead of previous status.txHash which wasn't being set // Need to clean up txHash vs txId @@ -144,109 +146,109 @@ function send(req, res) { err: err && err.message, txHash: status && status.txHash, txId: status && status.txId - }); - }); + }) + }) } -function cashOut(req, res) { - logger.info({tx: req.body, cmd: 'cashOut'}); - plugins.cashOut(session(req), req.body, function(err, bitcoinAddress) { - if (err) logger.error(err); +function cashOut (req, res) { + logger.info({tx: req.body, cmd: 'cashOut'}) + plugins.cashOut(session(req), req.body, function (err, bitcoinAddress) { + if (err) logger.error(err) res.json({ err: err && err.message, errType: err && err.name, bitcoinAddress: bitcoinAddress - }); - }); + }) + }) } -function dispenseAck(req, res) { - plugins.dispenseAck(session(req), req.body); - res.json(200); +function dispenseAck (req, res) { + plugins.dispenseAck(session(req), req.body) + res.json(200) } -function deviceEvent(req, res) { - plugins.logEvent(session(req), req.body); - res.json({err: null}); +function deviceEvent (req, res) { + plugins.logEvent(session(req), req.body) + res.json({err: null}) } -function verifyUser(req, res) { - if (mock) return res.json({success: true}); +function verifyUser (req, res) { + if (mock) return res.json({success: true}) plugins.verifyUser(req.body, function (err, idResult) { if (err) { - logger.error(err); - return res.json({err: 'Verification failed'}); + logger.error(err) + return res.json({err: 'Verification failed'}) } - res.json(idResult); - }); + res.json(idResult) + }) } -function verifyTx(req, res) { - if (mock) return res.json({success: true}); +function verifyTx (req, res) { + if (mock) return res.json({success: true}) plugins.verifyTx(req.body, function (err, idResult) { if (err) { - logger.error(err); - return res.json({err: 'Verification failed'}); + logger.error(err) + return res.json({err: 'Verification failed'}) } - res.json(idResult); - }); + res.json(idResult) + }) } -function pair(req, res) { - var token = req.body.token; - var name = req.body.name; +function pair (req, res) { + var token = req.body.token + var name = req.body.name lamassuConfig.pair( token, getFingerprint(req), name, - function(err) { - if (err) return res.json(500, { err: err.message }); + function (err) { + if (err) return res.json(500, { err: err.message }) - res.json(200); + res.json(200) } - ); + ) } -function raqia(req, res) { - var raqiaCreds; +function raqia (req, res) { + var raqiaCreds try { - var raqiaRec = require('../raqia.json'); - raqiaCreds = raqiaRec[getFingerprint(req)].apiKeys[0]; - } catch(ex) { - raqiaCreds = null; + var raqiaRec = require('../raqia.json') + raqiaCreds = raqiaRec[getFingerprint(req)].apiKeys[0] + } catch (ex) { + raqiaCreds = null } - res.json(raqiaCreds || {}); + res.json(raqiaCreds || {}) } -function init(localConfig) { - lamassuConfig = localConfig.lamassuConfig; - plugins = localConfig.plugins; - mock = localConfig.mock; +function init (localConfig) { + lamassuConfig = localConfig.lamassuConfig + plugins = localConfig.plugins + mock = localConfig.mock - var authMiddleware = localConfig.authMiddleware; - var reloadConfigMiddleware = localConfig.reloadConfigMiddleware; - var app = localConfig.app; + var authMiddleware = localConfig.authMiddleware + var reloadConfigMiddleware = localConfig.reloadConfigMiddleware + var app = localConfig.app var localApp = localConfig.localApp - app.get('/poll', authMiddleware, reloadConfigMiddleware, poll); + app.get('/poll', authMiddleware, reloadConfigMiddleware, poll) - app.post('/trade', authMiddleware, trade); - app.post('/send', authMiddleware, send); + app.post('/trade', authMiddleware, trade) + app.post('/send', authMiddleware, send) - app.post('/cash_out', authMiddleware, cashOut); - app.post('/dispense_ack', authMiddleware, dispenseAck); + app.post('/cash_out', authMiddleware, cashOut) + app.post('/dispense_ack', authMiddleware, dispenseAck) - app.post('/event', authMiddleware, deviceEvent); - app.post('/verify_user', authMiddleware, verifyUser); - app.post('/verify_transaction', authMiddleware, verifyTx); - app.post('/pair', pair); - app.get('/raqia', raqia); + app.post('/event', authMiddleware, deviceEvent) + app.post('/verify_user', authMiddleware, verifyUser) + app.post('/verify_transaction', authMiddleware, verifyTx) + app.post('/pair', pair) + app.get('/raqia', raqia) localApp.get('/pid', function (req, res) { var machineFingerprint = req.query.fingerprint @@ -268,14 +270,14 @@ function init(localConfig) { res.send(200) }) - return app; + return app } -function session(req) { - return {fingerprint: getFingerprint(req), id: req.get('session-id')}; +function session (req) { + return {fingerprint: getFingerprint(req), id: req.get('session-id')} } -function getFingerprint(req) { +function getFingerprint (req) { return (typeof req.connection.getPeerCertificate === 'function' && - req.connection.getPeerCertificate().fingerprint) || 'unknown'; + req.connection.getPeerCertificate().fingerprint) || 'unknown' }