diff --git a/lib/plugins.js b/lib/plugins.js index c5585d8e..c21bab22 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -21,7 +21,9 @@ const machineLoader = require('./machine-loader') const customers = require('./customers') const coinUtils = require('./coin-utils') -const mapValuesWithKey = _.mapValues.convert({cap: false}) +const mapValuesWithKey = _.mapValues.convert({ + cap: false +}) const TRADE_TTL = 2 * T.minutes const STALE_TICKER = 3 * T.minutes @@ -132,8 +134,9 @@ function plugins (settings, deviceId) { if (!config.cashOutEnabled) return Promise.resolve() - const denominations = [ config.topCashOutDenomination, - config.bottomCashOutDenomination ] + const denominations = [config.topCashOutDenomination, + config.bottomCashOutDenomination + ] const virtualCassettes = [config.virtualCashOutDenomination] return Promise.all([dbm.cassetteCounts(deviceId), cashOutHelper.redeemableTxs(deviceId, excludeTxId)]) @@ -162,17 +165,20 @@ function plugins (settings, deviceId) { } } catch (err) { logger.error(err) - return {cassettes, virtualCassettes} + return { + cassettes, + virtualCassettes + } } }) } function fetchCurrentConfigVersion () { const sql = `select id from user_config - where type=$1 - and valid - order by id desc - limit 1` + where type=$1 + and valid + order by id desc + limit 1` return db.one(sql, ['config']) .then(row => row.id) @@ -243,8 +249,10 @@ function plugins (settings, deviceId) { return Promise.all([ db.none(`insert into machine_pings(device_id, device_time) values($1, $2) - ON CONFLICT (device_id) DO UPDATE SET device_time = $2`, [deviceId, deviceTime]), - db.none(pgp.helpers.update(devices, null, 'devices') + 'WHERE device_id = ${deviceId}', { deviceId }) + ON CONFLICT (device_id) DO UPDATE SET device_time = $2`, [deviceId, deviceTime]), + db.none(pgp.helpers.update(devices, null, 'devices') + 'WHERE device_id = ${deviceId}', { + deviceId + }) ]) } @@ -270,8 +278,9 @@ function plugins (settings, deviceId) { function dispenseAck (tx) { const config = configManager.machineScoped(deviceId, settings.config) - const cassettes = [ config.topCashOutDenomination, - config.bottomCashOutDenomination ] + const cassettes = [config.topCashOutDenomination, + config.bottomCashOutDenomination + ] return dbm.addDispense(deviceId, tx, cassettes) } @@ -300,7 +309,10 @@ function plugins (settings, deviceId) { const shiftedRate = rate.shift(-unitScale) const fiatTransferBalance = balance.mul(shiftedRate).div(lowBalanceMargin) - return {timestamp: balanceRec.timestamp, balance: fiatTransferBalance.truncated().toString()} + return { + timestamp: balanceRec.timestamp, + balance: fiatTransferBalance.truncated().toString() + } }) } @@ -355,15 +367,15 @@ function plugins (settings, deviceId) { } const body = ` - - Transaction ID: ${tx.id} - - Status: ${status} - - Machine name: ${machineName} - - ${direction} - - ${fiat} - - ${crypto} - - Customer: ${customerName} - ${phone} - ` + - Transaction ID: ${tx.id} + - Status: ${status} + - Machine name: ${machineName} + - ${direction} + - ${fiat} + - ${crypto} + - Customer: ${customerName} + ${phone} + ` const subject = `A transaction just happened` return { @@ -387,7 +399,10 @@ function plugins (settings, deviceId) { sms: { body: `${subject} - ${body}` }, - email: { subject, body } + email: { + subject, + body + } } return sendTransactionMessage(rec) } @@ -399,16 +414,16 @@ function plugins (settings, deviceId) { function pongClear () { const sql = `delete from server_events - where event_type=$1 - and created < now() - interval $2` + where event_type=$1 + and created < now() - interval $2` db.none(sql, ['ping', PONG_TTL]) .catch(logger.error) } /* - * Trader functions - */ + * Trader functions + */ function buy (rec) { return buyAndSell(rec, true) @@ -489,7 +504,10 @@ function plugins (settings, deviceId) { const fiatCode = config.fiatCurrency const cryptoCodes = config.cryptoCurrencies - return cryptoCodes.map(cryptoCode => ({fiatCode, cryptoCode})) + return cryptoCodes.map(cryptoCode => ({ + fiatCode, + cryptoCode + })) }) const tradesPromises = _.uniq(_.flatten(lists)) @@ -527,6 +545,12 @@ function plugins (settings, deviceId) { return execute(settings, tradeEntry.cryptoAtoms, tradeEntry.fiatCode, tradeEntry.cryptoCode) .then(() => recordTrade(tradeEntry)) + .catch(err => { + return recordTrade(tradeEntry, err) + .then(() => { + throw err + }) + }) } function convertBigNumFields (obj) { @@ -541,14 +565,23 @@ function plugins (settings, deviceId) { return _.mapKeys(convertKey, mapValuesWithKey(convert, obj)) } - function recordTrade (_tradeEntry) { + function mergeTradeEntryAndError (tradeEntry, error) { + if (error && error.message) { + return Object.assign({}, tradeEntry, { + error: error.message.slice(0, 200) + }) + } + return tradeEntry + } + + function recordTrade (_tradeEntry, error) { const massage = _.flow( - _.pick(['cryptoCode', 'cryptoAtoms', 'fiatCode', 'type']), + mergeTradeEntryAndError, + _.pick(['cryptoCode', 'cryptoAtoms', 'fiatCode', 'type', 'error']), convertBigNumFields, _.mapKeys(_.snakeCase) ) - - const tradeEntry = massage(_tradeEntry) + const tradeEntry = massage(_tradeEntry, error) const sql = pgp.helpers.insert(tradeEntry, null, 'trades') return db.none(sql) } @@ -585,27 +618,36 @@ function plugins (settings, deviceId) { const cashOutEnabled = config.cashOutEnabled const cashInAlert = device.cashbox > config.cashInAlertThreshold - ? {code: 'CASH_BOX_FULL', machineName, deviceId: device.deviceId, notes: device.cashbox} + ? { + code: 'CASH_BOX_FULL', + machineName, + deviceId: device.deviceId, + notes: device.cashbox + } : null const cassette1Alert = cashOutEnabled && device.cassette1 < config.cashOutCassette1AlertThreshold - ? {code: 'LOW_CASH_OUT', + ? { + code: 'LOW_CASH_OUT', cassette: 1, machineName, deviceId: device.deviceId, notes: device.cassette1, denomination: denomination1, - fiatCode} + fiatCode + } : null const cassette2Alert = cashOutEnabled && device.cassette2 < config.cashOutCassette2AlertThreshold - ? {code: 'LOW_CASH_OUT', + ? { + code: 'LOW_CASH_OUT', cassette: 2, machineName, deviceId: device.deviceId, notes: device.cassette2, denomination: denomination2, - fiatCode} + fiatCode + } : null return _.compact([cashInAlert, cassette1Alert, cassette2Alert]) @@ -636,7 +678,12 @@ function plugins (settings, deviceId) { const cryptoAlertThreshold = config.cryptoAlertThreshold return BN(fiatBalance.balance).lt(cryptoAlertThreshold) - ? {code: 'LOW_CRYPTO_BALANCE', cryptoCode, fiatBalance, fiatCode} + ? { + code: 'LOW_CRYPTO_BALANCE', + cryptoCode, + fiatBalance, + fiatCode + } : null } @@ -683,7 +730,7 @@ function plugins (settings, deviceId) { logger.debug('[%s] Swept address with tx: %s', cryptoCode, txHash) const sql = `update cash_out_txs set swept='t' - where id=$1` + where id=$1` return db.none(sql, row.id) } @@ -693,7 +740,7 @@ function plugins (settings, deviceId) { function sweepHd () { const sql = `select id, crypto_code, hd_index from cash_out_txs - where hd_index is not null and not swept and status in ('confirmed', 'instant')` + where hd_index is not null and not swept and status in ('confirmed', 'instant')` return db.any(sql) .then(rows => Promise.all(rows.map(sweepHdRow))) diff --git a/migrations/1542811343367-add-error-to-trades.js b/migrations/1542811343367-add-error-to-trades.js new file mode 100644 index 00000000..c46a84d7 --- /dev/null +++ b/migrations/1542811343367-add-error-to-trades.js @@ -0,0 +1,15 @@ +var db = require('./db') + +exports.up = function (next) { + const sql = [ + 'alter table trades add column error text', + ] + + db.multi(sql, next) +} + +exports.down = function (next) { + const sql = ['alter table trades drop column error'] + + db.multi(sql, next) +} diff --git a/package-lock.json b/package-lock.json index a11148f6..fc3451ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3281,7 +3281,7 @@ "dependencies": { "doctrine": { "version": "1.5.0", - "resolved": "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": {