Merge remote-tracking branch 'upstream/release-8.0' into merge-release-8.0-into-dev-220906

This commit is contained in:
Taranto 2022-06-09 23:56:40 +01:00
commit 4023470fec
47 changed files with 410 additions and 149 deletions

View file

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

View file

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

View file

@ -6,7 +6,7 @@ const logger = require('../../../logger')
const NAME = 'CipherTrace'
const SUPPORTED_COINS = ['BTC', 'ETH', 'BCH', 'LTC', 'BNB', 'RSK']
function getClient(account) {
function getClient (account) {
if (_.isNil(account) || !account.enabled) return null
const [ctv1, username, secretKey] = account.authorizationValue.split(':')
@ -16,25 +16,35 @@ function getClient(account) {
const apiVersion = ctv1.slice(-2)
const authHeader = {
"Authorization": account.authorizationValue
'Authorization': account.authorizationValue
}
return { apiVersion, authHeader }
}
function rateWallet(account, cryptoCode, address) {
function rateWallet (account, cryptoCode, address) {
const client = getClient(account)
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
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) {
function isValidWalletScore (account, score) {
const client = getClient(account)
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)
}
function getTransactionHash(account, cryptoCode, receivingAddress) {
function getTransactionHash (account, cryptoCode, receivingAddress) {
const client = getClient(account)
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
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,16 +68,23 @@ 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) {
function getInputAddresses (account, cryptoCode, txHashes) {
const client = getClient(account)
if (!_.includes(_.toUpper(cryptoCode), SUPPORTED_COINS) || _.isNil(client)) return Promise.resolve(null)
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 = {

View file

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

View file

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

View file

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

View file

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