lamassu-server/lib/plugins/wallet-scoring/ciphertrace/ciphertrace.js
2022-01-25 15:59:31 +00:00

91 lines
3.1 KiB
JavaScript

const axios = require('axios')
const _ = require('lodash/fp')
const logger = require('../../../logger')
const NAME = 'CipherTrace'
const SUPPORTED_COINS = ['BTC', 'ETH', 'BCH', 'LTC', 'BNB', 'RSK']
function getClient(account) {
if (_.isNil(account) || !account.enabled) return null
const [ctv1, username, secretKey] = account.authorizationValue.split(':')
if (_.isNil(ctv1) || _.isNil(username) || _.isNil(secretKey)) {
throw new Error('Invalid CipherTrace configuration')
}
const apiVersion = ctv1.slice(-2)
const authHeader = {
"Authorization": account.authorizationValue
}
return { apiVersion, authHeader }
}
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
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 }))
}
function isValidWalletScore(account, score) {
const client = getClient(account)
if (_.isNil(client)) return Promise.resolve(true)
const threshold = account.scoreThreshold
return _.isNil(account) ? Promise.resolve(true) : Promise.resolve(score < threshold)
}
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}`, {
headers: authHeader
})
.then(res => {
const data = res.data
if (_.size(data.txHistory) > 1) {
logger.warn('An address generated by this wallet was used in more than one transaction')
}
return _.join(', ', _.map(it => it.txHash, data.txHistory))
})
}
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
return axios.get(`https://rest.ciphertrace.com/api/${apiVersion}/${_.toLower(cryptoCode) !== 'btc' ? `${_.toLower(cryptoCode)}_` : ``}tx?txhashes=${txHashes}`, {
headers: authHeader
})
.then(res => {
const data = res.data
if (_.size(data.transactions) > 1) {
logger.warn('An address generated by this wallet was used in more than one transaction')
}
const transactionInputs = _.map(it => it.inputs, data.transactions)
const inputAddresses = _.map(it => it.address, _.flatten(transactionInputs))
return inputAddresses
})
}
module.exports = {
NAME,
rateWallet,
isValidWalletScore,
getTransactionHash,
getInputAddresses
}