lamassu-server/packages/server/lib/coinatmradar/coinatmradar.js
2025-05-12 15:35:00 +01:00

171 lines
4.7 KiB
JavaScript

const axios = require('axios')
const _ = require('lodash/fp')
const db = require('../db')
const configManager = require('../new-config-manager')
const complianceTriggers = require('../compliance-triggers')
const logger = require('../logger')
const plugins = require('../plugins')
const { getOperatorId } = require('../operator')
const TIMEOUT = 10000
const MAX_CONTENT_LENGTH = 2000
const COIN_ATM_RADAR_URL = process.env.COIN_ATM_RADAR_URL
// How long a machine can be down before it's considered offline
const STALE_INTERVAL = '2 minutes'
module.exports = { update }
function mapCoin(rates, deviceId, settings, cryptoCode) {
const config = settings.config
const buildedRates = plugins(settings, deviceId).buildRates(rates)[
cryptoCode
] || { cashIn: null, cashOut: null }
const commissions = configManager.getCommissions(cryptoCode, deviceId, config)
const coinAtmRadar = configManager.getCoinAtmRadar(config)
const showCommissions = coinAtmRadar.commissions
const cashInFee = showCommissions ? commissions.cashIn / 100 : null
const cashOutFee = showCommissions ? commissions.cashOut / 100 : null
const cashInFixedFee = showCommissions ? commissions.fixedFee : null
const cashOutFixedFee = showCommissions ? commissions.cashOutFixedFee : null
const cashInRate = showCommissions
? _.invoke('cashIn.toNumber', buildedRates)
: null
const cashOutRate = showCommissions
? _.invoke('cashOut.toNumber', buildedRates)
: null
return {
cryptoCode,
cashInFee,
cashOutFee,
cashInFixedFee,
cashOutFixedFee,
cashInRate,
cashOutRate,
}
}
function mapIdentification(config) {
const triggers = configManager.getTriggers(config)
return {
isPhone: complianceTriggers.hasPhone(triggers),
isPalmVein: false,
isPhoto: complianceTriggers.hasFacephoto(triggers),
isIdDocScan: complianceTriggers.hasIdScan(triggers),
isFingerprint: false,
}
}
function mapMachine(rates, settings, machineRow) {
const deviceId = machineRow.device_id
const config = settings.config
const coinAtmRadar = configManager.getCoinAtmRadar(config)
const triggers = configManager.getTriggers(config)
const locale = configManager.getLocale(deviceId, config)
const cashOutConfig = configManager.getCashOut(deviceId, config)
const cashOutEnabled = cashOutConfig.active ? cashOutConfig.active : false
const lastOnline = machineRow.last_online.toISOString()
const status = machineRow.stale ? 'online' : 'offline'
const showLimitsAndVerification = coinAtmRadar.limitsAndVerification
const cashLimit = showLimitsAndVerification
? _.get('threshold', complianceTriggers.getCashLimit(triggers)) || Infinity
: null
const cryptoCurrencies = locale.cryptoCurrencies
const identification = mapIdentification(config)
const coins = _.map(
_.partial(mapCoin, [rates, deviceId, settings]),
cryptoCurrencies,
)
return {
machineId: deviceId,
address: {
streetAddress: null,
city: null,
region: null,
postalCode: null,
country: null,
},
location: {
name: null,
url: null,
phone: null,
},
status,
lastOnline,
cashIn: true,
cashOut: cashOutEnabled,
manufacturer: 'lamassu',
cashInTxLimit: cashLimit,
cashOutTxLimit: cashLimit,
cashInDailyLimit: cashLimit,
cashOutDailyLimit: cashLimit,
fiatCurrency: locale.fiatCurrency,
identification,
coins,
}
}
function getMachines(rates, settings) {
const sql = `select device_id, last_online, now() - last_online < $1 as stale from devices
where display=TRUE and
paired=TRUE
order by created`
return db
.any(sql, [STALE_INTERVAL])
.then(_.map(_.partial(mapMachine, [rates, settings])))
}
function sendRadar(data) {
const url = COIN_ATM_RADAR_URL
if (_.isEmpty(url)) {
return Promise.reject(new Error('Missing coinAtmRadar url!'))
}
const config = {
url,
method: 'post',
data,
timeout: TIMEOUT,
maxContentLength: MAX_CONTENT_LENGTH,
}
return axios.default(config).then(r => logger.info(r.status))
}
function mapRecord(rates, settings) {
const timestamp = new Date().toISOString()
return Promise.all([
getMachines(rates, settings),
getOperatorId('coinatmradar'),
]).then(([machines, operatorId]) => {
return {
operatorId: operatorId,
operator: {
name: null,
phone: null,
email: null,
},
timestamp,
machines,
}
})
}
function update(rates, settings) {
const coinAtmRadar = configManager.getCoinAtmRadar(settings.config)
if (!coinAtmRadar.active) return Promise.resolve()
return mapRecord(rates, settings)
.then(sendRadar)
.catch(err => logger.error(`Failure to update CoinATMRadar`, err))
}