Chore: fix regressions caused by rebase
This commit is contained in:
parent
ef60b15d82
commit
0d6349dbf4
26 changed files with 10471 additions and 34310 deletions
|
|
@ -9,8 +9,6 @@ const helper = require('./cash-out-helper')
|
|||
const cashOutActions = require('./cash-out-actions')
|
||||
const cashOutLow = require('./cash-out-low')
|
||||
|
||||
const notifier = require("../notifier/index")
|
||||
|
||||
const toObj = helper.toObj
|
||||
|
||||
module.exports = {atomic}
|
||||
|
|
@ -124,9 +122,8 @@ function updateCassettes (t, tx) {
|
|||
tx.deviceId
|
||||
]
|
||||
|
||||
return t.one(sql, values).then(r => {
|
||||
return socket.emit(_.assign(r, {op: 'cassetteUpdate', deviceId: tx.deviceId}))
|
||||
})
|
||||
return t.one(sql, values)
|
||||
.then(r => socket.emit(_.assign(r, {op: 'cassetteUpdate', deviceId: tx.deviceId})))
|
||||
}
|
||||
|
||||
function wasJustAuthorized (oldTx, newTx, isZeroConf) {
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ const typeDefs = gql`
|
|||
age: Float
|
||||
deviceTime: Date
|
||||
}
|
||||
|
||||
|
||||
type Rate {
|
||||
code: String
|
||||
name: String
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ function printSmsAlerts (alertRec, config) {
|
|||
const code = entry[0]
|
||||
const machineNames = _.filter(
|
||||
_.negate(_.isEmpty),
|
||||
_.map('machineName', entry[1]),
|
||||
_.map('machineName', entry[1])
|
||||
)
|
||||
|
||||
const cryptoCodes = _.filter(
|
||||
_.negate(_.isEmpty),
|
||||
_.map('cryptoCode', entry[1]),
|
||||
_.map('cryptoCode', entry[1])
|
||||
)
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -196,5 +196,5 @@ module.exports = {
|
|||
formatCurrency,
|
||||
formatAge,
|
||||
buildDetail,
|
||||
deviceAlerts,
|
||||
deviceAlerts
|
||||
}
|
||||
|
|
|
|||
343
lib/plugins.js
343
lib/plugins.js
|
|
@ -55,8 +55,7 @@ function plugins (settings, deviceId) {
|
|||
? undefined
|
||||
: BN(1).add(BN(commissions.cashOut).div(100))
|
||||
|
||||
if (Date.now() - rateRec.timestamp > STALE_TICKER)
|
||||
return logger.warn('Stale rate for ' + cryptoCode)
|
||||
if (Date.now() - rateRec.timestamp > STALE_TICKER) return logger.warn('Stale rate for ' + cryptoCode)
|
||||
const rate = rateRec.rates
|
||||
|
||||
withCommission ? rates[cryptoCode] = {
|
||||
|
|
@ -90,10 +89,8 @@ function plugins (settings, deviceId) {
|
|||
|
||||
cryptoCodes.forEach((cryptoCode, i) => {
|
||||
const balanceRec = balanceRecs[i]
|
||||
if (!balanceRec)
|
||||
return logger.warn('No balance for ' + cryptoCode + ' yet')
|
||||
if (Date.now() - balanceRec.timestamp > STALE_BALANCE)
|
||||
return logger.warn('Stale balance for ' + cryptoCode)
|
||||
if (!balanceRec) return logger.warn('No balance for ' + cryptoCode + ' yet')
|
||||
if (Date.now() - balanceRec.timestamp > STALE_BALANCE) return logger.warn('Stale balance for ' + cryptoCode)
|
||||
|
||||
balances[cryptoCode] = balanceRec.balance
|
||||
})
|
||||
|
|
@ -113,13 +110,10 @@ function plugins (settings, deviceId) {
|
|||
const sumTxs = (sum, tx) => {
|
||||
const bills = tx.bills
|
||||
const sameDenominations = a => a[0].denomination === a[1].denomination
|
||||
const doDenominationsMatch = _.every(
|
||||
sameDenominations,
|
||||
_.zip(cassettes, bills)
|
||||
)
|
||||
const doDenominationsMatch = _.every(sameDenominations, _.zip(cassettes, bills))
|
||||
|
||||
if (!doDenominationsMatch) {
|
||||
throw new Error("Denominations don't add up, cassettes were changed.")
|
||||
throw new Error('Denominations don\'t add up, cassettes were changed.')
|
||||
}
|
||||
|
||||
return _.map(r => r[0] + r[1].provisioned, _.zip(sum, tx.bills))
|
||||
|
|
@ -195,23 +189,18 @@ function plugins (settings, deviceId) {
|
|||
order by id desc
|
||||
limit 1`
|
||||
|
||||
return db.one(sql, ['config']).then(row => row.id)
|
||||
return db.one(sql, ['config'])
|
||||
.then(row => row.id)
|
||||
}
|
||||
|
||||
function mapCoinSettings (coinParams) {
|
||||
const cryptoCode = coinParams[0]
|
||||
const cryptoNetwork = coinParams[1]
|
||||
const commissions = configManager.getCommissions(
|
||||
cryptoCode,
|
||||
deviceId,
|
||||
settings.config
|
||||
)
|
||||
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 cashOutCommission = _.isNumber(commissions.cashOut) ? BN(commissions.cashOut) : null
|
||||
const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode)
|
||||
|
||||
return {
|
||||
|
|
@ -225,25 +214,15 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
}
|
||||
|
||||
function pollQueries (
|
||||
serialNumber,
|
||||
deviceTime,
|
||||
deviceRec,
|
||||
machineVersion,
|
||||
machineModel
|
||||
) {
|
||||
function pollQueries (serialNumber, deviceTime, deviceRec, machineVersion, machineModel) {
|
||||
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 tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
|
||||
const balancePromises = cryptoCodes.map(c => fiatBalance(fiatCode, c))
|
||||
const testnetPromises = cryptoCodes.map(c =>
|
||||
wallet.cryptoNetwork(settings, c)
|
||||
)
|
||||
const testnetPromises = cryptoCodes.map(c => wallet.cryptoNetwork(settings, c))
|
||||
const pingPromise = recordPing(deviceTime, machineVersion, machineModel)
|
||||
const currentConfigVersionPromise = fetchCurrentConfigVersion()
|
||||
const currentAvailablePromoCodes = promoCodes.getNumberOfAvailablePromoCodes()
|
||||
|
|
@ -278,12 +257,7 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
|
||||
function sendCoins (tx) {
|
||||
return wallet.sendCoins(
|
||||
settings,
|
||||
tx.toAddress,
|
||||
tx.cryptoAtoms,
|
||||
tx.cryptoCode
|
||||
)
|
||||
return wallet.sendCoins(settings, tx.toAddress, tx.cryptoAtoms, tx.cryptoCode)
|
||||
}
|
||||
|
||||
function recordPing (deviceTime, version, model) {
|
||||
|
|
@ -294,18 +268,11 @@ 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, updated = now()`,
|
||||
[deviceId, deviceTime]
|
||||
),
|
||||
db.none(
|
||||
pgp.helpers.update(devices, null, 'devices') +
|
||||
'WHERE device_id = ${deviceId}',
|
||||
{
|
||||
deviceId
|
||||
}
|
||||
)
|
||||
db.none(`insert into machine_pings(device_id, device_time) values($1, $2)
|
||||
ON CONFLICT (device_id) DO UPDATE SET device_time = $2, updated = now()`, [deviceId, deviceTime]),
|
||||
db.none(pgp.helpers.update(devices, null, 'devices') + `WHERE device_id = ${deviceId}`, {
|
||||
deviceId
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
|
|
@ -337,37 +304,34 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
|
||||
function fiatBalance (fiatCode, cryptoCode) {
|
||||
const commissions = configManager.getCommissions(
|
||||
cryptoCode,
|
||||
deviceId,
|
||||
settings.config
|
||||
)
|
||||
const commissions = configManager.getCommissions(cryptoCode, deviceId, settings.config)
|
||||
return Promise.all([
|
||||
ticker.getRates(settings, fiatCode, cryptoCode),
|
||||
wallet.balance(settings, cryptoCode)
|
||||
]).then(([rates, balanceRec]) => {
|
||||
if (!rates || !balanceRec) return null
|
||||
])
|
||||
.then(([rates, balanceRec]) => {
|
||||
if (!rates || !balanceRec) return null
|
||||
|
||||
const rawRate = rates.rates.ask
|
||||
const cashInCommission = BN(1).minus(BN(commissions.cashIn).div(100))
|
||||
const balance = balanceRec.balance
|
||||
const rawRate = rates.rates.ask
|
||||
const cashInCommission = BN(1).minus(BN(commissions.cashIn).div(100))
|
||||
const balance = balanceRec.balance
|
||||
|
||||
if (!rawRate || !balance) return null
|
||||
if (!rawRate || !balance) return null
|
||||
|
||||
const rate = rawRate.div(cashInCommission)
|
||||
const rate = rawRate.div(cashInCommission)
|
||||
|
||||
const lowBalanceMargin = BN(1.03)
|
||||
const lowBalanceMargin = BN(1.03)
|
||||
|
||||
const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode)
|
||||
const unitScale = cryptoRec.unitScale
|
||||
const shiftedRate = rate.shift(-unitScale)
|
||||
const fiatTransferBalance = balance.mul(shiftedRate).div(lowBalanceMargin)
|
||||
const cryptoRec = coinUtils.getCryptoCurrency(cryptoCode)
|
||||
const unitScale = cryptoRec.unitScale
|
||||
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()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function notifyConfirmation (tx) {
|
||||
|
|
@ -382,12 +346,13 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
}
|
||||
|
||||
return sms.sendMessage(settings, rec).then(() => {
|
||||
const sql = 'update cash_out_txs set notified=$1 where id=$2'
|
||||
const values = [true, tx.id]
|
||||
return sms.sendMessage(settings, rec)
|
||||
.then(() => {
|
||||
const sql = 'update cash_out_txs set notified=$1 where id=$2'
|
||||
const values = [true, tx.id]
|
||||
|
||||
return db.none(sql, values)
|
||||
})
|
||||
return db.none(sql, values)
|
||||
})
|
||||
}
|
||||
|
||||
function notifyOperator (tx, rec) {
|
||||
|
|
@ -396,17 +361,14 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
|
||||
function clearOldLogs () {
|
||||
return logs.clearOldLogs().catch(logger.error)
|
||||
return logs.clearOldLogs()
|
||||
.catch(logger.error)
|
||||
}
|
||||
|
||||
function pong () {
|
||||
return db
|
||||
.none(
|
||||
`UPDATE server_events SET created=now() WHERE event_type=$1;
|
||||
return db.none(`UPDATE server_events SET created=now() WHERE event_type=$1;
|
||||
INSERT INTO server_events (event_type) SELECT $1
|
||||
WHERE NOT EXISTS (SELECT 1 FROM server_events WHERE event_type=$1);`,
|
||||
['ping']
|
||||
)
|
||||
WHERE NOT EXISTS (SELECT 1 FROM server_events WHERE event_type=$1);`, ['ping'])
|
||||
.catch(logger.error)
|
||||
}
|
||||
|
||||
|
|
@ -447,18 +409,15 @@ function plugins (settings, deviceId) {
|
|||
const marketTradesQueues = tradesQueues[market]
|
||||
if (!marketTradesQueues || marketTradesQueues.length === 0) return null
|
||||
|
||||
logger.debug(
|
||||
'[%s] tradesQueues size: %d',
|
||||
market,
|
||||
marketTradesQueues.length
|
||||
)
|
||||
logger.debug('[%s] tradesQueues size: %d', market, marketTradesQueues.length)
|
||||
logger.debug('[%s] tradesQueues head: %j', market, marketTradesQueues[0])
|
||||
|
||||
const t1 = Date.now()
|
||||
|
||||
const filtered = marketTradesQueues.filter(tradeEntry => {
|
||||
return t1 - tradeEntry.timestamp < TRADE_TTL
|
||||
})
|
||||
const filtered = marketTradesQueues
|
||||
.filter(tradeEntry => {
|
||||
return t1 - tradeEntry.timestamp < TRADE_TTL
|
||||
})
|
||||
|
||||
const filteredCount = marketTradesQueues.length - filtered.length
|
||||
|
||||
|
|
@ -469,14 +428,10 @@ function plugins (settings, deviceId) {
|
|||
|
||||
if (filtered.length === 0) return null
|
||||
|
||||
const cryptoAtoms = filtered.reduce(
|
||||
(prev, current) => prev.plus(current.cryptoAtoms),
|
||||
BN(0)
|
||||
)
|
||||
const cryptoAtoms = filtered
|
||||
.reduce((prev, current) => prev.plus(current.cryptoAtoms), BN(0))
|
||||
|
||||
const timestamp = filtered
|
||||
.map(r => r.timestamp)
|
||||
.reduce((acc, r) => Math.max(acc, r), 0)
|
||||
const timestamp = filtered.map(r => r.timestamp).reduce((acc, r) => Math.max(acc, r), 0)
|
||||
|
||||
const consolidatedTrade = {
|
||||
fiatCode,
|
||||
|
|
@ -492,15 +447,11 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
|
||||
function executeTrades () {
|
||||
return machineLoader
|
||||
.getMachines()
|
||||
return machineLoader.getMachines()
|
||||
.then(devices => {
|
||||
const deviceIds = devices.map(device => device.deviceId)
|
||||
const lists = deviceIds.map(deviceId => {
|
||||
const localeConfig = configManager.getLocale(
|
||||
deviceId,
|
||||
settings.config
|
||||
)
|
||||
const localeConfig = configManager.getLocale(deviceId, settings.config)
|
||||
const fiatCode = localeConfig.fiatCurrency
|
||||
const cryptoCodes = localeConfig.cryptoCurrencies
|
||||
|
||||
|
|
@ -510,9 +461,8 @@ function plugins (settings, deviceId) {
|
|||
}))
|
||||
})
|
||||
|
||||
const tradesPromises = _.uniq(_.flatten(lists)).map(r =>
|
||||
executeTradesForMarket(settings, r.fiatCode, r.cryptoCode)
|
||||
)
|
||||
const tradesPromises = _.uniq(_.flatten(lists))
|
||||
.map(r => executeTradesForMarket(settings, r.fiatCode, r.cryptoCode))
|
||||
|
||||
return Promise.all(tradesPromises)
|
||||
})
|
||||
|
|
@ -527,43 +477,41 @@ function plugins (settings, deviceId) {
|
|||
|
||||
if (tradeEntry === null || tradeEntry.cryptoAtoms.eq(0)) return
|
||||
|
||||
return executeTradeForType(tradeEntry).catch(err => {
|
||||
tradesQueues[market].push(tradeEntry)
|
||||
if (err.name === 'orderTooSmall') return logger.debug(err.message)
|
||||
logger.error(err)
|
||||
})
|
||||
return executeTradeForType(tradeEntry)
|
||||
.catch(err => {
|
||||
tradesQueues[market].push(tradeEntry)
|
||||
if (err.name === 'orderTooSmall') return logger.debug(err.message)
|
||||
logger.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
function executeTradeForType (_tradeEntry) {
|
||||
const expand = te =>
|
||||
_.assign(te, {
|
||||
cryptoAtoms: te.cryptoAtoms.abs(),
|
||||
type: te.cryptoAtoms.gte(0) ? 'buy' : 'sell'
|
||||
})
|
||||
const expand = te => _.assign(te, {
|
||||
cryptoAtoms: te.cryptoAtoms.abs(),
|
||||
type: te.cryptoAtoms.gte(0) ? 'buy' : 'sell'
|
||||
})
|
||||
|
||||
const tradeEntry = expand(_tradeEntry)
|
||||
const execute = tradeEntry.type === 'buy' ? exchange.buy : exchange.sell
|
||||
|
||||
return execute(
|
||||
settings,
|
||||
tradeEntry.cryptoAtoms,
|
||||
tradeEntry.fiatCode,
|
||||
tradeEntry.cryptoCode
|
||||
)
|
||||
return execute(settings, tradeEntry.cryptoAtoms, tradeEntry.fiatCode, tradeEntry.cryptoCode)
|
||||
.then(() => recordTrade(tradeEntry))
|
||||
.catch(err => {
|
||||
return recordTrade(tradeEntry, err).then(() => {
|
||||
throw err
|
||||
})
|
||||
return recordTrade(tradeEntry, err)
|
||||
.then(() => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function convertBigNumFields (obj) {
|
||||
const convert = (value, key) =>
|
||||
_.includes(key, ['cryptoAtoms', 'fiat']) ? value.toString() : value
|
||||
const convert = (value, key) => _.includes(key, ['cryptoAtoms', 'fiat'])
|
||||
? value.toString()
|
||||
: value
|
||||
|
||||
const convertKey = key =>
|
||||
_.includes(key, ['cryptoAtoms', 'fiat']) ? key + '#' : key
|
||||
const convertKey = key => _.includes(key, ['cryptoAtoms', 'fiat'])
|
||||
? key + '#'
|
||||
: key
|
||||
|
||||
return _.mapKeys(convertKey, mapValuesWithKey(convert, obj))
|
||||
}
|
||||
|
|
@ -604,64 +552,53 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
|
||||
function checkDeviceCashBalances (fiatCode, device) {
|
||||
const cashOutConfig = configManager.getCashOut(
|
||||
device.deviceId,
|
||||
settings.config
|
||||
)
|
||||
const cashOutConfig = configManager.getCashOut(device.deviceId, settings.config)
|
||||
const denomination1 = cashOutConfig.top
|
||||
const denomination2 = cashOutConfig.bottom
|
||||
const cashOutEnabled = cashOutConfig.active
|
||||
|
||||
const notifications = configManager.getNotifications(
|
||||
null,
|
||||
device.deviceId,
|
||||
settings.config
|
||||
)
|
||||
const notifications = configManager.getNotifications(null, device.deviceId, settings.config)
|
||||
|
||||
const machineName = device.name
|
||||
|
||||
const cashInAlert =
|
||||
device.cashbox > notifications.cashInAlertThreshold
|
||||
? {
|
||||
code: 'CASH_BOX_FULL',
|
||||
machineName,
|
||||
deviceId: device.deviceId,
|
||||
notes: device.cashbox
|
||||
}
|
||||
: null
|
||||
const cashInAlert = device.cashbox > notifications.cashInAlertThreshold
|
||||
? {
|
||||
code: 'CASH_BOX_FULL',
|
||||
machineName,
|
||||
deviceId: device.deviceId,
|
||||
notes: device.cashbox
|
||||
}
|
||||
: null
|
||||
|
||||
const cassette1Alert =
|
||||
cashOutEnabled && device.cassette1 < notifications.fiatBalanceCassette1
|
||||
? {
|
||||
code: 'LOW_CASH_OUT',
|
||||
cassette: 1,
|
||||
machineName,
|
||||
deviceId: device.deviceId,
|
||||
notes: device.cassette1,
|
||||
denomination: denomination1,
|
||||
fiatCode
|
||||
}
|
||||
: null
|
||||
const cassette1Alert = cashOutEnabled && device.cassette1 < notifications.fiatBalanceCassette1
|
||||
? {
|
||||
code: 'LOW_CASH_OUT',
|
||||
cassette: 1,
|
||||
machineName,
|
||||
deviceId: device.deviceId,
|
||||
notes: device.cassette1,
|
||||
denomination: denomination1,
|
||||
fiatCode
|
||||
}
|
||||
: null
|
||||
|
||||
const cassette2Alert =
|
||||
cashOutEnabled && device.cassette2 < notifications.fiatBalanceCassette2
|
||||
? {
|
||||
code: 'LOW_CASH_OUT',
|
||||
cassette: 2,
|
||||
machineName,
|
||||
deviceId: device.deviceId,
|
||||
notes: device.cassette2,
|
||||
denomination: denomination2,
|
||||
fiatCode
|
||||
}
|
||||
: null
|
||||
const cassette2Alert = cashOutEnabled && device.cassette2 < notifications.fiatBalanceCassette2
|
||||
? {
|
||||
code: 'LOW_CASH_OUT',
|
||||
cassette: 2,
|
||||
machineName,
|
||||
deviceId: device.deviceId,
|
||||
notes: device.cassette2,
|
||||
denomination: denomination2,
|
||||
fiatCode
|
||||
}
|
||||
: null
|
||||
|
||||
return _.compact([cashInAlert, cassette1Alert, cassette2Alert])
|
||||
}
|
||||
|
||||
function checkCryptoBalances (fiatCode, devices) {
|
||||
const fiatBalancePromises = cryptoCodes =>
|
||||
_.map(c => fiatBalance(fiatCode, c), cryptoCodes)
|
||||
const fiatBalancePromises = cryptoCodes => _.map(c => fiatBalance(fiatCode, c), cryptoCodes)
|
||||
|
||||
const fetchCryptoCodes = _deviceId => {
|
||||
const localeConfig = configManager.getLocale(_deviceId, settings.config)
|
||||
|
|
@ -672,20 +609,15 @@ function plugins (settings, deviceId) {
|
|||
const cryptoCodes = union(devices)
|
||||
const checkCryptoBalanceWithFiat = _.partial(checkCryptoBalance, [fiatCode])
|
||||
|
||||
return Promise.all(fiatBalancePromises(cryptoCodes)).then(balances =>
|
||||
_.map(checkCryptoBalanceWithFiat, _.zip(cryptoCodes, balances))
|
||||
)
|
||||
return Promise.all(fiatBalancePromises(cryptoCodes))
|
||||
.then(balances => _.map(checkCryptoBalanceWithFiat, _.zip(cryptoCodes, balances)))
|
||||
}
|
||||
|
||||
function checkCryptoBalance (fiatCode, rec) {
|
||||
const [cryptoCode, fiatBalance] = rec
|
||||
if (!fiatBalance) return null
|
||||
|
||||
const notifications = configManager.getNotifications(
|
||||
cryptoCode,
|
||||
null,
|
||||
settings.config
|
||||
)
|
||||
const notifications = configManager.getNotifications(cryptoCode, null, settings.config)
|
||||
const lowAlertThreshold = notifications.cryptoLowBalance
|
||||
const highAlertThreshold = notifications.cryptoHighBalance
|
||||
|
||||
|
|
@ -710,23 +642,24 @@ function plugins (settings, deviceId) {
|
|||
const localeConfig = configManager.getGlobalLocale(settings.config)
|
||||
const fiatCode = localeConfig.fiatCurrency
|
||||
|
||||
return machineLoader.getMachines().then(devices => {
|
||||
return Promise.all([
|
||||
checkCryptoBalances(fiatCode, devices),
|
||||
checkDevicesCashBalances(fiatCode, devices)
|
||||
]).then(_.flow(_.flattenDeep, _.compact))
|
||||
})
|
||||
return machineLoader.getMachines()
|
||||
.then(devices => {
|
||||
return Promise.all([
|
||||
checkCryptoBalances(fiatCode, devices),
|
||||
checkDevicesCashBalances(fiatCode, devices)
|
||||
])
|
||||
.then(_.flow(_.flattenDeep, _.compact))
|
||||
})
|
||||
}
|
||||
|
||||
function randomCode () {
|
||||
return BN(crypto.randomBytes(3).toString('hex'), 16)
|
||||
.shift(-6)
|
||||
.toFixed(6)
|
||||
.slice(-6)
|
||||
return BN(crypto.randomBytes(3).toString('hex'), 16).shift(-6).toFixed(6).slice(-6)
|
||||
}
|
||||
|
||||
function getPhoneCode (phone) {
|
||||
const code = argv.mockSms ? '123' : randomCode()
|
||||
const code = argv.mockSms
|
||||
? '123'
|
||||
: randomCode()
|
||||
|
||||
const rec = {
|
||||
sms: {
|
||||
|
|
@ -735,14 +668,14 @@ function plugins (settings, deviceId) {
|
|||
}
|
||||
}
|
||||
|
||||
return sms.sendMessage(settings, rec).then(() => code)
|
||||
return sms.sendMessage(settings, rec)
|
||||
.then(() => code)
|
||||
}
|
||||
|
||||
function sweepHdRow (row) {
|
||||
const cryptoCode = row.crypto_code
|
||||
|
||||
return wallet
|
||||
.sweep(settings, cryptoCode, row.hd_index)
|
||||
return wallet.sweep(settings, cryptoCode, row.hd_index)
|
||||
.then(txHash => {
|
||||
if (txHash) {
|
||||
logger.debug('[%s] Swept address with tx: %s', cryptoCode, txHash)
|
||||
|
|
@ -753,17 +686,14 @@ function plugins (settings, deviceId) {
|
|||
return db.none(sql, row.id)
|
||||
}
|
||||
})
|
||||
.catch(err =>
|
||||
logger.error('[%s] Sweep error: %s', cryptoCode, err.message)
|
||||
)
|
||||
.catch(err => logger.error('[%s] Sweep error: %s', cryptoCode, err.message))
|
||||
}
|
||||
|
||||
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')`
|
||||
|
||||
return db
|
||||
.any(sql)
|
||||
return db.any(sql)
|
||||
.then(rows => Promise.all(rows.map(sweepHdRow)))
|
||||
.catch(err => logger.error(err))
|
||||
}
|
||||
|
|
@ -777,15 +707,14 @@ function plugins (settings, deviceId) {
|
|||
const fiatCode = localeConfig.fiatCurrency
|
||||
|
||||
const cryptoCodes = configManager.getAllCryptoCurrencies(settings.config)
|
||||
const tickerPromises = cryptoCodes.map(c =>
|
||||
ticker.getRates(settings, fiatCode, c)
|
||||
)
|
||||
const tickerPromises = cryptoCodes.map(c => ticker.getRates(settings, fiatCode, c))
|
||||
|
||||
return Promise.all(tickerPromises)
|
||||
}
|
||||
|
||||
function getRates () {
|
||||
return getRawRates().then(buildRates)
|
||||
return getRawRates()
|
||||
.then(buildRates)
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const _ = require('lodash/fp')
|
||||
|
||||
const plugins = require('./plugins')
|
||||
const notifier = require('./notifier/index')
|
||||
const notifier = require('./notifier')
|
||||
const T = require('./time')
|
||||
const logger = require('./logger')
|
||||
const cashOutTx = require('./cash-out/cash-out-tx')
|
||||
|
|
|
|||
|
|
@ -324,7 +324,6 @@ function updateCustomer (req, res, next) {
|
|||
}
|
||||
|
||||
function triggerSanctions (req, res, next) {
|
||||
console.log("SANCTIONS TRIGGERED")
|
||||
const id = req.params.id
|
||||
|
||||
customers.getById(id)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ const mem = require('mem')
|
|||
const configManager = require('./new-config-manager')
|
||||
const ph = require('./plugin-helper')
|
||||
const logger = require('./logger')
|
||||
const axios = require('axios')
|
||||
|
||||
const lastRate = {}
|
||||
|
||||
|
|
@ -40,26 +39,4 @@ const getRates = mem(_getRates, {
|
|||
cacheKey: (settings, fiatCode, cryptoCode) => JSON.stringify([fiatCode, cryptoCode])
|
||||
})
|
||||
|
||||
const getBtcRates = (to = null, from = 'USD') => {
|
||||
// if to !== null, then we return only the rates with from (default USD) and to (so an array with 2 items)
|
||||
return axios.get('https://bitpay.com/api/rates').then(response => {
|
||||
const fxRates = response.data
|
||||
if (to === null) {
|
||||
return fxRates
|
||||
}
|
||||
const toRate = fxRates.find(o => o.code === to)
|
||||
const fromRate = fxRates.find(o => o.code === from)
|
||||
|
||||
let res = []
|
||||
if (toRate && to !== from) {
|
||||
res = [...res, toRate]
|
||||
}
|
||||
if (fromRate) {
|
||||
res = [...res, fromRate]
|
||||
}
|
||||
|
||||
return res
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = { getBtcRates, getRates }
|
||||
module.exports = { getRates }
|
||||
|
|
|
|||
43032
new-lamassu-admin/package-lock.json
generated
43032
new-lamassu-admin/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -91,7 +91,6 @@ const TL2 = pBuilder('tl2')
|
|||
const Label1 = pBuilder('label1')
|
||||
const Label2 = pBuilder('label2')
|
||||
const Label3 = pBuilder('label3')
|
||||
const Label4 = pBuilder('regularLabel')
|
||||
|
||||
function pBuilder(elementClass) {
|
||||
return ({ inline, noMargin, className, children, ...props }) => {
|
||||
|
|
@ -125,6 +124,5 @@ export {
|
|||
Mono,
|
||||
Label1,
|
||||
Label2,
|
||||
Label3,
|
||||
Label4
|
||||
Label3
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const base = {
|
|||
color: fontColor
|
||||
}
|
||||
|
||||
const styles = {
|
||||
export default {
|
||||
h1: {
|
||||
extend: base,
|
||||
fontSize: fontSize1,
|
||||
|
|
@ -132,5 +132,3 @@ const styles = {
|
|||
margin: 0
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import {
|
|||
TransactionsList,
|
||||
ComplianceDetails
|
||||
} from './components'
|
||||
import { /* getFormattedPhone, */ getName } from './helper'
|
||||
import { getFormattedPhone, getName } from './helper'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
|
|
@ -147,13 +147,12 @@ const CustomerProfile = memo(() => {
|
|||
Customers
|
||||
</Label1>
|
||||
<Label2 noMargin className={classes.labelLink}>
|
||||
{name.length ? name : R.path(['phone'])(customerData)}
|
||||
{/* {name.length
|
||||
{name.length
|
||||
? name
|
||||
: getFormattedPhone(
|
||||
R.path(['phone'])(customerData),
|
||||
locale.country
|
||||
)} */}
|
||||
)}
|
||||
</Label2>
|
||||
</Breadcrumbs>
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,7 @@ import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-ou
|
|||
import { ifNotNull } from 'src/utils/nullCheck'
|
||||
|
||||
import styles from './CustomersList.styles'
|
||||
import {
|
||||
getAuthorizedStatus,
|
||||
getName
|
||||
/* getFormattedPhone */
|
||||
} from './helper'
|
||||
import { getAuthorizedStatus, getFormattedPhone, getName } from './helper'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
|
|
@ -26,7 +22,7 @@ const CustomersList = ({ data, locale, onClick, loading }) => {
|
|||
{
|
||||
header: 'Phone',
|
||||
width: 172,
|
||||
view: it => it.phone // getFormattedPhone(it.phone, locale.country)
|
||||
view: it => getFormattedPhone(it.phone, locale.country)
|
||||
},
|
||||
{
|
||||
header: 'Name',
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { ReactComponent as LawIconInverse } from 'src/styling/icons/circle butto
|
|||
import { ReactComponent as LawIcon } from 'src/styling/icons/circle buttons/law/zodiac.svg'
|
||||
|
||||
import mainStyles from '../CustomersList.styles'
|
||||
import { /* getFormattedPhone, */ getName } from '../helper'
|
||||
import { getFormattedPhone, getName } from '../helper'
|
||||
|
||||
import FrontCameraPhoto from './FrontCameraPhoto'
|
||||
|
||||
|
|
@ -22,7 +22,7 @@ const CustomerDetails = memo(({ customer, locale, setShowCompliance }) => {
|
|||
{
|
||||
header: 'Phone number',
|
||||
size: 172,
|
||||
value: customer.phone // getFormattedPhone(customer.phone, locale.country)
|
||||
value: getFormattedPhone(customer.phone, locale.country)
|
||||
},
|
||||
{
|
||||
header: 'ID number',
|
||||
|
|
@ -47,8 +47,9 @@ const CustomerDetails = memo(({ customer, locale, setShowCompliance }) => {
|
|||
<div className={classes.name}>
|
||||
<IdIcon className={classes.idIcon} />
|
||||
<H2 noMargin>
|
||||
{name.length ? name : R.path(['phone'])(customer)}
|
||||
{/* getFormattedPhone(R.path(['phone'])(customer), locale.country)} */}
|
||||
{name.length
|
||||
? name
|
||||
: getFormattedPhone(R.path(['phone'])(customer), locale.country)}
|
||||
</H2>
|
||||
<SubpageButton
|
||||
className={classes.subpageButton}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ const getAuthorizedStatus = it =>
|
|||
: { label: 'Authorized', type: 'success' }
|
||||
|
||||
const getFormattedPhone = (phone, country) => {
|
||||
return phone && country
|
||||
? parsePhoneNumberFromString(phone, country).formatInternational()
|
||||
: ''
|
||||
const phoneNumber =
|
||||
phone && country ? parsePhoneNumberFromString(phone, country) : null
|
||||
|
||||
return phoneNumber ? phoneNumber.formatInternational() : phone
|
||||
}
|
||||
|
||||
const getName = it => {
|
||||
|
|
|
|||
|
|
@ -53,10 +53,7 @@ const Alerts = ({ onReset, onExpand, size }) => {
|
|||
{showAllItems && (
|
||||
<Label1 className={classes.upperButtonLabel}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
console.log('aaaa')
|
||||
onReset()
|
||||
}}
|
||||
onClick={onReset}
|
||||
size="small"
|
||||
disableRipple
|
||||
disableFocusRipple
|
||||
|
|
|
|||
|
|
@ -31,42 +31,49 @@ const styles = {
|
|||
other: {
|
||||
minWidth: '6px',
|
||||
borderRadius: 2
|
||||
},
|
||||
inWidth: {
|
||||
width: value => `${value}%`
|
||||
},
|
||||
outWidth: {
|
||||
width: value => `${100 - value}%`,
|
||||
marginRight: 4
|
||||
}
|
||||
}
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const PercentageChart = ({ cashIn, cashOut }) => {
|
||||
const classes = useStyles()
|
||||
const value = cashIn || cashOut !== 0 ? cashIn : 50
|
||||
const classes = useStyles(value)
|
||||
|
||||
const buildPercentageView = value => {
|
||||
if (value > 15) {
|
||||
return <Label1 className={classes.label}>{` ${value}%`}</Label1>
|
||||
}
|
||||
if (value <= 15) return
|
||||
return <Label1 className={classes.label}>{value}%</Label1>
|
||||
}
|
||||
|
||||
const percentageClasses = {
|
||||
[classes.percentageBox]: true,
|
||||
[classes.other]: value < 5 && value > 0
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<div
|
||||
className={classnames(
|
||||
classes.percentageBox,
|
||||
classes.inColor,
|
||||
// if value between [1, 4], percentage box should not go below 6 px and border radius is 2px
|
||||
// if value is 0 or 100, then width will be allowed to be 0px in one of the boxes, making it disappear
|
||||
value < 5 && value > 0 ? classes.other : null
|
||||
)}
|
||||
style={{ width: `${value}%`, marginRight: 4 }}>
|
||||
{buildPercentageView(value, 'cashIn')}
|
||||
percentageClasses,
|
||||
classes.outColor,
|
||||
classes.outWidth
|
||||
)}>
|
||||
{buildPercentageView(100 - value, 'cashOut')}
|
||||
</div>
|
||||
<div
|
||||
className={classnames(
|
||||
classes.percentageBox,
|
||||
classes.outColor,
|
||||
100 - value < 5 && 100 - value > 0 ? classes.other : null
|
||||
)}
|
||||
style={{ width: `${100 - value}%` }}>
|
||||
{buildPercentageView(100 - value, 'cashOut')}
|
||||
percentageClasses,
|
||||
classes.inColor,
|
||||
classes.inWidth
|
||||
)}>
|
||||
{buildPercentageView(value, 'cashIn')}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,74 +0,0 @@
|
|||
import { makeStyles } from '@material-ui/core/styles'
|
||||
import classnames from 'classnames'
|
||||
import * as R from 'ramda'
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { CopyToClipboard as ReactCopyToClipboard } from 'react-copy-to-clipboard'
|
||||
|
||||
import Popover from 'src/components/Popper'
|
||||
import { ReactComponent as CopyIcon } from 'src/styling/icons/action/copy/copy.svg'
|
||||
import { comet } from 'src/styling/variables'
|
||||
|
||||
import { cpcStyles } from './Transactions.styles'
|
||||
|
||||
const useStyles = makeStyles(cpcStyles)
|
||||
|
||||
const CopyToClipboard = ({
|
||||
className,
|
||||
buttonClassname,
|
||||
children,
|
||||
...props
|
||||
}) => {
|
||||
const [anchorEl, setAnchorEl] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (anchorEl) setTimeout(() => setAnchorEl(null), 3000)
|
||||
}, [anchorEl])
|
||||
|
||||
const classes = useStyles()
|
||||
|
||||
const handleClick = event => {
|
||||
setAnchorEl(anchorEl ? null : event.currentTarget)
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null)
|
||||
}
|
||||
|
||||
const open = Boolean(anchorEl)
|
||||
const id = open ? 'simple-popper' : undefined
|
||||
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
{children && (
|
||||
<>
|
||||
<div className={classnames(classes.address, className)}>
|
||||
{children}
|
||||
</div>
|
||||
<div className={classnames(classes.buttonWrapper, buttonClassname)}>
|
||||
<ReactCopyToClipboard text={R.replace(/\s/g, '')(children)}>
|
||||
<button
|
||||
aria-describedby={id}
|
||||
onClick={event => handleClick(event)}>
|
||||
<CopyIcon />
|
||||
</button>
|
||||
</ReactCopyToClipboard>
|
||||
</div>
|
||||
<Popover
|
||||
id={id}
|
||||
open={open}
|
||||
anchorEl={anchorEl}
|
||||
onClose={handleClose}
|
||||
arrowSize={3}
|
||||
bgColor={comet}
|
||||
placement="top">
|
||||
<div className={classes.popoverContent}>
|
||||
<div>Copied to clipboard!</div>
|
||||
</div>
|
||||
</Popover>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CopyToClipboard
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
import { zircon } from 'src/styling/variables'
|
||||
|
||||
const styles = {
|
||||
expandButton: {
|
||||
outline: 'none',
|
||||
border: 'none',
|
||||
backgroundColor: 'transparent',
|
||||
cursor: 'pointer',
|
||||
padding: 4
|
||||
},
|
||||
rowWrapper: {
|
||||
// workaround to shadows cut by r-virtualized when scroll is visible
|
||||
padding: 1
|
||||
},
|
||||
row: {
|
||||
border: [[2, 'solid', 'transparent']],
|
||||
borderRadius: 0
|
||||
},
|
||||
expanded: {
|
||||
border: [[2, 'solid', zircon]],
|
||||
boxShadow: '0 0 8px 0 rgba(0,0,0,0.08)'
|
||||
},
|
||||
before: {
|
||||
paddingTop: 12
|
||||
},
|
||||
after: {
|
||||
paddingBottom: 12
|
||||
},
|
||||
pointer: {
|
||||
cursor: 'pointer'
|
||||
},
|
||||
body: {
|
||||
flex: [[1, 1, 'auto']]
|
||||
},
|
||||
table: ({ width }) => ({
|
||||
marginBottom: 30,
|
||||
minHeight: 200,
|
||||
width,
|
||||
flex: 1,
|
||||
display: 'flex',
|
||||
flexDirection: 'column'
|
||||
})
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,195 +0,0 @@
|
|||
import { makeStyles, Box } from '@material-ui/core'
|
||||
import BigNumber from 'bignumber.js'
|
||||
import moment from 'moment'
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import { IDButton } from 'src/components/buttons'
|
||||
import { Label1 } from 'src/components/typography'
|
||||
import { ReactComponent as CardIdInverseIcon } from 'src/styling/icons/ID/card/white.svg'
|
||||
import { ReactComponent as CardIdIcon } from 'src/styling/icons/ID/card/zodiac.svg'
|
||||
import { ReactComponent as PhoneIdInverseIcon } from 'src/styling/icons/ID/phone/white.svg'
|
||||
import { ReactComponent as PhoneIdIcon } from 'src/styling/icons/ID/phone/zodiac.svg'
|
||||
import { ReactComponent as CamIdInverseIcon } from 'src/styling/icons/ID/photo/white.svg'
|
||||
import { ReactComponent as CamIdIcon } from 'src/styling/icons/ID/photo/zodiac.svg'
|
||||
import { ReactComponent as TxInIcon } from 'src/styling/icons/direction/cash-in.svg'
|
||||
import { ReactComponent as TxOutIcon } from 'src/styling/icons/direction/cash-out.svg'
|
||||
import { URI } from 'src/utils/apollo'
|
||||
import { toUnit, formatCryptoAddress } from 'src/utils/coin'
|
||||
import { onlyFirstToUpper } from 'src/utils/string'
|
||||
|
||||
import CopyToClipboard from './CopyToClipboard'
|
||||
import styles from './DetailsCard.styles'
|
||||
import { getStatus } from './helper'
|
||||
|
||||
const useStyles = makeStyles(styles)
|
||||
|
||||
const formatAddress = (cryptoCode = '', address = '') =>
|
||||
formatCryptoAddress(cryptoCode, address).replace(/(.{5})/g, '$1 ')
|
||||
|
||||
const Label = ({ children }) => {
|
||||
const classes = useStyles()
|
||||
return <Label1 className={classes.label}>{children}</Label1>
|
||||
}
|
||||
|
||||
const DetailsRow = ({ it: tx }) => {
|
||||
const classes = useStyles()
|
||||
|
||||
const fiat = Number.parseFloat(tx.fiat)
|
||||
const crypto = toUnit(new BigNumber(tx.cryptoAtoms), tx.cryptoCode)
|
||||
const commissionPercentage = Number.parseFloat(tx.commissionPercentage, 2)
|
||||
const commission = Number(fiat * commissionPercentage).toFixed(2)
|
||||
const exchangeRate = Number(fiat / crypto).toFixed(3)
|
||||
const displayExRate = `1 ${tx.cryptoCode} = ${exchangeRate} ${tx.fiatCode}`
|
||||
|
||||
const customer = tx.customerIdCardData && {
|
||||
name: `${onlyFirstToUpper(
|
||||
tx.customerIdCardData.firstName
|
||||
)} ${onlyFirstToUpper(tx.customerIdCardData.lastName)}`,
|
||||
age: moment().diff(moment(tx.customerIdCardData.dateOfBirth), 'years'),
|
||||
country: tx.customerIdCardData.country,
|
||||
idCardNumber: tx.customerIdCardData.documentNumber,
|
||||
idCardExpirationDate: moment(tx.customerIdCardData.expirationDate).format(
|
||||
'DD-MM-YYYY'
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.wrapper}>
|
||||
<div className={classes.row}>
|
||||
<div className={classes.direction}>
|
||||
<Label>Direction</Label>
|
||||
<div>
|
||||
<span className={classes.txIcon}>
|
||||
{tx.txClass === 'cashOut' ? <TxOutIcon /> : <TxInIcon />}
|
||||
</span>
|
||||
<span>{tx.txClass === 'cashOut' ? 'Cash-out' : 'Cash-in'}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes.availableIds}>
|
||||
<Label>Available IDs</Label>
|
||||
<Box display="flex" flexDirection="row">
|
||||
{tx.customerPhone && (
|
||||
<IDButton
|
||||
className={classes.idButton}
|
||||
name="phone"
|
||||
Icon={PhoneIdIcon}
|
||||
InverseIcon={PhoneIdInverseIcon}>
|
||||
{tx.customerPhone}
|
||||
</IDButton>
|
||||
)}
|
||||
{tx.customerIdCardPhotoPath && !tx.customerIdCardData && (
|
||||
<IDButton
|
||||
popoverClassname={classes.popover}
|
||||
className={classes.idButton}
|
||||
name="card"
|
||||
Icon={CardIdIcon}
|
||||
InverseIcon={CardIdInverseIcon}>
|
||||
<img
|
||||
className={classes.idCardPhoto}
|
||||
src={`${URI}/id-card-photo/${tx.customerIdCardPhotoPath}`}
|
||||
alt=""
|
||||
/>
|
||||
</IDButton>
|
||||
)}
|
||||
{tx.customerIdCardData && (
|
||||
<IDButton
|
||||
className={classes.idButton}
|
||||
name="card"
|
||||
Icon={CardIdIcon}
|
||||
InverseIcon={CardIdInverseIcon}>
|
||||
<div className={classes.idCardDataCard}>
|
||||
<div>
|
||||
<div>
|
||||
<Label>Name</Label>
|
||||
<div>{customer.name}</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Age</Label>
|
||||
<div>{customer.age}</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Country</Label>
|
||||
<div>{customer.country}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<Label>ID number</Label>
|
||||
<div>{customer.idCardNumber}</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Expiration date</Label>
|
||||
<div>{customer.idCardExpirationDate}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</IDButton>
|
||||
)}
|
||||
{tx.customerFrontCameraPath && (
|
||||
<IDButton
|
||||
name="cam"
|
||||
Icon={CamIdIcon}
|
||||
InverseIcon={CamIdInverseIcon}>
|
||||
<img
|
||||
src={`${URI}/front-camera-photo/${tx.customerFrontCameraPath}`}
|
||||
alt=""
|
||||
/>
|
||||
</IDButton>
|
||||
)}
|
||||
</Box>
|
||||
</div>
|
||||
<div className={classes.exchangeRate}>
|
||||
<Label>Exchange rate</Label>
|
||||
<div>{crypto > 0 ? displayExRate : '-'}</div>
|
||||
</div>
|
||||
<div className={classes.commission}>
|
||||
<Label>Commission</Label>
|
||||
<div>
|
||||
{`${commission} ${tx.fiatCode} (${commissionPercentage * 100} %)`}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label>Fixed fee</Label>
|
||||
<div>
|
||||
{tx.txClass === 'cashIn'
|
||||
? `${Number.parseFloat(tx.cashInFee)} ${tx.fiatCode}`
|
||||
: 'N/A'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.secondRow}>
|
||||
<div className={classes.address}>
|
||||
<Label>Address</Label>
|
||||
<div>
|
||||
<CopyToClipboard>
|
||||
{formatAddress(tx.cryptoCode, tx.toAddress)}
|
||||
</CopyToClipboard>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.transactionId}>
|
||||
<Label>Transaction ID</Label>
|
||||
<div>
|
||||
{tx.txClass === 'cashOut' ? (
|
||||
'N/A'
|
||||
) : (
|
||||
<CopyToClipboard>{tx.txHash}</CopyToClipboard>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.sessionId}>
|
||||
<Label>Session ID</Label>
|
||||
<CopyToClipboard>{tx.id}</CopyToClipboard>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes.lastRow}>
|
||||
<div>
|
||||
<Label>Transaction status</Label>
|
||||
<span className={classes.bold}>{getStatus(tx)}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(DetailsRow, (prev, next) => prev.id === next.id)
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
import typographyStyles from 'src/components/typography/styles'
|
||||
import { offColor } from 'src/styling/variables'
|
||||
|
||||
const { p } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
marginTop: 24
|
||||
},
|
||||
row: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
marginBottom: 36
|
||||
},
|
||||
secondRow: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 36
|
||||
},
|
||||
lastRow: {
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
marginBottom: 32
|
||||
},
|
||||
label: {
|
||||
color: offColor,
|
||||
margin: [[0, 0, 6, 0]]
|
||||
},
|
||||
txIcon: {
|
||||
marginRight: 10
|
||||
},
|
||||
popover: {
|
||||
height: 164,
|
||||
width: 215
|
||||
},
|
||||
idButton: {
|
||||
marginRight: 4
|
||||
},
|
||||
idCardDataCard: {
|
||||
extend: p,
|
||||
display: 'flex',
|
||||
padding: [[11, 8]],
|
||||
// rework this into a proper component
|
||||
'& > div': {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
'& > div': {
|
||||
width: 144,
|
||||
height: 37,
|
||||
marginBottom: 15,
|
||||
'&:last-child': {
|
||||
marginBottom: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
bold: {
|
||||
fontWeight: 700
|
||||
},
|
||||
direction: {
|
||||
width: 233
|
||||
},
|
||||
availableIds: {
|
||||
width: 232
|
||||
},
|
||||
exchangeRate: {
|
||||
width: 250
|
||||
},
|
||||
commission: {
|
||||
width: 217
|
||||
},
|
||||
address: {
|
||||
width: 280
|
||||
},
|
||||
transactionId: {
|
||||
width: 280
|
||||
},
|
||||
sessionId: {
|
||||
width: 215
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import React from 'react'
|
||||
|
||||
import { Td } from 'src/components/fake-table/Table'
|
||||
import { ReactComponent as StripesSvg } from 'src/styling/icons/stripes.svg'
|
||||
|
||||
const Stripes = ({ width }) => (
|
||||
<Td width={width}>
|
||||
<StripesSvg />
|
||||
</Td>
|
||||
)
|
||||
|
||||
export default Stripes
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
const getCashOutStatus = it => {
|
||||
if (it.hasError) return 'Error'
|
||||
if (it.dispense) return 'Success'
|
||||
if (it.expired) return 'Expired'
|
||||
return 'Pending'
|
||||
}
|
||||
|
||||
const getCashInStatus = it => {
|
||||
if (it.operatorCompleted) return 'Cancelled'
|
||||
if (it.hasError) return 'Error'
|
||||
if (it.sendConfirmed) return 'Sent'
|
||||
if (it.expired) return 'Expired'
|
||||
return 'Pending'
|
||||
}
|
||||
|
||||
const getStatus = it => {
|
||||
if (it.class === 'cashOut') {
|
||||
return getCashOutStatus(it)
|
||||
}
|
||||
return getCashInStatus(it)
|
||||
}
|
||||
|
||||
export { getStatus }
|
||||
|
|
@ -9,8 +9,8 @@ import { transformNumber } from 'src/utils/number'
|
|||
|
||||
import NotificationsCtx from '../NotificationsContext'
|
||||
|
||||
const HIGH_BALANCE_KEY = 'cryptoHighBalance'
|
||||
const LOW_BALANCE_KEY = 'cryptoLowBalance'
|
||||
const HIGH_BALANCE_KEY = 'highBalance'
|
||||
const LOW_BALANCE_KEY = 'lowBalance'
|
||||
const CRYPTOCURRENCY_KEY = 'cryptoCurrency'
|
||||
const NAME = 'cryptoBalanceOverrides'
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { offColor } from 'src/styling/variables'
|
|||
|
||||
const { p } = typographyStyles
|
||||
|
||||
const styles = {
|
||||
export default {
|
||||
wrapper: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
|
@ -81,5 +81,3 @@ const styles = {
|
|||
width: 215
|
||||
}
|
||||
}
|
||||
|
||||
export default styles
|
||||
|
|
|
|||
833
package-lock.json
generated
833
package-lock.json
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue