diff --git a/bin/lamassu-display-config.js b/bin/lamassu-display-config.js
index ed29d4b7..2b4cb00b 100644
--- a/bin/lamassu-display-config.js
+++ b/bin/lamassu-display-config.js
@@ -1,4 +1,4 @@
-const settingsLoader = require('../lib/settings-loader')
+const settingsLoader = require('../lib/new-settings-loader')
const pp = require('../lib/pp')
settingsLoader.loadLatest()
@@ -9,4 +9,4 @@ settingsLoader.loadLatest()
.catch(e => {
console.log(e.stack)
process.exit(1)
- })
+ })
\ No newline at end of file
diff --git a/bin/lamassu-send-coins b/bin/lamassu-send-coins
index 51ac67b3..9d829002 100755
--- a/bin/lamassu-send-coins
+++ b/bin/lamassu-send-coins
@@ -1,7 +1,7 @@
#!/usr/bin/env node
-const settingsLoader = require('../lib/settings-loader')
-const configManager = require('../lib/config-manager')
+const settingsLoader = require('../lib/new-settings-loader')
+const configManager = require('../lib/new-config-manager')
const wallet = require('../lib/wallet')
const coinUtils = require('../lib/coin-utils')
const BN = require('../lib/bn')
@@ -40,8 +40,7 @@ console.log('Loading ticker...')
settingsLoader.loadLatest()
.then(settings => {
- const config = configManager.unscoped(settings.config)
- const fiatCode = config.fiatCurrency
+ const fiatCode = configManager.getGlobalLocale(settings.config).fiatCurrency
return wallet.isStrictAddress(settings, cryptoCode, toAddress)
.then(isValid => {
diff --git a/dev/coinatmradar.js b/dev/coinatmradar.js
index 62161f25..4f4cf1be 100644
--- a/dev/coinatmradar.js
+++ b/dev/coinatmradar.js
@@ -1,14 +1,13 @@
const car = require('../lib/coinatmradar/coinatmradar')
const plugins = require('../lib/plugins')
-require('../lib/settings-loader').loadLatest()
+require('../lib/new-settings-loader').loadLatest()
.then(settings => {
const pi = plugins(settings)
- const config = settings.config
return pi.getRawRates()
.then(rates => {
- return car.update({rates, config}, settings)
+ return car.update(rates, settings)
.then(require('../lib/pp')('DEBUG100'))
.catch(console.log)
.then(() => process.exit())
diff --git a/dev/config.js b/dev/config.js
index 51dc2c3e..97a2d33a 100644
--- a/dev/config.js
+++ b/dev/config.js
@@ -1,8 +1,8 @@
-const settingsLoader = require('../lib/settings-loader')
-const configManager = require('../lib/config-manager')
+const settingsLoader = require('../lib/new-settings-loader')
+const configManager = require('../lib/new-config-manager')
settingsLoader.loadLatest()
.then(settings => {
const config = settings.config
- require('../lib/pp')('config')(configManager.all('cryptoCurrencies', config))
+ require('../lib/pp')('config')(configManager.getAllCryptoCurrencies(config))
})
diff --git a/dev/plugins.js b/dev/plugins.js
index aea224a3..30488199 100644
--- a/dev/plugins.js
+++ b/dev/plugins.js
@@ -1,5 +1,5 @@
const plugins = require('../lib/plugins')
-const settingsLoader = require('../lib/settings-loader')
+const settingsLoader = require('../lib/new-settings-loader')
const pp = require('../lib/pp')
settingsLoader.loadLatest()
diff --git a/dev/send-message.js b/dev/send-message.js
index f72f6faf..dcf8acd2 100644
--- a/dev/send-message.js
+++ b/dev/send-message.js
@@ -1,6 +1,6 @@
require('es6-promise').polyfill()
-var config = require('../lib/settings-loader')
+var config = require('../lib/new-settings-loader')
var sms = require('../lib/sms')
var rand = Math.floor(Math.random() * 1e6)
diff --git a/lib/app.js b/lib/app.js
index a5661ebf..293f5b74 100644
--- a/lib/app.js
+++ b/lib/app.js
@@ -6,8 +6,9 @@ const argv = require('minimist')(process.argv.slice(2))
const routes = require('./routes')
const logger = require('./logger')
const poller = require('./poller')
-const settingsLoader = require('./settings-loader')
-const configManager = require('./config-manager')
+const settingsLoader = require('./new-settings-loader')
+const configManager = require('./new-config-manager')
+const complianceTriggers = require('./compliance-triggers')
const options = require('./options')
const ofac = require('./ofac/index')
const ofacUpdate = require('./ofac/update')
@@ -43,9 +44,10 @@ function run () {
function loadSanctions (settings) {
return Promise.resolve()
.then(() => {
- const config = configManager.unscoped(settings.config)
+ const triggers = configManager.getTriggers(settings.config)
+ const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
- if (!config.sanctionsVerificationActive) return
+ if (!compatTriggers.sanctions) return
logger.info('Loading sanctions DB...')
return ofacUpdate.update()
diff --git a/lib/cash-in/cash-in-tx.js b/lib/cash-in/cash-in-tx.js
index 0ef93717..2c8da04f 100644
--- a/lib/cash-in/cash-in-tx.js
+++ b/lib/cash-in/cash-in-tx.js
@@ -6,8 +6,8 @@ const blacklist = require('../blacklist')
const db = require('../db')
const plugins = require('../plugins')
const logger = require('../logger')
-const settingsLoader = require('../settings-loader')
-const configManager = require('../config-manager')
+const settingsLoader = require('../new-settings-loader')
+// const configManager = require('../new-config-manager')
const cashInAtomic = require('./cash-in-atomic')
const cashInLow = require('./cash-in-low')
@@ -26,7 +26,9 @@ function post (machineTx, pi) {
return Promise.all([settingsLoader.loadLatest(), checkForBlacklisted(updatedTx)])
.then(([{ config }, blacklistItems]) => {
- const rejectAddressReuseActive = configManager.unscoped(config).rejectAddressReuseActive
+ // TODO new-admin: addressReuse doesnt exist
+ // const rejectAddressReuseActive = configManager.unscoped(config).rejectAddressReuseActive
+ const rejectAddressReuseActive = true
if (_.some(it => it.created_by_operator === true)(blacklistItems)) {
blacklisted = true
@@ -123,8 +125,9 @@ function postProcess (r, pi, isBlacklisted, addressReuse) {
})
.then(sendRec => {
settingsLoader.loadLatest().then(it => {
- const config = configManager.unscoped(it.config)
- if (config.rejectAddressReuseActive) {
+ // TODO new-admin: addressReuse doesnt exist
+ // const config = configManager.unscoped(it.config)
+ if (true) {
blacklist.addToUsedAddresses(r.tx.toAddress, r.tx.cryptoCode)
.catch(err => logger.error('Failure adding to addressReuse', err))
}
diff --git a/lib/coinatmradar/coinatmradar.js b/lib/coinatmradar/coinatmradar.js
index 78acf983..f774a4c4 100644
--- a/lib/coinatmradar/coinatmradar.js
+++ b/lib/coinatmradar/coinatmradar.js
@@ -7,7 +7,8 @@ const fs = pify(require('fs'))
const db = require('../db')
const mnemonicHelpers = require('../mnemonic-helpers')
-const configManager = require('../config-manager')
+const configManager = require('../new-config-manager')
+const complianceTriggers = require('../compliance-triggers')
const options = require('../options')
const logger = require('../logger')
const plugins = require('../plugins')
@@ -18,19 +19,21 @@ const MAX_CONTENT_LENGTH = 2000
// How long a machine can be down before it's considered offline
const STALE_INTERVAL = '2 minutes'
-module.exports = { update, mapRecord }
+module.exports = { update }
-function mapCoin (info, deviceId, settings, cryptoCode) {
- const config = info.config
- const rates = plugins(settings, deviceId).buildRates(info.rates)[cryptoCode] || { cashIn: null, cashOut: null }
- const cryptoConfig = configManager.scoped(cryptoCode, deviceId, config)
- const unscoped = configManager.unscoped(config)
- const showRates = unscoped.coinAtmRadarShowRates
+function mapCoin (rates, deviceId, settings, cryptoCode) {
+ const config = settings.config
+ const buildedRates = plugins(settings, deviceId).buildRates(rates)[cryptoCode] || { cashIn: null, cashOut: null }
- const cashInFee = showRates ? cryptoConfig.cashInCommission / 100 : null
- const cashOutFee = showRates ? cryptoConfig.cashOutCommission / 100 : null
- const cashInRate = showRates ? _.invoke('cashIn.toNumber', rates) : null
- const cashOutRate = showRates ? _.invoke('cashOut.toNumber', rates) : 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 cashInRate = showCommissions ? _.invoke('cashIn.toNumber', buildedRates) : null
+ const cashOutRate = showCommissions ? _.invoke('cashOut.toNumber', buildedRates) : null
return {
cryptoCode,
@@ -41,33 +44,51 @@ function mapCoin (info, deviceId, settings, cryptoCode) {
}
}
-function mapIdentification (info, deviceId) {
- const machineConfig = configManager.machineScoped(deviceId, info.config)
+function mapIdentification (config, deviceId) {
+ const triggers = configManager.getTriggers(deviceId, config)
+ const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
return {
- isPhone: machineConfig.smsVerificationActive,
+ isPhone: !!compatTriggers.sms,
isPalmVein: false,
- isPhoto: false,
- isIdDocScan: machineConfig.idCardDataVerificationActive,
+ isPhoto: !!compatTriggers.facephoto,
+ isIdDocScan: !!compatTriggers.idData,
isFingerprint: false
}
}
-function mapMachine (info, settings, machineRow) {
+function mapMachine (rates, settings, machineRow) {
const deviceId = machineRow.device_id
- const config = info.config
- const machineConfig = configManager.machineScoped(deviceId, config)
+ const config = settings.config
+
+ const coinAtmRadar = configManager.getCoinAtmRadar(config)
+ const triggers = configManager.getTriggers(deviceId, config)
+ const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
+ const locale = configManager.getLocale(deviceId, config)
+ const cashOutConfig = configManager.getCashOut(deviceId, config)
const lastOnline = machineRow.last_online.toISOString()
const status = machineRow.stale ? 'online' : 'offline'
+ const showSupportedCryptocurrencies = coinAtmRadar.supportedCryptocurrencies
+ const showSupportedFiat = coinAtmRadar.supportedFiat
+ const showSupportedBuySellDirection = coinAtmRadar.supportedBuySellDirection
+ const showLimitsAndVerification = coinAtmRadar.limitsAndVerification
- const cashLimit = machineConfig.hardLimitVerificationActive
- ? machineConfig.hardLimitVerificationThreshold
- : Infinity
+ // TODO new-admin: this is relaying info with backwards compatible triggers
+ // need to get in touch with coinatmradar before updating this
+ const cashLimit = showLimitsAndVerification ? (
+ !!compatTriggers.block
+ ? compatTriggers.block
+ : Infinity ) : null
- const cryptoCurrencies = machineConfig.cryptoCurrencies
- const identification = mapIdentification(info, deviceId)
- const coins = _.map(_.partial(mapCoin, [info, deviceId, settings]), cryptoCurrencies)
+ const cryptoCurrencies = locale.cryptoCurrencies
+ const cashInEnabled = showSupportedBuySellDirection ? true : null
+ const cashOutEnabled = showSupportedBuySellDirection ? cashOutConfig.active : null
+ const fiat = showSupportedFiat ? locale.fiatCurrency : null
+ const identification = mapIdentification(config, deviceId)
+ const coins = showSupportedCryptocurrencies ?
+ _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies)
+ : null
return {
machineId: deviceId,
@@ -85,27 +106,27 @@ function mapMachine (info, settings, machineRow) {
},
status,
lastOnline,
- cashIn: true,
- cashOut: machineConfig.cashOutEnabled,
+ cashIn: cashInEnabled,
+ cashOut: cashOutEnabled,
manufacturer: 'lamassu',
cashInTxLimit: cashLimit,
cashOutTxLimit: cashLimit,
cashInDailyLimit: cashLimit,
cashOutDailyLimit: cashLimit,
- fiatCurrency: machineConfig.fiatCurrency,
+ fiatCurrency: fiat,
identification,
coins
}
}
-function getMachines (info, settings) {
+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, [info, settings])))
+ .then(_.map(_.partial(mapMachine, [rates, settings])))
}
function sendRadar (data) {
@@ -129,9 +150,9 @@ function sendRadar (data) {
.then(r => console.log(r.status))
}
-function mapRecord (info, settings) {
+function mapRecord (rates, settings) {
const timestamp = new Date().toISOString()
- return Promise.all([getMachines(info, settings), fs.readFile(options.mnemonicPath, 'utf8')])
+ return Promise.all([getMachines(rates, settings), fs.readFile(options.mnemonicPath, 'utf8')])
.then(([machines, mnemonic]) => {
return {
operatorId: computeOperatorId(mnemonicHelpers.toEntropyBuffer(mnemonic)),
@@ -146,12 +167,12 @@ function mapRecord (info, settings) {
})
}
-function update (info, settings) {
- const config = configManager.unscoped(info.config)
+function update (rates, settings) {
+ const coinAtmRadar = configManager.getCoinAtmRadar(settings.config)
- if (!config.coinAtmRadarActive) return Promise.resolve()
+ if (!coinAtmRadar.active) return Promise.resolve()
- return mapRecord(info, settings)
+ return mapRecord(rates, settings)
.then(sendRadar)
.catch(err => logger.error(`Failure to update CoinATMRadar`, err))
}
diff --git a/lib/coinatmradar/new-coinatmradar.js b/lib/coinatmradar/new-coinatmradar.js
deleted file mode 100644
index 5c590d11..00000000
--- a/lib/coinatmradar/new-coinatmradar.js
+++ /dev/null
@@ -1,178 +0,0 @@
-const axios = require('axios')
-const _ = require('lodash/fp')
-const hkdf = require('futoin-hkdf')
-
-const pify = require('pify')
-const fs = pify(require('fs'))
-
-const db = require('../db')
-const mnemonicHelpers = require('../mnemonic-helpers')
-const configManager = require('../config-manager')
-const options = require('../options')
-const logger = require('../logger')
-const plugins = require('../plugins')
-
-const TIMEOUT = 10000
-const MAX_CONTENT_LENGTH = 2000
-
-// How long a machine can be down before it's considered offline
-const STALE_INTERVAL = '2 minutes'
-
-module.exports = { update, mapRecord }
-
-function mapCoin (info, deviceId, settings, cryptoCode) {
- const config = info.config
- const rates = plugins(settings, deviceId).buildRates(info.rates)[cryptoCode] || { cashIn: null, cashOut: null }
- const cryptoConfig = configManager.scoped(cryptoCode, deviceId, config)
- const unscoped = configManager.unscoped(config)
- const showCommissions = unscoped.coinAtmRadar.sendCommissions
-
- const cashInFee = showCommissions ? cryptoConfig.cashInCommission / 100 : null
- const cashOutFee = showCommissions ? cryptoConfig.cashOutCommission / 100 : null
- const cashInRate = showCommissions ? _.invoke('cashIn.toNumber', rates) : null
- const cashOutRate = showCommissions ? _.invoke('cashOut.toNumber', rates) : null
-
- return {
- cryptoCode,
- cashInFee,
- cashOutFee,
- cashInRate,
- cashOutRate
- }
-}
-
-function mapIdentification (info, deviceId) {
- const machineConfig = configManager.machineScoped(deviceId, info.config)
-
- return {
- isPhone: machineConfig.smsVerificationActive,
- isPalmVein: false,
- isPhoto: false,
- isIdDocScan: machineConfig.idCardDataVerificationActive,
- isFingerprint: false
- }
-}
-
-function mapMachine (info, settings, machineRow) {
- const deviceId = machineRow.device_id
- const config = info.config
- const unscoped = configManager.unscoped(config)
- const machineConfig = configManager.machineScoped(deviceId, config)
-
- const lastOnline = machineRow.last_online.toISOString()
- const status = machineRow.stale ? 'online' : 'offline'
- const showSupportedCryptocurrencies =
- unscoped.coinAtmRadar.sendSupportedCryptocurrencies
- const showSupportedFiat =
- unscoped.coinAtmRadar.sendSupportedFiat
- const showSupportedBuySellDirection =
- unscoped.coinAtmRadar.sendSupportedBuySellDirection
- const showLimitsAndVerification =
- unscoped.coinAtmRadar.sendLimitsAndVerification
-
- const cashLimit = showLimitsAndVerification ? (
- machineConfig.hardLimitVerificationActive
- ? machineConfig.hardLimitVerificationThreshold
- : Infinity ) : null
-
- const cryptoCurrencies = machineConfig.cryptoCurrencies
- const cashInEnabled = showSupportedBuySellDirection ? true : null
- const cashOutEnabled = showSupportedBuySellDirection
- ? machineConfig.cashOutEnabled
- : null
- const fiat = showSupportedFiat ? machineConfig.fiatCurrency : null
- const identification = mapIdentification(info, deviceId)
- const coins = showSupportedCryptocurrencies ?
- _.map(_.partial(mapCoin, [info, deviceId, settings]), cryptoCurrencies)
- : null
-
- return {
- machineId: deviceId,
- address: {
- streetAddress: null,
- city: null,
- region: null,
- postalCode: null,
- country: null
- },
- location: {
- name: null,
- url: null,
- phone: null
- },
- status,
- lastOnline,
- cashIn: cashInEnabled,
- cashOut: cashOutEnabled,
- manufacturer: 'lamassu',
- cashInTxLimit: cashLimit,
- cashOutTxLimit: cashLimit,
- cashInDailyLimit: cashLimit,
- cashOutDailyLimit: cashLimit,
- fiatCurrency: fiat,
- identification,
- coins
- }
-}
-
-function getMachines (info, 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, [info, settings])))
-}
-
-function sendRadar (data) {
- const url = _.get(['coinAtmRadar', 'url'], options)
-
- if (_.isEmpty(url)) {
- return Promise.reject(new Error('Missing coinAtmRadar url!'))
- }
-
- const config = {
- url,
- method: 'post',
- data,
- timeout: TIMEOUT,
- maxContentLength: MAX_CONTENT_LENGTH
- }
-
- console.log('%j', data)
-
- return axios(config)
- .then(r => console.log(r.status))
-}
-
-function mapRecord (info, settings) {
- const timestamp = new Date().toISOString()
- return Promise.all([getMachines(info, settings), fs.readFile(options.mnemonicPath, 'utf8')])
- .then(([machines, mnemonic]) => {
- return {
- operatorId: computeOperatorId(mnemonicHelpers.toEntropyBuffer(mnemonic)),
- operator: {
- name: null,
- phone: null,
- email: null
- },
- timestamp,
- machines
- }
- })
-}
-
-function update (info, settings) {
- const config = configManager.unscoped(info.config)
-
- if (!config.coinAtmRadar.active) return Promise.resolve()
-
- return mapRecord(info, settings)
- .then(sendRadar)
- .catch(err => logger.error(`Failure to update CoinATMRadar`, err))
-}
-
-function computeOperatorId (masterSeed) {
- return hkdf(masterSeed, 16, { salt: 'lamassu-server-salt', info: 'operator-id' }).toString('hex')
-}
diff --git a/lib/compliance-triggers.js b/lib/compliance-triggers.js
new file mode 100644
index 00000000..d08cfdb7
--- /dev/null
+++ b/lib/compliance-triggers.js
@@ -0,0 +1,9 @@
+const _ = require('lodash/fp')
+
+function getBackwardsCompatibleTriggers (triggers) {
+ const filtered = _.filter(_.matches({ triggerType: 'volume', cashDirection: 'both' }))(triggers)
+ const grouped = _.groupBy(_.prop('requirement'))(filtered)
+ return _.mapValues(_.compose(_.get('threshold'), _.minBy('threshold')))(grouped)
+}
+
+module.exports = { getBackwardsCompatibleTriggers}
\ No newline at end of file
diff --git a/lib/email.js b/lib/email.js
index 73c46b04..b69b2124 100644
--- a/lib/email.js
+++ b/lib/email.js
@@ -1,10 +1,13 @@
-const configManager = require('./config-manager')
+// const configManager = require('./new-config-manager')
+const logger = require('./logger')
const ph = require('./plugin-helper')
function sendMessage (settings, rec) {
return Promise.resolve()
.then(() => {
- const pluginCode = configManager.unscoped(settings.config).email
+ // TODO new-admin
+ // const pluginCode = configManager.unscoped(settings.config).email
+ const pluginCode = 'mailgun'
const plugin = ph.load(ph.EMAIL, pluginCode)
const account = settings.accounts[pluginCode]
diff --git a/lib/exchange.js b/lib/exchange.js
index a15a4b5b..10070c2b 100644
--- a/lib/exchange.js
+++ b/lib/exchange.js
@@ -1,8 +1,8 @@
-const configManager = require('./config-manager')
+const configManager = require('./new-config-manager')
const ph = require('./plugin-helper')
function lookupExchange (settings, cryptoCode) {
- const exchange = configManager.cryptoScoped(cryptoCode, settings.config).exchange
+ const exchange = configManager.getWalletSettings(cryptoCode, settings.config).exchange
if (exchange === 'no-exchange') return null
return exchange
}
diff --git a/lib/layer2.js b/lib/layer2.js
index 3376eb53..b77403da 100644
--- a/lib/layer2.js
+++ b/lib/layer2.js
@@ -1,10 +1,9 @@
-const configManager = require('./config-manager')
+const configManager = require('./new-config-manager')
const ph = require('./plugin-helper')
const _ = require('lodash/fp')
-const logger = require('./logger')
function fetch (settings, cryptoCode) {
- const plugin = configManager.cryptoScoped(cryptoCode, settings.config).layer2
+ const plugin = configManager.getWalletSettings(cryptoCode, settings.config).layer2
if (_.isEmpty(plugin) || plugin === 'no-layer2') return Promise.resolve()
@@ -34,7 +33,7 @@ function getStatus (settings, tx) {
}
function cryptoNetwork (settings, cryptoCode) {
- const plugin = configManager.cryptoScoped(cryptoCode, settings.config).layer2
+ const plugin = configManager.getWalletSettings(cryptoCode, settings.config).layer2
const layer2 = ph.load(ph.LAYER2, plugin)
const account = settings.accounts[plugin]
diff --git a/lib/machine-loader.js b/lib/machine-loader.js
index 4bce608b..37e5f11f 100644
--- a/lib/machine-loader.js
+++ b/lib/machine-loader.js
@@ -3,8 +3,8 @@ const axios = require('axios')
const db = require('./db')
const pairing = require('./pairing')
-const configManager = require('./config-manager')
-const settingsLoader = require('./settings-loader')
+const configManager = require('./new-config-manager')
+const settingsLoader = require('./new-settings-loader')
module.exports = {getMachineName, getMachines, getMachineNames, setMachine}
@@ -17,6 +17,7 @@ function getMachines () {
cassette2: r.cassette2,
pairedAt: new Date(r.created).valueOf(),
lastPing: new Date(r.last_online).valueOf(),
+ name: r.name,
// TODO: we shall start using this JSON field at some point
// location: r.location,
paired: r.paired
@@ -26,18 +27,20 @@ function getMachines () {
function getConfig (defaultConfig) {
if (defaultConfig) return Promise.resolve(defaultConfig)
- return settingsLoader.loadRecentConfig()
+ return settingsLoader.loadLatest().config
}
function getMachineNames (config) {
return Promise.all([getMachines(), getConfig(config)])
.then(([machines, config]) => {
const addName = r => {
- const machineScoped = configManager.machineScoped(r.deviceId, config)
- const name = _.defaultTo('', machineScoped.machineName)
- const cashOut = machineScoped.cashOutEnabled
- const machineModel = _.defaultTo('', machineScoped.machineModel)
- const machineLocation = _.defaultTo('', machineScoped.machineLocation)
+ const cashOutConfig = configManager.getCashOut(r.deviceId, config)
+
+ const cashOut = cashOutConfig.active
+
+ // TODO new-admin: these two fields were not ever working
+ const machineModel = ''
+ const machineLocation = ''
// TODO: obtain next fields from somewhere
const printer = null
@@ -45,7 +48,7 @@ function getMachineNames (config) {
const statuses = [{label: 'Unknown detailed status', type: 'warning'}]
const softwareVersion = ''
- return _.assign(r, {name, cashOut, machineModel, machineLocation, printer, pingTime, statuses, softwareVersion})
+ return _.assign(r, {cashOut, machineModel, machineLocation, printer, pingTime, statuses, softwareVersion})
}
return _.map(addName, machines)
@@ -63,11 +66,9 @@ function getMachineNames (config) {
* @returns {string} machine name
*/
function getMachineName (machineId) {
- return settingsLoader.loadRecentConfig()
- .then(config => {
- const machineScoped = configManager.machineScoped(machineId, config)
- return machineScoped.machineName
- })
+ const sql = 'select * from devices where device_id=$1'
+ return db.oneOrNone(sql, [machineId])
+ .then(it => it.name)
}
function resetCashOutBills (rec) {
diff --git a/lib/new-admin/admin-server.js b/lib/new-admin/admin-server.js
index 9c4e3751..0f416fff 100644
--- a/lib/new-admin/admin-server.js
+++ b/lib/new-admin/admin-server.js
@@ -59,8 +59,8 @@ apolloServer.applyMiddleware({
// cors on app for /api/register endpoint.
app.use(cors({ credentials: true, origin: devMode && 'https://localhost:3000' }))
-app.use('/id-card-photo', serveStatic(idPhotoCardBasedir, {index: false}))
-app.use('/front-camera-photo', serveStatic(frontCameraBasedir, {index: false}))
+app.use('/id-card-photo', serveStatic(idPhotoCardBasedir, { index: false }))
+app.use('/front-camera-photo', serveStatic(frontCameraBasedir, { index: false }))
app.get('/api/register', (req, res, next) => {
const otp = req.query.otp
@@ -90,7 +90,7 @@ app.get('/api/register', (req, res, next) => {
})
// Everything not on graphql or api/register is redirected to the front-end
-app.get('*', (req, res) => res.sendFile(path.resolve('client', 'build', 'index.html')))
+app.get('*', (req, res) => res.sendFile(path.resolve(__dirname, '..', '..', 'public', 'index.html')))
const certOptions = {
key: fs.readFileSync(options.keyPath),
diff --git a/lib/new-admin/config/accounts.js b/lib/new-admin/config/accounts.js
index a972a4e3..4d0a9ac4 100644
--- a/lib/new-admin/config/accounts.js
+++ b/lib/new-admin/config/accounts.js
@@ -11,7 +11,7 @@ const ID_VERIFIER = 'idVerifier'
const EMAIL = 'email'
const ZERO_CONF = 'zeroConf'
-const ACCOUNT_LIST = [
+const ALL_ACCOUNTS = [
{ code: 'bitpay', display: 'Bitpay', class: TICKER, cryptos: [BTC, BCH] },
{ code: 'kraken', display: 'Kraken', class: TICKER, cryptos: [BTC, ETH, LTC, DASH, ZEC, BCH] },
{ code: 'bitstamp', display: 'Bitstamp', class: TICKER, cryptos: [BTC, ETH, LTC, BCH] },
@@ -43,4 +43,7 @@ const ACCOUNT_LIST = [
{ code: 'mock-zero-conf', display: 'Mock 0-conf', class: ZERO_CONF, cryptos: [BTC, ZEC, LTC, DASH, BCH, ETH], dev: true }
]
+const devMode = require('minimist')(process.argv.slice(2)).dev
+const ACCOUNT_LIST = devMode ? ALL_ACCOUNTS : _.filter(it => !it.dev)(ALL_ACCOUNTS)
+
module.exports = { ACCOUNT_LIST }
diff --git a/lib/new-admin/funding.js b/lib/new-admin/funding.js
index c896a4bb..cbb32b37 100644
--- a/lib/new-admin/funding.js
+++ b/lib/new-admin/funding.js
@@ -1,11 +1,10 @@
const _ = require('lodash/fp')
const BN = require('../bn')
-const settingsLoader = require('../settings-loader')
-const configManager = require('../config-manager')
+const settingsLoader = require('../new-settings-loader')
+const configManager = require('../new-config-manager')
const wallet = require('../wallet')
const ticker = require('../ticker')
const coinUtils = require('../coin-utils')
-const machineLoader = require('../machine-loader')
function allScopes (cryptoScopes, machineScopes) {
const scopes = []
@@ -25,18 +24,6 @@ function allMachineScopes (machineList, machineScope) {
return machineScopes
}
-function getCryptos (config, machineList) {
- const scopes = allScopes(['global'], allMachineScopes(machineList, 'both'))
- const scoped = scope => configManager.scopedValue(scope[0], scope[1], 'cryptoCurrencies', config)
-
- return _.uniq(_.flatten(_.map(scoped, scopes)))
-}
-
-function fetchMachines () {
- return machineLoader.getMachines()
- .then(machineList => machineList.map(r => r.deviceId))
-}
-
function computeCrypto (cryptoCode, _balance) {
const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode)
const unitScale = cryptoRec.unitScale
@@ -82,11 +69,9 @@ function getSingleCoinFunding (settings, fiatCode, cryptoCode) {
}
function getFunding () {
- return Promise.all([settingsLoader.loadLatest(), fetchMachines()])
- .then(([settings, machineList]) => {
- const config = configManager.unscoped(settings.config)
- const cryptoCodes = getCryptos(settings.config, machineList)
- const fiatCode = config.fiatCurrency
+ return settingsLoader.loadLatest().then(settings => {
+ const cryptoCodes = configManager.getAllCryptoCurrencies(settings.config)
+ const fiatCode = configManager.getGlobalLocale(settings.config).fiatCurrency
const pareCoins = c => _.includes(c.cryptoCode, cryptoCodes)
const cryptoCurrencies = coinUtils.cryptoCurrencies()
const cryptoDisplays = _.filter(pareCoins, cryptoCurrencies)
diff --git a/lib/new-admin/graphql/schema.js b/lib/new-admin/graphql/schema.js
index 08e0a4f4..07bedf12 100644
--- a/lib/new-admin/graphql/schema.js
+++ b/lib/new-admin/graphql/schema.js
@@ -62,7 +62,7 @@ const typeDefs = gql`
type Customer {
id: ID!
- name: String!
+ name: String
authorizedOverride: String
frontCameraPath: String
phone: String
@@ -215,7 +215,7 @@ const typeDefs = gql`
}
type Mutation {
- machineAction(deviceId:ID!, action: MachineAction!, cassettes: [Int]): Machine
+ machineAction(deviceId:ID!, action: MachineAction!, cassette1: Int, cassette2: Int): Machine
machineSupportLogs(deviceId: ID!): SupportLogsResponse
serverSupportLogs: SupportLogsResponse
setCustomer(customerId: ID!, customerInput: CustomerInput): Customer
@@ -254,7 +254,7 @@ const resolvers = {
accounts: () => settingsLoader.getAccounts()
},
Mutation: {
- machineAction: (...[, { deviceId, action, cassettes }]) => machineAction({ deviceId, action, cassettes }),
+ machineAction: (...[, { deviceId, action, cassette1, cassette2 }]) => machineAction({ deviceId, action, cassette1, cassette2 }),
machineSupportLogs: (...[, { deviceId }]) => supportLogs.insert(deviceId),
createPairingTotem: (...[, { name }]) => pairing.totem(name),
serverSupportLogs: () => serverLogs.insert(),
diff --git a/lib/new-admin/machines.js b/lib/new-admin/machines.js
index cb0924ff..9fd779ef 100644
--- a/lib/new-admin/machines.js
+++ b/lib/new-admin/machines.js
@@ -6,13 +6,13 @@ function getMachine (machineId) {
.then(machines => machines.find(({ deviceId }) => deviceId === machineId))
}
-function machineAction ({ deviceId, action, cassettes }) {
+function machineAction ({ deviceId, action, cassette1, cassette2 }) {
return getMachine(deviceId)
.then(machine => {
if (!machine) throw new UserInputError(`machine:${deviceId} not found`, { deviceId })
return machine
})
- .then(machineLoader.setMachine({ deviceId, action, cassettes }))
+ .then(machineLoader.setMachine({ deviceId, action, cassettes: [cassette1, cassette2] }))
.then(getMachine(deviceId))
}
diff --git a/lib/new-config-manager.js b/lib/new-config-manager.js
new file mode 100644
index 00000000..caddcbb4
--- /dev/null
+++ b/lib/new-config-manager.js
@@ -0,0 +1,93 @@
+const _ = require('lodash/fp')
+const logger = require('./logger')
+
+const namespaces = {
+ WALLETS: 'wallets',
+ OPERATOR_INFO: 'operatorInfo',
+ NOTIFICATIONS: 'notifications',
+ LOCALE: 'locale',
+ COMMISSIONS: 'commissions',
+ RECEIPT: 'receipt',
+ COIN_ATM_RADAR: 'coinAtmRadar',
+ TERMS_CONDITIONS: 'termsConditions',
+ CASH_OUT: 'cashOut'
+}
+
+const stripl = _.curry((q, str) => _.startsWith(q, str) ? str.slice(q.length) : str)
+const filter = namespace => _.pickBy((value, key) => _.startsWith(`${namespace}_`)(key))
+const strip = key => _.mapKeys(stripl(`${key}_`))
+
+const fromNamespace = _.curry((key, config) => _.compose(strip(key), filter(key))(config))
+const toNamespace = (key, config) => _.mapKeys(it => `${key}_${it}`)(config)
+
+const resolveOverrides = (original, filter, overrides, overridesPath = 'overrides') => {
+ if (_.isEmpty(overrides)) return original
+
+ return _.omit(overridesPath, _.mergeAll([original, ..._.filter(filter)(overrides)]))
+}
+
+const getCommissions = (cryptoCode, deviceId, config) => {
+ const commissions = fromNamespace(namespaces.COMMISSIONS)(config)
+
+ const filter = it => it.machine === deviceId && _.includes(cryptoCode)(it.cryptoCurrencies)
+ return resolveOverrides(commissions, filter, commissions.overrides)
+}
+
+const getLocale = (deviceId, it) => {
+ const locale = fromNamespace(namespaces.LOCALE)(it)
+
+ const filter = _.matches({ machine: deviceId })
+ return resolveOverrides(locale, filter, locale.overrides)
+}
+
+const getGlobalLocale = it => getLocale(null, it)
+
+const getWalletSettings = (key, it) => _.compose(fromNamespace(key), fromNamespace(namespaces.WALLETS))(it)
+const getCashOut = (key, it) => _.compose(fromNamespace(key), fromNamespace(namespaces.CASH_OUT))(it)
+const getOperatorInfo = fromNamespace(namespaces.OPERATOR_INFO)
+const getCoinAtmRadar = fromNamespace(namespaces.COIN_ATM_RADAR)
+const getTermsConditions = fromNamespace(namespaces.TERMS_CONDITIONS)
+const getReceipt = fromNamespace(namespaces.RECEIPT)
+
+const getAllCryptoCurrencies = (config) => {
+ const locale = fromNamespace(namespaces.LOCALE)(config)
+ const cryptos = locale.cryptoCurrencies
+ const overridesCryptos = _.map(_.get('cryptoCurrencies'))(locale.overrides)
+ return _.uniq(_.flatten([cryptos, ...overridesCryptos]))
+}
+
+const getNotifications = (cryptoCurrency, machine, config) => {
+ const notifications = fromNamespace(namespaces.NOTIFICATIONS)(config)
+
+ const cryptoFilter = _.matches({ cryptoCurrency })
+ const withCryptoBalance = resolveOverrides(notifications, cryptoFilter, notifications.cryptoBalanceOverrides, 'cryptoBalanceOverrides')
+
+ const fiatFilter = _.matches({ machine })
+ const withFiatBalance = resolveOverrides(withCryptoBalance, fiatFilter, withCryptoBalance.fiatBalanceOverrides, 'fiatBalanceOverrides')
+
+ const withSms = fromNamespace('sms', withFiatBalance)
+ const withEmail = fromNamespace('email', withFiatBalance)
+
+ const final = { ...withFiatBalance, sms: withSms, email: withEmail }
+ return final
+}
+
+const getGlobalNotifications = config => getNotifications(null, null, config)
+
+const getTriggers = _.get('triggers')
+
+module.exports = {
+ getWalletSettings,
+ getOperatorInfo,
+ getNotifications,
+ getGlobalNotifications,
+ getLocale,
+ getGlobalLocale,
+ getCommissions,
+ getReceipt,
+ getCoinAtmRadar,
+ getTermsConditions,
+ getAllCryptoCurrencies,
+ getTriggers,
+ getCashOut
+}
diff --git a/lib/new-settings-loader.js b/lib/new-settings-loader.js
index e789a436..3c53bd08 100644
--- a/lib/new-settings-loader.js
+++ b/lib/new-settings-loader.js
@@ -42,4 +42,28 @@ function getConfig () {
return (state && state.config) || {}
}
-module.exports = { getConfig, saveConfig, saveAccounts, getAccounts }
+function loadLatest () {
+ return new Promise((resolve) => {
+ if (!db) {
+ setTimeout(() => {
+ return resolve(db.getState())
+ }, 1000)
+ } else {
+ return resolve(db.getState())
+ }
+ })
+}
+
+function load (versionId) {
+ return new Promise((resolve) => {
+ if (!db) {
+ setTimeout(() => {
+ return resolve(db.getState())
+ }, 1000)
+ } else {
+ return resolve(db.getState())
+ }
+ })
+}
+
+module.exports = { getConfig, saveConfig, saveAccounts, getAccounts, loadLatest, load }
diff --git a/lib/notifier.js b/lib/notifier.js
index 0885fd12..5413062f 100644
--- a/lib/notifier.js
+++ b/lib/notifier.js
@@ -15,6 +15,7 @@ const ALERT_SEND_INTERVAL = T.hour
const PING = 'PING'
const STALE = 'STALE'
const LOW_CRYPTO_BALANCE = 'LOW_CRYPTO_BALANCE'
+const HIGH_CRYPTO_BALANCE = 'HIGH_CRYPTO_BALANCE'
const CASH_BOX_FULL = 'CASH_BOX_FULL'
const LOW_CASH_OUT = 'LOW_CASH_OUT'
@@ -22,6 +23,7 @@ const CODES_DISPLAY = {
PING: 'Machine Down',
STALE: 'Machine Stuck',
LOW_CRYPTO_BALANCE: 'Low Crypto Balance',
+ HIGH_CRYPTO_BALANCE: 'High Crypto Balance',
CASH_BOX_FULL: 'Cash box full',
LOW_CASH_OUT: 'Low Cash-out'
}
@@ -41,47 +43,54 @@ function sameState (a, b) {
return a.note.txId === b.note.txId && a.note.state === b.note.state
}
-function sendNoAlerts (plugins) {
+function sendNoAlerts (plugins, smsEnabled, emailEnabled) {
const subject = '[Lamassu] All clear'
- const rec = {
- sms: {
- body: subject
- },
- email: {
- subject,
- body: 'No errors are reported for your machines.'
- }
+
+ let rec = {}
+ if (smsEnabled) {
+ rec = _.set(['sms', 'body'])(subject)(rec)
+ }
+
+ if (emailEnabled) {
+ rec = _.set(['email', 'subject'])(subject)(rec)
+ rec = _.set(['email', 'body'])('No errors are reported for your machines.')(rec)
}
return plugins.sendMessage(rec)
}
function checkNotification (plugins) {
- if (!plugins.notificationsEnabled()) return Promise.resolve()
+ const notifications = plugins.getNotificationConfig()
+ const isActive = it => it.active && (it.balance || it.errors)
+ const smsEnabled = isActive(notifications.sms)
+ const emailEnabled = isActive(notifications.email)
+
+ if (!smsEnabled && !emailEnabled) return Promise.resolve()
return checkStatus(plugins)
.then(alertRec => {
- const currentAlertFingerprint = buildAlertFingerprint(alertRec)
+ const currentAlertFingerprint = buildAlertFingerprint(alertRec, notifications)
if (!currentAlertFingerprint) {
const inAlert = !!alertFingerprint
alertFingerprint = null
lastAlertTime = null
- if (inAlert) return sendNoAlerts(plugins)
+ if (inAlert) return sendNoAlerts(plugins, smsEnabled, emailEnabled)
}
const alertChanged = currentAlertFingerprint === alertFingerprint &&
lastAlertTime - Date.now() < ALERT_SEND_INTERVAL
if (alertChanged) return
- const rec = {
- sms: {
- body: printSmsAlerts(alertRec)
- },
- email: {
- subject: alertSubject(alertRec),
- body: printEmailAlerts(alertRec)
- }
+ let rec = {}
+ if (smsEnabled) {
+ rec = _.set(['sms', 'body'])(printSmsAlerts(alertRec, notifications.sms))(rec)
}
+
+ if (emailEnabled) {
+ rec = _.set(['email', 'subject'])(alertSubject(alertRec, notifications.email))(rec)
+ rec = _.set(['email', 'body'])(printEmailAlerts(alertRec, notifications.email))(rec)
+ }
+
alertFingerprint = currentAlertFingerprint
lastAlertTime = Date.now()
@@ -162,12 +171,13 @@ function checkStatus (plugins) {
return eventRow.device_id === deviceId
})
- const balanceAlerts = _.filter(['deviceId', deviceId], balances)
const ping = pings[deviceId] || []
const stuckScreen = checkStuckScreen(deviceEvents, deviceName)
- const deviceAlerts = _.isEmpty(ping) ? stuckScreen : ping
- alerts.devices[deviceId] = _.concat(deviceAlerts, balanceAlerts)
+ if (!alerts.devices[deviceId]) alerts.devices[deviceId] = {}
+ alerts.devices[deviceId].balanceAlerts = _.filter(['deviceId', deviceId], balances)
+ alerts.devices[deviceId].deviceAlerts = _.isEmpty(ping) ? stuckScreen : ping
+
alerts.deviceNames[deviceId] = deviceName
})
@@ -194,6 +204,9 @@ function emailAlert (alert) {
case LOW_CRYPTO_BALANCE:
const balance = formatCurrency(alert.fiatBalance.balance, alert.fiatCode)
return `Low balance in ${alert.cryptoCode} [${balance}]`
+ case HIGH_CRYPTO_BALANCE:
+ const highBalance = formatCurrency(alert.fiatBalance.balance, alert.fiatCode)
+ return `High balance in ${alert.cryptoCode} [${highBalance}]`
case CASH_BOX_FULL:
return `Cash box full on ${alert.machineName} [${alert.notes} banknotes]`
case LOW_CASH_OUT:
@@ -205,28 +218,48 @@ function emailAlerts (alerts) {
return alerts.map(emailAlert).join('\n') + '\n'
}
-function printEmailAlerts (alertRec) {
+function printEmailAlerts (alertRec, config) {
let body = 'Errors were reported by your Lamassu Machines.\n'
- if (alertRec.general.length !== 0) {
+ if (config.balance && alertRec.general.length !== 0) {
body = body + '\nGeneral errors:\n'
- body = body + emailAlerts(alertRec.general)
+ body = body + emailAlerts(alertRec.general) + '\n'
}
_.keys(alertRec.devices).forEach(function (device) {
const deviceName = alertRec.deviceNames[device]
body = body + '\nErrors for ' + deviceName + ':\n'
- body = body + emailAlerts(alertRec.devices[device])
+
+ let alerts = []
+ if (config.balance) {
+ alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
+ }
+
+ if (config.errors) {
+ alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
+ }
+
+ body = body + emailAlerts(alerts)
})
return body
}
-function alertSubject (alertRec) {
- let alerts = alertRec.general
+function alertSubject (alertRec, config) {
+ let alerts = []
+
+ if (config.balance) {
+ alerts = _.concat(alerts, alertRec.general)
+ }
_.keys(alertRec.devices).forEach(function (device) {
- alerts = _.concat(alerts, alertRec.devices[device])
+ if (config.balance) {
+ alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
+ }
+
+ if (config.errors) {
+ alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
+ }
})
if (alerts.length === 0) return null
@@ -235,11 +268,21 @@ function alertSubject (alertRec) {
return '[Lamassu] Errors reported: ' + alertTypes.join(', ')
}
-function printSmsAlerts (alertRec) {
- let alerts = alertRec.general
+function printSmsAlerts (alertRec, config) {
+ let alerts = []
+
+ if (config.balance) {
+ alerts = _.concat(alerts, alertRec.general)
+ }
_.keys(alertRec.devices).forEach(function (device) {
- alerts = _.concat(alerts, alertRec.devices[device])
+ if (config.balance) {
+ alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
+ }
+
+ if (config.errors) {
+ alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
+ }
})
if (alerts.length === 0) return null
@@ -265,9 +308,39 @@ function printSmsAlerts (alertRec) {
return '[Lamassu] Errors reported: ' + displayAlertTypes.join(', ')
}
-function buildAlertFingerprint (alertRec) {
- const subject = alertSubject(alertRec)
- if (!subject) return null
+function getAlertTypes (alertRec, config) {
+ let alerts = []
+
+ if (!config.active || (!config.balance && !config.errors)) return alerts
+
+ if (config.balance) {
+ alerts = _.concat(alerts, alertRec.general)
+ }
+
+ _.keys(alertRec.devices).forEach(function (device) {
+ if (config.balance) {
+ alerts = _.concat(alerts, alertRec.devices[device].balanceAlerts)
+ }
+
+ if (config.errors) {
+ alerts = _.concat(alerts, alertRec.devices[device].deviceAlerts)
+ }
+ })
+
+ return alerts
+}
+
+function buildAlertFingerprint (alertRec, notifications) {
+ const sms = getAlertTypes(alertRec, notifications.sms)
+ const email = getAlertTypes(alertRec, notifications.email)
+
+ if (sms.length === 0 && email.length === 0) return null
+
+ const smsTypes = _.map(codeDisplay, _.uniq(_.map('code', sms))).sort()
+ const emailTypes = _.map(codeDisplay, _.uniq(_.map('code', email))).sort()
+
+ const subject = _.concat(smsTypes, emailTypes).join(', ')
+
return crypto.createHash('sha256').update(subject).digest('hex')
}
diff --git a/lib/pairing.js b/lib/pairing.js
index 180aae6b..5932878c 100644
--- a/lib/pairing.js
+++ b/lib/pairing.js
@@ -4,7 +4,6 @@ const readFile = pify(fs.readFile)
const db = require('./db')
const options = require('./options')
const logger = require('./logger')
-const settingsLoader = require('./settings-loader')
function pullToken (token) {
const sql = `delete from pairing_tokens
@@ -13,33 +12,12 @@ function pullToken (token) {
return db.one(sql, [token])
}
-function configureNewDevice (deviceId, machineName, machineModel) {
- const scope = {crypto: 'global', machine: deviceId}
- const newFields = [
- settingsLoader.configAddField(scope, 'cashOutEnabled', 'onOff', null, false),
- settingsLoader.configAddField(scope, 'machineName', 'string', null, machineName),
- settingsLoader.configAddField(scope, 'machineModel', 'string', null, machineModel)
- ]
-
- return settingsLoader.modifyConfig(newFields)
-}
-
-function removeDeviceConfig (deviceId) {
- const scope = {crypto: 'global', machine: deviceId}
- const newFields = [
- settingsLoader.configDeleteField(scope, 'cashOutEnabled'),
- settingsLoader.configDeleteField(scope, 'machineName'),
- settingsLoader.configDeleteField(scope, 'machineModel')
- ]
-
- return settingsLoader.modifyConfig(newFields)
-}
-
function unpair (deviceId) {
const sql = 'delete from devices where device_id=$1'
const deleteMachinePings = 'delete from machine_pings where device_id=$1'
+
+ // TODO new-admin: We should remove all configs related to that device. This can get tricky.
return Promise.all([db.none(sql, [deviceId]), db.none(deleteMachinePings, [deviceId])])
- .then(() => removeDeviceConfig(deviceId))
}
function pair (token, deviceId, machineModel) {
@@ -51,8 +29,7 @@ function pair (token, deviceId, machineModel) {
on conflict (device_id)
do update set paired=TRUE, display=TRUE`
- return configureNewDevice(deviceId, r.name, machineModel)
- .then(() => db.none(insertSql, [deviceId, r.name]))
+ return db.none(insertSql, [deviceId, r.name])
.then(() => true)
})
.catch(err => {
diff --git a/lib/plugins.js b/lib/plugins.js
index 0b55a815..f128f2a2 100644
--- a/lib/plugins.js
+++ b/lib/plugins.js
@@ -11,7 +11,7 @@ const db = require('./db')
const logger = require('./logger')
const logs = require('./logs')
const T = require('./time')
-const configManager = require('./config-manager')
+const configManager = require('./new-config-manager')
const ticker = require('./ticker')
const wallet = require('./wallet')
const exchange = require('./exchange')
@@ -34,22 +34,22 @@ const tradesQueues = {}
function plugins (settings, deviceId) {
function buildRates (tickers) {
- const config = configManager.machineScoped(deviceId, settings.config)
- const cryptoCodes = config.cryptoCurrencies
+ const localeConfig = configManager.getLocale(deviceId, settings.config)
+ const cryptoCodes = localeConfig.cryptoCurrencies
const rates = {}
cryptoCodes.forEach((cryptoCode, i) => {
- const cryptoConfig = configManager.scoped(cryptoCode, deviceId, settings.config)
+ const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config)
const rateRec = tickers[i]
if (!rateRec) return
- const cashInCommission = BN(1).add(BN(cryptoConfig.cashInCommission).div(100))
+ const cashInCommission = BN(1).add(BN(commissions.cashIn).div(100))
- const cashOutCommission = _.isNil(cryptoConfig.cashOutCommission)
+ const cashOutCommission = _.isNil(commissions.cashOut)
? undefined
- : BN(1).add(BN(cryptoConfig.cashOutCommission).div(100))
+ : BN(1).add(BN(commissions.cashOut).div(100))
if (Date.now() - rateRec.timestamp > STALE_TICKER) return logger.warn('Stale rate for ' + cryptoCode)
const rate = rateRec.rates
@@ -62,19 +62,13 @@ function plugins (settings, deviceId) {
return rates
}
- function transactionNotificationsEnabled () {
- const config = configManager.unscoped(settings.config)
- return config.transactionNotificationsEnabled
- }
-
- function notificationsEnabled () {
- const config = configManager.unscoped(settings.config)
- return config.notificationsEnabled
+ function getNotificationConfig () {
+ return configManager.getGlobalNotifications(settings.config)
}
function buildBalances (balanceRecs) {
- const config = configManager.machineScoped(deviceId, settings.config)
- const cryptoCodes = config.cryptoCurrencies
+ const localeConfig = configManager.getLocale(deviceId, settings.config)
+ const cryptoCodes = localeConfig.cryptoCurrencies
const balances = {}
@@ -90,8 +84,8 @@ function plugins (settings, deviceId) {
}
function isZeroConf (tx) {
- const config = configManager.scoped(tx.cryptoCode, deviceId, settings.config)
- const zeroConfLimit = config.zeroConfLimit
+ const cashOutConfig = configManager.getCashOut(deviceId, settings.config)
+ const zeroConfLimit = cashOutConfig.zeroConfLimit
return tx.fiat.lte(zeroConfLimit)
}
@@ -131,14 +125,14 @@ function plugins (settings, deviceId) {
}
function buildAvailableCassettes (excludeTxId) {
- const config = configManager.machineScoped(deviceId, settings.config)
+ const cashOutConfig = configManager.getCashOut(deviceId, settings.config)
- if (!config.cashOutEnabled) return Promise.resolve()
+ if (!cashOutConfig.active) return Promise.resolve()
- const denominations = [config.topCashOutDenomination,
- config.bottomCashOutDenomination
- ]
- const virtualCassettes = [config.virtualCashOutDenomination]
+ const denominations = [cashOutConfig.top, cashOutConfig.bottom]
+
+ // TODO new-admin: will this actually be calculated?
+ const virtualCassettes = [cashOutConfig.top + cashOutConfig.bottom]
return Promise.all([dbm.cassetteCounts(deviceId), cashOutHelper.redeemableTxs(deviceId, excludeTxId)])
.then(([rec, _redeemableTxs]) => {
@@ -188,11 +182,11 @@ function plugins (settings, deviceId) {
function mapCoinSettings (coinParams) {
const cryptoCode = coinParams[0]
const cryptoNetwork = coinParams[1]
- const config = configManager.scoped(cryptoCode, deviceId, settings.config)
- const minimumTx = BN(config.minimumTx)
- const cashInFee = BN(config.cashInFee)
- const cashInCommission = BN(config.cashInCommission)
- const cashOutCommission = _.isNumber(config.cashOutCommission) ? BN(config.cashOutCommission) : null
+ const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config)
+ const minimumTx = BN(commissions.minimumTx)
+ const cashInFee = BN(commissions.fixedFee)
+ const cashInCommission = BN(commissions.cashIn)
+ const cashOutCommission = _.isNumber(commissions.cashOut) ? BN(commissions.cashOut) : null
const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode)
return {
@@ -207,9 +201,10 @@ function plugins (settings, deviceId) {
}
function pollQueries (serialNumber, deviceTime, deviceRec) {
- const config = configManager.machineScoped(deviceId, settings.config)
- const fiatCode = config.fiatCurrency
- const cryptoCodes = config.cryptoCurrencies
+ const localeConfig = configManager.getLocale(deviceId, settings.config)
+
+ const fiatCode = localeConfig.fiatCurrency
+ const cryptoCodes = localeConfig.cryptoCurrencies
const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
const balancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c))
@@ -283,16 +278,14 @@ function plugins (settings, deviceId) {
}
function dispenseAck (tx) {
- const config = configManager.machineScoped(deviceId, settings.config)
- const cassettes = [config.topCashOutDenomination,
- config.bottomCashOutDenomination
- ]
+ const cashOutConfig = configManager.getCashOut(deviceId, settings.config)
+ const cassettes = [cashOutConfig.top, cashOutConfig.bottom]
return dbm.addDispense(deviceId, tx, cassettes)
}
function fiatBalance (fiatCode, cryptoCode) {
- const config = configManager.scoped(cryptoCode, deviceId, settings.config)
+ const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config)
return Promise.all([
ticker.getRates(settings, fiatCode, cryptoCode),
wallet.balance(settings, cryptoCode)
@@ -301,7 +294,7 @@ function plugins (settings, deviceId) {
if (!rates || !balanceRec) return null
const rawRate = rates.rates.ask
- const cashInCommission = BN(1).minus(BN(config.cashInCommission).div(100))
+ const cashInCommission = BN(1).minus(BN(commissions.cashIn).div(100))
const balance = balanceRec.balance
if (!rawRate || !balance) return null
@@ -344,7 +337,12 @@ function plugins (settings, deviceId) {
}
function notifyOperator (tx, rec) {
- if (!transactionNotificationsEnabled()) return Promise.resolve()
+ const notifications = configManager.getGlobalNotifications(settings.config)
+
+ const notificationsEnabled = notifications.sms.transactions || notifications.email.transactions
+ const highValueTx = tx.fiat.gt(notifications.highValueTransaction)
+
+ if (!notificationsEnabled || !highValueTx) return Promise.resolve()
const isCashOut = tx.direction === 'cashOut'
const zeroConf = isCashOut && isZeroConf(tx)
@@ -504,9 +502,9 @@ function plugins (settings, deviceId) {
.then(devices => {
const deviceIds = devices.map(device => device.deviceId)
const lists = deviceIds.map(deviceId => {
- const config = configManager.machineScoped(deviceId, settings.config)
- const fiatCode = config.fiatCurrency
- const cryptoCodes = config.cryptoCurrencies
+ const localeConfig = configManager.getLocale(deviceId, settings.config)
+ const fiatCode = localeConfig.fiatCurrency
+ const cryptoCodes = localeConfig.cryptoCurrencies
return cryptoCodes.map(cryptoCode => ({
fiatCode,
@@ -591,21 +589,25 @@ function plugins (settings, deviceId) {
}
function sendMessage (rec) {
- const config = configManager.unscoped(settings.config)
+ const notifications = configManager.getGlobalNotifications(settings.config)
let promises = []
- if (config.notificationsEmailEnabled) promises.push(email.sendMessage(settings, rec))
- if (config.notificationsSMSEnabled) promises.push(sms.sendMessage(settings, rec))
+ if (notifications.email.active && rec.email) promises.push(email.sendMessage(settings, rec))
+ if (notifications.sms.active && rec.sms) promises.push(sms.sendMessage(settings, rec))
return Promise.all(promises)
}
function sendTransactionMessage (rec) {
- const config = configManager.unscoped(settings.config)
+ const notifications = configManager.getGlobalNotifications(settings.config)
let promises = []
- if (config.transactionNotificationsEmailEnabled) promises.push(email.sendMessage(settings, rec))
- if (config.transactionNotificationsSMSEnabled) promises.push(sms.sendMessage(settings, rec))
+
+ const emailActive = notifications.email.active && notifications.email.transactions
+ if (emailActive) promises.push(email.sendMessage(settings, rec))
+
+ const smsActive = notifications.sms.active && notifications.sms.transactions
+ if (smsActive) promises.push(sms.sendMessage(settings, rec))
return Promise.all(promises)
}
@@ -615,13 +617,16 @@ function plugins (settings, deviceId) {
}
function checkDeviceCashBalances (fiatCode, device) {
- const config = configManager.machineScoped(device.deviceId, settings.config)
- const denomination1 = config.topCashOutDenomination
- const denomination2 = config.bottomCashOutDenomination
- const machineName = config.machineName
- const cashOutEnabled = config.cashOutEnabled
+ const cashOutConfig = configManager.getCashOut(device.deviceId, settings.config)
+ const denomination1 = cashOutConfig.top
+ const denomination2 = cashOutConfig.bottom
+ const cashOutEnabled = cashOutConfig.active
- const cashInAlert = device.cashbox > config.cashInAlertThreshold
+ const notifications = configManager.getNotifications(null, device.deviceId, settings.config)
+
+ const machineName = device.machineName
+
+ const cashInAlert = device.cashbox > notifications.cashInAlertThreshold
? {
code: 'CASH_BOX_FULL',
machineName,
@@ -630,7 +635,7 @@ function plugins (settings, deviceId) {
}
: null
- const cassette1Alert = cashOutEnabled && device.cassette1 < config.cashOutCassette1AlertThreshold
+ const cassette1Alert = cashOutEnabled && device.cassette1 < notifications.fiatBalanceCassette1
? {
code: 'LOW_CASH_OUT',
cassette: 1,
@@ -642,7 +647,7 @@ function plugins (settings, deviceId) {
}
: null
- const cassette2Alert = cashOutEnabled && device.cassette2 < config.cashOutCassette2AlertThreshold
+ const cassette2Alert = cashOutEnabled && device.cassette2 < notifications.fiatBalanceCassette2
? {
code: 'LOW_CASH_OUT',
cassette: 2,
@@ -661,8 +666,8 @@ function plugins (settings, deviceId) {
const fiatBalancePromises = cryptoCodes => _.map(c => fiatBalance(fiatCode, c), cryptoCodes)
const fetchCryptoCodes = _deviceId => {
- const config = configManager.machineScoped(_deviceId, settings.config)
- return config.cryptoCurrencies
+ const localeConfig = configManager.getLocale(_deviceId, settings.config)
+ return localeConfig.cryptoCurrencies
}
const union = _.flow(_.map(fetchCryptoCodes), _.flatten, _.uniq)
@@ -678,22 +683,28 @@ function plugins (settings, deviceId) {
if (!fiatBalance) return null
- const config = configManager.cryptoScoped(cryptoCode, settings.config)
- const cryptoAlertThreshold = config.cryptoAlertThreshold
+ const notifications = configManager.getNotifications(cryptoCode, null, settings.config)
+ const lowAlertThreshold = notifications.cryptoLowBalance
+ const highAlertThreshold = notifications.cryptoHighBalance
- return BN(fiatBalance.balance).lt(cryptoAlertThreshold)
- ? {
- code: 'LOW_CRYPTO_BALANCE',
- cryptoCode,
- fiatBalance,
- fiatCode
- }
- : null
+ const req = {
+ cryptoCode,
+ fiatBalance,
+ fiatCode,
+ }
+
+ if (BN(fiatBalance.balance).lt(lowAlertThreshold))
+ return _.set('code')('LOW_CRYPTO_BALANCE')(req)
+
+ if (BN(fiatBalance.balance).gt(highAlertThreshold))
+ return _.set('code')('HIGH_CRYPTO_BALANCE')(req)
+
+ return null
}
function checkBalances () {
- const globalConfig = configManager.unscoped(settings.config)
- const fiatCode = globalConfig.fiatCurrency
+ const localeConfig = configManager.getGlobalLocale(settings.config)
+ const fiatCode = localeConfig.fiatCurrency
return machineLoader.getMachines()
.then(devices => {
@@ -756,9 +767,10 @@ function plugins (settings, deviceId) {
}
function getRawRates () {
- const config = configManager.unscoped(settings.config)
- const cryptoCodes = _.flatten(configManager.all('cryptoCurrencies', settings.config))
- const fiatCode = config.fiatCurrency
+ const localeConfig = configManager.getGlobalLocale(settings.config)
+ const fiatCode = localeConfig.fiatCurrency
+
+ const cryptoCodes = configManager.getAllCryptoCurrencies(settings.config)
const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
return Promise.all(tickerPromises)
@@ -792,7 +804,7 @@ function plugins (settings, deviceId) {
buildAvailableCassettes,
buy,
sell,
- notificationsEnabled,
+ getNotificationConfig,
notifyOperator,
fetchCurrentConfigVersion
}
diff --git a/lib/poller.js b/lib/poller.js
index 22b15b27..bbd3f708 100644
--- a/lib/poller.js
+++ b/lib/poller.js
@@ -9,7 +9,8 @@ const cashInTx = require('./cash-in/cash-in-tx')
const sanctionsUpdater = require('./ofac/update')
const sanctions = require('./ofac/index')
const coinAtmRadar = require('./coinatmradar/coinatmradar')
-const configManager = require('./config-manager')
+const configManager = require('./new-config-manager')
+const complianceTriggers = require('./compliance-triggers')
const INCOMING_TX_INTERVAL = 30 * T.seconds
const LIVE_INCOMING_TX_INTERVAL = 5 * T.seconds
@@ -48,9 +49,10 @@ function initialSanctionsDownload () {
}
function updateAndLoadSanctions () {
- const config = configManager.unscoped(settings().config)
+ const triggers = configManager.getTriggers(settings().config)
+ const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
- if (!config.sanctionsVerificationActive) return Promise.resolve()
+ if (!compatTriggers.sanctions) return Promise.resolve()
logger.info('Updating sanctions database...')
return sanctionsUpdater.update()
@@ -59,10 +61,8 @@ function updateAndLoadSanctions () {
}
function updateCoinAtmRadar () {
- const config = settings().config
-
return pi().getRawRates()
- .then(rates => coinAtmRadar.update({ rates, config }, settings()))
+ .then(rates => coinAtmRadar.update(rates, settings()))
}
function start (__settings) {
diff --git a/lib/route-helpers.js b/lib/route-helpers.js
index 857dded8..4351f7d9 100644
--- a/lib/route-helpers.js
+++ b/lib/route-helpers.js
@@ -4,7 +4,6 @@ const db = require('./db')
const dbm = require('./postgresql_interface')
const T = require('./time')
const BN = require('./bn')
-const settingsLoader = require('./settings-loader')
const TRANSACTION_EXPIRATION = T.day
@@ -90,33 +89,9 @@ function updateDeviceConfigVersion (versionId) {
return db.none('update devices set user_config_id=$1', [versionId])
}
-function updateMachineDefaults (deviceId) {
- const newFields = [{
- fieldLocator: {
- fieldScope: {
- crypto: 'global',
- machine: deviceId
- },
- code: 'cashOutEnabled',
- fieldType: 'onOff',
- fieldClass: null
- },
- fieldValue: {
- fieldType: 'onOff',
- value: false
- }
- }]
-
- return settingsLoader.loadLatest()
- .then(settings => {
- return settingsLoader.save(settingsLoader.mergeValues(settings.config, newFields))
- })
-}
-
module.exports = {
stateChange,
fetchPhoneTx,
fetchStatusTx,
- updateDeviceConfigVersion,
- updateMachineDefaults
+ updateDeviceConfigVersion
}
diff --git a/lib/routes.js b/lib/routes.js
index 52ba93fb..8a6490d4 100644
--- a/lib/routes.js
+++ b/lib/routes.js
@@ -12,9 +12,11 @@ const semver = require('semver')
const dbErrorCodes = require('./db-error-codes')
const options = require('./options')
const logger = require('./logger')
-const configManager = require('./config-manager')
+const configManager = require('./new-config-manager')
+const complianceTriggers = require('./compliance-triggers')
const pairing = require('./pairing')
-const settingsLoader = require('./settings-loader')
+// TODO new-admin: remove old settings loader from here.
+const newSettingsLoader = require('./new-settings-loader')
const plugins = require('./plugins')
const helpers = require('./route-helpers')
const poller = require('./poller')
@@ -44,7 +46,7 @@ const settingsCache = {}
const devMode = argv.dev || options.http
function checkHasLightning (settings) {
- return configManager.cryptoScoped('BTC', settings.config).layer2 !== 'no-layer2'
+ return configManager.getWalletSettings('BTC', settings.config).layer2 !== 'no-layer2'
}
function poll (req, res, next) {
@@ -54,10 +56,18 @@ function poll (req, res, next) {
const serialNumber = req.query.sn
const pid = req.query.pid
const settings = req.settings
- const config = configManager.machineScoped(deviceId, settings.config)
+ const localeConfig = configManager.getLocale(deviceId, settings.config)
const pi = plugins(settings, deviceId)
const hasLightning = checkHasLightning(settings)
+ const triggers = configManager.getTriggers(settings.config)
+ const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
+
+ const operatorInfo = configManager.getOperatorInfo(settings.config)
+ const terms = configManager.getTermsConditions(settings.config)
+ const cashOutConfig = configManager.getCashOut(deviceId, settings.config)
+ const receipt = configManager.getReceipt(settings.config)
+
pids[deviceId] = { pid, ts: Date.now() }
return pi.pollQueries(serialNumber, deviceTime, req.query)
@@ -66,14 +76,14 @@ function poll (req, res, next) {
const reboot = pid && reboots[deviceId] && reboots[deviceId] === pid
const restartServices = pid && restartServicesMap[deviceId] && restartServicesMap[deviceId] === pid
- const langs = config.machineLanguages
+ const langs = localeConfig.languages
const locale = {
- fiatCode: config.fiatCurrency,
+ fiatCode: localeConfig.fiatCurrency,
localeInfo: {
primaryLocale: langs[0],
primaryLocales: langs,
- country: config.country
+ country: localeConfig.country
}
}
@@ -81,47 +91,33 @@ function poll (req, res, next) {
error: null,
locale,
version,
- txLimit: config.cashInTransactionLimit,
- idVerificationEnabled: config.idVerificationEnabled,
- smsVerificationActive: config.smsVerificationActive,
- smsVerificationThreshold: config.smsVerificationThreshold,
- hardLimitVerificationActive: config.hardLimitVerificationActive,
- hardLimitVerificationThreshold: config.hardLimitVerificationThreshold,
- idCardDataVerificationActive: config.idCardDataVerificationActive,
- idCardDataVerificationThreshold: config.idCardDataVerificationThreshold,
- idCardPhotoVerificationActive: config.idCardPhotoVerificationActive,
- idCardPhotoVerificationThreshold: config.idCardPhotoVerificationThreshold,
- sanctionsVerificationActive: config.sanctionsVerificationActive,
- sanctionsVerificationThreshold: config.sanctionsVerificationThreshold,
- crossRefVerificationActive: config.crossRefVerificationActive,
- crossRefVerificationThreshold: config.crossRefVerificationThreshold,
- frontCameraVerificationActive: config.frontCameraVerificationActive,
- frontCameraVerificationThreshold: config.frontCameraVerificationThreshold,
- receiptPrintingActive: config.receiptPrintingActive,
+ smsVerificationActive: !!compatTriggers.sms,
+ smsVerificationThreshold: compatTriggers.sms,
+ hardLimitVerificationActive: !!compatTriggers.block,
+ hardLimitVerificationThreshold: compatTriggers.block,
+ idCardDataVerificationActive: !!compatTriggers.idData,
+ idCardDataVerificationThreshold: compatTriggers.idData,
+ idCardPhotoVerificationActive: !!compatTriggers.idPhoto,
+ idCardPhotoVerificationThreshold: compatTriggers.idPhoto,
+ sanctionsVerificationActive: !!compatTriggers.sancations,
+ sanctionsVerificationThreshold: compatTriggers.sancations,
+ frontCameraVerificationActive: !!compatTriggers.facephoto,
+ frontCameraVerificationThreshold: compatTriggers.facephoto,
+ receiptPrintingActive: receipt.active,
cassettes,
- twoWayMode: config.cashOutEnabled,
- zeroConfLimit: config.zeroConfLimit,
+ twoWayMode: cashOutConfig.active,
+ zeroConfLimit: cashOutConfig.zeroConfLimit,
reboot,
restartServices,
hasLightning,
- operatorInfo: {
- active: config.operatorInfoActive,
- name: config.operatorInfoName,
- phone: config.operatorInfoPhone,
- email: config.operatorInfoEmail,
- website: config.operatorInfoWebsite,
- companyNumber: config.operatorInfoCompanyNumber
- }
+ receipt,
+ operatorInfo
}
// BACKWARDS_COMPATIBILITY 7.5
// machines before 7.5 expect t&c on poll
if (!machineVersion || semver.lt(machineVersion, '7.5.0-beta')) {
- response.terms = config.termsScreenActive && config.termsScreenText ? createTerms(config) : null
- }
-
- if (response.idVerificationEnabled) {
- response.idVerificationLimit = config.idVerificationLimit
+ response.terms = createTerms(terms)
}
return res.json(_.assign(response, results))
@@ -133,13 +129,12 @@ function getTermsConditions (req, res, next) {
const deviceId = req.deviceId
const settings = req.settings
- const config = configManager.unscoped(req.settings.config)
+ const terms = configManager.getTermsConditions(settings.config)
+
const pi = plugins(settings, deviceId)
- const terms = config.termsScreenActive && config.termsScreenText ? createTerms(config) : null
-
return pi.fetchCurrentConfigVersion().then(version => {
- return res.json({ terms, version })
+ return res.json({ terms: createTerms(terms), version })
})
.catch(next)
}
@@ -213,7 +208,8 @@ function verifyTx (req, res, next) {
function addOrUpdateCustomer (req) {
const customerData = req.body
- const config = configManager.unscoped(req.settings.config)
+ const triggers = configManager.getTriggers(req.settings.config)
+ const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
return customers.get(customerData.phone)
.then(customer => {
@@ -222,7 +218,7 @@ function addOrUpdateCustomer (req) {
return customers.add(req.body)
})
.then(customer => {
- return compliance.validationPatch(req.deviceId, config, customer)
+ return compliance.validationPatch(req.deviceId, !!compatTriggers.sanctions, customer)
.then(patch => {
if (_.isEmpty(patch)) return customer
return customers.update(customer.id, patch)
@@ -250,14 +246,15 @@ function updateCustomer (req, res, next) {
const id = req.params.id
const txId = req.query.txId
const patch = req.body
- const config = configManager.unscoped(req.settings.config)
+ const triggers = configManager.getTriggers(req.settings.config)
+ const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers)
customers.getById(id)
.then(customer => {
if (!customer) { throw httpError('Not Found', 404) }
const mergedCustomer = _.merge(customer, patch)
- return compliance.validationPatch(req.deviceId, config, mergedCustomer)
+ return compliance.validationPatch(req.deviceId, !!compatTriggers.sanctions, mergedCustomer)
.then(_.merge(patch))
.then(newPatch => customers.updatePhotoCard(id, newPatch))
.then(newPatch => customers.updateFrontCamera(id, newPatch))
@@ -305,8 +302,7 @@ function pair (req, res, next) {
return pairing.pair(token, deviceId, model)
.then(valid => {
if (valid) {
- return helpers.updateMachineDefaults(deviceId)
- .then(() => res.json({ status: 'paired' }))
+ return res.json({ status: 'paired' })
}
throw httpError('Pairing failed')
@@ -457,7 +453,7 @@ localApp.post('/restartServices', (req, res) => {
localApp.post('/dbChange', (req, res, next) => {
settingsCache.cache = null
- return settingsLoader.loadLatest()
+ return newSettingsLoader.loadLatest()
.then(poller.reload)
.then(() => logger.info('Config reloaded'))
.catch(err => {
@@ -504,7 +500,7 @@ function populateSettings (req, res, next) {
}
if (!versionId && !settingsCache.cache) {
- return settingsLoader.loadLatest()
+ return newSettingsLoader.loadLatest()
.then(settings => {
settingsCache.cache = settings
settingsCache.timestamp = Date.now()
@@ -514,20 +510,22 @@ function populateSettings (req, res, next) {
.catch(next)
}
- settingsLoader.load(versionId)
+ newSettingsLoader.load(versionId)
.then(settings => { req.settings = settings })
.then(() => helpers.updateDeviceConfigVersion(versionId))
.then(() => next())
.catch(next)
}
-function createTerms (config) {
+function createTerms (terms) {
+ if (!terms.active || !terms.text) return null
+
return {
- active: config.termsScreenActive,
- title: config.termsScreenTitle,
- text: nmd(config.termsScreenText),
- accept: config.termsAcceptButtonText,
- cancel: config.termsCancelButtonText
+ active: terms.active,
+ title: terms.title,
+ text: nmd(terms.text),
+ accept: terms.acceptButtonText,
+ cancel: terms.cancelButtonText
}
}
diff --git a/lib/sms.js b/lib/sms.js
index b6b0a82e..c338113b 100644
--- a/lib/sms.js
+++ b/lib/sms.js
@@ -1,10 +1,12 @@
-const configManager = require('./config-manager')
+// const configManager = require('./config-manager')
const ph = require('./plugin-helper')
function sendMessage (settings, rec) {
return Promise.resolve()
.then(() => {
- const pluginCode = configManager.unscoped(settings.config).sms
+ // TODO new-admin: how to load mock here? Only on dev?
+ // const pluginCode = configManager.unscoped(settings.config).sms
+ const pluginCode = 'twilio'
const plugin = ph.load(ph.SMS, pluginCode)
const account = settings.accounts[pluginCode]
diff --git a/lib/ticker.js b/lib/ticker.js
index ed42c7af..5ea068ec 100644
--- a/lib/ticker.js
+++ b/lib/ticker.js
@@ -1,5 +1,5 @@
const mem = require('mem')
-const configManager = require('./config-manager')
+const configManager = require('./new-config-manager')
const ph = require('./plugin-helper')
const logger = require('./logger')
@@ -11,8 +11,9 @@ function _getRates (settings, fiatCode, cryptoCode) {
return Promise.resolve()
.then(() => {
const config = settings.config
- const plugin = configManager.cryptoScoped(cryptoCode, config).ticker
+ const plugin = configManager.getWalletSettings(cryptoCode, config).ticker
+ logger.info(plugin)
const account = settings.accounts[plugin]
const ticker = ph.load(ph.TICKER, plugin)
diff --git a/lib/wallet.js b/lib/wallet.js
index 0e069f8c..086d9a4f 100644
--- a/lib/wallet.js
+++ b/lib/wallet.js
@@ -2,7 +2,7 @@ const _ = require('lodash/fp')
const mem = require('mem')
const hkdf = require('futoin-hkdf')
-const configManager = require('./config-manager')
+const configManager = require('./new-config-manager')
const pify = require('pify')
const fs = pify(require('fs'))
@@ -32,7 +32,7 @@ function fetchWallet (settings, cryptoCode) {
return fs.readFile(options.mnemonicPath, 'utf8')
.then(mnemonic => {
const masterSeed = mnemonicHelpers.toEntropyBuffer(mnemonic)
- const plugin = configManager.cryptoScoped(cryptoCode, settings.config).wallet
+ const plugin = configManager.getWalletSettings(cryptoCode, settings.config).wallet
const wallet = ph.load(ph.WALLET, plugin)
const rawAccount = settings.accounts[plugin]
const account = _.set('seed', computeSeed(masterSeed), rawAccount)
@@ -135,10 +135,9 @@ function getWalletStatus (settings, tx) {
}
function authorizeZeroConf (settings, tx, machineId) {
- const cryptoConfig = configManager.cryptoScoped(tx.cryptoCode, settings.config)
- const machineConfig = configManager.machineScoped(machineId, settings.config)
- const plugin = cryptoConfig.zeroConf
- const zeroConfLimit = machineConfig.zeroConfLimit
+ const plugin = configManager.getWalletSettings(tx.cryptoCode, settings.config).zeroConf
+ const cashOutConfig = configManager.cashOutConfig(machineId, settings.config)
+ const zeroConfLimit = cashOutConfig.zeroConfLimit
if (!_.isObject(tx.fiat)) {
return Promise.reject(new Error('tx.fiat is undefined!'))
@@ -189,7 +188,7 @@ function isHd (settings, cryptoCode) {
}
function cryptoNetwork (settings, cryptoCode) {
- const plugin = configManager.cryptoScoped(cryptoCode, settings.config).wallet
+ const plugin = configManager.getWalletSettings(cryptoCode, settings.config).wallet
const wallet = ph.load(ph.WALLET, plugin)
const account = settings.accounts[plugin]
diff --git a/new-lamassu-admin/src/components/Modal.js b/new-lamassu-admin/src/components/Modal.js
index 7651be26..fc84d0a8 100644
--- a/new-lamassu-admin/src/components/Modal.js
+++ b/new-lamassu-admin/src/components/Modal.js
@@ -3,17 +3,19 @@ import classnames from 'classnames'
import React from 'react'
import { IconButton } from 'src/components/buttons'
-import { H1 } from 'src/components/typography'
+import { H1, H2 } from 'src/components/typography'
import { ReactComponent as CloseIcon } from 'src/styling/icons/action/close/zodiac.svg'
const styles = {
modal: {
display: 'flex',
justifyContent: 'center',
+ flexDirection: 'column',
alignItems: 'center'
},
- wrapper: ({ width }) => ({
+ wrapper: ({ width, height }) => ({
width,
+ height,
display: 'flex',
flexDirection: 'column',
minHeight: 400,
@@ -45,7 +47,10 @@ const useStyles = makeStyles(styles)
const Modal = ({
width,
+ height,
title,
+ titleSmall,
+ infoPanel,
handleClose,
children,
className,
@@ -53,7 +58,9 @@ const Modal = ({
closeOnBackdropClick,
...props
}) => {
- const classes = useStyles({ width })
+ const classes = useStyles({ width, height })
+ const TitleCase = titleSmall ? H2 : H1
+ const closeSize = titleSmall ? 16 : 20
const innerClose = (evt, reason) => {
if (!closeOnBackdropClick && reason === 'backdropClick') return
@@ -63,18 +70,25 @@ const Modal = ({
return (
{title}
}
-