Merge remote-tracking branch 'upstream/release-8.0' into merge-release-8.0-into-dev-220906
This commit is contained in:
commit
4023470fec
47 changed files with 410 additions and 149 deletions
|
|
@ -27,6 +27,13 @@ function updateCore (coinRec, isCurrentlyRunning) {
|
||||||
common.es(`rm -r /tmp/${coinRec.dir.replace('/bin', '')}`)
|
common.es(`rm -r /tmp/${coinRec.dir.replace('/bin', '')}`)
|
||||||
common.es(`rm /tmp/bitcoin.tar.gz`)
|
common.es(`rm /tmp/bitcoin.tar.gz`)
|
||||||
|
|
||||||
|
if (common.es(`grep "addresstype=p2sh-segwit" /mnt/blockchains/bitcoin/bitcoin.conf || true`)) {
|
||||||
|
common.logger.info(`Enabling bech32 receiving addresses in config file..`)
|
||||||
|
common.es(`sed -i 's/addresstype=p2sh-segwit/addresstype=bech32/g' /mnt/blockchains/bitcoin/bitcoin.conf`)
|
||||||
|
} else {
|
||||||
|
common.logger.info(`bech32 receiving addresses already defined, skipping...`)
|
||||||
|
}
|
||||||
|
|
||||||
if (common.es(`grep "changetype=" /mnt/blockchains/bitcoin/bitcoin.conf || true`)) {
|
if (common.es(`grep "changetype=" /mnt/blockchains/bitcoin/bitcoin.conf || true`)) {
|
||||||
common.logger.info(`changetype already defined, skipping...`)
|
common.logger.info(`changetype already defined, skipping...`)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -58,7 +65,7 @@ connections=40
|
||||||
keypool=10000
|
keypool=10000
|
||||||
prune=4000
|
prune=4000
|
||||||
daemon=0
|
daemon=0
|
||||||
addresstype=p2sh-segwit
|
addresstype=bech32
|
||||||
changetype=bech32
|
changetype=bech32
|
||||||
walletrbf=1
|
walletrbf=1
|
||||||
bind=0.0.0.0:8332
|
bind=0.0.0.0:8332
|
||||||
|
|
|
||||||
|
|
@ -23,24 +23,28 @@ module.exports = {
|
||||||
|
|
||||||
const BINARIES = {
|
const BINARIES = {
|
||||||
BTC: {
|
BTC: {
|
||||||
url: 'https://bitcoincore.org/bin/bitcoin-core-22.0/bitcoin-22.0-x86_64-linux-gnu.tar.gz',
|
defaultUrl: 'https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz',
|
||||||
dir: 'bitcoin-22.0/bin'
|
defaultDir: 'bitcoin-0.20.1/bin',
|
||||||
|
url: 'https://bitcoincore.org/bin/bitcoin-core-23.0/bitcoin-23.0-x86_64-linux-gnu.tar.gz',
|
||||||
|
dir: 'bitcoin-23.0/bin'
|
||||||
},
|
},
|
||||||
ETH: {
|
ETH: {
|
||||||
url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.10.17-25c9b49f.tar.gz',
|
url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.10.17-25c9b49f.tar.gz',
|
||||||
dir: 'geth-linux-amd64-1.10.17-25c9b49f'
|
dir: 'geth-linux-amd64-1.10.17-25c9b49f'
|
||||||
},
|
},
|
||||||
ZEC: {
|
ZEC: {
|
||||||
url: 'https://z.cash/downloads/zcash-4.6.0-2-linux64-debian-bullseye.tar.gz',
|
url: 'https://z.cash/downloads/zcash-5.0.0-linux64-debian-bullseye.tar.gz',
|
||||||
dir: 'zcash-4.6.0-2/bin'
|
dir: 'zcash-5.0.0/bin'
|
||||||
},
|
},
|
||||||
DASH: {
|
DASH: {
|
||||||
url: 'https://github.com/dashpay/dash/releases/download/v0.17.0.3/dashcore-0.17.0.3-x86_64-linux-gnu.tar.gz',
|
url: 'https://github.com/dashpay/dash/releases/download/v0.17.0.3/dashcore-0.17.0.3-x86_64-linux-gnu.tar.gz',
|
||||||
dir: 'dashcore-0.17.0/bin'
|
dir: 'dashcore-0.17.0/bin'
|
||||||
},
|
},
|
||||||
LTC: {
|
LTC: {
|
||||||
url: 'https://download.litecoin.org/litecoin-0.18.1/linux/litecoin-0.18.1-x86_64-linux-gnu.tar.gz',
|
defaultUrl: 'https://download.litecoin.org/litecoin-0.18.1/linux/litecoin-0.18.1-x86_64-linux-gnu.tar.gz',
|
||||||
dir: 'litecoin-0.18.1/bin'
|
defaultDir: 'litecoin-0.18.1/bin',
|
||||||
|
url: 'https://download.litecoin.org/litecoin-0.21.2/linux/litecoin-0.21.2-x86_64-linux-gnu.tar.gz',
|
||||||
|
dir: 'litecoin-0.21.2/bin'
|
||||||
},
|
},
|
||||||
BCH: {
|
BCH: {
|
||||||
url: 'https://github.com/bitcoin-cash-node/bitcoin-cash-node/releases/download/v24.0.0/bitcoin-cash-node-24.0.0-x86_64-linux-gnu.tar.gz',
|
url: 'https://github.com/bitcoin-cash-node/bitcoin-cash-node/releases/download/v24.0.0/bitcoin-cash-node-24.0.0-x86_64-linux-gnu.tar.gz',
|
||||||
|
|
@ -48,13 +52,13 @@ const BINARIES = {
|
||||||
files: [['bitcoind', 'bitcoincashd'], ['bitcoin-cli', 'bitcoincash-cli']]
|
files: [['bitcoind', 'bitcoincashd'], ['bitcoin-cli', 'bitcoincash-cli']]
|
||||||
},
|
},
|
||||||
XMR: {
|
XMR: {
|
||||||
url: 'https://downloads.getmonero.org/cli/monero-linux-x64-v0.17.3.0.tar.bz2',
|
url: 'https://downloads.getmonero.org/cli/monero-linux-x64-v0.17.3.2.tar.bz2',
|
||||||
dir: 'monero-x86_64-linux-gnu-v0.17.3.0',
|
dir: 'monero-x86_64-linux-gnu-v0.17.3.2',
|
||||||
files: [['monerod', 'monerod'], ['monero-wallet-rpc', 'monero-wallet-rpc']]
|
files: [['monerod', 'monerod'], ['monero-wallet-rpc', 'monero-wallet-rpc']]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const coinsUpdateDependent = []
|
const coinsUpdateDependent = ['BTC', 'LTC']
|
||||||
|
|
||||||
function firewall (ports) {
|
function firewall (ports) {
|
||||||
if (!ports || ports.length === 0) throw new Error('No ports supplied')
|
if (!ports || ports.length === 0) throw new Error('No ports supplied')
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,13 @@ function updateCore (coinRec, isCurrentlyRunning) {
|
||||||
common.es(`rm -r /tmp/${coinRec.dir.replace('/bin', '')}`)
|
common.es(`rm -r /tmp/${coinRec.dir.replace('/bin', '')}`)
|
||||||
common.es(`rm /tmp/zcash.tar.gz`)
|
common.es(`rm /tmp/zcash.tar.gz`)
|
||||||
|
|
||||||
|
if (common.es(`grep "walletrequirebackup=" /mnt/blockchains/zcash/zcash.conf || true`)) {
|
||||||
|
common.logger.info(`walletrequirebackup already defined, skipping...`)
|
||||||
|
} else {
|
||||||
|
common.logger.info(`Setting 'walletrequirebackup=false' in config file...`)
|
||||||
|
common.es(`echo "\nwalletrequirebackup=false" >> /mnt/blockchains/zcash/zcash.conf`)
|
||||||
|
}
|
||||||
|
|
||||||
if (isCurrentlyRunning) {
|
if (isCurrentlyRunning) {
|
||||||
common.logger.info('Starting wallet...')
|
common.logger.info('Starting wallet...')
|
||||||
common.es(`sudo supervisorctl start zcash`)
|
common.es(`sudo supervisorctl start zcash`)
|
||||||
|
|
@ -50,5 +57,6 @@ rpcuser=lamassuserver
|
||||||
rpcpassword=${common.randomPass()}
|
rpcpassword=${common.randomPass()}
|
||||||
dbcache=500
|
dbcache=500
|
||||||
keypool=10000
|
keypool=10000
|
||||||
|
walletrequirebackup=false
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -140,23 +140,23 @@ function getWalletScore (tx, pi) {
|
||||||
: _.assign(tx, {
|
: _.assign(tx, {
|
||||||
walletScore: highestScore.score,
|
walletScore: highestScore.score,
|
||||||
error: 'Address score is above defined threshold',
|
error: 'Address score is above defined threshold',
|
||||||
errorCode: 'operatorCancel',
|
errorCode: 'scoreThresholdReached',
|
||||||
dispense: true
|
dispense: true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(error => _.assign(tx, {
|
.catch(error => _.assign(tx, {
|
||||||
walletScore: 10,
|
walletScore: 10,
|
||||||
error: `Failure getting address score: ${error?.message}`,
|
error: `Failure getting address score: ${error.message}`,
|
||||||
errorCode: 'operatorCancel',
|
errorCode: 'ciphertraceError',
|
||||||
dispense: true
|
dispense: true
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_.includes(tx.status, statuses) && !_.isNil(tx.walletScore)) {
|
if (_.includes(tx.status, statuses) && !_.isNil(tx.walletScore) && _.get('errorCode', tx) !== 'ciphertraceError') {
|
||||||
return pi.isValidWalletScore(tx.walletScore)
|
return pi.isValidWalletScore(tx.walletScore)
|
||||||
.then(isValid => isValid ? tx : _.assign(tx, {
|
.then(isValid => isValid ? tx : _.assign(tx, {
|
||||||
error: 'Address score is above defined threshold',
|
error: 'Address score is above defined threshold',
|
||||||
errorCode: 'operatorCancel',
|
errorCode: 'scoreThresholdReached',
|
||||||
dispense: true
|
dispense: true
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ function mapMachine (rates, settings, machineRow) {
|
||||||
const lastOnline = machineRow.last_online.toISOString()
|
const lastOnline = machineRow.last_online.toISOString()
|
||||||
const status = machineRow.stale ? 'online' : 'offline'
|
const status = machineRow.stale ? 'online' : 'offline'
|
||||||
const showLimitsAndVerification = coinAtmRadar.limitsAndVerification
|
const showLimitsAndVerification = coinAtmRadar.limitsAndVerification
|
||||||
const cashLimit = showLimitsAndVerification ? ( complianceTriggers.getCashLimit(triggers)?.threshold || Infinity ) : null
|
const cashLimit = showLimitsAndVerification ? (_.get('threshold', complianceTriggers.getCashLimit(triggers)) || Infinity) : null
|
||||||
const cryptoCurrencies = locale.cryptoCurrencies
|
const cryptoCurrencies = locale.cryptoCurrencies
|
||||||
const identification = mapIdentification(config)
|
const identification = mapIdentification(config)
|
||||||
const coins = _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies)
|
const coins = _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const sms = require('./sms')
|
||||||
const settingsLoader = require('./new-settings-loader')
|
const settingsLoader = require('./new-settings-loader')
|
||||||
const logger = require('./logger')
|
const logger = require('./logger')
|
||||||
|
|
||||||
const TX_PASSTHROUGH_ERROR_CODES = ['operatorCancel']
|
const TX_PASSTHROUGH_ERROR_CODES = ['operatorCancel', 'scoreThresholdReached', 'ciphertraceError']
|
||||||
|
|
||||||
const ID_PHOTO_CARD_DIR = process.env.ID_PHOTO_CARD_DIR
|
const ID_PHOTO_CARD_DIR = process.env.ID_PHOTO_CARD_DIR
|
||||||
const FRONT_CAMERA_DIR = process.env.FRONT_CAMERA_DIR
|
const FRONT_CAMERA_DIR = process.env.FRONT_CAMERA_DIR
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ const { getOperatorId } = require('../operator')
|
||||||
|
|
||||||
function findOperatorId (req, res, next) {
|
function findOperatorId (req, res, next) {
|
||||||
return getOperatorId('middleware')
|
return getOperatorId('middleware')
|
||||||
.then(({ operatorId }) => {
|
.then(operatorId => {
|
||||||
res.locals.operatorId = operatorId
|
res.locals.operatorId = operatorId
|
||||||
return next()
|
return next()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ function machineAction (type, value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function reload (operatorId) {
|
function reload (operatorId) {
|
||||||
state.needsSettingsReload[operatorId.operatorId] = true
|
state.needsSettingsReload[operatorId] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
const populateSettings = function (req, res, next) {
|
const populateSettings = function (req, res, next) {
|
||||||
|
|
|
||||||
|
|
@ -10,17 +10,6 @@ const anonymous = require('../../../constants').anonymousCustomer
|
||||||
const logDateFormat = require('../../../logs').logDateFormat
|
const logDateFormat = require('../../../logs').logDateFormat
|
||||||
|
|
||||||
const transactionsLoader = new DataLoader(ids => transactions.getCustomerTransactionsBatch(ids), { cache: false })
|
const transactionsLoader = new DataLoader(ids => transactions.getCustomerTransactionsBatch(ids), { cache: false })
|
||||||
const txLogFields = ['txClass', 'id', 'deviceId', 'toAddress', 'cryptoAtoms',
|
|
||||||
'cryptoCode', 'fiat', 'fiatCode', 'fee', 'status', 'fiatProfit',
|
|
||||||
'dispense', 'notified', 'redeem', 'phone', 'error',
|
|
||||||
'created', 'confirmedAt', 'hdIndex', 'swept', 'timedout',
|
|
||||||
'dispenseConfirmed', 'provisioned1', 'provisioned2',
|
|
||||||
'denomination1', 'denomination2', 'errorCode', 'customerId',
|
|
||||||
'txVersion', 'publishedAt', 'termsAccepted', 'layer2Address',
|
|
||||||
'commissionPercentage', 'rawTickerPrice', 'receivedCryptoAtoms',
|
|
||||||
'discount', 'txHash', 'customerPhone', 'customerIdCardDataNumber',
|
|
||||||
'customerIdCardDataExpiration', 'customerIdCardData', 'customerName',
|
|
||||||
'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName', 'walletScore']
|
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Customer: {
|
Customer: {
|
||||||
|
|
@ -34,7 +23,7 @@ const resolvers = {
|
||||||
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers),
|
transactions.batch(from, until, limit, offset, deviceId, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers),
|
||||||
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, timezone, excludeTestingCustomers, simplified }]) =>
|
transactionsCsv: (...[, { from, until, limit, offset, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, timezone, excludeTestingCustomers, simplified }]) =>
|
||||||
transactions.batch(from, until, limit, offset, null, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers, simplified)
|
transactions.batch(from, until, limit, offset, null, txClass, machineName, customerName, fiatCode, cryptoCode, toAddress, status, excludeTestingCustomers, simplified)
|
||||||
.then(data => parseAsync(logDateFormat(timezone, data, ['created', 'sendTime']), { fields: txLogFields })),
|
.then(data => parseAsync(logDateFormat(timezone, data, ['created', 'sendTime']))),
|
||||||
transactionCsv: (...[, { id, txClass, timezone }]) =>
|
transactionCsv: (...[, { id, txClass, timezone }]) =>
|
||||||
transactions.getTx(id, txClass).then(data =>
|
transactions.getTx(id, txClass).then(data =>
|
||||||
parseAsync(logDateFormat(timezone, [data], ['created', 'sendTime']))
|
parseAsync(logDateFormat(timezone, [data], ['created', 'sendTime']))
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const db = require('../../db')
|
||||||
const { USER_SESSIONS_TABLE_NAME } = require('../../constants')
|
const { USER_SESSIONS_TABLE_NAME } = require('../../constants')
|
||||||
const { getOperatorId } = require('../../operator')
|
const { getOperatorId } = require('../../operator')
|
||||||
|
|
||||||
router.use('*', async (req, res, next) => getOperatorId('authentication').then(({ operatorId }) => session({
|
router.use('*', async (req, res, next) => getOperatorId('authentication').then(operatorId => session({
|
||||||
store: new PgSession({
|
store: new PgSession({
|
||||||
pgPromise: db,
|
pgPromise: db,
|
||||||
tableName: USER_SESSIONS_TABLE_NAME
|
tableName: USER_SESSIONS_TABLE_NAME
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ function batch (
|
||||||
toAddress = null,
|
toAddress = null,
|
||||||
status = null,
|
status = null,
|
||||||
excludeTestingCustomers = false,
|
excludeTestingCustomers = false,
|
||||||
simplified = false
|
simplified
|
||||||
) {
|
) {
|
||||||
const packager = _.flow(_.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addProfits, addNames)
|
const packager = _.flow(_.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addProfits, addNames)
|
||||||
|
|
||||||
|
|
@ -120,13 +120,40 @@ function batch (
|
||||||
.then(packager)
|
.then(packager)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (simplified) return simplifiedBatch(res)
|
if (simplified) return simplifiedBatch(res)
|
||||||
else return res
|
// GQL transactions and transactionsCsv both use this function and
|
||||||
|
// if we don't check for the correct simplified value, the Transactions page polling
|
||||||
|
// will continuously build a csv in the background
|
||||||
|
else if (simplified === false) return advancedBatch(res)
|
||||||
|
return res
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function advancedBatch (data) {
|
||||||
|
const fields = ['txClass', 'id', 'deviceId', 'toAddress', 'cryptoAtoms',
|
||||||
|
'cryptoCode', 'fiat', 'fiatCode', 'fee', 'status', 'fiatProfit', 'cryptoAmount',
|
||||||
|
'dispense', 'notified', 'redeem', 'phone', 'error',
|
||||||
|
'created', 'confirmedAt', 'hdIndex', 'swept', 'timedout',
|
||||||
|
'dispenseConfirmed', 'provisioned1', 'provisioned2',
|
||||||
|
'denomination1', 'denomination2', 'errorCode', 'customerId',
|
||||||
|
'txVersion', 'publishedAt', 'termsAccepted', 'layer2Address',
|
||||||
|
'commissionPercentage', 'rawTickerPrice', 'receivedCryptoAtoms',
|
||||||
|
'discount', 'txHash', 'customerPhone', 'customerIdCardDataNumber',
|
||||||
|
'customerIdCardDataExpiration', 'customerIdCardData', 'customerName',
|
||||||
|
'customerFrontCameraPath', 'customerIdCardPhotoPath', 'expired', 'machineName', 'walletScore']
|
||||||
|
|
||||||
|
const addAdvancedFields = _.map(it => ({
|
||||||
|
...it,
|
||||||
|
status: getStatus(it),
|
||||||
|
fiatProfit: getProfit(it).toString(),
|
||||||
|
cryptoAmount: getCryptoAmount(it).toString()
|
||||||
|
}))
|
||||||
|
|
||||||
|
return _.compose(_.map(_.pick(fields)), addAdvancedFields)(data)
|
||||||
|
}
|
||||||
|
|
||||||
function simplifiedBatch (data) {
|
function simplifiedBatch (data) {
|
||||||
const fields = ['txClass', 'id', 'created', 'machineName',
|
const fields = ['txClass', 'id', 'created', 'machineName',
|
||||||
'cryptoCode', 'fiat', 'fiatCode', 'phone', 'toAddress',
|
'cryptoCode', 'cryptoAtoms', 'fiat', 'fiatCode', 'phone', 'toAddress',
|
||||||
'txHash', 'dispense', 'error', 'status', 'fiatProfit', 'cryptoAmount']
|
'txHash', 'dispense', 'error', 'status', 'fiatProfit', 'cryptoAmount']
|
||||||
|
|
||||||
const addSimplifiedFields = _.map(it => ({
|
const addSimplifiedFields = _.map(it => ({
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,13 @@ const accountsSql = `update user_config set data = $2, valid = $3, schema_versio
|
||||||
insert into user_config (type, data, valid, schema_version)
|
insert into user_config (type, data, valid, schema_version)
|
||||||
select $1, $2, $3, $4 where $1 not in (select type from user_config)`
|
select $1, $2, $3, $4 where $1 not in (select type from user_config)`
|
||||||
function saveAccounts (accounts) {
|
function saveAccounts (accounts) {
|
||||||
return loadAccounts()
|
return Promise.all([loadAccounts(), getOperatorId('middleware')])
|
||||||
.then(currentAccounts => {
|
.then(([currentAccounts, operatorId]) => {
|
||||||
const newAccounts = _.merge(currentAccounts, accounts)
|
const newAccounts = _.merge(currentAccounts, accounts)
|
||||||
return db.none(accountsSql, ['accounts', { accounts: newAccounts }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
|
return db.tx(t => {
|
||||||
|
return t.none(accountsSql, ['accounts', { accounts: newAccounts }, true, NEW_SETTINGS_LOADER_SCHEMA_VERSION])
|
||||||
|
.then(() => t.none('NOTIFY $1:name, $2', ['reload', JSON.stringify({ schema: asyncLocalStorage.getStore().get('schema'), operatorId })]))
|
||||||
|
}).catch(console.error)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
function resetAccounts (schemaVersion) {
|
function resetAccounts (schemaVersion) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ const _ = require('lodash/fp')
|
||||||
function getOperatorId (service) {
|
function getOperatorId (service) {
|
||||||
const sql = `SELECT operator_id FROM operator_ids WHERE service = '${service}'`
|
const sql = `SELECT operator_id FROM operator_ids WHERE service = '${service}'`
|
||||||
return db.oneOrNone(sql)
|
return db.oneOrNone(sql)
|
||||||
.then(_.mapKeys(_.camelCase))
|
.then(_.get('operator_id'))
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { getOperatorId }
|
module.exports = { getOperatorId }
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,11 @@ const _ = require('lodash/fp')
|
||||||
const request = require('request-promise')
|
const request = require('request-promise')
|
||||||
const { utils: coinUtils } = require('@lamassu/coins')
|
const { utils: coinUtils } = require('@lamassu/coins')
|
||||||
|
|
||||||
|
const logger = require('../../logger')
|
||||||
|
|
||||||
const BLOCKCHAIN_DIR = process.env.BLOCKCHAIN_DIR
|
const BLOCKCHAIN_DIR = process.env.BLOCKCHAIN_DIR
|
||||||
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
fetch, fetchDigest, parseConf, rpcConfig
|
fetch, fetchDigest, parseConf, rpcConfig
|
||||||
}
|
}
|
||||||
|
|
@ -114,6 +117,9 @@ function rpcConfig (cryptoRec) {
|
||||||
port: config.rpcport || cryptoRec.defaultPort
|
port: config.rpcport || cryptoRec.defaultPort
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error('Wallet is currently not installed')
|
logger.error('Wallet is currently not installed!')
|
||||||
|
return {
|
||||||
|
port: cryptoRec.defaultPort
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,12 @@ const loadConfig = (account) => {
|
||||||
'privateKey': 'secret'
|
'privateKey': 'secret'
|
||||||
}
|
}
|
||||||
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
|
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
|
||||||
return { ...mapped, timeout: 3000 }
|
|
||||||
|
return {
|
||||||
|
...mapped,
|
||||||
|
timeout: 3000,
|
||||||
|
nonce: function () { return this.microseconds() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadOptions = () => ({ expiretm: '+60' })
|
const loadOptions = () => ({ expiretm: '+60' })
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ const logger = require('../../../logger')
|
||||||
const NAME = 'CipherTrace'
|
const NAME = 'CipherTrace'
|
||||||
const SUPPORTED_COINS = ['BTC', 'ETH', 'BCH', 'LTC', 'BNB', 'RSK']
|
const SUPPORTED_COINS = ['BTC', 'ETH', 'BCH', 'LTC', 'BNB', 'RSK']
|
||||||
|
|
||||||
function getClient(account) {
|
function getClient (account) {
|
||||||
if (_.isNil(account) || !account.enabled) return null
|
if (_.isNil(account) || !account.enabled) return null
|
||||||
|
|
||||||
const [ctv1, username, secretKey] = account.authorizationValue.split(':')
|
const [ctv1, username, secretKey] = account.authorizationValue.split(':')
|
||||||
|
|
@ -16,25 +16,35 @@ function getClient(account) {
|
||||||
|
|
||||||
const apiVersion = ctv1.slice(-2)
|
const apiVersion = ctv1.slice(-2)
|
||||||
const authHeader = {
|
const authHeader = {
|
||||||
"Authorization": account.authorizationValue
|
'Authorization': account.authorizationValue
|
||||||
}
|
}
|
||||||
return { apiVersion, authHeader }
|
return { apiVersion, authHeader }
|
||||||
}
|
}
|
||||||
|
|
||||||
function rateWallet(account, cryptoCode, address) {
|
function rateWallet (account, cryptoCode, address) {
|
||||||
const client = getClient(account)
|
const client = getClient(account)
|
||||||
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
|
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
|
||||||
|
|
||||||
const { apiVersion, authHeader } = client
|
const { apiVersion, authHeader } = client
|
||||||
const threshold = account.scoreThreshold
|
const threshold = account.scoreThreshold
|
||||||
|
|
||||||
|
console.log(`** DEBUG ** rateWallet ENDPOINT: https://rest.ciphertrace.com/aml/${apiVersion}/${_.toLower(cryptoCode)}/risk?address=${address}`)
|
||||||
|
|
||||||
return axios.get(`https://rest.ciphertrace.com/aml/${apiVersion}/${_.toLower(cryptoCode)}/risk?address=${address}`, {
|
return axios.get(`https://rest.ciphertrace.com/aml/${apiVersion}/${_.toLower(cryptoCode)}/risk?address=${address}`, {
|
||||||
headers: authHeader
|
headers: authHeader
|
||||||
})
|
})
|
||||||
.then(res => ({ address, score: res.data.risk, isValid: res.data.risk < threshold }))
|
.then(res => ({ address, score: res.data.risk, isValid: res.data.risk < threshold }))
|
||||||
|
.then(result => {
|
||||||
|
console.log(`** DEBUG ** rateWallet RETURN: ${result}`)
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(`** DEBUG ** rateWallet ERROR: ${err.message}`)
|
||||||
|
throw err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function isValidWalletScore(account, score) {
|
function isValidWalletScore (account, score) {
|
||||||
const client = getClient(account)
|
const client = getClient(account)
|
||||||
if (_.isNil(client)) return Promise.resolve(true)
|
if (_.isNil(client)) return Promise.resolve(true)
|
||||||
|
|
||||||
|
|
@ -42,13 +52,15 @@ function isValidWalletScore(account, score) {
|
||||||
return _.isNil(account) ? Promise.resolve(true) : Promise.resolve(score < threshold)
|
return _.isNil(account) ? Promise.resolve(true) : Promise.resolve(score < threshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransactionHash(account, cryptoCode, receivingAddress) {
|
function getTransactionHash (account, cryptoCode, receivingAddress) {
|
||||||
const client = getClient(account)
|
const client = getClient(account)
|
||||||
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
|
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
|
||||||
|
|
||||||
const { apiVersion, authHeader } = client
|
const { apiVersion, authHeader } = client
|
||||||
|
|
||||||
return axios.get(`https://rest.ciphertrace.com/api/${apiVersion}/${_.toLower(cryptoCode) !== 'btc' ? `${_.toLower(cryptoCode)}_` : ``}address/search?features=tx&address=${receivingAddress}`, {
|
console.log(`** DEBUG ** getTransactionHash ENDPOINT: https://rest.ciphertrace.com/api/${apiVersion}/${_.toLower(cryptoCode) !== 'btc' ? `${_.toLower(cryptoCode)}_` : ``}address/search?features=tx&address=${receivingAddress}&mempool=true`)
|
||||||
|
|
||||||
|
return axios.get(`https://rest.ciphertrace.com/api/${apiVersion}/${_.toLower(cryptoCode) !== 'btc' ? `${_.toLower(cryptoCode)}_` : ``}address/search?features=tx&address=${receivingAddress}&mempool=true`, {
|
||||||
headers: authHeader
|
headers: authHeader
|
||||||
})
|
})
|
||||||
.then(res => {
|
.then(res => {
|
||||||
|
|
@ -56,16 +68,23 @@ function getTransactionHash(account, cryptoCode, receivingAddress) {
|
||||||
if (_.size(data.txHistory) > 1) {
|
if (_.size(data.txHistory) > 1) {
|
||||||
logger.warn('An address generated by this wallet was used in more than one transaction')
|
logger.warn('An address generated by this wallet was used in more than one transaction')
|
||||||
}
|
}
|
||||||
|
console.log(`** DEBUG ** getTransactionHash RETURN: ${_.join(', ', _.map(it => it.txHash, data.txHistory))}`)
|
||||||
return _.join(', ', _.map(it => it.txHash, data.txHistory))
|
return _.join(', ', _.map(it => it.txHash, data.txHistory))
|
||||||
})
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(`** DEBUG ** getTransactionHash ERROR: ${err}`)
|
||||||
|
throw err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getInputAddresses(account, cryptoCode, txHashes) {
|
function getInputAddresses (account, cryptoCode, txHashes) {
|
||||||
const client = getClient(account)
|
const client = getClient(account)
|
||||||
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
|
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
|
||||||
|
|
||||||
const { apiVersion, authHeader } = client
|
const { apiVersion, authHeader } = client
|
||||||
|
|
||||||
|
console.log(`** DEBUG ** getInputAddresses ENDPOINT: https://rest.ciphertrace.com/api/${apiVersion}/${_.toLower(cryptoCode) !== 'btc' ? `${_.toLower(cryptoCode)}_` : ``}tx?txhashes=${txHashes}`)
|
||||||
|
|
||||||
return axios.get(`https://rest.ciphertrace.com/api/${apiVersion}/${_.toLower(cryptoCode) !== 'btc' ? `${_.toLower(cryptoCode)}_` : ``}tx?txhashes=${txHashes}`, {
|
return axios.get(`https://rest.ciphertrace.com/api/${apiVersion}/${_.toLower(cryptoCode) !== 'btc' ? `${_.toLower(cryptoCode)}_` : ``}tx?txhashes=${txHashes}`, {
|
||||||
headers: authHeader
|
headers: authHeader
|
||||||
})
|
})
|
||||||
|
|
@ -78,8 +97,14 @@ function getInputAddresses(account, cryptoCode, txHashes) {
|
||||||
const transactionInputs = _.flatMap(it => it.inputs, data.transactions)
|
const transactionInputs = _.flatMap(it => it.inputs, data.transactions)
|
||||||
const inputAddresses = _.map(it => it.address, transactionInputs)
|
const inputAddresses = _.map(it => it.address, transactionInputs)
|
||||||
|
|
||||||
|
console.log(`** DEBUG ** getInputAddresses RETURN: ${inputAddresses}`)
|
||||||
|
|
||||||
return inputAddresses
|
return inputAddresses
|
||||||
})
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(`** DEBUG ** getInputAddresses ERROR: ${err.message}`)
|
||||||
|
throw err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
||||||
|
|
@ -20,17 +20,10 @@ function fetch (method, params) {
|
||||||
function errorHandle (e) {
|
function errorHandle (e) {
|
||||||
const err = JSON.parse(e.message)
|
const err = JSON.parse(e.message)
|
||||||
switch (err.code) {
|
switch (err.code) {
|
||||||
case -4:
|
|
||||||
return loadWallet()
|
|
||||||
case -5:
|
case -5:
|
||||||
return logger.error(`${err}`)
|
return logger.error(`${err}`)
|
||||||
case -6:
|
case -6:
|
||||||
throw new E.InsufficientFundsError()
|
throw new E.InsufficientFundsError()
|
||||||
case -18:
|
|
||||||
return createWallet()
|
|
||||||
case -35:
|
|
||||||
// Wallet is already loaded, just return
|
|
||||||
return
|
|
||||||
default:
|
default:
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
|
|
@ -38,20 +31,7 @@ function errorHandle (e) {
|
||||||
|
|
||||||
function checkCryptoCode (cryptoCode) {
|
function checkCryptoCode (cryptoCode) {
|
||||||
if (cryptoCode !== 'BTC') return Promise.reject(new Error('Unsupported crypto: ' + cryptoCode))
|
if (cryptoCode !== 'BTC') return Promise.reject(new Error('Unsupported crypto: ' + cryptoCode))
|
||||||
return Promise.resolve().then(loadWallet)
|
return Promise.resolve()
|
||||||
}
|
|
||||||
|
|
||||||
function createWallet () {
|
|
||||||
return fetch('createwallet', ['wallet'])
|
|
||||||
.then(loadWallet)
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadWallet () {
|
|
||||||
return fetch('loadwallet', ['wallet', true])
|
|
||||||
// Catching the error here to suppress error code -35
|
|
||||||
// This improves UX on the initial wallet load and serves as error sink
|
|
||||||
// for wallet creation/loading related issues before actual business logic runs
|
|
||||||
.catch(errorHandle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function accountBalance (cryptoCode) {
|
function accountBalance (cryptoCode) {
|
||||||
|
|
@ -89,7 +69,7 @@ function calculateFeeDiscount (feeMultiplier) {
|
||||||
if (!estimatedFee) return AUTOMATIC_FEE
|
if (!estimatedFee) return AUTOMATIC_FEE
|
||||||
const newFee = estimatedFee.times(feeMultiplier)
|
const newFee = estimatedFee.times(feeMultiplier)
|
||||||
if (newFee.lt(0.00001) || newFee.gt(0.1)) return AUTOMATIC_FEE
|
if (newFee.lt(0.00001) || newFee.gt(0.1)) return AUTOMATIC_FEE
|
||||||
return newFee
|
return newFee.toFixed(8)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -143,8 +143,8 @@ function newFunding (account, cryptoCode, settings, operatorId) {
|
||||||
const fundingAddress = result.address
|
const fundingAddress = result.address
|
||||||
return wallet.updateAddress({ address: fundingAddress, label: 'Funding Address' })
|
return wallet.updateAddress({ address: fundingAddress, label: 'Funding Address' })
|
||||||
.then(() => ({
|
.then(() => ({
|
||||||
fundingPendingBalance: new BN(wallet._wallet.balanceString),
|
fundingPendingBalance: new BN(wallet._wallet.balance).minus(wallet._wallet.confirmedBalance),
|
||||||
fundingConfirmedBalance: new BN(wallet._wallet.confirmedBalanceString),
|
fundingConfirmedBalance: new BN(wallet._wallet.confirmedBalance),
|
||||||
fundingAddress: getCashAddress(fundingAddress, cryptoCode)
|
fundingAddress: getCashAddress(fundingAddress, cryptoCode)
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,6 @@ function connect (url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const hex = bigNum => '0x' + bigNum.integerValue(BN.ROUND_DOWN).toString(16)
|
const hex = bigNum => '0x' + bigNum.integerValue(BN.ROUND_DOWN).toString(16)
|
||||||
const bn2bn = bn => new BN(bn.toString(16), 16)
|
|
||||||
|
|
||||||
function privateKey (account) {
|
function privateKey (account) {
|
||||||
return defaultWallet(account).getPrivateKey()
|
return defaultWallet(account).getPrivateKey()
|
||||||
|
|
@ -92,7 +91,7 @@ function _balance (includePending, address, cryptoCode) {
|
||||||
const block = includePending ? 'pending' : undefined
|
const block = includePending ? 'pending' : undefined
|
||||||
return pify(web3.eth.getBalance)(address.toLowerCase(), block)
|
return pify(web3.eth.getBalance)(address.toLowerCase(), block)
|
||||||
/* NOTE: Convert bn.js bignum to bignumber.js bignum */
|
/* NOTE: Convert bn.js bignum to bignumber.js bignum */
|
||||||
.then(balance => balance ? BN(balance.toString(16), 16) : BN(0))
|
.then(balance => balance ? BN(balance) : BN(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
|
function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
|
||||||
|
|
@ -125,11 +124,10 @@ function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
|
||||||
]
|
]
|
||||||
|
|
||||||
return Promise.all(promises)
|
return Promise.all(promises)
|
||||||
.then(([gas, gasPrice, txCount, { baseFeePerGas }]) => [
|
.then(([gas, gasPrice, txCount]) => [
|
||||||
bn2bn(gas),
|
BN(gas),
|
||||||
bn2bn(gasPrice),
|
BN(gasPrice),
|
||||||
_.max([1, txCount, lastUsedNonces[fromAddress] + 1]),
|
_.max([0, txCount, lastUsedNonces[fromAddress] + 1])
|
||||||
bn2bn(baseFeePerGas)
|
|
||||||
])
|
])
|
||||||
.then(([gas, gasPrice, txCount, baseFeePerGas]) => {
|
.then(([gas, gasPrice, txCount, baseFeePerGas]) => {
|
||||||
lastUsedNonces[fromAddress] = txCount
|
lastUsedNonces[fromAddress] = txCount
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,8 @@ const { default: PQueue } = require('p-queue')
|
||||||
|
|
||||||
const BN = require('../../../bn')
|
const BN = require('../../../bn')
|
||||||
const E = require('../../../error')
|
const E = require('../../../error')
|
||||||
const { logger } = require('../../../blockchain/common')
|
const logger = require('../../../logger')
|
||||||
|
const options = require('../../../options')
|
||||||
const jsonRpc = require('../../common/json-rpc')
|
const jsonRpc = require('../../common/json-rpc')
|
||||||
|
|
||||||
const BLOCKCHAIN_DIR = process.env.BLOCKCHAIN_DIR
|
const BLOCKCHAIN_DIR = process.env.BLOCKCHAIN_DIR
|
||||||
|
|
@ -39,7 +40,12 @@ function rpcConfig () {
|
||||||
port: cryptoRec.walletPort || cryptoRec.defaultPort
|
port: cryptoRec.walletPort || cryptoRec.defaultPort
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error('wallet is currently not installed')
|
logger.error('Wallet is currently not installed!')
|
||||||
|
return {
|
||||||
|
username: '',
|
||||||
|
password: '',
|
||||||
|
port: cryptoRec.walletPort || cryptoRec.defaultPort
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ const plugins = require('../plugins')
|
||||||
const createTerms = terms => (terms.active && terms.text) ? ({
|
const createTerms = terms => (terms.active && terms.text) ? ({
|
||||||
delay: terms.delay,
|
delay: terms.delay,
|
||||||
active: terms.active,
|
active: terms.active,
|
||||||
|
tcPhoto: terms.tcPhoto,
|
||||||
title: terms.title,
|
title: terms.title,
|
||||||
text: nmd(terms.text),
|
text: nmd(terms.text),
|
||||||
accept: terms.acceptButtonText,
|
accept: terms.acceptButtonText,
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,6 @@ function cancel (txId) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function customerHistory (customerId, thresholdDays) {
|
function customerHistory (customerId, thresholdDays) {
|
||||||
const sql = `SELECT * FROM (
|
const sql = `SELECT * FROM (
|
||||||
SELECT txIn.id, txIn.created, txIn.fiat, 'cashIn' AS direction,
|
SELECT txIn.id, txIn.created, txIn.fiat, 'cashIn' AS direction,
|
||||||
|
|
@ -84,7 +83,7 @@ function customerHistory (customerId, thresholdDays) {
|
||||||
FROM cash_out_txs txOut
|
FROM cash_out_txs txOut
|
||||||
WHERE txOut.customer_id = $1
|
WHERE txOut.customer_id = $1
|
||||||
AND txOut.created > now() - interval $2
|
AND txOut.created > now() - interval $2
|
||||||
AND error_code IS DISTINCT FROM 'operatorCancel'
|
AND error_code NOT IN ('operatorCancel', 'scoreThresholdReached', 'ciphertraceError')
|
||||||
AND fiat > 0
|
AND fiat > 0
|
||||||
) ch WHERE NOT ch.expired ORDER BY ch.created`
|
) ch WHERE NOT ch.expired ORDER BY ch.created`
|
||||||
|
|
||||||
|
|
|
||||||
34
new-lamassu-admin/package-lock.json
generated
34
new-lamassu-admin/package-lock.json
generated
|
|
@ -4394,9 +4394,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@lamassu/coins": {
|
"@lamassu/coins": {
|
||||||
"version": "1.0.0-beta.3",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.0.0-beta.3.tgz",
|
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.2.0.tgz",
|
||||||
"integrity": "sha512-P/CTK1ChFedtHqYHnKcJWFzxMumU43VvtOlc088hdM9phXY1uuQ6+3xyOmojZuqPXKooFN/1BIDA0a4OE6FPOw==",
|
"integrity": "sha512-xp1R2+hd++6WfDOrHxpUdPBqnQiWDz0KttoSHu4KkQsCKCmjr2zUcf6NRKr3syqAhBKekYX+8kDL27VVG+OuUw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bech32": "2.0.0",
|
"bech32": "2.0.0",
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
|
|
@ -8307,7 +8307,7 @@
|
||||||
"bigi": {
|
"bigi": {
|
||||||
"version": "1.4.2",
|
"version": "1.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz",
|
||||||
"integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU="
|
"integrity": "sha512-ddkU+dFIuEIW8lE7ZwdIAf2UPoM90eaprg5m3YXAVVTmKlqV/9BX4A2M8BOK2yOq6/VgZFVhK6QAxJebhlbhzw=="
|
||||||
},
|
},
|
||||||
"bignumber.js": {
|
"bignumber.js": {
|
||||||
"version": "9.0.0",
|
"version": "9.0.0",
|
||||||
|
|
@ -8356,7 +8356,7 @@
|
||||||
"bip66": {
|
"bip66": {
|
||||||
"version": "1.1.5",
|
"version": "1.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
|
||||||
"integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
|
"integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.0.1"
|
"safe-buffer": "^5.0.1"
|
||||||
}
|
}
|
||||||
|
|
@ -8396,9 +8396,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bitcore-lib": {
|
"bitcore-lib": {
|
||||||
"version": "8.25.25",
|
"version": "8.25.28",
|
||||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.25.tgz",
|
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.28.tgz",
|
||||||
"integrity": "sha512-H6qNCVl4M8/MglXhvc04mmeus1d6nrmqTJGQ+xezJLvL7hs7R3dyBPtOqSP3YSw0iq/GWspMd8f5OOlyXVipJQ==",
|
"integrity": "sha512-UrNHh0Ba8GUiHUYRmm2IKlb8eomsbvk/Z6oQdaOPQoLiamiKnu45pAMqtcHg06wMDF8at54oIdoD2WEU+TQujw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bech32": "=2.0.0",
|
"bech32": "=2.0.0",
|
||||||
"bip-schnorr": "=0.6.4",
|
"bip-schnorr": "=0.6.4",
|
||||||
|
|
@ -8418,11 +8418,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bitcore-lib-cash": {
|
"bitcore-lib-cash": {
|
||||||
"version": "8.25.25",
|
"version": "8.25.28",
|
||||||
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.25.tgz",
|
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.28.tgz",
|
||||||
"integrity": "sha512-p/KEBlCKNTTxOZFJLt/bA1b7pQ1JFapHkoWL8mSLxfz9wTK4ScN74zpbBwhG+O7dk7XMo8iRrKigvanmkce35g==",
|
"integrity": "sha512-Zaue7z/iDdQDTNsDoX8LkxH04/pCpHKpSgbxJe2D/2n1YLi1JtzOl9Ox4agYQtR/k9SWCg4p8qJ1W7lVWVP8+A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bitcore-lib": "^8.25.25",
|
"bitcore-lib": "^8.25.28",
|
||||||
"bn.js": "=4.11.8",
|
"bn.js": "=4.11.8",
|
||||||
"bs58": "^4.0.1",
|
"bs58": "^4.0.1",
|
||||||
"buffer-compare": "=1.1.1",
|
"buffer-compare": "=1.1.1",
|
||||||
|
|
@ -8800,7 +8800,7 @@
|
||||||
"bs58": {
|
"bs58": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
|
||||||
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
|
"integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"base-x": "^3.0.2"
|
"base-x": "^3.0.2"
|
||||||
}
|
}
|
||||||
|
|
@ -8852,7 +8852,7 @@
|
||||||
"buffer-compare": {
|
"buffer-compare": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz",
|
||||||
"integrity": "sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY="
|
"integrity": "sha512-O6NvNiHZMd3mlIeMDjP6t/gPG75OqGPeiRZXoMQZJ6iy9GofCls4Ijs5YkPZZwoysizLiedhticmdyx/GyHghA=="
|
||||||
},
|
},
|
||||||
"buffer-from": {
|
"buffer-from": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
|
@ -18638,9 +18638,9 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-gyp-build": {
|
"node-gyp-build": {
|
||||||
"version": "4.3.0",
|
"version": "4.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz",
|
||||||
"integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q=="
|
"integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ=="
|
||||||
},
|
},
|
||||||
"node-int64": {
|
"node-int64": {
|
||||||
"version": "0.4.0",
|
"version": "0.4.0",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"license": "unlicense",
|
"license": "unlicense",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@apollo/react-hooks": "^3.1.3",
|
"@apollo/react-hooks": "^3.1.3",
|
||||||
"@lamassu/coins": "1.0.0-beta.3",
|
"@lamassu/coins": "1.2.0",
|
||||||
"@material-ui/core": "4.11.0",
|
"@material-ui/core": "4.11.0",
|
||||||
"@material-ui/icons": "4.9.1",
|
"@material-ui/icons": "4.9.1",
|
||||||
"@material-ui/lab": "^4.0.0-alpha.56",
|
"@material-ui/lab": "^4.0.0-alpha.56",
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ import { primaryColor } from 'src/styling/variables'
|
||||||
|
|
||||||
import styles from './Funding.styles'
|
import styles from './Funding.styles'
|
||||||
|
|
||||||
|
const NODE_NOT_CONNECTED_ERR =
|
||||||
|
"Couldn't establish connection with the node. Make sure it is installed and try again"
|
||||||
|
|
||||||
const useStyles = makeStyles(styles)
|
const useStyles = makeStyles(styles)
|
||||||
const sizes = {
|
const sizes = {
|
||||||
big: 165,
|
big: 165,
|
||||||
|
|
@ -176,7 +179,11 @@ const Funding = () => {
|
||||||
{selected && !viewHistory && selected.errorMsg && (
|
{selected && !viewHistory && selected.errorMsg && (
|
||||||
<div className={classes.main}>
|
<div className={classes.main}>
|
||||||
<div className={classes.firstSide}>
|
<div className={classes.firstSide}>
|
||||||
<Info3 className={classes.error}>{selected.errorMsg}</Info3>
|
<Info3 className={classes.error}>
|
||||||
|
{R.includes('ECONNREFUSED', selected.errorMsg)
|
||||||
|
? NODE_NOT_CONNECTED_ERR
|
||||||
|
: selected.errorMsg}
|
||||||
|
</Info3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,7 @@ const TermsConditions = () => {
|
||||||
const formData = termsAndConditions ?? {}
|
const formData = termsAndConditions ?? {}
|
||||||
const showOnScreen = termsAndConditions?.active ?? false
|
const showOnScreen = termsAndConditions?.active ?? false
|
||||||
const addDelayOnScreen = termsAndConditions?.delay ?? false
|
const addDelayOnScreen = termsAndConditions?.delay ?? false
|
||||||
|
const tcPhoto = termsAndConditions?.tcPhoto ?? false
|
||||||
|
|
||||||
const save = it =>
|
const save = it =>
|
||||||
saveConfig({
|
saveConfig({
|
||||||
|
|
@ -183,6 +184,23 @@ const TermsConditions = () => {
|
||||||
<Label2>{showOnScreen ? 'Yes' : 'No'}</Label2>
|
<Label2>{showOnScreen ? 'Yes' : 'No'}</Label2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={classes.switchRow}>
|
||||||
|
<P>
|
||||||
|
Capture customer photo on acceptance <br /> of Terms & Conditions
|
||||||
|
screen
|
||||||
|
</P>
|
||||||
|
<div className={classes.switch}>
|
||||||
|
<Switch
|
||||||
|
checked={tcPhoto}
|
||||||
|
onChange={event =>
|
||||||
|
save({
|
||||||
|
tcPhoto: event.target.checked
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<Label2>{tcPhoto ? 'Yes' : 'No'}</Label2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className={classes.switchRow}>
|
<div className={classes.switchRow}>
|
||||||
<P>Add 7 seconds delay on screen</P>
|
<P>Add 7 seconds delay on screen</P>
|
||||||
<div className={classes.switch}>
|
<div className={classes.switch}>
|
||||||
|
|
|
||||||
|
|
@ -202,10 +202,10 @@ const DetailsRow = ({ it: tx, timezone }) => {
|
||||||
r={3.5}
|
r={3.5}
|
||||||
fill={
|
fill={
|
||||||
it < tx.walletScore
|
it < tx.walletScore
|
||||||
? !R.includes('score is above', tx.hasError ?? '')
|
? R.isNil(tx.hasError)
|
||||||
? primaryColor
|
? primaryColor
|
||||||
: errorColor
|
: errorColor
|
||||||
: !R.includes('score is above', tx.hasError ?? '')
|
: R.isNil(tx.hasError)
|
||||||
? subheaderColor
|
? subheaderColor
|
||||||
: offErrorColor
|
: offErrorColor
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +218,7 @@ const DetailsRow = ({ it: tx, timezone }) => {
|
||||||
noMargin
|
noMargin
|
||||||
className={classNames({
|
className={classNames({
|
||||||
[classes.bold]: true,
|
[classes.bold]: true,
|
||||||
[classes.error]: R.includes('score is above', tx.hasError ?? '')
|
[classes.error]: !R.isNil(tx.hasError)
|
||||||
})}>
|
})}>
|
||||||
{tx.walletScore}
|
{tx.walletScore}
|
||||||
</P>
|
</P>
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ const Wallet = ({ name: SCREEN_KEY }) => {
|
||||||
const [advancedSettings, setAdvancedSettings] = useState(false)
|
const [advancedSettings, setAdvancedSettings] = useState(false)
|
||||||
const { data } = useQuery(GET_INFO)
|
const { data } = useQuery(GET_INFO)
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
|
const [saveConfig, { error }] = useMutation(SAVE_CONFIG, {
|
||||||
onCompleted: () => setWizard(false),
|
onCompleted: () => setWizard(false),
|
||||||
refetchQueries: () => ['getData']
|
refetchQueries: () => ['getData']
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,18 @@ const viewFeeMultiplier = it =>
|
||||||
R.compose(R.prop(['display']), R.find(R.propEq('code', it)))(feeOptions)
|
R.compose(R.prop(['display']), R.find(R.propEq('code', it)))(feeOptions)
|
||||||
|
|
||||||
const feeOptions = [
|
const feeOptions = [
|
||||||
|
{ display: '+60%', code: '1.6' },
|
||||||
|
{ display: '+50%', code: '1.5' },
|
||||||
|
{ display: '+40%', code: '1.4' },
|
||||||
|
{ display: '+30%', code: '1.3' },
|
||||||
{ display: '+20%', code: '1.2' },
|
{ display: '+20%', code: '1.2' },
|
||||||
|
{ display: '+10%', code: '1.1' },
|
||||||
{ display: 'Default', code: '1' },
|
{ display: 'Default', code: '1' },
|
||||||
|
{ display: '-10%', code: '0.9' },
|
||||||
{ display: '-20%', code: '0.8' },
|
{ display: '-20%', code: '0.8' },
|
||||||
|
{ display: '-30%', code: '0.7' },
|
||||||
{ display: '-40%', code: '0.6' },
|
{ display: '-40%', code: '0.6' },
|
||||||
|
{ display: '-50%', code: '0.5' },
|
||||||
{ display: '-60%', code: '0.4' }
|
{ display: '-60%', code: '0.4' }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
40
package-lock.json
generated
40
package-lock.json
generated
|
|
@ -3220,9 +3220,9 @@
|
||||||
"integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg=="
|
"integrity": "sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg=="
|
||||||
},
|
},
|
||||||
"@lamassu/coins": {
|
"@lamassu/coins": {
|
||||||
"version": "1.0.0-beta.3",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.0.0-beta.3.tgz",
|
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.2.0.tgz",
|
||||||
"integrity": "sha512-P/CTK1ChFedtHqYHnKcJWFzxMumU43VvtOlc088hdM9phXY1uuQ6+3xyOmojZuqPXKooFN/1BIDA0a4OE6FPOw==",
|
"integrity": "sha512-xp1R2+hd++6WfDOrHxpUdPBqnQiWDz0KttoSHu4KkQsCKCmjr2zUcf6NRKr3syqAhBKekYX+8kDL27VVG+OuUw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bech32": "2.0.0",
|
"bech32": "2.0.0",
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
|
|
@ -6432,9 +6432,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bitcore-lib": {
|
"bitcore-lib": {
|
||||||
"version": "8.25.25",
|
"version": "8.25.28",
|
||||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.25.tgz",
|
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.28.tgz",
|
||||||
"integrity": "sha512-H6qNCVl4M8/MglXhvc04mmeus1d6nrmqTJGQ+xezJLvL7hs7R3dyBPtOqSP3YSw0iq/GWspMd8f5OOlyXVipJQ==",
|
"integrity": "sha512-UrNHh0Ba8GUiHUYRmm2IKlb8eomsbvk/Z6oQdaOPQoLiamiKnu45pAMqtcHg06wMDF8at54oIdoD2WEU+TQujw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bech32": "=2.0.0",
|
"bech32": "=2.0.0",
|
||||||
"bip-schnorr": "=0.6.4",
|
"bip-schnorr": "=0.6.4",
|
||||||
|
|
@ -6459,11 +6459,11 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bitcore-lib-cash": {
|
"bitcore-lib-cash": {
|
||||||
"version": "8.25.25",
|
"version": "8.25.28",
|
||||||
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.25.tgz",
|
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.28.tgz",
|
||||||
"integrity": "sha512-p/KEBlCKNTTxOZFJLt/bA1b7pQ1JFapHkoWL8mSLxfz9wTK4ScN74zpbBwhG+O7dk7XMo8iRrKigvanmkce35g==",
|
"integrity": "sha512-Zaue7z/iDdQDTNsDoX8LkxH04/pCpHKpSgbxJe2D/2n1YLi1JtzOl9Ox4agYQtR/k9SWCg4p8qJ1W7lVWVP8+A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"bitcore-lib": "^8.25.25",
|
"bitcore-lib": "^8.25.28",
|
||||||
"bn.js": "=4.11.8",
|
"bn.js": "=4.11.8",
|
||||||
"bs58": "^4.0.1",
|
"bs58": "^4.0.1",
|
||||||
"buffer-compare": "=1.1.1",
|
"buffer-compare": "=1.1.1",
|
||||||
|
|
@ -8443,13 +8443,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"crc-32": {
|
"crc-32": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||||
"integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
|
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
|
||||||
"requires": {
|
|
||||||
"exit-on-epipe": "~1.0.1",
|
|
||||||
"printj": "~1.1.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"create-ecdh": {
|
"create-ecdh": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
|
|
@ -10569,11 +10565,6 @@
|
||||||
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"exit-on-epipe": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw=="
|
|
||||||
},
|
|
||||||
"expand-brackets": {
|
"expand-brackets": {
|
||||||
"version": "2.1.4",
|
"version": "2.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||||
|
|
@ -17665,11 +17656,6 @@
|
||||||
"plur": "^1.0.0"
|
"plur": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"printj": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ=="
|
|
||||||
},
|
|
||||||
"process": {
|
"process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ethereumjs/common": "^2.6.4",
|
"@ethereumjs/common": "^2.6.4",
|
||||||
"@ethereumjs/tx": "^3.5.1",
|
"@ethereumjs/tx": "^3.5.1",
|
||||||
"@lamassu/coins": "1.0.0-beta.3",
|
"@lamassu/coins": "1.2.0",
|
||||||
"@simplewebauthn/server": "^3.0.0",
|
"@simplewebauthn/server": "^3.0.0",
|
||||||
"apollo-server-express": "2.25.1",
|
"apollo-server-express": "2.25.1",
|
||||||
"argon2": "0.28.2",
|
"argon2": "0.28.2",
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.js": "/static/js/main.4a3fa58d.chunk.js",
|
"main.js": "/static/js/main.a4b79bb3.chunk.js",
|
||||||
"main.js.map": "/static/js/main.4a3fa58d.chunk.js.map",
|
"main.js.map": "/static/js/main.a4b79bb3.chunk.js.map",
|
||||||
"runtime-main.js": "/static/js/runtime-main.5b925903.js",
|
"runtime-main.js": "/static/js/runtime-main.5b925903.js",
|
||||||
"runtime-main.js.map": "/static/js/runtime-main.5b925903.js.map",
|
"runtime-main.js.map": "/static/js/runtime-main.5b925903.js.map",
|
||||||
"static/js/2.208e5597.chunk.js": "/static/js/2.208e5597.chunk.js",
|
"static/js/2.b2c71226.chunk.js": "/static/js/2.b2c71226.chunk.js",
|
||||||
"static/js/2.208e5597.chunk.js.map": "/static/js/2.208e5597.chunk.js.map",
|
"static/js/2.b2c71226.chunk.js.map": "/static/js/2.b2c71226.chunk.js.map",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"static/js/2.208e5597.chunk.js.LICENSE.txt": "/static/js/2.208e5597.chunk.js.LICENSE.txt",
|
"static/js/2.b2c71226.chunk.js.LICENSE.txt": "/static/js/2.b2c71226.chunk.js.LICENSE.txt",
|
||||||
"static/media/3-cassettes-open-1-left.d6d9aa73.svg": "/static/media/3-cassettes-open-1-left.d6d9aa73.svg",
|
"static/media/3-cassettes-open-1-left.d6d9aa73.svg": "/static/media/3-cassettes-open-1-left.d6d9aa73.svg",
|
||||||
"static/media/3-cassettes-open-2-left.a9ee8d4c.svg": "/static/media/3-cassettes-open-2-left.a9ee8d4c.svg",
|
"static/media/3-cassettes-open-2-left.a9ee8d4c.svg": "/static/media/3-cassettes-open-2-left.a9ee8d4c.svg",
|
||||||
"static/media/3-cassettes-open-3-left.08fed660.svg": "/static/media/3-cassettes-open-3-left.08fed660.svg",
|
"static/media/3-cassettes-open-3-left.08fed660.svg": "/static/media/3-cassettes-open-3-left.08fed660.svg",
|
||||||
|
|
@ -152,7 +152,7 @@
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/js/runtime-main.5b925903.js",
|
"static/js/runtime-main.5b925903.js",
|
||||||
"static/js/2.208e5597.chunk.js",
|
"static/js/2.b2c71226.chunk.js",
|
||||||
"static/js/main.4a3fa58d.chunk.js"
|
"static/js/main.a4b79bb3.chunk.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -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.208e5597.chunk.js"></script><script src="/static/js/main.4a3fa58d.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.b2c71226.chunk.js"></script><script src="/static/js/main.a4b79bb3.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
3
public/static/js/2.f974d6ce.chunk.js
Normal file
3
public/static/js/2.f974d6ce.chunk.js
Normal file
File diff suppressed because one or more lines are too long
174
public/static/js/2.f974d6ce.chunk.js.LICENSE.txt
Normal file
174
public/static/js/2.f974d6ce.chunk.js.LICENSE.txt
Normal file
|
|
@ -0,0 +1,174 @@
|
||||||
|
/*
|
||||||
|
object-assign
|
||||||
|
(c) Sindre Sorhus
|
||||||
|
@license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Copyright (c) 2017 Jed Watson.
|
||||||
|
Licensed under the MIT License (MIT), see
|
||||||
|
http://jedwatson.github.io/classnames
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The buffer module from node.js, for the browser.
|
||||||
|
*
|
||||||
|
* @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The buffer module from node.js, for the browser.
|
||||||
|
*
|
||||||
|
* @author Feross Aboukhadijeh <http://feross.org>
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*! *****************************************************************************
|
||||||
|
Copyright (c) Microsoft Corporation.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
***************************************************************************** */
|
||||||
|
|
||||||
|
/*! https://mths.be/base64 v1.0.0 by @mathias | MIT license */
|
||||||
|
|
||||||
|
/*! https://mths.be/punycode v1.4.1 by @mathias */
|
||||||
|
|
||||||
|
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||||
|
|
||||||
|
/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Lodash <https://lodash.com/>
|
||||||
|
* Copyright OpenJS Foundation and other contributors <https://openjsf.org/>
|
||||||
|
* Released under MIT license <https://lodash.com/license>
|
||||||
|
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||||||
|
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* https://github.com/bitcoincashjs/cashaddr
|
||||||
|
* Copyright (c) 2017-2018 Emilio Almansi
|
||||||
|
* Distributed under the MIT software license, see the accompanying
|
||||||
|
* file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A better abstraction over CSS.
|
||||||
|
*
|
||||||
|
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
|
||||||
|
* @website https://github.com/cssinjs/jss
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @license React v0.18.0
|
||||||
|
* scheduler.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @license React v0.19.1
|
||||||
|
* scheduler.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @license React v16.13.1
|
||||||
|
* react-is.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @license React v16.14.0
|
||||||
|
* react-dom.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @license React v16.14.0
|
||||||
|
* react-jsx-runtime.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @license React v16.14.0
|
||||||
|
* react.production.min.js
|
||||||
|
*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @preserve
|
||||||
|
* Counter block mode compatible with Dr Brian Gladman fileenc.c
|
||||||
|
* derived from CryptoJS.mode.CTR
|
||||||
|
* Jan Hruby jhruby.web@gmail.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @preserve
|
||||||
|
(c) 2012 by Cédric Mesnil. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**!
|
||||||
|
* @fileOverview Kickass library to create and place poppers near their reference elements.
|
||||||
|
* @version 1.16.1-lts
|
||||||
|
* @license
|
||||||
|
* Copyright (c) 2016 Federico Zivolo and contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @license
|
||||||
|
* https://github.com/bitcoincashjs/cashaddr
|
||||||
|
* Copyright (c) 2017 Emilio Almansi
|
||||||
|
* Distributed under the MIT software license, see the accompanying
|
||||||
|
* file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
*/
|
||||||
1
public/static/js/2.f974d6ce.chunk.js.map
Normal file
1
public/static/js/2.f974d6ce.chunk.js.map
Normal file
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
2
public/static/js/main.a4b79bb3.chunk.js
Normal file
2
public/static/js/main.a4b79bb3.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
public/static/js/main.a4b79bb3.chunk.js.map
Normal file
1
public/static/js/main.a4b79bb3.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
2
public/static/js/main.e11e43cb.chunk.js
Normal file
2
public/static/js/main.e11e43cb.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
public/static/js/main.e11e43cb.chunk.js.map
Normal file
1
public/static/js/main.e11e43cb.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
1
public/static/media/icon-tether-colour.92d7fda4.svg
Normal file
1
public/static/media/icon-tether-colour.92d7fda4.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2000" width="2500" height="2500"><path d="M1000 0c552.26 0 1000 447.74 1000 1000s-447.76 1000-1000 1000S0 1552.38 0 1000 447.68 0 1000 0" fill="#53ae94"/><path d="M1123.42 866.76V718h340.18V491.34H537.28V718H877.5v148.64C601 879.34 393.1 934.1 393.1 999.7s208 120.36 484.4 133.14v476.5h246V1132.8c276-12.74 483.48-67.46 483.48-133s-207.48-120.26-483.48-133m0 225.64v-.12c-6.94.44-42.6 2.58-122 2.58-63.48 0-108.14-1.8-123.88-2.62v.2C633.34 1081.66 451 1039.12 451 988.22S633.36 894.84 877.62 884v166.1c16 1.1 61.76 3.8 124.92 3.8 75.86 0 114-3.16 121-3.8V884c243.8 10.86 425.72 53.44 425.72 104.16s-182 93.32-425.72 104.18" fill="#fff"/></svg>
|
||||||
|
After Width: | Height: | Size: 701 B |
|
|
@ -4,7 +4,7 @@ const _ = require('lodash/fp')
|
||||||
const cashInTx = require('../../lib/cash-in/cash-in-tx')
|
const cashInTx = require('../../lib/cash-in/cash-in-tx')
|
||||||
const { CASH_OUT_TRANSACTION_STATES, REDEEMABLE_AGE } = require('../../lib/cash-out/cash-out-helper')
|
const { CASH_OUT_TRANSACTION_STATES, REDEEMABLE_AGE } = require('../../lib/cash-out/cash-out-helper')
|
||||||
|
|
||||||
const TX_PASSTHROUGH_ERROR_CODES = ['operatorCancel']
|
const TX_PASSTHROUGH_ERROR_CODES = ['operatorCancel', 'scoreThresholdReached', 'ciphertraceError']
|
||||||
|
|
||||||
function filterTransaction () {
|
function filterTransaction () {
|
||||||
const sql = `EXPLAIN ANALYZE
|
const sql = `EXPLAIN ANALYZE
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue