Chore: fix regressions caused by rebase

This commit is contained in:
csrapr 2021-02-05 17:06:29 +00:00 committed by Josh Harvey
parent ef60b15d82
commit 0d6349dbf4
26 changed files with 10471 additions and 34310 deletions

View file

@ -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) {

View file

@ -241,7 +241,7 @@ const typeDefs = gql`
age: Float
deviceTime: Date
}
type Rate {
code: String
name: String

View file

@ -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 {

View file

@ -196,5 +196,5 @@ module.exports = {
formatCurrency,
formatAge,
buildDetail,
deviceAlerts,
deviceAlerts
}

View file

@ -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 {

View file

@ -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')

View file

@ -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)

View file

@ -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 }

File diff suppressed because it is too large Load diff

View file

@ -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
}

View file

@ -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

View file

@ -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>

View file

@ -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',

View file

@ -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}

View file

@ -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 => {

View file

@ -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

View file

@ -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>
)

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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 }

View file

@ -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'

View file

@ -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

File diff suppressed because it is too large Load diff