diff --git a/lib/compliance.js b/lib/compliance.js index 22562587..8ecd1770 100644 --- a/lib/compliance.js +++ b/lib/compliance.js @@ -72,13 +72,11 @@ function validateOfac (deviceId, sanctionsActive, customer) { function validationPatch (deviceId, sanctionsActive, customer) { return validateOfac(deviceId, sanctionsActive, customer) - .then(ofacValidation => { - if (_.isNil(customer.sanctions) || customer.sanctions !== ofacValidation) { - return {sanctions: ofacValidation} - } - - return {} - }) + .then(sactions => + _.isNil(customer.sanctions) || customer.sanctions !== sactions ? + { sanctions } : + {} + ) } module.exports = {validationPatch} diff --git a/lib/notifier/index.js b/lib/notifier/index.js index ab75d84e..06163030 100644 --- a/lib/notifier/index.js +++ b/lib/notifier/index.js @@ -166,17 +166,15 @@ function transactionNotify (tx, rec) { }) } -function complianceNotify (customer, deviceId, action, period) { - return Promise.all([ - settingsLoader.loadLatest(), - queries.getMachineName(deviceId) - ]) - .then(([settings, machineName]) => { +function complianceNotify (settings, customer, deviceId, action, period) { + return queries.getMachineName(deviceId) + .then(machineName => { const notifications = configManager.getGlobalNotifications(settings.config) const msgCore = { BLOCKED: `was blocked`, - SUSPENDED: `was suspended for ${!!period && period} days` + SUSPENDED: `was suspended for ${!!period && period} days`, + PENDING_COMPLIANCE: `is waiting for your manual approval`, } const rec = { diff --git a/lib/notifier/notificationCenter.js b/lib/notifier/notificationCenter.js index c5ac36fd..11392248 100644 --- a/lib/notifier/notificationCenter.js +++ b/lib/notifier/notificationCenter.js @@ -38,7 +38,9 @@ const customerComplianceNotify = (customer, deviceId, code, days = null) => { if (days) { date.setDate(date.getDate() + days) } - const message = code === 'SUSPENDED' ? `Customer suspended until ${date.toLocaleString()}` : `Customer blocked` + const message = code === 'SUSPENDED' ? `Customer ${customer.phone} suspended until ${date.toLocaleString()}` : + code === 'BLOCKED' ? `Customer ${customer.phone} blocked` : + `Customer ${customer.phone} has pending compliance` return clearOldCustomerSuspendedNotifications(customer.id, deviceId) .then(() => queries.getValidNotifications(COMPLIANCE, detailB)) diff --git a/lib/routes/customerRoutes.js b/lib/routes/customerRoutes.js index 963cb1f1..d0e11431 100644 --- a/lib/routes/customerRoutes.js +++ b/lib/routes/customerRoutes.js @@ -4,6 +4,7 @@ const semver = require('semver') const _ = require('lodash/fp') const { zonedTimeToUtc, utcToZonedTime } = require('date-fns-tz/fp') const { add, intervalToDuration } = require('date-fns/fp') +const uuid = require('uuid') const sms = require('../sms') const BN = require('../bn') @@ -25,15 +26,54 @@ const Tx = require('../tx') const loyalty = require('../loyalty') const logger = require('../logger') -function updateCustomerCustomInfoRequest (customerId, patch, req, res) { - if (_.isNil(patch.data)) { - return customers.getById(customerId) - .then(customer => respond(req, res, { customer })) +function updateCustomerCustomInfoRequest (customerId, patch) { + const promise = _.isNil(patch.data) ? + Promise.resolve(null) : + customInfoRequestQueries.setCustomerDataViaMachine(customerId, patch.infoRequestId, patch) + return promise.then(() => customers.getById(customerId)) +} + +const createPendingManualComplianceNotifs = (settings, customer, deviceId) => { + const customInfoRequests = _.reduce( + (reqs, req) => _.set(req.info_request_id, req, reqs), + {}, + _.get(['customInfoRequestData'], customer) + ) + + const isPending = field => + uuid.validate(field) ? + _.get([field, 'override'], customInfoRequests) === 'automatic' : + customer[`${field}At`] + && (!customer[`${field}OverrideAt`] + || customer[`${field}OverrideAt`].getTime() < customer[`${field}At`].getTime()) + + const unnestCustomTriggers = triggersAutomation => { + const customTriggers = _.fromPairs(_.map(({ id, type }) => [id, type], triggersAutomation.custom)) + return _.flow( + _.unset('custom'), + _.mapKeys(k => k === 'facephoto' ? 'frontCamera' : k), + _.assign(customTriggers), + )(triggersAutomation) } - return customInfoRequestQueries.setCustomerDataViaMachine(customerId, patch.infoRequestId, patch) - .then(() => customers.getById(customerId)) - .then(customer => respond(req, res, { customer })) + const isManual = v => v === 'Manual' + + const hasManualAutomation = triggersAutomation => + _.any(isManual, _.values(triggersAutomation)) + + configManager.getTriggersAutomation(customInfoRequestQueries.getCustomInfoRequests(true), settings.config) + .then(triggersAutomation => { + triggersAutomation = unnestCustomTriggers(triggersAutomation) + if (!hasManualAutomation(triggersAutomation)) return + + const pendingFields = _.filter( + field => isManual(triggersAutomation[field]) && isPending(field), + _.keys(triggersAutomation) + ) + + if (!_.isEmpty(pendingFields)) + notifier.complianceNotify(settings, customer, deviceId, 'PENDING_COMPLIANCE') + }) } function updateCustomer (req, res, next) { @@ -43,32 +83,35 @@ function updateCustomer (req, res, next) { const patch = req.body const triggers = configManager.getTriggers(req.settings.config) const compatTriggers = complianceTriggers.getBackwardsCompatibleTriggers(triggers) + const deviceId = req.deviceId + const settings = req.settings if (patch.customRequestPatch) { - return updateCustomerCustomInfoRequest(id, patch.customRequestPatch, req, res).catch(next) + return updateCustomerCustomInfoRequest(id, patch.customRequestPatch) + .then(customer => { + createPendingManualComplianceNotifs(settings, customer, deviceId) + respond(req, res, { customer }) + }) + .catch(next) } + // BACKWARDS_COMPATIBILITY 7.5 + // machines before 7.5 expect customer with sanctions result + const isOlderMachineVersion = !machineVersion || semver.lt(machineVersion, '7.5.0-beta.0') customers.getById(id) + .then(customer => + !customer ? Promise.reject(httpError('Not Found', 404)) : + !isOlderMachineVersion ? {} : + compliance.validationPatch(deviceId, !!compatTriggers.sanctions, _.merge(customer, patch)) + ) + .then(_.merge(patch)) + .then(newPatch => customers.updatePhotoCard(id, newPatch)) + .then(newPatch => customers.updateFrontCamera(id, newPatch)) + .then(newPatch => customers.update(id, newPatch, null, txId)) .then(customer => { - if (!customer) { throw httpError('Not Found', 404) } - - const mergedCustomer = _.merge(customer, patch) - - // BACKWARDS_COMPATIBILITY 7.5 - // machines before 7.5 expect customer with sanctions result - const isOlderMachineVersion = !machineVersion || semver.lt(machineVersion, '7.5.0-beta.0') - - return Promise.resolve({}) - .then(emptyObj => { - if (!isOlderMachineVersion) return Promise.resolve(emptyObj) - return compliance.validationPatch(req.deviceId, !!compatTriggers.sanctions, mergedCustomer) - }) - .then(_.merge(patch)) - .then(newPatch => customers.updatePhotoCard(id, newPatch)) - .then(newPatch => customers.updateFrontCamera(id, newPatch)) - .then(newPatch => customers.update(id, newPatch, null, txId)) + createPendingManualComplianceNotifs(settings, customer, deviceId) + respond(req, res, { customer }) }) - .then(customer => respond(req, res, { customer })) .catch(next) } @@ -100,10 +143,11 @@ function triggerSanctions (req, res, next) { function triggerBlock (req, res, next) { const id = req.params.id + const settings = req.settings customers.update(id, { authorizedOverride: 'blocked' }) .then(customer => { - notifier.complianceNotify(customer, req.deviceId, 'BLOCKED') + notifier.complianceNotify(settings, customer, req.deviceId, 'BLOCKED') return respond(req, res, { customer }) }) .catch(next) @@ -112,6 +156,7 @@ function triggerBlock (req, res, next) { function triggerSuspend (req, res, next) { const id = req.params.id const triggerId = req.body.triggerId + const settings = req.settings const triggers = configManager.getTriggers(req.settings.config) const getSuspendDays = _.compose(_.get('suspensionDays'), _.find(_.matches({ id: triggerId }))) @@ -122,7 +167,7 @@ function triggerSuspend (req, res, next) { customers.update(id, { suspendedUntil: add(suspensionDuration, new Date()) }) .then(customer => { - notifier.complianceNotify(customer, req.deviceId, 'SUSPENDED', days) + notifier.complianceNotify(settings, customer, req.deviceId, 'SUSPENDED', days) return respond(req, res, { customer }) }) .catch(next) diff --git a/new-lamassu-admin/src/pages/Customers/components/CustomInfoRequestsData.js b/new-lamassu-admin/src/pages/Customers/components/CustomInfoRequestsData.js index d8ca647d..635b1c78 100644 --- a/new-lamassu-admin/src/pages/Customers/components/CustomInfoRequestsData.js +++ b/new-lamassu-admin/src/pages/Customers/components/CustomInfoRequestsData.js @@ -130,13 +130,12 @@ const CustomInfoRequestsData = ({ data }) => { ) } - const getAuthorizedStatus = it => { - return it.approved === null + const getAuthorizedStatus = it => + it.approved === null ? { label: 'Pending', type: 'neutral' } : it.approved === false ? { label: 'Rejected', type: 'error' } : { label: 'Accepted', type: 'success' } - } return ( <> diff --git a/package-lock.json b/package-lock.json index c2b92e80..b6a2541a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "10.0.0-rc.10", + "version": "10.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -770,6 +770,36 @@ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" }, + "bitcoinjs-message": { + "version": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.2", + "resolved": "https://registry.npmjs.org/@bitgo-forks/bitcoinjs-message/-/bitcoinjs-message-1.0.0-master.2.tgz", + "integrity": "sha512-XSDGM3rA75vcDxeKqHPexika/TgWUFWdfKTv1lV8TZTb5XFHHD6ARckLdMOBiCf29eZSzbJQvF/OIWqNqMl/2A==", + "requires": { + "bech32": "^1.1.3", + "bs58check": "^2.1.2", + "buffer-equals": "^1.0.3", + "create-hash": "^1.1.2", + "secp256k1": "5.0.0", + "varuint-bitcoin": "^1.0.1" + }, + "dependencies": { + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + } + } + } + }, "ethereumjs-util": { "version": "7.1.5", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", @@ -960,6 +990,38 @@ "secp256k1": "^4.0.2", "secrets.js-grempe": "^1.1.0", "superagent": "3.8.3" + }, + "dependencies": { + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "bitcoinjs-message": { + "version": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.2", + "resolved": "https://registry.npmjs.org/@bitgo-forks/bitcoinjs-message/-/bitcoinjs-message-1.0.0-master.2.tgz", + "integrity": "sha512-XSDGM3rA75vcDxeKqHPexika/TgWUFWdfKTv1lV8TZTb5XFHHD6ARckLdMOBiCf29eZSzbJQvF/OIWqNqMl/2A==", + "requires": { + "bech32": "^1.1.3", + "bs58check": "^2.1.2", + "buffer-equals": "^1.0.3", + "create-hash": "^1.1.2", + "secp256k1": "5.0.0", + "varuint-bitcoin": "^1.0.1" + }, + "dependencies": { + "secp256k1": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-5.0.0.tgz", + "integrity": "sha512-TKWX8xvoGHrxVdqbYeZM9w+izTF4b9z3NhSaDkdn81btvuh+ivbIMGT/zQvDtTFWhRlThpoz6LEYTr7n8A5GcA==", + "requires": { + "elliptic": "^6.5.4", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + } + } + } + } } }, "@bitgo/sdk-coin-bch": { @@ -1058,6 +1120,26 @@ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" }, + "bitcoinjs-message": { + "version": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.2", + "resolved": "https://registry.npmjs.org/@bitgo-forks/bitcoinjs-message/-/bitcoinjs-message-1.0.0-master.2.tgz", + "integrity": "sha512-XSDGM3rA75vcDxeKqHPexika/TgWUFWdfKTv1lV8TZTb5XFHHD6ARckLdMOBiCf29eZSzbJQvF/OIWqNqMl/2A==", + "requires": { + "bech32": "^1.1.3", + "bs58check": "^2.1.2", + "buffer-equals": "^1.0.3", + "create-hash": "^1.1.2", + "secp256k1": "5.0.0", + "varuint-bitcoin": "^1.0.1" + }, + "dependencies": { + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + } + } + }, "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -1148,25 +1230,6 @@ "fastpriorityqueue": "^0.7.1", "typeforce": "^1.11.3", "varuint-bitcoin": "^1.1.2" - }, - "dependencies": { - "bitcoinjs-lib": { - "version": "npm:@bitgo-forks/bitcoinjs-lib@7.1.0-master.7", - "resolved": "https://registry.npmjs.org/@bitgo-forks/bitcoinjs-lib/-/bitcoinjs-lib-7.1.0-master.7.tgz", - "integrity": "sha512-FZle7954KnbbVXFCc5uYGtjq+0PFOnFxVchNwt3Kcv2nVusezTp29aeQwDi2Y+lM1dCoup2gJGXMkkREenY7KQ==", - "requires": { - "bech32": "^2.0.0", - "bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4", - "bs58check": "^2.1.2", - "create-hash": "^1.1.0", - "fastpriorityqueue": "^0.7.1", - "json5": "^2.2.3", - "ripemd160": "^2.0.2", - "typeforce": "^1.11.3", - "varuint-bitcoin": "^1.1.2", - "wif": "^2.0.1" - } - } } }, "@bitgo/utxo-ord": { @@ -1278,6 +1341,26 @@ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz", "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==" }, + "bitcoinjs-message": { + "version": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.2", + "resolved": "https://registry.npmjs.org/@bitgo-forks/bitcoinjs-message/-/bitcoinjs-message-1.0.0-master.2.tgz", + "integrity": "sha512-XSDGM3rA75vcDxeKqHPexika/TgWUFWdfKTv1lV8TZTb5XFHHD6ARckLdMOBiCf29eZSzbJQvF/OIWqNqMl/2A==", + "requires": { + "bech32": "^1.1.3", + "bs58check": "^2.1.2", + "buffer-equals": "^1.0.3", + "create-hash": "^1.1.2", + "secp256k1": "5.0.0", + "varuint-bitcoin": "^1.0.1" + }, + "dependencies": { + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + } + } + }, "bs58": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", @@ -2943,27 +3026,6 @@ "undici-types": "~5.26.4" } }, - "@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "requires": { - "@types/node": "*", - "form-data": "^4.0.0" - }, - "dependencies": { - "form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - } - } - }, "@types/normalize-package-data": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", @@ -3142,34 +3204,24 @@ } }, "@vonage/server-client": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@vonage/server-client/-/server-client-1.12.0.tgz", - "integrity": "sha512-+EiVh8dGy7Yp2VRSRsxLYntE008ufM/l0Kuv5cvJePZxsCfU0GhkIwG5R04PdZE+5wQuqvxFhntxBSUuNUXDhw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@vonage/server-client/-/server-client-1.7.0.tgz", + "integrity": "sha512-KxqGnlUQxtWOPF5QqGMNsYfPIAXvSPeR29vbetAB65UW+KXRn+NFubqSymcEU471woiYQ4wdg9UqvSlrNYJmdQ==", "requires": { - "@vonage/auth": "^1.10.0", - "@vonage/vetch": "^1.7.1", + "@vonage/auth": "^1.5.0", + "@vonage/vetch": "^1.5.0", "debug": "^4.3.4", "lodash.camelcase": "^4.3.0", "lodash.isobject": "3.0.2", "lodash.kebabcase": "^4.1.1", "lodash.partial": "^4.2.1", - "lodash.snakecase": "^4.1.1", - "node-fetch": "^2" + "lodash.snakecase": "^4.1.1" }, "dependencies": { - "@vonage/auth": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@vonage/auth/-/auth-1.10.0.tgz", - "integrity": "sha512-jDBcgDs/wMc3/9rKPqu2oXKndiw8My8qddyVL8foUMSwEDKv46Kkr8H6yNMKtu2sBXcJZVVzDFQFyec2cOl9CQ==", - "requires": { - "@vonage/jwt": "^1.10.0", - "debug": "^4.3.4" - } - }, "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "requires": { "ms": "2.1.2" } @@ -3206,12 +3258,28 @@ } }, "@vonage/vetch": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@vonage/vetch/-/vetch-1.7.1.tgz", - "integrity": "sha512-CHEgFgslQHtVBGJMOOu2/36y9p00XH+b2LJgjbS3aybqTq2BdnHkBqRv6Vk1RwT9L53VVd/EcIGI/DfprrLOaA==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@vonage/vetch/-/vetch-1.5.0.tgz", + "integrity": "sha512-Bw0o5mOJOpBbUYUmYBzDRzZad8yE+897v0GlZj9tQ+weAj7JppXJzw2D4bUiXN4fggnnEhTFzIQ3roi9a+IQ0A==", "requires": { - "@types/node-fetch": "2.6.11", - "node-fetch": "^2.7" + "debug": "^4.3.4", + "lodash.merge": "^4.6.2", + "node-fetch": "^2.6" + }, + "dependencies": { + "debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "@wasmer/wasi": { @@ -4264,6 +4332,23 @@ "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz", "integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==" }, + "bitcoinjs-lib": { + "version": "npm:@bitgo-forks/bitcoinjs-lib@7.1.0-master.7", + "resolved": "https://registry.npmjs.org/@bitgo-forks/bitcoinjs-lib/-/bitcoinjs-lib-7.1.0-master.7.tgz", + "integrity": "sha512-FZle7954KnbbVXFCc5uYGtjq+0PFOnFxVchNwt3Kcv2nVusezTp29aeQwDi2Y+lM1dCoup2gJGXMkkREenY7KQ==", + "requires": { + "bech32": "^2.0.0", + "bip174": "npm:@bitgo-forks/bip174@3.1.0-master.4", + "bs58check": "^2.1.2", + "create-hash": "^1.1.0", + "fastpriorityqueue": "^0.7.1", + "json5": "^2.2.3", + "ripemd160": "^2.0.2", + "typeforce": "^1.11.3", + "varuint-bitcoin": "^1.1.2", + "wif": "^2.0.1" + } + }, "bitcoinjs-message": { "version": "npm:@bitgo-forks/bitcoinjs-message@1.0.0-master.2", "resolved": "https://registry.npmjs.org/@bitgo-forks/bitcoinjs-message/-/bitcoinjs-message-1.0.0-master.2.tgz", diff --git a/package.json b/package.json index d6586f51..19f8fbeb 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "lamassu-server", "description": "bitcoin atm client server protocol module", "keywords": [], - "version": "10.0.0-rc.10", + "version": "10.0.0", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { @@ -20,6 +20,8 @@ "@simplewebauthn/server": "^3.0.0", "@vonage/auth": "1.5.0", "@vonage/sms": "1.7.0", + "@vonage/server-client": "1.7.0", + "@vonage/vetch": "1.5.0", "apollo-server-express": "2.25.1", "argon2": "0.28.2", "axios": "0.21.1",