Prevent address reuse option
This commit is contained in:
parent
55cdc2fa52
commit
98cc3b18b7
9 changed files with 141 additions and 13 deletions
|
|
@ -12,7 +12,7 @@ const rl = readline.createInterface({
|
||||||
})
|
})
|
||||||
|
|
||||||
const sql = `select regexp_replace(crypto_code, '$', ' ') as code,regexp_replace(address, '^', ' ') as address from blacklist`
|
const sql = `select regexp_replace(crypto_code, '$', ' ') as code,regexp_replace(address, '^', ' ') as address from blacklist`
|
||||||
const insertSql = `insert into blacklist(crypto_code, address) values ($1, $2)`
|
const insertSql = `insert into blacklist(crypto_code, address, created_by_operator) values ($1, $2, 't')`
|
||||||
const makeDimAndReset = '\x1b[2m%s\x1b[0m'
|
const makeDimAndReset = '\x1b[2m%s\x1b[0m'
|
||||||
|
|
||||||
db.query(sql)
|
db.query(sql)
|
||||||
|
|
|
||||||
58
bin/lamassu-remove-from-blacklist
Normal file
58
bin/lamassu-remove-from-blacklist
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const os = require('os')
|
||||||
|
const readline = require('readline')
|
||||||
|
|
||||||
|
const coinUtils = require('../lib/coin-utils')
|
||||||
|
const db = require('../lib/db')
|
||||||
|
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: process.stdin,
|
||||||
|
output: process.stdout
|
||||||
|
})
|
||||||
|
|
||||||
|
const sql = `select regexp_replace(crypto_code, '$', ' ') as code,regexp_replace(address, '^', ' ') as address from blacklist`
|
||||||
|
const deleteSql = `delete from blacklist where crypto_code = $1 and address = $2`
|
||||||
|
const makeDimAndReset = '\x1b[2m%s\x1b[0m'
|
||||||
|
|
||||||
|
db.query(sql)
|
||||||
|
.then(many => {
|
||||||
|
console.log(os.EOL, 'Here is your current list of prohibited addresses:', os.EOL)
|
||||||
|
console.log(many.map(it => `${it.code} | ${it.address}`).join(os.EOL), os.EOL)
|
||||||
|
console.log('What address would you like to remove from the list?', os.EOL)
|
||||||
|
console.log(makeDimAndReset, 'Example:', 'bc1q8pu2zlfxg8jf4cyuf844rl3uxmmw8sj9yaa393', os.EOL)
|
||||||
|
|
||||||
|
rl.question('Address: ', (address) => {
|
||||||
|
var aphaNumericRegex = /^([0-9]|[a-z])+([0-9a-z]+)$/i
|
||||||
|
if (!address.match(aphaNumericRegex)) {
|
||||||
|
return errorHandler(new Error('Invalid address'))
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(os.EOL, 'What is the ticker symbol of the coin that this address belongs to?', os.EOL)
|
||||||
|
console.log(makeDimAndReset, 'Example:', 'BTC', os.EOL)
|
||||||
|
|
||||||
|
rl.question('Ticker symbol: ', (cryptoCode) => {
|
||||||
|
try {
|
||||||
|
coinUtils.getCryptoCurrency(cryptoCode)
|
||||||
|
} catch (err) {
|
||||||
|
errorHandler(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
db.none(deleteSql, [cryptoCode, address])
|
||||||
|
.then(() => db.query(sql))
|
||||||
|
.then(many2 => {
|
||||||
|
console.log(os.EOL, `Address removed. Here's the new list of prohibited addresses:`, os.EOL)
|
||||||
|
console.log(many2.map(it => `${it.code} | ${it.address}`).join(os.EOL))
|
||||||
|
rl.close()
|
||||||
|
process.exit(0)
|
||||||
|
})
|
||||||
|
.catch(errorHandler)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}).catch(errorHandler)
|
||||||
|
|
||||||
|
function errorHandler (err) {
|
||||||
|
rl.close()
|
||||||
|
console.log(err)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
@ -1149,6 +1149,7 @@ complianceTableView model =
|
||||||
, row "Sanctions" "sanctionsVerificationActive" "sanctionsVerificationThreshold"
|
, row "Sanctions" "sanctionsVerificationActive" "sanctionsVerificationThreshold"
|
||||||
, row "Hard Limit" "hardLimitVerificationActive" "hardLimitVerificationThreshold"
|
, row "Hard Limit" "hardLimitVerificationActive" "hardLimitVerificationThreshold"
|
||||||
, row "Receipt Printing" "receiptPrintingActive" ""
|
, row "Receipt Printing" "receiptPrintingActive" ""
|
||||||
|
, row "Reject Address Reuse" "rejectAddressReuseActive" ""
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,8 @@
|
||||||
"frontCameraVerificationThreshold",
|
"frontCameraVerificationThreshold",
|
||||||
"hardLimitVerificationActive",
|
"hardLimitVerificationActive",
|
||||||
"hardLimitVerificationThreshold",
|
"hardLimitVerificationThreshold",
|
||||||
"receiptPrintingActive"
|
"receiptPrintingActive",
|
||||||
|
"rejectAddressReuseActive"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -163,6 +164,20 @@
|
||||||
],
|
],
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"code": "rejectAddressReuseActive",
|
||||||
|
"displayTop": "Reject Address Reuse",
|
||||||
|
"displayBottom": "Reject Address Reuse",
|
||||||
|
"displayTopCount": 2,
|
||||||
|
"fieldType": "onOff",
|
||||||
|
"fieldClass": null,
|
||||||
|
"fieldValidation": [
|
||||||
|
{
|
||||||
|
"code": "required"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"code": "hardLimitVerificationActive",
|
"code": "hardLimitVerificationActive",
|
||||||
"displayTop": "Hard Limit",
|
"displayTop": "Hard Limit",
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,15 @@ function blocked (address, cryptoCode) {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { blocked }
|
function addToUsedAddresses (address, cryptoCode) {
|
||||||
|
// ETH reuses addresses
|
||||||
|
if (cryptoCode === 'ETH') return Promise.resolve()
|
||||||
|
|
||||||
|
const sql = `insert into blacklist(crypto_code, address, created_by_operator) values ($1, $2, 'f')`
|
||||||
|
return db.oneOrNone(sql, [
|
||||||
|
cryptoCode,
|
||||||
|
address
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { blocked, addToUsedAddresses }
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ const E = require('../error')
|
||||||
|
|
||||||
const PENDING_INTERVAL_MS = 60 * T.minutes
|
const PENDING_INTERVAL_MS = 60 * T.minutes
|
||||||
|
|
||||||
const massage = _.flow(_.omit(['direction', 'cryptoNetwork', 'bills', 'blacklisted']),
|
const massage = _.flow(_.omit(['direction', 'cryptoNetwork', 'bills', 'blacklisted', 'addressReuse']),
|
||||||
convertBigNumFields, _.mapKeys(_.snakeCase))
|
convertBigNumFields, _.mapKeys(_.snakeCase))
|
||||||
|
|
||||||
module.exports = {toObj, upsert, insert, update, massage, isClearToSend}
|
module.exports = {toObj, upsert, insert, update, massage, isClearToSend}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ const blacklist = require('../blacklist')
|
||||||
const db = require('../db')
|
const db = require('../db')
|
||||||
const plugins = require('../plugins')
|
const plugins = require('../plugins')
|
||||||
const logger = require('../logger')
|
const logger = require('../logger')
|
||||||
|
const settingsLoader = require('../settings-loader')
|
||||||
|
const configManager = require('../config-manager')
|
||||||
|
|
||||||
const cashInAtomic = require('./cash-in-atomic')
|
const cashInAtomic = require('./cash-in-atomic')
|
||||||
const cashInLow = require('./cash-in-low')
|
const cashInLow = require('./cash-in-low')
|
||||||
|
|
@ -20,15 +22,24 @@ function post (machineTx, pi) {
|
||||||
.then(r => {
|
.then(r => {
|
||||||
const updatedTx = r.tx
|
const updatedTx = r.tx
|
||||||
let blacklisted = false
|
let blacklisted = false
|
||||||
|
let addressReuse = false
|
||||||
|
|
||||||
return checkForBlacklisted(updatedTx)
|
return checkForBlacklisted(updatedTx)
|
||||||
.then(isBlacklisted => {
|
.then(blacklistItem => {
|
||||||
blacklisted = !!isBlacklisted
|
if (blacklistItem && blacklistItem.created_by_operator) {
|
||||||
return postProcess(r, pi, blacklisted)
|
blacklisted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blacklistItem && !blacklistItem.created_by_operator) {
|
||||||
|
addressReuse = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return postProcess(r, pi, blacklisted, addressReuse)
|
||||||
})
|
})
|
||||||
.then(changes => cashInLow.update(db, updatedTx, changes))
|
.then(changes => cashInLow.update(db, updatedTx, changes))
|
||||||
.then(tx => _.set('bills', machineTx.bills, tx))
|
.then(tx => _.set('bills', machineTx.bills, tx))
|
||||||
.then(tx => _.set('blacklisted', blacklisted, tx))
|
.then(tx => _.set('blacklisted', blacklisted, tx))
|
||||||
|
.then(tx => _.set('addressReuse', addressReuse, tx))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +77,14 @@ function checkForBlacklisted (tx) {
|
||||||
return Promise.resolve(false)
|
return Promise.resolve(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
function postProcess (r, pi, isBlacklisted) {
|
function postProcess (r, pi, isBlacklisted, addressReuse) {
|
||||||
|
if (addressReuse) {
|
||||||
|
return Promise.resolve({
|
||||||
|
operatorCompleted: true,
|
||||||
|
error: 'Address Reused'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (isBlacklisted) {
|
if (isBlacklisted) {
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
operatorCompleted: true,
|
operatorCompleted: true,
|
||||||
|
|
@ -104,6 +122,14 @@ function postProcess (r, pi, isBlacklisted) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then(sendRec => {
|
.then(sendRec => {
|
||||||
|
settingsLoader.loadLatest().then(it => {
|
||||||
|
const config = configManager.unscoped(it.config)
|
||||||
|
if (config.rejectAddressReuseActive) {
|
||||||
|
blacklist.addToUsedAddresses(r.tx.toAddress, r.tx.cryptoCode)
|
||||||
|
.catch(err => logger.error('Failure adding to addressReuse', err))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
pi.notifyOperator(r.tx, sendRec)
|
pi.notifyOperator(r.tx, sendRec)
|
||||||
.catch((err) => logger.error('Failure sending transaction notification', err))
|
.catch((err) => logger.error('Failure sending transaction notification', err))
|
||||||
return logAction(sendRec, r.tx)
|
return logAction(sendRec, r.tx)
|
||||||
|
|
|
||||||
13
migrations/1564485980102-alter-blacklist.js
Normal file
13
migrations/1564485980102-alter-blacklist.js
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
const db = require('./db')
|
||||||
|
|
||||||
|
exports.up = function (next) {
|
||||||
|
var sql = [
|
||||||
|
"ALTER TABLE blacklist ADD COLUMN created_by_operator boolean not null default 't' "
|
||||||
|
]
|
||||||
|
|
||||||
|
db.multi(sql, next)
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.down = function (next) {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
|
@ -31189,8 +31189,8 @@ var _user$project$Config$updateSelectize = F3(
|
||||||
return _elm_lang$core$Native_Utils.crashCase(
|
return _elm_lang$core$Native_Utils.crashCase(
|
||||||
'Config',
|
'Config',
|
||||||
{
|
{
|
||||||
start: {line: 1555, column: 17},
|
start: {line: 1556, column: 17},
|
||||||
end: {line: 1560, column: 56}
|
end: {line: 1561, column: 56}
|
||||||
},
|
},
|
||||||
_p4)('Shouldn\'t be here');
|
_p4)('Shouldn\'t be here');
|
||||||
}
|
}
|
||||||
|
|
@ -31386,8 +31386,8 @@ var _user$project$Config$isField = function (fieldValue) {
|
||||||
return _elm_lang$core$Native_Utils.crashCase(
|
return _elm_lang$core$Native_Utils.crashCase(
|
||||||
'Config',
|
'Config',
|
||||||
{
|
{
|
||||||
start: {line: 1229, column: 5},
|
start: {line: 1230, column: 5},
|
||||||
end: {line: 1234, column: 59}
|
end: {line: 1235, column: 59}
|
||||||
},
|
},
|
||||||
_p12)('Referenced field must be boolean');
|
_p12)('Referenced field must be boolean');
|
||||||
}
|
}
|
||||||
|
|
@ -32877,7 +32877,11 @@ var _user$project$Config$complianceTableView = function (model) {
|
||||||
_1: {
|
_1: {
|
||||||
ctor: '::',
|
ctor: '::',
|
||||||
_0: A3(row, 'Receipt Printing', 'receiptPrintingActive', ''),
|
_0: A3(row, 'Receipt Printing', 'receiptPrintingActive', ''),
|
||||||
_1: {ctor: '[]'}
|
_1: {
|
||||||
|
ctor: '::',
|
||||||
|
_0: A3(row, 'Reject Address Reuse', 'rejectAddressReuseActive', ''),
|
||||||
|
_1: {ctor: '[]'}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue