Merge branch 'dev' into fix/lam-266/profits-calculation

This commit is contained in:
André Sá 2022-02-04 18:25:06 +00:00
commit c985458bff
33 changed files with 95 additions and 114 deletions

View file

@ -3,7 +3,7 @@
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 { utils: coinUtils } = require('lamassu-coins')
const BN = require('../lib/bn')
const inquirer = require('inquirer')
const ticker = require('../lib/ticker')

View file

@ -47,6 +47,7 @@ const typeDef = gql`
txCustomerPhotoAt: Date
batched: Boolean
batchTime: Date
batchError: String
walletScore: Int
}

View file

@ -4,6 +4,7 @@ const settingsLoader = require('../../new-settings-loader')
const configManager = require('../../new-config-manager')
const wallet = require('../../wallet')
const ticker = require('../../ticker')
const txBatching = require('../../tx-batching')
const { utils: coinUtils } = require('lamassu-coins')
function computeCrypto (cryptoCode, _balance) {
@ -23,16 +24,17 @@ function computeFiat (rate, cryptoCode, _balance) {
function getSingleCoinFunding (settings, fiatCode, cryptoCode) {
const promises = [
wallet.newFunding(settings, cryptoCode),
ticker.getRates(settings, fiatCode, cryptoCode)
ticker.getRates(settings, fiatCode, cryptoCode),
txBatching.getOpenBatchCryptoValue(cryptoCode)
]
return Promise.all(promises)
.then(([fundingRec, ratesRec]) => {
.then(([fundingRec, ratesRec, batchRec]) => {
const rates = ratesRec.rates
const rate = (rates.ask.plus(rates.bid)).div(2)
const fundingConfirmedBalance = fundingRec.fundingConfirmedBalance
const fiatConfirmedBalance = computeFiat(rate, cryptoCode, fundingConfirmedBalance)
const pending = fundingRec.fundingPendingBalance
const pending = fundingRec.fundingPendingBalance.minus(batchRec)
const fiatPending = computeFiat(rate, cryptoCode, pending)
const fundingAddress = fundingRec.fundingAddress
const fundingAddressUrl = coinUtils.buildUrl(cryptoCode, fundingAddress)

View file

@ -54,10 +54,12 @@ function batch (
c.id_card_photo_path AS customer_id_card_photo_path,
txs.tx_customer_photo_at AS tx_customer_photo_at,
txs.tx_customer_photo_path AS tx_customer_photo_path,
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired,
tb.error_message AS batch_error
FROM (SELECT *, ${cashInTx.TRANSACTION_STATES} AS txStatus FROM cash_in_txs) AS txs
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
LEFT JOIN devices d ON txs.device_id = d.device_id
LEFT OUTER JOIN transaction_batches tb ON txs.batch_id = tb.id
WHERE txs.created >= $2 AND txs.created <= $3 ${
id !== null ? `AND txs.device_id = $6` : ``
}
@ -69,7 +71,7 @@ function batch (
AND ($12 is null or txs.to_address = $12)
AND ($13 is null or txs.txStatus = $13)
${excludeTestingCustomers ? `AND c.is_test_customer is false` : ``}
AND (error IS NOT null OR fiat > 0)
AND (error IS NOT null OR tb.error_message IS NOT null OR fiat > 0)
ORDER BY created DESC limit $4 offset $5`
const cashOutSql = `SELECT 'cashOut' AS tx_class,
@ -158,6 +160,7 @@ const getCashOutStatus = it => {
const getCashInStatus = it => {
if (it.operatorCompleted) return 'Cancelled'
if (it.hasError) return 'Error'
if (it.batchError) return 'Error'
if (it.sendConfirmed) return 'Sent'
if (it.expired) return 'Expired'
return 'Pending'
@ -183,9 +186,11 @@ function getCustomerTransactionsBatch (ids) {
c.name AS customer_name,
c.front_camera_path AS customer_front_camera_path,
c.id_card_photo_path AS customer_id_card_photo_path,
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $2)) AS expired
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $2)) AS expired,
tb.error_message AS batch_error
FROM cash_in_txs AS txs
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
LEFT OUTER JOIN transaction_batches tb ON txs.batch_id = tb.id
WHERE c.id IN ($1^)
ORDER BY created DESC limit $3`
@ -227,9 +232,11 @@ function single (txId) {
c.name AS customer_name,
c.front_camera_path AS customer_front_camera_path,
c.id_card_photo_path AS customer_id_card_photo_path,
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired,
tb.error_message AS batch_error
FROM cash_in_txs AS txs
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
LEFT OUTER JOIN transaction_batches tb ON txs.batch_id = tb.id
WHERE id=$2`
const cashOutSql = `SELECT 'cashOut' AS tx_class,

View file

@ -8,8 +8,6 @@ const { utils: coinUtils } = require('lamassu-coins')
const cryptoRec = coinUtils.getCryptoCurrency('BCH')
const unitScale = cryptoRec.unitScale
const SUPPORTS_BATCHING = false
const rpcConfig = jsonRpc.rpcConfig(cryptoRec)
function fetch (method, params) {
@ -118,11 +116,6 @@ function cryptoNetwork (account, cryptoCode, settings, operatorId) {
.then(() => parseInt(rpcConfig.port, 10) === 18332 ? 'test' : 'main')
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => fetch('getblockchaininfo'))
@ -136,6 +129,5 @@ module.exports = {
getStatus,
newFunding,
cryptoNetwork,
supportsBatching,
checkBlockchainStatus
}

View file

@ -9,7 +9,6 @@ const { utils: coinUtils } = require('lamassu-coins')
const cryptoRec = coinUtils.getCryptoCurrency('BTC')
const unitScale = cryptoRec.unitScale
const SUPPORTS_BATCHING = true
const rpcConfig = jsonRpc.rpcConfig(cryptoRec)
function fetch (method, params) {
@ -80,19 +79,19 @@ function sendCoins (account, tx, settings, operatorId, feeMultiplier) {
})
}
function sendCoinsBatch (account, txs, cryptoCode) {
function sendCoinsBatch (account, txs, cryptoCode, feeMultiplier) {
return checkCryptoCode(cryptoCode)
.then(() => calculateFeeDiscount(feeMultiplier))
.then(newFee => fetch('settxfee', [newFee]))
.then(() => {
const txAddressAmountPairs = _.map(tx => [tx.address, tx.cryptoAtoms.shift(-unitScale).toFixed(8)], txs)
const txAddressAmountPairs = _.map(tx => [tx.address, tx.cryptoAtoms.shiftedBy(-unitScale).toFixed(8)], txs)
return Promise.all([JSON.stringify(_.fromPairs(txAddressAmountPairs))])
})
.then(([obj]) => fetch('sendmany', ['', obj]))
.then((txId) => fetch('gettransaction', [txId]))
.then((res) => _.pick(['fee', 'txid'], res))
.then((pickedObj) => ({
fee: BN(pickedObj.fee).abs().shift(unitScale).round(),
fee: new BN(pickedObj.fee).abs().shiftedBy(unitScale).decimalPlaces(0),
txid: pickedObj.txid
}))
.catch(err => {
@ -171,11 +170,6 @@ function fetchRBF (txId) {
})
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => fetch('getblockchaininfo'))
@ -192,6 +186,5 @@ module.exports = {
fetchRBF,
estimateFee,
sendCoinsBatch,
supportsBatching,
checkBlockchainStatus
}

View file

@ -14,8 +14,6 @@ const NAME = 'BitGo'
const SUPPORTED_COINS = ['BTC', 'ZEC', 'LTC', 'BCH', 'DASH']
const BCH_CODES = ['BCH', 'TBCH']
const SUPPORTS_BATCHING = false
function buildBitgo (account) {
const env = account.environment === 'test' ? 'test' : 'prod'
return new BitGo.BitGo({ accessToken: account.token.trim(), env, userAgent: userAgent })
@ -159,11 +157,6 @@ function cryptoNetwork (account, cryptoCode, settings, operatorId) {
.then(() => account.environment === 'test' ? 'test' : 'main')
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => Promise.resolve('ready'))
@ -177,6 +170,5 @@ module.exports = {
getStatus,
newFunding,
cryptoNetwork,
supportsBatching,
checkBlockchainStatus
}

View file

@ -9,7 +9,6 @@ const E = require('../../../error')
const cryptoRec = coinUtils.getCryptoCurrency('DASH')
const unitScale = cryptoRec.unitScale
const SUPPORTS_BATCHING = false
const rpcConfig = jsonRpc.rpcConfig(cryptoRec)
function fetch (method, params) {
@ -113,11 +112,6 @@ function newFunding (account, cryptoCode, settings, operatorId) {
}))
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => fetch('getblockchaininfo'))
@ -130,6 +124,5 @@ module.exports = {
newAddress,
getStatus,
newFunding,
supportsBatching,
checkBlockchainStatus
}

View file

@ -17,8 +17,6 @@ const paymentPrefixPath = "m/44'/60'/0'/0'"
const defaultPrefixPath = "m/44'/60'/1'/0'"
let lastUsedNonces = {}
const SUPPORTS_BATCHING = false
module.exports = {
NAME,
balance,
@ -32,7 +30,6 @@ module.exports = {
privateKey,
isStrictAddress,
connect,
supportsBatching,
checkBlockchainStatus
}
@ -227,11 +224,6 @@ function newFunding (account, cryptoCode, settings, operatorId) {
})
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(pify(web3.eth.isSyncing))

View file

@ -9,7 +9,6 @@ const E = require('../../../error')
const cryptoRec = coinUtils.getCryptoCurrency('LTC')
const unitScale = cryptoRec.unitScale
const SUPPORTS_BATCHING = false
const rpcConfig = jsonRpc.rpcConfig(cryptoRec)
function fetch (method, params) {
@ -113,11 +112,6 @@ function newFunding (account, cryptoCode, settings, operatorId) {
}))
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => fetch('getblockchaininfo'))
@ -130,6 +124,5 @@ module.exports = {
newAddress,
getStatus,
newFunding,
supportsBatching,
checkBlockchainStatus
}

View file

@ -5,7 +5,6 @@ const E = require('../../../error')
const { utils: coinUtils } = require('lamassu-coins')
const NAME = 'FakeWallet'
const BATCHABLE_COINS = ['BTC']
const SECONDS = 1000
const PUBLISH_TIME = 3 * SECONDS
@ -111,10 +110,6 @@ function getStatus (account, tx, requested, settings, operatorId) {
return Promise.resolve({status: 'confirmed'})
}
function supportsBatching (cryptoCode) {
return Promise.resolve(_.includes(cryptoCode, BATCHABLE_COINS))
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => Promise.resolve('ready'))
@ -128,6 +123,5 @@ module.exports = {
newAddress,
getStatus,
newFunding,
supportsBatching,
checkBlockchainStatus
}

View file

@ -17,8 +17,6 @@ const configPath = utils.configPath(cryptoRec, blockchainDir)
const walletDir = path.resolve(utils.cryptoDir(cryptoRec, blockchainDir), 'wallets')
const unitScale = cryptoRec.unitScale
const SUPPORTS_BATCHING = false
function rpcConfig () {
try {
const config = jsonRpc.parseConf(configPath)
@ -92,7 +90,7 @@ function accountBalance (cryptoCode) {
.then(() => refreshWallet())
.then(() => fetch('get_balance', { account_index: 0, address_indices: [0] }))
.then(res => {
return BN(res.unlocked_balance).shift(unitScale).round()
return BN(res.unlocked_balance).shiftedBy(unitScale).decimalPlaces(0)
})
.catch(err => handleError(err))
}
@ -177,7 +175,7 @@ function newFunding (account, cryptoCode) {
fetch('create_address', { account_index: 0 })
]))
.then(([balanceRes, addressRes]) => ({
fundingPendingBalance: BN(balanceRes.balance).sub(balanceRes.unlocked_balance),
fundingPendingBalance: BN(balanceRes.balance).minus(balanceRes.unlocked_balance),
fundingConfirmedBalance: BN(balanceRes.unlocked_balance),
fundingAddress: addressRes.address
}))
@ -200,11 +198,6 @@ function cryptoNetwork (account, cryptoCode) {
})
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => {
@ -236,6 +229,5 @@ module.exports = {
getStatus,
newFunding,
cryptoNetwork,
supportsBatching,
checkBlockchainStatus
}

View file

@ -9,7 +9,6 @@ const E = require('../../../error')
const cryptoRec = coinUtils.getCryptoCurrency('ZEC')
const unitScale = cryptoRec.unitScale
const SUPPORTS_BATCHING = false
const rpcConfig = jsonRpc.rpcConfig(cryptoRec)
@ -139,11 +138,6 @@ function newFunding (account, cryptoCode, settings, operatorId) {
}))
}
function supportsBatching (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => SUPPORTS_BATCHING)
}
function checkBlockchainStatus (cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => fetch('getblockchaininfo'))
@ -156,6 +150,5 @@ module.exports = {
newAddress,
getStatus,
newFunding,
supportsBatching,
checkBlockchainStatus
}

View file

@ -48,8 +48,7 @@ const lastBalance = {}
function _balance (settings, cryptoCode) {
return fetchWallet(settings, cryptoCode)
.then(r => r.wallet.balance(r.account, cryptoCode, settings, r.operatorId))
.then(balance => Promise.all([balance, supportsBatching(settings, cryptoCode)]))
.then(([balance, supportsBatching]) => Promise.all([balance, supportsBatching ? getOpenBatchCryptoValue(cryptoCode) : Promise.resolve(BN(0))]))
.then(balance => Promise.all([balance, getOpenBatchCryptoValue(cryptoCode)]))
.then(([balance, reservedBalance]) => ({ balance: balance.minus(reservedBalance), reservedBalance, timestamp: Date.now() }))
.then(r => {
lastBalance[cryptoCode] = r
@ -82,7 +81,8 @@ function sendCoins (settings, tx) {
function sendCoinsBatch (settings, txs, cryptoCode) {
return fetchWallet(settings, cryptoCode)
.then(r => {
return r.wallet.sendCoinsBatch(r.account, txs, cryptoCode)
const feeMultiplier = settings[`wallets_${cryptoCode}_feeMultiplier`]
return r.wallet.sendCoinsBatch(r.account, txs, cryptoCode, feeMultiplier)
.then(res => {
mem.clear(module.exports.balance)
return res
@ -233,8 +233,7 @@ function isStrictAddress (settings, cryptoCode, toAddress) {
}
function supportsBatching (settings, cryptoCode) {
return fetchWallet(settings, cryptoCode)
.then(r => r.wallet.supportsBatching(cryptoCode))
return Promise.resolve(!!configManager.getWalletSettings(cryptoCode, settings.config).allowTransactionBatching)
}
function checkBlockchainStatus (settings, cryptoCode) {

View file

@ -41,14 +41,14 @@ const useStyles = makeStyles({
})
const CheckboxInput = ({ name, onChange, value, settings, ...props }) => {
const { enabled, label, disabledMessage } = settings
const { enabled, label, disabledMessage, rightSideLabel } = settings
const classes = useStyles()
return (
<>
{enabled ? (
<div className={classes.checkBoxLabel}>
<Label2>{label}</Label2>
{!rightSideLabel && <Label2>{label}</Label2>}
<Checkbox
id={name}
classes={{
@ -67,6 +67,7 @@ const CheckboxInput = ({ name, onChange, value, settings, ...props }) => {
disableRipple
{...props}
/>
{rightSideLabel && <Label2>{label}</Label2>}
</div>
) : (
<div className={classes.wrapper}>

View file

@ -61,9 +61,9 @@ const Row = ({
expandable && expandRow(id, data)
onClick && onClick(data)
}}
error={data.error || data.hasError}
error={data.error || data.hasError || data.batchError}
shouldShowError={false}
errorMessage={data.errorMessage || data.hasError}>
errorMessage={data.errorMessage || data.hasError || data.batchError}>
{elements.map(({ view = it => it?.toString(), ...props }, idx) => (
<Td key={idx} {...props}>
{view(data)}

View file

@ -21,7 +21,6 @@ export default {
display: 'flex',
flexDirection: 'column',
'& > div': {
width: 144,
height: 37,
marginBottom: 15,
marginRight: 55

View file

@ -27,9 +27,11 @@ export default {
settings: {
field: 'wallets_BTC_wallet',
enabled: true,
disabledMessage: 'RBF verification not available',
disabledMessage:
'Lower the confidence of RBF transactions (Available when using bitcoind.)',
label: 'Lower the confidence of RBF transactions',
requirement: 'bitcoind'
requirement: 'bitcoind',
rightSideLabel: true
},
face: true
}

View file

@ -169,8 +169,8 @@ const DetailsRow = ({ it: tx, timezone }) => {
''
}
const from = sub({ minutes: MINUTES_OFFSET }, tx.created)
const until = add({ minutes: MINUTES_OFFSET }, tx.created)
const from = sub({ minutes: MINUTES_OFFSET }, new Date(tx.created))
const until = add({ minutes: MINUTES_OFFSET }, new Date(tx.created))
const downloadRawLogs = ({ id: txId, deviceId, txClass }, timezone) => {
fetchSummary({
@ -438,5 +438,6 @@ export default memo(
(prev, next) =>
prev.it.id === next.it.id &&
prev.it.hasError === next.it.hasError &&
prev.it.batchError === next.it.batchError &&
getStatus(prev.it) === getStatus(next.it)
)

View file

@ -117,6 +117,7 @@ const GET_TRANSACTIONS = gql`
batched
batchTime
rawTickerPrice
batchError
walletScore
}
}
@ -191,7 +192,7 @@ const Transactions = () => {
<div className={classes.overflowTd}>{getCustomerDisplayName(it)}</div>
{!it.isAnonymous && (
<div onClick={() => redirect(it.customerId)}>
{it.hasError ? (
{it.hasError || it.batchError ? (
<CustomerLinkWhiteIcon className={classes.customerLinkIcon} />
) : (
<CustomerLinkIcon className={classes.customerLinkIcon} />

View file

@ -1,3 +1,5 @@
import * as R from 'ramda'
const getCashOutStatus = it => {
if (it.hasError === 'Operator cancel') return 'Cancelled'
if (it.hasError) return 'Error'
@ -8,7 +10,7 @@ const getCashOutStatus = it => {
const getCashInStatus = it => {
if (it.operatorCompleted) return 'Cancelled'
if (it.hasError) return 'Error'
if (it.hasError || it.batchError) return 'Error'
if (it.sendConfirmed) return 'Sent'
if (it.expired) return 'Expired'
if (it.batched) return 'Batched'
@ -23,11 +25,14 @@ const getStatus = it => {
}
const getStatusDetails = it => {
return it.hasError ? it.hasError : null
if (!R.isNil(it.hasError)) return it.hasError
if (!R.isNil(it.batchError)) return `Batch error: ${it.batchError}`
return null
}
const getStatusProperties = status => ({
hasError: status === 'Error' || null,
batchError: status === 'Error' || null,
dispense: status === 'Success' || null,
expired: status === 'Expired' || null,
operatorCompleted: status === 'Cancelled' || null,

View file

@ -118,6 +118,9 @@ const styles = {
actionButtonWrapper: {
display: 'flex',
gap: 12
},
enterButton: {
display: 'none'
}
}

View file

@ -7,7 +7,11 @@ import React from 'react'
import { NamespacedTable as EditableTable } from 'src/components/editableTable'
import { fromNamespace, toNamespace, namespaces } from 'src/utils/config'
import { AdvancedWalletSchema, getAdvancedWalletElements } from './helper'
import {
WalletSchema,
AdvancedWalletSchema,
getAdvancedWalletElements
} from './helper'
const SAVE_CONFIG = gql`
mutation Save($config: JSONObject, $accounts: JSONObject) {
@ -51,8 +55,9 @@ const AdvancedWallet = () => {
enableEdit
editWidth={174}
save={save}
stripeWhen={it => !WalletSchema.isValidSync(it)}
validationSchema={AdvancedWalletSchema}
elements={getAdvancedWalletElements(cryptoCurrencies, coinUtils)}
elements={getAdvancedWalletElements(cryptoCurrencies, coinUtils, config)}
/>
)
}

View file

@ -1,8 +1,11 @@
import * as R from 'ramda'
import * as Yup from 'yup'
import { NumberInput } from 'src/components/inputs/formik'
import Autocomplete from 'src/components/inputs/formik/Autocomplete.js'
import {
Autocomplete,
Checkbox,
NumberInput
} from 'src/components/inputs/formik'
import { disabledColor } from 'src/styling/variables'
import { CURRENCY_MAX } from 'src/utils/constants'
import { transformNumber } from 'src/utils/number'
@ -29,10 +32,11 @@ const WalletSchema = Yup.object().shape({
})
const AdvancedWalletSchema = Yup.object().shape({
cryptoUnits: Yup.string().required()
cryptoUnits: Yup.string().required(),
allowTransactionBatching: Yup.boolean()
})
const getAdvancedWalletElements = (cryptoCurrencies, coinUtils) => {
const getAdvancedWalletElements = (cryptoCurrencies, coinUtils, config) => {
const viewCryptoCurrency = it =>
R.compose(
R.prop(['display']),
@ -66,6 +70,19 @@ const getAdvancedWalletElements = (cryptoCurrencies, coinUtils) => {
valueProp: 'code',
labelProp: 'display'
}
},
{
name: 'allowTransactionBatching',
size: 'sm',
stripe: true,
width: 250,
view: (_, ite) => {
if (ite.id !== 'BTC')
return <span style={classes.editDisabled}>{`No`}</span>
return config[`${ite.id}_allowTransactionBatching`] ? 'Yes' : 'No'
},
input: Checkbox,
editable: it => it.id === 'BTC'
}
]
}

View file

@ -1,4 +1,8 @@
const url = `https://${window.location.hostname}`
const url = `https://${
process.env.NODE_ENV === 'development'
? window.location.host
: window.location.hostname
}`
const urlResolver = content => `${url}${content}`

View file

@ -1,7 +1,7 @@
{
"files": {
"main.js": "/static/js/main.6ef30c04.chunk.js",
"main.js.map": "/static/js/main.6ef30c04.chunk.js.map",
"main.js": "/static/js/main.8cb55c42.chunk.js",
"main.js.map": "/static/js/main.8cb55c42.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.5b925903.js",
"runtime-main.js.map": "/static/js/runtime-main.5b925903.js.map",
"static/js/2.c4e7abab.chunk.js": "/static/js/2.c4e7abab.chunk.js",
@ -17,8 +17,8 @@
"static/media/4-cassettes-open-4-left.bc1a9829.svg": "/static/media/4-cassettes-open-4-left.bc1a9829.svg",
"static/media/acceptor-left.f37bcb1a.svg": "/static/media/acceptor-left.f37bcb1a.svg",
"static/media/both-filled.7af80d5f.svg": "/static/media/both-filled.7af80d5f.svg",
"static/media/carousel-left-arrow.04e38344.svg": "/static/media/carousel-left-arrow.04e38344.svg",
"static/media/carousel-right-arrow.4748b93d.svg": "/static/media/carousel-right-arrow.4748b93d.svg",
"static/media/carousel-left-arrow.c6575d9d.svg": "/static/media/carousel-left-arrow.c6575d9d.svg",
"static/media/carousel-right-arrow.1d5e04d1.svg": "/static/media/carousel-right-arrow.1d5e04d1.svg",
"static/media/cash-in.c06970a7.svg": "/static/media/cash-in.c06970a7.svg",
"static/media/cash-out.f029ae96.svg": "/static/media/cash-out.f029ae96.svg",
"static/media/cashbox-empty.828bd3b9.svg": "/static/media/cashbox-empty.828bd3b9.svg",
@ -151,6 +151,6 @@
"entrypoints": [
"static/js/runtime-main.5b925903.js",
"static/js/2.c4e7abab.chunk.js",
"static/js/main.6ef30c04.chunk.js"
"static/js/main.8cb55c42.chunk.js"
]
}

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="robots" content="noindex"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Lamassu Admin</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root" class="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],i=r[1],f=r[2],c=0,s=[];c<l.length;c++)a=l[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var i=t[l];0!==o[i]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/";var l=this["webpackJsonplamassu-admin"]=this["webpackJsonplamassu-admin"]||[],i=l.push.bind(l);l.push=r,l=l.slice();for(var f=0;f<l.length;f++)r(l[f]);var p=i;t()}([])</script><script src="/static/js/2.c4e7abab.chunk.js"></script><script src="/static/js/main.6ef30c04.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="robots" content="noindex"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Lamassu Admin</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root" class="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],i=r[1],f=r[2],c=0,s=[];c<l.length;c++)a=l[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var i=t[l];0!==o[i]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/";var l=this["webpackJsonplamassu-admin"]=this["webpackJsonplamassu-admin"]||[],i=l.push.bind(l);l.push=r,l=l.slice();for(var f=0;f<l.length;f++)r(l[f]);var p=i;t()}([])</script><script src="/static/js/2.c4e7abab.chunk.js"></script><script src="/static/js/main.8cb55c42.chunk.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="13px" height="33px" viewBox="0 0 13 33" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon id="Simple-Arrow-White" fill="#FFFFFF" fill-rule="nonzero" points="12.1912718 1.56064837 10.8306233 0.395663059 0.196798664 16.2200463 10.8250965 32.3956631 12.1967987 31.2473125 2.33241023 16.233075"></polygon>
<polygon id="Simple-Arrow-White" fill="#1b2559" fill-rule="nonzero" points="12.1912718 1.56064837 10.8306233 0.395663059 0.196798664 16.2200463 10.8250965 32.3956631 12.1967987 31.2473125 2.33241023 16.233075"></polygon>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 512 B

After

Width:  |  Height:  |  Size: 512 B

Before After
Before After

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="34px" viewBox="0 0 15 34" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-2-Copy" transform="translate(1.000000, 1.000000)" stroke="#FFFFFF" stroke-width="2">
<g id="Group-2-Copy" transform="translate(1.000000, 1.000000)" stroke="#1b2559" stroke-width="2">
<polyline id="Path-4-Copy" points="0 0 12 15.8202247 0 32"></polyline>
</g>
</g>

Before

Width:  |  Height:  |  Size: 485 B

After

Width:  |  Height:  |  Size: 485 B

Before After
Before After