Merge pull request #1254 from RafaelTaranto/merge-release-8.0-into-dev-220906
Merge release 8.0 into dev 220906
This commit is contained in:
commit
9b4ee6ceab
41 changed files with 228 additions and 149 deletions
|
|
@ -27,6 +27,13 @@ function updateCore (coinRec, isCurrentlyRunning) {
|
|||
common.es(`rm -r /tmp/${coinRec.dir.replace('/bin', '')}`)
|
||||
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`)) {
|
||||
common.logger.info(`changetype already defined, skipping...`)
|
||||
} else {
|
||||
|
|
@ -58,7 +65,7 @@ connections=40
|
|||
keypool=10000
|
||||
prune=4000
|
||||
daemon=0
|
||||
addresstype=p2sh-segwit
|
||||
addresstype=bech32
|
||||
changetype=bech32
|
||||
walletrbf=1
|
||||
bind=0.0.0.0:8332
|
||||
|
|
|
|||
|
|
@ -23,24 +23,28 @@ module.exports = {
|
|||
|
||||
const BINARIES = {
|
||||
BTC: {
|
||||
url: 'https://bitcoincore.org/bin/bitcoin-core-22.0/bitcoin-22.0-x86_64-linux-gnu.tar.gz',
|
||||
dir: 'bitcoin-22.0/bin'
|
||||
defaultUrl: 'https://bitcoincore.org/bin/bitcoin-core-0.20.1/bitcoin-0.20.1-x86_64-linux-gnu.tar.gz',
|
||||
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: {
|
||||
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'
|
||||
},
|
||||
ZEC: {
|
||||
url: 'https://z.cash/downloads/zcash-4.6.0-2-linux64-debian-bullseye.tar.gz',
|
||||
dir: 'zcash-4.6.0-2/bin'
|
||||
url: 'https://z.cash/downloads/zcash-5.0.0-linux64-debian-bullseye.tar.gz',
|
||||
dir: 'zcash-5.0.0/bin'
|
||||
},
|
||||
DASH: {
|
||||
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'
|
||||
},
|
||||
LTC: {
|
||||
url: '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'
|
||||
defaultUrl: 'https://download.litecoin.org/litecoin-0.18.1/linux/litecoin-0.18.1-x86_64-linux-gnu.tar.gz',
|
||||
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: {
|
||||
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']]
|
||||
},
|
||||
XMR: {
|
||||
url: 'https://downloads.getmonero.org/cli/monero-linux-x64-v0.17.3.0.tar.bz2',
|
||||
dir: 'monero-x86_64-linux-gnu-v0.17.3.0',
|
||||
url: 'https://downloads.getmonero.org/cli/monero-linux-x64-v0.17.3.2.tar.bz2',
|
||||
dir: 'monero-x86_64-linux-gnu-v0.17.3.2',
|
||||
files: [['monerod', 'monerod'], ['monero-wallet-rpc', 'monero-wallet-rpc']]
|
||||
}
|
||||
}
|
||||
|
||||
const coinsUpdateDependent = []
|
||||
const coinsUpdateDependent = ['BTC', 'LTC']
|
||||
|
||||
function firewall (ports) {
|
||||
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 /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) {
|
||||
common.logger.info('Starting wallet...')
|
||||
common.es(`sudo supervisorctl start zcash`)
|
||||
|
|
@ -50,5 +57,6 @@ rpcuser=lamassuserver
|
|||
rpcpassword=${common.randomPass()}
|
||||
dbcache=500
|
||||
keypool=10000
|
||||
walletrequirebackup=false
|
||||
`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,23 +140,23 @@ function getWalletScore (tx, pi) {
|
|||
: _.assign(tx, {
|
||||
walletScore: highestScore.score,
|
||||
error: 'Address score is above defined threshold',
|
||||
errorCode: 'operatorCancel',
|
||||
errorCode: 'scoreThresholdReached',
|
||||
dispense: true
|
||||
})
|
||||
})
|
||||
.catch(error => _.assign(tx, {
|
||||
walletScore: 10,
|
||||
error: `Failure getting address score: ${error?.message}`,
|
||||
errorCode: 'operatorCancel',
|
||||
error: `Failure getting address score: ${error.message}`,
|
||||
errorCode: 'ciphertraceError',
|
||||
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)
|
||||
.then(isValid => isValid ? tx : _.assign(tx, {
|
||||
error: 'Address score is above defined threshold',
|
||||
errorCode: 'operatorCancel',
|
||||
errorCode: 'scoreThresholdReached',
|
||||
dispense: true
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ function mapMachine (rates, settings, machineRow) {
|
|||
const lastOnline = machineRow.last_online.toISOString()
|
||||
const status = machineRow.stale ? 'online' : 'offline'
|
||||
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 identification = mapIdentification(config)
|
||||
const coins = _.map(_.partial(mapCoin, [rates, deviceId, settings]), cryptoCurrencies)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ const sms = require('./sms')
|
|||
const settingsLoader = require('./new-settings-loader')
|
||||
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 FRONT_CAMERA_DIR = process.env.FRONT_CAMERA_DIR
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ const { getOperatorId } = require('../operator')
|
|||
|
||||
function findOperatorId (req, res, next) {
|
||||
return getOperatorId('middleware')
|
||||
.then(({ operatorId }) => {
|
||||
.then(operatorId => {
|
||||
res.locals.operatorId = operatorId
|
||||
return next()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ function machineAction (type, value) {
|
|||
}
|
||||
|
||||
function reload (operatorId) {
|
||||
state.needsSettingsReload[operatorId.operatorId] = true
|
||||
state.needsSettingsReload[operatorId] = true
|
||||
}
|
||||
|
||||
const populateSettings = function (req, res, next) {
|
||||
|
|
|
|||
|
|
@ -10,17 +10,6 @@ const anonymous = require('../../../constants').anonymousCustomer
|
|||
const logDateFormat = require('../../../logs').logDateFormat
|
||||
|
||||
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 = {
|
||||
Customer: {
|
||||
|
|
@ -34,7 +23,7 @@ const resolvers = {
|
|||
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 }]) =>
|
||||
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 }]) =>
|
||||
transactions.getTx(id, txClass).then(data =>
|
||||
parseAsync(logDateFormat(timezone, [data], ['created', 'sendTime']))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const db = require('../../db')
|
|||
const { USER_SESSIONS_TABLE_NAME } = require('../../constants')
|
||||
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({
|
||||
pgPromise: db,
|
||||
tableName: USER_SESSIONS_TABLE_NAME
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ function batch (
|
|||
toAddress = null,
|
||||
status = null,
|
||||
excludeTestingCustomers = false,
|
||||
simplified = false
|
||||
simplified
|
||||
) {
|
||||
const packager = _.flow(_.flatten, _.orderBy(_.property('created'), ['desc']), _.map(camelize), addProfits, addNames)
|
||||
|
||||
|
|
@ -120,13 +120,40 @@ function batch (
|
|||
.then(packager)
|
||||
.then(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) {
|
||||
const fields = ['txClass', 'id', 'created', 'machineName',
|
||||
'cryptoCode', 'fiat', 'fiatCode', 'phone', 'toAddress',
|
||||
'cryptoCode', 'cryptoAtoms', 'fiat', 'fiatCode', 'phone', 'toAddress',
|
||||
'txHash', 'dispense', 'error', 'status', 'fiatProfit', 'cryptoAmount']
|
||||
|
||||
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)
|
||||
select $1, $2, $3, $4 where $1 not in (select type from user_config)`
|
||||
function saveAccounts (accounts) {
|
||||
return loadAccounts()
|
||||
.then(currentAccounts => {
|
||||
return Promise.all([loadAccounts(), getOperatorId('middleware')])
|
||||
.then(([currentAccounts, operatorId]) => {
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ const _ = require('lodash/fp')
|
|||
function getOperatorId (service) {
|
||||
const sql = `SELECT operator_id FROM operator_ids WHERE service = '${service}'`
|
||||
return db.oneOrNone(sql)
|
||||
.then(_.mapKeys(_.camelCase))
|
||||
.then(_.get('operator_id'))
|
||||
}
|
||||
|
||||
module.exports = { getOperatorId }
|
||||
|
|
|
|||
|
|
@ -6,8 +6,11 @@ const _ = require('lodash/fp')
|
|||
const request = require('request-promise')
|
||||
const { utils: coinUtils } = require('@lamassu/coins')
|
||||
|
||||
const logger = require('../../logger')
|
||||
|
||||
const BLOCKCHAIN_DIR = process.env.BLOCKCHAIN_DIR
|
||||
|
||||
|
||||
module.exports = {
|
||||
fetch, fetchDigest, parseConf, rpcConfig
|
||||
}
|
||||
|
|
@ -114,6 +117,9 @@ function rpcConfig (cryptoRec) {
|
|||
port: config.rpcport || cryptoRec.defaultPort
|
||||
}
|
||||
} 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'
|
||||
}
|
||||
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' })
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ function getClient(account) {
|
|||
|
||||
const apiVersion = ctv1.slice(-2)
|
||||
const authHeader = {
|
||||
"Authorization": account.authorizationValue
|
||||
'Authorization': account.authorizationValue
|
||||
}
|
||||
return { apiVersion, authHeader }
|
||||
}
|
||||
|
|
@ -28,10 +28,20 @@ function rateWallet(account, cryptoCode, address) {
|
|||
const { apiVersion, authHeader } = client
|
||||
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}`, {
|
||||
headers: authHeader
|
||||
})
|
||||
.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) {
|
||||
|
|
@ -48,7 +58,9 @@ function getTransactionHash(account, cryptoCode, receivingAddress) {
|
|||
|
||||
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
|
||||
})
|
||||
.then(res => {
|
||||
|
|
@ -56,8 +68,13 @@ function getTransactionHash(account, cryptoCode, receivingAddress) {
|
|||
if (_.size(data.txHistory) > 1) {
|
||||
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))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`** DEBUG ** getTransactionHash ERROR: ${err}`)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
function getInputAddresses (account, cryptoCode, txHashes) {
|
||||
|
|
@ -66,6 +83,8 @@ function getInputAddresses(account, cryptoCode, txHashes) {
|
|||
|
||||
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}`, {
|
||||
headers: authHeader
|
||||
})
|
||||
|
|
@ -78,8 +97,14 @@ function getInputAddresses(account, cryptoCode, txHashes) {
|
|||
const transactionInputs = _.flatMap(it => it.inputs, data.transactions)
|
||||
const inputAddresses = _.map(it => it.address, transactionInputs)
|
||||
|
||||
console.log(`** DEBUG ** getInputAddresses RETURN: ${inputAddresses}`)
|
||||
|
||||
return inputAddresses
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(`** DEBUG ** getInputAddresses ERROR: ${err.message}`)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
|
|
|||
|
|
@ -20,17 +20,10 @@ function fetch (method, params) {
|
|||
function errorHandle (e) {
|
||||
const err = JSON.parse(e.message)
|
||||
switch (err.code) {
|
||||
case -4:
|
||||
return loadWallet()
|
||||
case -5:
|
||||
return logger.error(`${err}`)
|
||||
case -6:
|
||||
throw new E.InsufficientFundsError()
|
||||
case -18:
|
||||
return createWallet()
|
||||
case -35:
|
||||
// Wallet is already loaded, just return
|
||||
return
|
||||
default:
|
||||
throw e
|
||||
}
|
||||
|
|
@ -38,20 +31,7 @@ function errorHandle (e) {
|
|||
|
||||
function checkCryptoCode (cryptoCode) {
|
||||
if (cryptoCode !== 'BTC') return Promise.reject(new Error('Unsupported crypto: ' + cryptoCode))
|
||||
return Promise.resolve().then(loadWallet)
|
||||
}
|
||||
|
||||
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)
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
function accountBalance (cryptoCode) {
|
||||
|
|
@ -89,7 +69,7 @@ function calculateFeeDiscount (feeMultiplier) {
|
|||
if (!estimatedFee) return AUTOMATIC_FEE
|
||||
const newFee = estimatedFee.times(feeMultiplier)
|
||||
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
|
||||
return wallet.updateAddress({ address: fundingAddress, label: 'Funding Address' })
|
||||
.then(() => ({
|
||||
fundingPendingBalance: new BN(wallet._wallet.balanceString),
|
||||
fundingConfirmedBalance: new BN(wallet._wallet.confirmedBalanceString),
|
||||
fundingPendingBalance: new BN(wallet._wallet.balance).minus(wallet._wallet.confirmedBalance),
|
||||
fundingConfirmedBalance: new BN(wallet._wallet.confirmedBalance),
|
||||
fundingAddress: getCashAddress(fundingAddress, cryptoCode)
|
||||
}))
|
||||
})
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ function connect (url) {
|
|||
}
|
||||
|
||||
const hex = bigNum => '0x' + bigNum.integerValue(BN.ROUND_DOWN).toString(16)
|
||||
const bn2bn = bn => new BN(bn.toString(16), 16)
|
||||
|
||||
function privateKey (account) {
|
||||
return defaultWallet(account).getPrivateKey()
|
||||
|
|
@ -92,7 +91,7 @@ function _balance (includePending, address, cryptoCode) {
|
|||
const block = includePending ? 'pending' : undefined
|
||||
return pify(web3.eth.getBalance)(address.toLowerCase(), block)
|
||||
/* 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) {
|
||||
|
|
@ -125,11 +124,10 @@ function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
|
|||
]
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(([gas, gasPrice, txCount, { baseFeePerGas }]) => [
|
||||
bn2bn(gas),
|
||||
bn2bn(gasPrice),
|
||||
_.max([1, txCount, lastUsedNonces[fromAddress] + 1]),
|
||||
bn2bn(baseFeePerGas)
|
||||
.then(([gas, gasPrice, txCount]) => [
|
||||
BN(gas),
|
||||
BN(gasPrice),
|
||||
_.max([0, txCount, lastUsedNonces[fromAddress] + 1])
|
||||
])
|
||||
.then(([gas, gasPrice, txCount, baseFeePerGas]) => {
|
||||
lastUsedNonces[fromAddress] = txCount
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ const { default: PQueue } = require('p-queue')
|
|||
|
||||
const BN = require('../../../bn')
|
||||
const E = require('../../../error')
|
||||
const { logger } = require('../../../blockchain/common')
|
||||
const logger = require('../../../logger')
|
||||
const options = require('../../../options')
|
||||
const jsonRpc = require('../../common/json-rpc')
|
||||
|
||||
const BLOCKCHAIN_DIR = process.env.BLOCKCHAIN_DIR
|
||||
|
|
@ -39,7 +40,12 @@ function rpcConfig () {
|
|||
port: cryptoRec.walletPort || cryptoRec.defaultPort
|
||||
}
|
||||
} 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) ? ({
|
||||
delay: terms.delay,
|
||||
active: terms.active,
|
||||
tcPhoto: terms.tcPhoto,
|
||||
title: terms.title,
|
||||
text: nmd(terms.text),
|
||||
accept: terms.acceptButtonText,
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ function cancel (txId) {
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
function customerHistory (customerId, thresholdDays) {
|
||||
const sql = `SELECT * FROM (
|
||||
SELECT txIn.id, txIn.created, txIn.fiat, 'cashIn' AS direction,
|
||||
|
|
@ -84,7 +83,7 @@ function customerHistory (customerId, thresholdDays) {
|
|||
FROM cash_out_txs txOut
|
||||
WHERE txOut.customer_id = $1
|
||||
AND txOut.created > now() - interval $2
|
||||
AND error_code IS DISTINCT FROM 'operatorCancel'
|
||||
AND error_code NOT IN ('operatorCancel', 'scoreThresholdReached', 'ciphertraceError')
|
||||
AND fiat > 0
|
||||
) 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": {
|
||||
"version": "1.0.0-beta.3",
|
||||
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.0.0-beta.3.tgz",
|
||||
"integrity": "sha512-P/CTK1ChFedtHqYHnKcJWFzxMumU43VvtOlc088hdM9phXY1uuQ6+3xyOmojZuqPXKooFN/1BIDA0a4OE6FPOw==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.2.0.tgz",
|
||||
"integrity": "sha512-xp1R2+hd++6WfDOrHxpUdPBqnQiWDz0KttoSHu4KkQsCKCmjr2zUcf6NRKr3syqAhBKekYX+8kDL27VVG+OuUw==",
|
||||
"requires": {
|
||||
"bech32": "2.0.0",
|
||||
"big-integer": "^1.6.48",
|
||||
|
|
@ -8307,7 +8307,7 @@
|
|||
"bigi": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz",
|
||||
"integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU="
|
||||
"integrity": "sha512-ddkU+dFIuEIW8lE7ZwdIAf2UPoM90eaprg5m3YXAVVTmKlqV/9BX4A2M8BOK2yOq6/VgZFVhK6QAxJebhlbhzw=="
|
||||
},
|
||||
"bignumber.js": {
|
||||
"version": "9.0.0",
|
||||
|
|
@ -8356,7 +8356,7 @@
|
|||
"bip66": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
|
||||
"integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
|
||||
"integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
|
|
@ -8396,9 +8396,9 @@
|
|||
}
|
||||
},
|
||||
"bitcore-lib": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.25.tgz",
|
||||
"integrity": "sha512-H6qNCVl4M8/MglXhvc04mmeus1d6nrmqTJGQ+xezJLvL7hs7R3dyBPtOqSP3YSw0iq/GWspMd8f5OOlyXVipJQ==",
|
||||
"version": "8.25.28",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.28.tgz",
|
||||
"integrity": "sha512-UrNHh0Ba8GUiHUYRmm2IKlb8eomsbvk/Z6oQdaOPQoLiamiKnu45pAMqtcHg06wMDF8at54oIdoD2WEU+TQujw==",
|
||||
"requires": {
|
||||
"bech32": "=2.0.0",
|
||||
"bip-schnorr": "=0.6.4",
|
||||
|
|
@ -8418,11 +8418,11 @@
|
|||
}
|
||||
},
|
||||
"bitcore-lib-cash": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.25.tgz",
|
||||
"integrity": "sha512-p/KEBlCKNTTxOZFJLt/bA1b7pQ1JFapHkoWL8mSLxfz9wTK4ScN74zpbBwhG+O7dk7XMo8iRrKigvanmkce35g==",
|
||||
"version": "8.25.28",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.28.tgz",
|
||||
"integrity": "sha512-Zaue7z/iDdQDTNsDoX8LkxH04/pCpHKpSgbxJe2D/2n1YLi1JtzOl9Ox4agYQtR/k9SWCg4p8qJ1W7lVWVP8+A==",
|
||||
"requires": {
|
||||
"bitcore-lib": "^8.25.25",
|
||||
"bitcore-lib": "^8.25.28",
|
||||
"bn.js": "=4.11.8",
|
||||
"bs58": "^4.0.1",
|
||||
"buffer-compare": "=1.1.1",
|
||||
|
|
@ -8800,7 +8800,7 @@
|
|||
"bs58": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
|
||||
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
|
||||
"integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==",
|
||||
"requires": {
|
||||
"base-x": "^3.0.2"
|
||||
}
|
||||
|
|
@ -8852,7 +8852,7 @@
|
|||
"buffer-compare": {
|
||||
"version": "1.1.1",
|
||||
"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": {
|
||||
"version": "1.1.1",
|
||||
|
|
@ -18638,9 +18638,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node-gyp-build": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz",
|
||||
"integrity": "sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q=="
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz",
|
||||
"integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ=="
|
||||
},
|
||||
"node-int64": {
|
||||
"version": "0.4.0",
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
"license": "unlicense",
|
||||
"dependencies": {
|
||||
"@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/icons": "4.9.1",
|
||||
"@material-ui/lab": "^4.0.0-alpha.56",
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ import { primaryColor } from 'src/styling/variables'
|
|||
|
||||
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 sizes = {
|
||||
big: 165,
|
||||
|
|
@ -176,7 +179,11 @@ const Funding = () => {
|
|||
{selected && !viewHistory && selected.errorMsg && (
|
||||
<div className={classes.main}>
|
||||
<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>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ const TermsConditions = () => {
|
|||
const formData = termsAndConditions ?? {}
|
||||
const showOnScreen = termsAndConditions?.active ?? false
|
||||
const addDelayOnScreen = termsAndConditions?.delay ?? false
|
||||
const tcPhoto = termsAndConditions?.tcPhoto ?? false
|
||||
|
||||
const save = it =>
|
||||
saveConfig({
|
||||
|
|
@ -183,6 +184,23 @@ const TermsConditions = () => {
|
|||
<Label2>{showOnScreen ? 'Yes' : 'No'}</Label2>
|
||||
</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}>
|
||||
<P>Add 7 seconds delay on screen</P>
|
||||
<div className={classes.switch}>
|
||||
|
|
|
|||
|
|
@ -202,10 +202,10 @@ const DetailsRow = ({ it: tx, timezone }) => {
|
|||
r={3.5}
|
||||
fill={
|
||||
it < tx.walletScore
|
||||
? !R.includes('score is above', tx.hasError ?? '')
|
||||
? R.isNil(tx.hasError)
|
||||
? primaryColor
|
||||
: errorColor
|
||||
: !R.includes('score is above', tx.hasError ?? '')
|
||||
: R.isNil(tx.hasError)
|
||||
? subheaderColor
|
||||
: offErrorColor
|
||||
}
|
||||
|
|
@ -218,7 +218,7 @@ const DetailsRow = ({ it: tx, timezone }) => {
|
|||
noMargin
|
||||
className={classNames({
|
||||
[classes.bold]: true,
|
||||
[classes.error]: R.includes('score is above', tx.hasError ?? '')
|
||||
[classes.error]: !R.isNil(tx.hasError)
|
||||
})}>
|
||||
{tx.walletScore}
|
||||
</P>
|
||||
|
|
|
|||
|
|
@ -58,10 +58,18 @@ const viewFeeMultiplier = it =>
|
|||
R.compose(R.prop(['display']), R.find(R.propEq('code', it)))(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: '+10%', code: '1.1' },
|
||||
{ display: 'Default', code: '1' },
|
||||
{ display: '-10%', code: '0.9' },
|
||||
{ display: '-20%', code: '0.8' },
|
||||
{ display: '-30%', code: '0.7' },
|
||||
{ display: '-40%', code: '0.6' },
|
||||
{ display: '-50%', code: '0.5' },
|
||||
{ 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=="
|
||||
},
|
||||
"@lamassu/coins": {
|
||||
"version": "1.0.0-beta.3",
|
||||
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.0.0-beta.3.tgz",
|
||||
"integrity": "sha512-P/CTK1ChFedtHqYHnKcJWFzxMumU43VvtOlc088hdM9phXY1uuQ6+3xyOmojZuqPXKooFN/1BIDA0a4OE6FPOw==",
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.2.0.tgz",
|
||||
"integrity": "sha512-xp1R2+hd++6WfDOrHxpUdPBqnQiWDz0KttoSHu4KkQsCKCmjr2zUcf6NRKr3syqAhBKekYX+8kDL27VVG+OuUw==",
|
||||
"requires": {
|
||||
"bech32": "2.0.0",
|
||||
"big-integer": "^1.6.48",
|
||||
|
|
@ -6432,9 +6432,9 @@
|
|||
}
|
||||
},
|
||||
"bitcore-lib": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.25.tgz",
|
||||
"integrity": "sha512-H6qNCVl4M8/MglXhvc04mmeus1d6nrmqTJGQ+xezJLvL7hs7R3dyBPtOqSP3YSw0iq/GWspMd8f5OOlyXVipJQ==",
|
||||
"version": "8.25.28",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib/-/bitcore-lib-8.25.28.tgz",
|
||||
"integrity": "sha512-UrNHh0Ba8GUiHUYRmm2IKlb8eomsbvk/Z6oQdaOPQoLiamiKnu45pAMqtcHg06wMDF8at54oIdoD2WEU+TQujw==",
|
||||
"requires": {
|
||||
"bech32": "=2.0.0",
|
||||
"bip-schnorr": "=0.6.4",
|
||||
|
|
@ -6459,11 +6459,11 @@
|
|||
}
|
||||
},
|
||||
"bitcore-lib-cash": {
|
||||
"version": "8.25.25",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.25.tgz",
|
||||
"integrity": "sha512-p/KEBlCKNTTxOZFJLt/bA1b7pQ1JFapHkoWL8mSLxfz9wTK4ScN74zpbBwhG+O7dk7XMo8iRrKigvanmkce35g==",
|
||||
"version": "8.25.28",
|
||||
"resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-8.25.28.tgz",
|
||||
"integrity": "sha512-Zaue7z/iDdQDTNsDoX8LkxH04/pCpHKpSgbxJe2D/2n1YLi1JtzOl9Ox4agYQtR/k9SWCg4p8qJ1W7lVWVP8+A==",
|
||||
"requires": {
|
||||
"bitcore-lib": "^8.25.25",
|
||||
"bitcore-lib": "^8.25.28",
|
||||
"bn.js": "=4.11.8",
|
||||
"bs58": "^4.0.1",
|
||||
"buffer-compare": "=1.1.1",
|
||||
|
|
@ -8443,13 +8443,9 @@
|
|||
}
|
||||
},
|
||||
"crc-32": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
|
||||
"integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
|
||||
"requires": {
|
||||
"exit-on-epipe": "~1.0.1",
|
||||
"printj": "~1.1.0"
|
||||
}
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
|
||||
"integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="
|
||||
},
|
||||
"create-ecdh": {
|
||||
"version": "4.0.4",
|
||||
|
|
@ -10569,11 +10565,6 @@
|
|||
"integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
|
||||
"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": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
|
||||
|
|
@ -17665,11 +17656,6 @@
|
|||
"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": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
"dependencies": {
|
||||
"@ethereumjs/common": "^2.6.4",
|
||||
"@ethereumjs/tx": "^3.5.1",
|
||||
"@lamassu/coins": "1.0.0-beta.3",
|
||||
"@lamassu/coins": "1.2.0",
|
||||
"@simplewebauthn/server": "^3.0.0",
|
||||
"apollo-server-express": "2.25.1",
|
||||
"argon2": "0.28.2",
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"files": {
|
||||
"main.js": "/static/js/main.4a3fa58d.chunk.js",
|
||||
"main.js.map": "/static/js/main.4a3fa58d.chunk.js.map",
|
||||
"main.js": "/static/js/main.b7e0a067.chunk.js",
|
||||
"main.js.map": "/static/js/main.b7e0a067.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.208e5597.chunk.js": "/static/js/2.208e5597.chunk.js",
|
||||
"static/js/2.208e5597.chunk.js.map": "/static/js/2.208e5597.chunk.js.map",
|
||||
"static/js/2.cac754a9.chunk.js": "/static/js/2.cac754a9.chunk.js",
|
||||
"static/js/2.cac754a9.chunk.js.map": "/static/js/2.cac754a9.chunk.js.map",
|
||||
"index.html": "/index.html",
|
||||
"static/js/2.208e5597.chunk.js.LICENSE.txt": "/static/js/2.208e5597.chunk.js.LICENSE.txt",
|
||||
"static/js/2.cac754a9.chunk.js.LICENSE.txt": "/static/js/2.cac754a9.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-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",
|
||||
|
|
@ -61,6 +61,7 @@
|
|||
"static/media/icon-ethereum-colour.761723a2.svg": "/static/media/icon-ethereum-colour.761723a2.svg",
|
||||
"static/media/icon-litecoin-colour.bd861b5e.svg": "/static/media/icon-litecoin-colour.bd861b5e.svg",
|
||||
"static/media/icon-monero-colour.650b7bd1.svg": "/static/media/icon-monero-colour.650b7bd1.svg",
|
||||
"static/media/icon-tether-colour.92d7fda4.svg": "/static/media/icon-tether-colour.92d7fda4.svg",
|
||||
"static/media/icon-zcash-colour.68b1c20b.svg": "/static/media/icon-zcash-colour.68b1c20b.svg",
|
||||
"static/media/keyboard.cc22b859.svg": "/static/media/keyboard.cc22b859.svg",
|
||||
"static/media/keypad.dfb6094e.svg": "/static/media/keypad.dfb6094e.svg",
|
||||
|
|
@ -152,7 +153,7 @@
|
|||
},
|
||||
"entrypoints": [
|
||||
"static/js/runtime-main.5b925903.js",
|
||||
"static/js/2.208e5597.chunk.js",
|
||||
"static/js/main.4a3fa58d.chunk.js"
|
||||
"static/js/2.cac754a9.chunk.js",
|
||||
"static/js/main.b7e0a067.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.cac754a9.chunk.js"></script><script src="/static/js/main.b7e0a067.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
2
public/static/js/main.b7e0a067.chunk.js
Normal file
2
public/static/js/main.b7e0a067.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
public/static/js/main.b7e0a067.chunk.js.map
Normal file
1
public/static/js/main.b7e0a067.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 { 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 () {
|
||||
const sql = `EXPLAIN ANALYZE
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue