Merge pull request #1089 from chaotixkilla/fix-btc-batching-bn-functions
Fix BigNumber functions on BTC batching function
This commit is contained in:
commit
c58cfcb8f7
9 changed files with 35 additions and 18 deletions
|
|
@ -47,6 +47,7 @@ const typeDef = gql`
|
||||||
txCustomerPhotoAt: Date
|
txCustomerPhotoAt: Date
|
||||||
batched: Boolean
|
batched: Boolean
|
||||||
batchTime: Date
|
batchTime: Date
|
||||||
|
batchError: String
|
||||||
walletScore: Int
|
walletScore: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ const settingsLoader = require('../../new-settings-loader')
|
||||||
const configManager = require('../../new-config-manager')
|
const configManager = require('../../new-config-manager')
|
||||||
const wallet = require('../../wallet')
|
const wallet = require('../../wallet')
|
||||||
const ticker = require('../../ticker')
|
const ticker = require('../../ticker')
|
||||||
|
const txBatching = require('../../tx-batching')
|
||||||
const { utils: coinUtils } = require('lamassu-coins')
|
const { utils: coinUtils } = require('lamassu-coins')
|
||||||
|
|
||||||
function computeCrypto (cryptoCode, _balance) {
|
function computeCrypto (cryptoCode, _balance) {
|
||||||
|
|
@ -23,16 +24,17 @@ function computeFiat (rate, cryptoCode, _balance) {
|
||||||
function getSingleCoinFunding (settings, fiatCode, cryptoCode) {
|
function getSingleCoinFunding (settings, fiatCode, cryptoCode) {
|
||||||
const promises = [
|
const promises = [
|
||||||
wallet.newFunding(settings, cryptoCode),
|
wallet.newFunding(settings, cryptoCode),
|
||||||
ticker.getRates(settings, fiatCode, cryptoCode)
|
ticker.getRates(settings, fiatCode, cryptoCode),
|
||||||
|
txBatching.getOpenBatchCryptoValue(cryptoCode)
|
||||||
]
|
]
|
||||||
|
|
||||||
return Promise.all(promises)
|
return Promise.all(promises)
|
||||||
.then(([fundingRec, ratesRec]) => {
|
.then(([fundingRec, ratesRec, batchRec]) => {
|
||||||
const rates = ratesRec.rates
|
const rates = ratesRec.rates
|
||||||
const rate = (rates.ask.plus(rates.bid)).div(2)
|
const rate = (rates.ask.plus(rates.bid)).div(2)
|
||||||
const fundingConfirmedBalance = fundingRec.fundingConfirmedBalance
|
const fundingConfirmedBalance = fundingRec.fundingConfirmedBalance
|
||||||
const fiatConfirmedBalance = computeFiat(rate, cryptoCode, fundingConfirmedBalance)
|
const fiatConfirmedBalance = computeFiat(rate, cryptoCode, fundingConfirmedBalance)
|
||||||
const pending = fundingRec.fundingPendingBalance
|
const pending = fundingRec.fundingPendingBalance.minus(batchRec)
|
||||||
const fiatPending = computeFiat(rate, cryptoCode, pending)
|
const fiatPending = computeFiat(rate, cryptoCode, pending)
|
||||||
const fundingAddress = fundingRec.fundingAddress
|
const fundingAddress = fundingRec.fundingAddress
|
||||||
const fundingAddressUrl = coinUtils.buildUrl(cryptoCode, fundingAddress)
|
const fundingAddressUrl = coinUtils.buildUrl(cryptoCode, fundingAddress)
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,12 @@ function batch (
|
||||||
c.id_card_photo_path AS customer_id_card_photo_path,
|
c.id_card_photo_path AS customer_id_card_photo_path,
|
||||||
txs.tx_customer_photo_at AS tx_customer_photo_at,
|
txs.tx_customer_photo_at AS tx_customer_photo_at,
|
||||||
txs.tx_customer_photo_path AS tx_customer_photo_path,
|
txs.tx_customer_photo_path AS tx_customer_photo_path,
|
||||||
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired
|
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired,
|
||||||
|
tb.error_message AS batch_error
|
||||||
FROM (SELECT *, ${cashInTx.TRANSACTION_STATES} AS txStatus FROM cash_in_txs) AS txs
|
FROM (SELECT *, ${cashInTx.TRANSACTION_STATES} AS txStatus FROM cash_in_txs) AS txs
|
||||||
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
|
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
|
||||||
LEFT JOIN devices d ON txs.device_id = d.device_id
|
LEFT JOIN devices d ON txs.device_id = d.device_id
|
||||||
|
LEFT OUTER JOIN transaction_batches tb ON txs.batch_id = tb.id
|
||||||
WHERE txs.created >= $2 AND txs.created <= $3 ${
|
WHERE txs.created >= $2 AND txs.created <= $3 ${
|
||||||
id !== null ? `AND txs.device_id = $6` : ``
|
id !== null ? `AND txs.device_id = $6` : ``
|
||||||
}
|
}
|
||||||
|
|
@ -69,7 +71,7 @@ function batch (
|
||||||
AND ($12 is null or txs.to_address = $12)
|
AND ($12 is null or txs.to_address = $12)
|
||||||
AND ($13 is null or txs.txStatus = $13)
|
AND ($13 is null or txs.txStatus = $13)
|
||||||
${excludeTestingCustomers ? `AND c.is_test_customer is false` : ``}
|
${excludeTestingCustomers ? `AND c.is_test_customer is false` : ``}
|
||||||
AND (error IS NOT null OR fiat > 0)
|
AND (error IS NOT null OR tb.error_message IS NOT null OR fiat > 0)
|
||||||
ORDER BY created DESC limit $4 offset $5`
|
ORDER BY created DESC limit $4 offset $5`
|
||||||
|
|
||||||
const cashOutSql = `SELECT 'cashOut' AS tx_class,
|
const cashOutSql = `SELECT 'cashOut' AS tx_class,
|
||||||
|
|
@ -151,6 +153,7 @@ const getCashOutStatus = it => {
|
||||||
const getCashInStatus = it => {
|
const getCashInStatus = it => {
|
||||||
if (it.operatorCompleted) return 'Cancelled'
|
if (it.operatorCompleted) return 'Cancelled'
|
||||||
if (it.hasError) return 'Error'
|
if (it.hasError) return 'Error'
|
||||||
|
if (it.batchError) return 'Error'
|
||||||
if (it.sendConfirmed) return 'Sent'
|
if (it.sendConfirmed) return 'Sent'
|
||||||
if (it.expired) return 'Expired'
|
if (it.expired) return 'Expired'
|
||||||
return 'Pending'
|
return 'Pending'
|
||||||
|
|
@ -176,9 +179,11 @@ function getCustomerTransactionsBatch (ids) {
|
||||||
c.name AS customer_name,
|
c.name AS customer_name,
|
||||||
c.front_camera_path AS customer_front_camera_path,
|
c.front_camera_path AS customer_front_camera_path,
|
||||||
c.id_card_photo_path AS customer_id_card_photo_path,
|
c.id_card_photo_path AS customer_id_card_photo_path,
|
||||||
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $2)) AS expired
|
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $2)) AS expired,
|
||||||
|
tb.error_message AS batch_error
|
||||||
FROM cash_in_txs AS txs
|
FROM cash_in_txs AS txs
|
||||||
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
|
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
|
||||||
|
LEFT OUTER JOIN transaction_batches tb ON txs.batch_id = tb.id
|
||||||
WHERE c.id IN ($1^)
|
WHERE c.id IN ($1^)
|
||||||
ORDER BY created DESC limit $3`
|
ORDER BY created DESC limit $3`
|
||||||
|
|
||||||
|
|
@ -220,9 +225,11 @@ function single (txId) {
|
||||||
c.name AS customer_name,
|
c.name AS customer_name,
|
||||||
c.front_camera_path AS customer_front_camera_path,
|
c.front_camera_path AS customer_front_camera_path,
|
||||||
c.id_card_photo_path AS customer_id_card_photo_path,
|
c.id_card_photo_path AS customer_id_card_photo_path,
|
||||||
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired
|
((NOT txs.send_confirmed) AND (txs.created <= now() - interval $1)) AS expired,
|
||||||
|
tb.error_message AS batch_error
|
||||||
FROM cash_in_txs AS txs
|
FROM cash_in_txs AS txs
|
||||||
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
|
LEFT OUTER JOIN customers c ON txs.customer_id = c.id
|
||||||
|
LEFT OUTER JOIN transaction_batches tb ON txs.batch_id = tb.id
|
||||||
WHERE id=$2`
|
WHERE id=$2`
|
||||||
|
|
||||||
const cashOutSql = `SELECT 'cashOut' AS tx_class,
|
const cashOutSql = `SELECT 'cashOut' AS tx_class,
|
||||||
|
|
|
||||||
|
|
@ -80,19 +80,19 @@ function sendCoins (account, tx, settings, operatorId, feeMultiplier) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendCoinsBatch (account, txs, cryptoCode) {
|
function sendCoinsBatch (account, txs, cryptoCode, feeMultiplier) {
|
||||||
return checkCryptoCode(cryptoCode)
|
return checkCryptoCode(cryptoCode)
|
||||||
.then(() => calculateFeeDiscount(feeMultiplier))
|
.then(() => calculateFeeDiscount(feeMultiplier))
|
||||||
.then(newFee => fetch('settxfee', [newFee]))
|
.then(newFee => fetch('settxfee', [newFee]))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
const txAddressAmountPairs = _.map(tx => [tx.address, tx.cryptoAtoms.shift(-unitScale).toFixed(8)], txs)
|
const txAddressAmountPairs = _.map(tx => [tx.address, tx.cryptoAtoms.shiftedBy(-unitScale).toFixed(8)], txs)
|
||||||
return Promise.all([JSON.stringify(_.fromPairs(txAddressAmountPairs))])
|
return Promise.all([JSON.stringify(_.fromPairs(txAddressAmountPairs))])
|
||||||
})
|
})
|
||||||
.then(([obj]) => fetch('sendmany', ['', obj]))
|
.then(([obj]) => fetch('sendmany', ['', obj]))
|
||||||
.then((txId) => fetch('gettransaction', [txId]))
|
.then((txId) => fetch('gettransaction', [txId]))
|
||||||
.then((res) => _.pick(['fee', 'txid'], res))
|
.then((res) => _.pick(['fee', 'txid'], res))
|
||||||
.then((pickedObj) => ({
|
.then((pickedObj) => ({
|
||||||
fee: BN(pickedObj.fee).abs().shift(unitScale).round(),
|
fee: new BN(pickedObj.fee).abs().shiftedBy(unitScale).decimalPlaces(0),
|
||||||
txid: pickedObj.txid
|
txid: pickedObj.txid
|
||||||
}))
|
}))
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,7 @@ const lastBalance = {}
|
||||||
function _balance (settings, cryptoCode) {
|
function _balance (settings, cryptoCode) {
|
||||||
return fetchWallet(settings, cryptoCode)
|
return fetchWallet(settings, cryptoCode)
|
||||||
.then(r => r.wallet.balance(r.account, cryptoCode, settings, r.operatorId))
|
.then(r => r.wallet.balance(r.account, cryptoCode, settings, r.operatorId))
|
||||||
.then(balance => Promise.all([balance, supportsBatching(settings, cryptoCode)]))
|
.then(balance => Promise.all([balance, getOpenBatchCryptoValue(cryptoCode)]))
|
||||||
.then(([balance, supportsBatching]) => Promise.all([balance, supportsBatching ? getOpenBatchCryptoValue(cryptoCode) : Promise.resolve(BN(0))]))
|
|
||||||
.then(([balance, reservedBalance]) => ({ balance: balance.minus(reservedBalance), reservedBalance, timestamp: Date.now() }))
|
.then(([balance, reservedBalance]) => ({ balance: balance.minus(reservedBalance), reservedBalance, timestamp: Date.now() }))
|
||||||
.then(r => {
|
.then(r => {
|
||||||
lastBalance[cryptoCode] = r
|
lastBalance[cryptoCode] = r
|
||||||
|
|
@ -82,7 +81,8 @@ function sendCoins (settings, tx) {
|
||||||
function sendCoinsBatch (settings, txs, cryptoCode) {
|
function sendCoinsBatch (settings, txs, cryptoCode) {
|
||||||
return fetchWallet(settings, cryptoCode)
|
return fetchWallet(settings, cryptoCode)
|
||||||
.then(r => {
|
.then(r => {
|
||||||
return r.wallet.sendCoinsBatch(r.account, txs, cryptoCode)
|
const feeMultiplier = settings[`wallets_${cryptoCode}_feeMultiplier`]
|
||||||
|
return r.wallet.sendCoinsBatch(r.account, txs, cryptoCode, feeMultiplier)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
mem.clear(module.exports.balance)
|
mem.clear(module.exports.balance)
|
||||||
return res
|
return res
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,9 @@ const Row = ({
|
||||||
expandable && expandRow(id, data)
|
expandable && expandRow(id, data)
|
||||||
onClick && onClick(data)
|
onClick && onClick(data)
|
||||||
}}
|
}}
|
||||||
error={data.error || data.hasError}
|
error={data.error || data.hasError || data.batchError}
|
||||||
shouldShowError={false}
|
shouldShowError={false}
|
||||||
errorMessage={data.errorMessage || data.hasError}>
|
errorMessage={data.errorMessage || data.hasError || data.batchError}>
|
||||||
{elements.map(({ view = it => it?.toString(), ...props }, idx) => (
|
{elements.map(({ view = it => it?.toString(), ...props }, idx) => (
|
||||||
<Td key={idx} {...props}>
|
<Td key={idx} {...props}>
|
||||||
{view(data)}
|
{view(data)}
|
||||||
|
|
|
||||||
|
|
@ -419,5 +419,6 @@ export default memo(
|
||||||
(prev, next) =>
|
(prev, next) =>
|
||||||
prev.it.id === next.it.id &&
|
prev.it.id === next.it.id &&
|
||||||
prev.it.hasError === next.it.hasError &&
|
prev.it.hasError === next.it.hasError &&
|
||||||
|
prev.it.batchError === next.it.batchError &&
|
||||||
getStatus(prev.it) === getStatus(next.it)
|
getStatus(prev.it) === getStatus(next.it)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,7 @@ const GET_TRANSACTIONS = gql`
|
||||||
isAnonymous
|
isAnonymous
|
||||||
batched
|
batched
|
||||||
batchTime
|
batchTime
|
||||||
|
batchError
|
||||||
walletScore
|
walletScore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +191,7 @@ const Transactions = () => {
|
||||||
<div className={classes.overflowTd}>{getCustomerDisplayName(it)}</div>
|
<div className={classes.overflowTd}>{getCustomerDisplayName(it)}</div>
|
||||||
{!it.isAnonymous && (
|
{!it.isAnonymous && (
|
||||||
<div onClick={() => redirect(it.customerId)}>
|
<div onClick={() => redirect(it.customerId)}>
|
||||||
{it.hasError ? (
|
{it.hasError || it.batchError ? (
|
||||||
<CustomerLinkWhiteIcon className={classes.customerLinkIcon} />
|
<CustomerLinkWhiteIcon className={classes.customerLinkIcon} />
|
||||||
) : (
|
) : (
|
||||||
<CustomerLinkIcon className={classes.customerLinkIcon} />
|
<CustomerLinkIcon className={classes.customerLinkIcon} />
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import * as R from 'ramda'
|
||||||
|
|
||||||
const getCashOutStatus = it => {
|
const getCashOutStatus = it => {
|
||||||
if (it.hasError === 'Operator cancel') return 'Cancelled'
|
if (it.hasError === 'Operator cancel') return 'Cancelled'
|
||||||
if (it.hasError) return 'Error'
|
if (it.hasError) return 'Error'
|
||||||
|
|
@ -8,7 +10,7 @@ const getCashOutStatus = it => {
|
||||||
|
|
||||||
const getCashInStatus = it => {
|
const getCashInStatus = it => {
|
||||||
if (it.operatorCompleted) return 'Cancelled'
|
if (it.operatorCompleted) return 'Cancelled'
|
||||||
if (it.hasError) return 'Error'
|
if (it.hasError || it.batchError) return 'Error'
|
||||||
if (it.sendConfirmed) return 'Sent'
|
if (it.sendConfirmed) return 'Sent'
|
||||||
if (it.expired) return 'Expired'
|
if (it.expired) return 'Expired'
|
||||||
if (it.batched) return 'Batched'
|
if (it.batched) return 'Batched'
|
||||||
|
|
@ -23,11 +25,14 @@ const getStatus = it => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStatusDetails = it => {
|
const getStatusDetails = it => {
|
||||||
return it.hasError ? it.hasError : null
|
if (!R.isNil(it.hasError)) return it.hasError
|
||||||
|
if (!R.isNil(it.batchError)) return `Batch error: ${it.batchError}`
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const getStatusProperties = status => ({
|
const getStatusProperties = status => ({
|
||||||
hasError: status === 'Error' || null,
|
hasError: status === 'Error' || null,
|
||||||
|
batchError: status === 'Error' || null,
|
||||||
dispense: status === 'Success' || null,
|
dispense: status === 'Success' || null,
|
||||||
expired: status === 'Expired' || null,
|
expired: status === 'Expired' || null,
|
||||||
operatorCompleted: status === 'Cancelled' || null,
|
operatorCompleted: status === 'Cancelled' || null,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue