From 3465173e1a09a085d56c220a3380d57e657aac57 Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Fri, 9 Feb 2024 19:05:25 +0000 Subject: [PATCH 01/17] fix: check for invoice fulfillment --- lib/plugins/wallet/galoy/galoy.js | 32 +++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/plugins/wallet/galoy/galoy.js b/lib/plugins/wallet/galoy/galoy.js index 0299aab0..ec4e57c8 100644 --- a/lib/plugins/wallet/galoy/galoy.js +++ b/lib/plugins/wallet/galoy/galoy.js @@ -152,7 +152,6 @@ function sendProbeRequest (walletId, invoice, cryptoAtoms, token, endpoint) { function sendCoins (account, tx, settings, operatorId) { const { toAddress, cryptoAtoms, cryptoCode } = tx - const externalCryptoCode = coinUtils.getEquivalentCode(cryptoCode) return checkCryptoCode(cryptoCode) .then(() => getGaloyWallet(account.apiSecret, account.endpoint, account.walletId)) .then(wallet => { @@ -166,7 +165,7 @@ function sendCoins (account, tx, settings, operatorId) { case 'ALREADY_PAID': throw new Error('Transaction already exists!') case 'FAILURE': - throw new Error('Transaction failed!') + throw new Error('Transaction failed!', JSON.stringify(result.errors)) case 'SUCCESS': return '' case 'PENDING': @@ -253,6 +252,25 @@ function newAddress (account, info, tx, settings, operatorId) { }) } +function getInvoiceStatus (token, endpoint, address) { + const query = { + 'operationName': 'lnInvoicePaymentStatus', + 'query': `query lnInvoicePaymentStatus($input: LnInvoicePaymentStatusInput!) { + lnInvoicePaymentStatus(input: $input) { + status + } + }`, + 'variables': {"input": {"paymentRequest": address}} + } + return request(query, token, endpoint) + .then(r => { + return r?.data?.lnInvoicePaymentStatus?.status + }) + .catch(err => { + throw new Error(err) + }) +} + function getStatus (account, tx, requested, settings, operatorId) { const { toAddress, cryptoAtoms, cryptoCode } = tx const getBalance = _.reduce((acc, value) => { @@ -260,13 +278,16 @@ function getStatus (account, tx, requested, settings, operatorId) { return acc }, { SUCCESS: new BN(0), PENDING: new BN(0), FAILURE: new BN(0) }) - const externalCryptoCode = coinUtils.getEquivalentCode(cryptoCode) return checkCryptoCode(cryptoCode) .then(() => { const address = coinUtils.parseUrl(cryptoCode, account.environment, toAddress, false) - // Consider all LN transactions successful if (isLightning(address)) { - return { receivedCryptoAtoms: cryptoAtoms, status: 'confirmed' } + return getInvoiceStatus(account.apiSecret, account.endpoint, address) + .then(it => { + const isPaid = it === 'PAID' + if (isPaid) return { receivedCryptoAtoms: cryptoAtoms, status: 'confirmed' } + return { receivedCryptoAtoms: BN(0), status: 'notSeen' } + }) } // On-chain and intra-ledger transactions return getTransactionsByAddress(account.apiSecret, account.endpoint, account.walletId, address) @@ -282,7 +303,6 @@ function getStatus (account, tx, requested, settings, operatorId) { } function newFunding (account, cryptoCode, settings, operatorId) { - const externalCryptoCode = coinUtils.getEquivalentCode(cryptoCode) // Regular BTC address return checkCryptoCode(cryptoCode) .then(() => getGaloyWallet(account.apiSecret, account.endpoint, account.walletId)) From d950a84e2a1a36c598c27f111cb1fc01bb70076f Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Fri, 9 Feb 2024 19:05:58 +0000 Subject: [PATCH 02/17] chore: declutter server logs --- lib/middlewares/populateDeviceId.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/middlewares/populateDeviceId.js b/lib/middlewares/populateDeviceId.js index 4c8913ae..dd2fd9e2 100644 --- a/lib/middlewares/populateDeviceId.js +++ b/lib/middlewares/populateDeviceId.js @@ -4,6 +4,7 @@ const crypto = require('crypto') const logger = require('../logger') function sha256 (buf) { + if (!buf) return null const hash = crypto.createHash('sha256') hash.update(buf) @@ -12,9 +13,10 @@ function sha256 (buf) { const populateDeviceId = function (req, res, next) { const deviceId = _.isFunction(req.connection.getPeerCertificate) - ? sha256(req.connection.getPeerCertificate().raw) + ? sha256(req.connection.getPeerCertificate()?.raw) : null + if (!deviceId) return res.status(500).json({ error: 'Unable to find certificate' }) req.deviceId = deviceId req.deviceTime = req.get('date') From fd2e9f24a57a644391f279e5bead48274af2f80d Mon Sep 17 00:00:00 2001 From: CrypticaScriptura <7396812+CrypticaScriptura@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:14:12 -0500 Subject: [PATCH 03/17] chore: v9.0.0-beta.8 (#1649) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8cd102a4..58bc3dc4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "9.0.0-beta.7", + "version": "9.0.0-beta.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 23110d46..f3c3bdce 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "lamassu-server", "description": "bitcoin atm client server protocol module", "keywords": [], - "version": "9.0.0-beta.7", + "version": "9.0.0-beta.8", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { From 15225024561372cd4bd77868f3657b2e6f821d79 Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Mon, 12 Feb 2024 21:44:44 +0000 Subject: [PATCH 04/17] chore: adjust probe numbers temporarily --- lib/plugins/wallet/galoy/galoy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/wallet/galoy/galoy.js b/lib/plugins/wallet/galoy/galoy.js index ec4e57c8..cc47da35 100644 --- a/lib/plugins/wallet/galoy/galoy.js +++ b/lib/plugins/wallet/galoy/galoy.js @@ -177,7 +177,7 @@ function sendCoins (account, tx, settings, operatorId) { } function probeLN (account, cryptoCode, invoice) { - const probeHardLimits = [100, 500, 1000] + const probeHardLimits = [200000, 1000000, 2000000] const promises = probeHardLimits.map(limit => { return sendProbeRequest(account.walletId, invoice, limit, account.apiSecret, account.endpoint) .then(r => _.isEmpty(r.errors)) From 5fb9f33b2be3102fb1a4ba2ebf26614f33cd7438 Mon Sep 17 00:00:00 2001 From: CrypticaScriptura <7396812+CrypticaScriptura@users.noreply.github.com> Date: Mon, 12 Feb 2024 16:53:51 -0500 Subject: [PATCH 05/17] chore: v9.0.0-beta.9 (#1650) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 58bc3dc4..1e641c43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "9.0.0-beta.8", + "version": "9.0.0-beta.9", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f3c3bdce..582ff9ce 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "lamassu-server", "description": "bitcoin atm client server protocol module", "keywords": [], - "version": "9.0.0-beta.8", + "version": "9.0.0-beta.9", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { From b996117fd1548aed429f816d88c0a8d503aff75d Mon Sep 17 00:00:00 2001 From: CrypticaScriptura <7396812+CrypticaScriptura@users.noreply.github.com> Date: Wed, 14 Feb 2024 19:50:44 -0500 Subject: [PATCH 06/17] chore: v10.0.0-beta.13 (#1654) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 704f6ae0..3ce15101 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "10.0.0-beta.12", + "version": "10.0.0-beta.13", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d7abd039..7f4f5804 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-beta.12", + "version": "10.0.0-beta.13", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { From 459f7148f8731ea7f5e9f5c888a844d65318fc99 Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Thu, 22 Feb 2024 10:50:48 +0000 Subject: [PATCH 07/17] fix: use simplified LN deposit URL --- lib/plugins/wallet/galoy/galoy.js | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/lib/plugins/wallet/galoy/galoy.js b/lib/plugins/wallet/galoy/galoy.js index cc47da35..dd75f4b2 100644 --- a/lib/plugins/wallet/galoy/galoy.js +++ b/lib/plugins/wallet/galoy/galoy.js @@ -240,16 +240,7 @@ function newAddress (account, info, tx, settings, operatorId) { const { cryptoAtoms, cryptoCode } = tx return checkCryptoCode(cryptoCode) .then(() => getGaloyWallet(account.apiSecret, account.endpoint, account.walletId)) - .then(wallet => { - const promises = [ - newOnChainAddress(wallet.id, account.apiSecret, account.endpoint), - newInvoice(wallet.id, cryptoAtoms, account.apiSecret, account.endpoint) - ] - return Promise.all(promises) - }) - .then(([onChainAddress, invoice]) => { - return `bitcoin:${onChainAddress}?amount=${cryptoAtoms}&lightning=${invoice}` - }) + .then(wallet => newInvoice(wallet.id, cryptoAtoms, account.apiSecret, account.endpoint)) } function getInvoiceStatus (token, endpoint, address) { From 83d18f9a1095e0aae6b85d7e244f5ce1d06884e0 Mon Sep 17 00:00:00 2001 From: CrypticaScriptura <7396812+CrypticaScriptura@users.noreply.github.com> Date: Thu, 22 Feb 2024 08:44:51 -0500 Subject: [PATCH 08/17] chore: v9.0.0-beta.10 (#1655) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1e641c43..5f9bd74e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "9.0.0-beta.9", + "version": "9.0.0-beta.10", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 582ff9ce..731cf246 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "lamassu-server", "description": "bitcoin atm client server protocol module", "keywords": [], - "version": "9.0.0-beta.9", + "version": "9.0.0-beta.10", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { From 45fa1a8d936436b8a144090a28a1109b167b30e3 Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Thu, 29 Feb 2024 13:23:49 +0000 Subject: [PATCH 09/17] feat: lnurl support --- lib/logger.js | 2 +- lib/plugins/wallet/galoy/galoy.js | 32 ++++++++++++++++++++--- package-lock.json | 42 ++++++++++++++++--------------- package.json | 2 +- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/lib/logger.js b/lib/logger.js index 65298e64..3fa0f242 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -21,7 +21,7 @@ const logger = new winston.Logger({ }) ], rewriters: [ - (...[,, meta]) => meta instanceof Error ? { message: meta.message, stack: meta.stack } : meta + (...[,, meta]) => meta instanceof Error ? { message: meta.message, stack: meta.stack, meta } : meta ], exitOnError: false }) diff --git a/lib/plugins/wallet/galoy/galoy.js b/lib/plugins/wallet/galoy/galoy.js index dd75f4b2..e0eeee63 100644 --- a/lib/plugins/wallet/galoy/galoy.js +++ b/lib/plugins/wallet/galoy/galoy.js @@ -92,8 +92,12 @@ function getGaloyWallet (token, endpoint, walletId) { }) } -function isLightning (address) { - return address.substr(0, 2) === 'ln' +function isLnInvoice (address) { + return address.startsWith('lnbc') +} + +function isLnurl (address) { + return address.startsWith('lnurl') } function sendFundsOnChain (walletId, address, cryptoAtoms, token, endpoint) { @@ -116,6 +120,23 @@ function sendFundsOnChain (walletId, address, cryptoAtoms, token, endpoint) { }) } +function sendFundsLNURL (walletId, lnurl, cryptoAtoms, token, endpoint) { + const sendLnNoAmount = { + 'operationName': 'lnurlPaymentSend', + 'query': `mutation lnurlPaymentSend($input: LnurlPaymentSendInput!) { + lnurlPaymentSend(input: $input) { + errors { + message + path + } + status + } + }`, + 'variables': { 'input': { 'lnurl': `${lnurl}`, 'walletId': `${walletId}`, 'amount': `${cryptoAtoms}` } } + } + return request(sendLnNoAmount, token, endpoint).then(result => result.data.lnurlPaymentSend) +} + function sendFundsLN (walletId, invoice, cryptoAtoms, token, endpoint) { const sendLnNoAmount = { 'operationName': 'lnNoAmountInvoicePaymentSend', @@ -155,9 +176,12 @@ function sendCoins (account, tx, settings, operatorId) { return checkCryptoCode(cryptoCode) .then(() => getGaloyWallet(account.apiSecret, account.endpoint, account.walletId)) .then(wallet => { - if (isLightning(toAddress)) { + if (isLnInvoice(toAddress)) { return sendFundsLN(wallet.id, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) } + if (isLnurl(toAddress)) { + return sendFundsLNURL(wallet.id, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) + } return sendFundsOnChain(wallet.id, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) }) .then(result => { @@ -272,7 +296,7 @@ function getStatus (account, tx, requested, settings, operatorId) { return checkCryptoCode(cryptoCode) .then(() => { const address = coinUtils.parseUrl(cryptoCode, account.environment, toAddress, false) - if (isLightning(address)) { + if (isLnInvoice(address)) { return getInvoiceStatus(account.apiSecret, account.endpoint, address) .then(it => { const isPaid = it === 'PAID' diff --git a/package-lock.json b/package-lock.json index 5f9bd74e..7f79dc8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1078,6 +1078,25 @@ "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": { @@ -2132,9 +2151,9 @@ } }, "@lamassu/coins": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.4.3.tgz", - "integrity": "sha512-29XRlhYZcKYQeUWUohBLvjdvhkIYUe+TAxWYN+crw/JXSd8Bz3yId88v+n6+F3eTAN6iCDtHnTTiYRhYD4DQ/Q==", + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.4.9.tgz", + "integrity": "sha512-psOTHCGJBaIP7mnMSY3zmAsX3k9m6PffnL1Kq9SE4waMyTX4fQu/heEkmWk/OACk2CSonahA4FbLNKc284cizg==", "requires": { "@lamassu/bolt11": "1.5.1", "bech32": "2.0.0", @@ -4393,23 +4412,6 @@ "resolved": "https://registry.npmjs.org/bitcoind-rpc/-/bitcoind-rpc-0.7.2.tgz", "integrity": "sha512-3alq5pH4/mAdEscucew98ls0s7BEaDvKTuYW34nSkTsmTC7G9R7Xh+ABXOxeVBfG/+rKfyQLmFAm2aRq92tJqw==" }, - "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 731cf246..3c3f4aeb 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@ethereumjs/common": "^2.6.4", "@ethereumjs/tx": "^3.5.1", "@graphql-tools/merge": "^6.2.5", - "@lamassu/coins": "v1.4.3", + "@lamassu/coins": "v1.4.9", "@simplewebauthn/server": "^3.0.0", "@vonage/auth": "^1.5.0", "@vonage/sms": "^1.7.0", From b371bccf6c976a6e757effd0a10de433eb4e215f Mon Sep 17 00:00:00 2001 From: CrypticaScriptura <7396812+CrypticaScriptura@users.noreply.github.com> Date: Thu, 29 Feb 2024 13:41:06 +0000 Subject: [PATCH 10/17] chore: v9.0.0-beta.11 (#1656) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7f79dc8e..a0570c7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "9.0.0-beta.10", + "version": "9.0.0-beta.11", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3c3f4aeb..d0debe9e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "lamassu-server", "description": "bitcoin atm client server protocol module", "keywords": [], - "version": "9.0.0-beta.10", + "version": "9.0.0-beta.11", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { From 508adb573fe63dafe36baecb4afdefc7d1aabb24 Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Thu, 29 Feb 2024 18:13:42 +0000 Subject: [PATCH 11/17] fix: case sensitivity --- lib/plugins/wallet/galoy/galoy.js | 4 +- package-lock.json | 127 +++++++++++------------------- package.json | 2 +- 3 files changed, 48 insertions(+), 85 deletions(-) diff --git a/lib/plugins/wallet/galoy/galoy.js b/lib/plugins/wallet/galoy/galoy.js index e0eeee63..e4a9a43e 100644 --- a/lib/plugins/wallet/galoy/galoy.js +++ b/lib/plugins/wallet/galoy/galoy.js @@ -93,11 +93,11 @@ function getGaloyWallet (token, endpoint, walletId) { } function isLnInvoice (address) { - return address.startsWith('lnbc') + return address.toLowerCase().startsWith('lnbc') } function isLnurl (address) { - return address.startsWith('lnurl') + return address.toLowerCase().startsWith('lnurl') } function sendFundsOnChain (walletId, address, cryptoAtoms, token, endpoint) { diff --git a/package-lock.json b/package-lock.json index a0570c7a..7f57679a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2108,41 +2108,6 @@ "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" }, - "bip32": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-1.0.4.tgz", - "integrity": "sha512-8T21eLWylZETolyqCPgia+MNp+kY37zFr7PTFDTPObHeNi9JlfG4qGIh8WzerIJidtwoK+NsWq2I5i66YfHoIw==", - "requires": { - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.0.0", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - } - }, - "bitcoinjs-lib": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-4.0.3.tgz", - "integrity": "sha512-cb5t55MYUpwQi095J+u6eyltgIU7lbhZfC6+annstncDhfH4cyctW5jmU/tac7NonZZFYH7DktWnDxUm9AWWDQ==", - "requires": { - "bech32": "^1.1.2", - "bip32": "^1.0.0", - "bip66": "^1.1.0", - "bitcoin-ops": "^1.4.0", - "bs58check": "^2.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.3", - "merkle-lib": "^2.0.10", - "pushdata-bitcoin": "^1.0.1", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.1", - "tiny-secp256k1": "^1.0.0", - "typeforce": "^1.11.3", - "varuint-bitcoin": "^1.0.4", - "wif": "^2.0.1" - } - }, "bn.js": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", @@ -2151,9 +2116,9 @@ } }, "@lamassu/coins": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.4.9.tgz", - "integrity": "sha512-psOTHCGJBaIP7mnMSY3zmAsX3k9m6PffnL1Kq9SE4waMyTX4fQu/heEkmWk/OACk2CSonahA4FbLNKc284cizg==", + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@lamassu/coins/-/coins-1.4.10.tgz", + "integrity": "sha512-0B3axtDVWE93Yss+DB/utQD7Mlcr0oF0kS7NB+HUxDGmzvc8qO02H0woGsJm/Pub9kf9bHic01Bv+G4U2K5Tzg==", "requires": { "@lamassu/bolt11": "1.5.1", "bech32": "2.0.0", @@ -2168,50 +2133,6 @@ "ethereumjs-icap": "^0.3.1", "keccak256": "^1.0.2", "lodash": "^4.17.10" - }, - "dependencies": { - "bip32": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-1.0.4.tgz", - "integrity": "sha512-8T21eLWylZETolyqCPgia+MNp+kY37zFr7PTFDTPObHeNi9JlfG4qGIh8WzerIJidtwoK+NsWq2I5i66YfHoIw==", - "requires": { - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.0.0", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - } - }, - "bitcoinjs-lib": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-4.0.3.tgz", - "integrity": "sha512-cb5t55MYUpwQi095J+u6eyltgIU7lbhZfC6+annstncDhfH4cyctW5jmU/tac7NonZZFYH7DktWnDxUm9AWWDQ==", - "requires": { - "bech32": "^1.1.2", - "bip32": "^1.0.0", - "bip66": "^1.1.0", - "bitcoin-ops": "^1.4.0", - "bs58check": "^2.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.3", - "merkle-lib": "^2.0.10", - "pushdata-bitcoin": "^1.0.1", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.1", - "tiny-secp256k1": "^1.0.0", - "typeforce": "^1.11.3", - "varuint-bitcoin": "^1.0.4", - "wif": "^2.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==" - } - } - } } }, "@mapbox/node-pre-gyp": { @@ -4412,6 +4333,48 @@ "resolved": "https://registry.npmjs.org/bitcoind-rpc/-/bitcoind-rpc-0.7.2.tgz", "integrity": "sha512-3alq5pH4/mAdEscucew98ls0s7BEaDvKTuYW34nSkTsmTC7G9R7Xh+ABXOxeVBfG/+rKfyQLmFAm2aRq92tJqw==" }, + "bitcoinjs-lib": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-4.0.3.tgz", + "integrity": "sha512-cb5t55MYUpwQi095J+u6eyltgIU7lbhZfC6+annstncDhfH4cyctW5jmU/tac7NonZZFYH7DktWnDxUm9AWWDQ==", + "requires": { + "bech32": "^1.1.2", + "bip32": "^1.0.0", + "bip66": "^1.1.0", + "bitcoin-ops": "^1.4.0", + "bs58check": "^2.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.3", + "merkle-lib": "^2.0.10", + "pushdata-bitcoin": "^1.0.1", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.1", + "tiny-secp256k1": "^1.0.0", + "typeforce": "^1.11.3", + "varuint-bitcoin": "^1.0.4", + "wif": "^2.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==" + }, + "bip32": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bip32/-/bip32-1.0.4.tgz", + "integrity": "sha512-8T21eLWylZETolyqCPgia+MNp+kY37zFr7PTFDTPObHeNi9JlfG4qGIh8WzerIJidtwoK+NsWq2I5i66YfHoIw==", + "requires": { + "bs58check": "^2.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "tiny-secp256k1": "^1.0.0", + "typeforce": "^1.11.5", + "wif": "^2.0.6" + } + } + } + }, "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 d0debe9e..2290875a 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "@ethereumjs/common": "^2.6.4", "@ethereumjs/tx": "^3.5.1", "@graphql-tools/merge": "^6.2.5", - "@lamassu/coins": "v1.4.9", + "@lamassu/coins": "v1.4.10", "@simplewebauthn/server": "^3.0.0", "@vonage/auth": "^1.5.0", "@vonage/sms": "^1.7.0", From 8b4e34644bd48a0833fbe5bfc979ebc8def5049d Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Mon, 11 Mar 2024 10:47:31 +0000 Subject: [PATCH 12/17] feat: new version of galoy API --- lib/plugins/wallet/galoy/galoy.js | 75 +++++++++++++++++++------------ 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/lib/plugins/wallet/galoy/galoy.js b/lib/plugins/wallet/galoy/galoy.js index e4a9a43e..a2e57906 100644 --- a/lib/plugins/wallet/galoy/galoy.js +++ b/lib/plugins/wallet/galoy/galoy.js @@ -3,14 +3,14 @@ const axios = require('axios') const { utils: coinUtils } = require('@lamassu/coins') const NAME = 'LN' -const SUPPORTED_COINS = ['LN', 'BTC'] +const SUPPORTED_COINS = ['LN'] const BN = require('../../../bn') function request (graphqlQuery, token, endpoint) { const headers = { 'content-type': 'application/json', - 'Authorization': `Bearer ${token}` + 'X-API-KEY': token } return axios({ method: 'post', @@ -38,12 +38,11 @@ function checkCryptoCode (cryptoCode) { function getTransactionsByAddress (token, endpoint, walletId, address) { const accountInfo = { 'operationName': 'me', - 'query': `query me { + 'query': `query me($walletId: WalletId!, , $address: OnChainAddress!) { me { defaultAccount { - wallets { - id - transactionsByAddress (address: "${address}") { + walletById(walletId: $walletId) { + transactionsByAddress (address: $address) { edges { node { direction @@ -56,11 +55,11 @@ function getTransactionsByAddress (token, endpoint, walletId, address) { } } }`, - 'variables': {} + 'variables': { walletId, address } } return request(accountInfo, token, endpoint) .then(r => { - return _.find(it => it.id === walletId, r.data.me.defaultAccount.wallets).transactionsByAddress + return r.data.me.defaultAccount.walletById.transactionsByAddress }) .catch(err => { throw new Error(err) @@ -70,10 +69,10 @@ function getTransactionsByAddress (token, endpoint, walletId, address) { function getGaloyWallet (token, endpoint, walletId) { const accountInfo = { 'operationName': 'me', - 'query': `query me { + 'query': `query me($walletId: WalletId!) { me { defaultAccount { - wallets { + walletById(walletId: $walletId) { id walletCurrency balance @@ -81,11 +80,11 @@ function getGaloyWallet (token, endpoint, walletId) { } } }`, - 'variables': {} + 'variables': { walletId } } return request(accountInfo, token, endpoint) .then(r => { - return _.find(it => it.id === walletId, r.data.me.defaultAccount.wallets) + return r.data.me.defaultAccount.walletById }) .catch(err => { throw new Error(err) @@ -112,7 +111,7 @@ function sendFundsOnChain (walletId, address, cryptoAtoms, token, endpoint) { status } }`, - 'variables': { 'input': { 'address': `${address}`, 'amount': `${cryptoAtoms}`, 'walletId': `${walletId}` } } + 'variables': { 'input': { address, amount: cryptoAtoms.toString(), walletId } } } return request(sendOnChain, token, endpoint) .then(result => { @@ -149,7 +148,7 @@ function sendFundsLN (walletId, invoice, cryptoAtoms, token, endpoint) { status } }`, - 'variables': { 'input': { 'paymentRequest': `${invoice}`, 'walletId': `${walletId}`, 'amount': `${cryptoAtoms}` } } + 'variables': { 'input': { 'paymentRequest': invoice, walletId, amount: cryptoAtoms.toString() } } } return request(sendLnNoAmount, token, endpoint).then(result => result.data.lnNoAmountInvoicePaymentSend) } @@ -166,7 +165,7 @@ function sendProbeRequest (walletId, invoice, cryptoAtoms, token, endpoint) { } } }`, - 'variables': { 'input': { 'paymentRequest': `${invoice}`, 'walletId': `${walletId}`, 'amount': `${cryptoAtoms}` } } + 'variables': { 'input': { paymentRequest: invoice, walletId, amount: cryptoAtoms.toString() } } } return request(sendProbeNoAmount, token, endpoint).then(result => result.data.lnNoAmountInvoiceFeeProbe) } @@ -174,15 +173,14 @@ function sendProbeRequest (walletId, invoice, cryptoAtoms, token, endpoint) { function sendCoins (account, tx, settings, operatorId) { const { toAddress, cryptoAtoms, cryptoCode } = tx return checkCryptoCode(cryptoCode) - .then(() => getGaloyWallet(account.apiSecret, account.endpoint, account.walletId)) - .then(wallet => { + .then(() => { if (isLnInvoice(toAddress)) { - return sendFundsLN(wallet.id, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) + return sendFundsLN(account.walletId, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) } if (isLnurl(toAddress)) { - return sendFundsLNURL(wallet.id, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) + return sendFundsLNURL(account.walletId, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) } - return sendFundsOnChain(wallet.id, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) + return sendFundsOnChain(account.walletId, toAddress, cryptoAtoms, account.apiSecret, account.endpoint) }) .then(result => { switch (result.status) { @@ -222,7 +220,7 @@ function newOnChainAddress (walletId, token, endpoint) { } } }`, - 'variables': { 'input': { 'walletId': `${walletId}` } } + 'variables': { 'input': { walletId } } } return request(createOnChainAddress, token, endpoint) .then(result => { @@ -230,6 +228,29 @@ function newOnChainAddress (walletId, token, endpoint) { }) } +function newNoAmountInvoice (walletId, token, endpoint) { + const createInvoice = { + 'operationName': 'lnNoAmountInvoiceCreate', + 'query': `mutation lnNoAmountInvoiceCreate($input: LnNoAmountInvoiceCreateInput!) { + lnNoAmountInvoiceCreate(input: $input) { + errors { + message + path + } + invoice { + paymentRequest + } + } + }`, + 'variables': { 'input': { walletId } } + } + return request(createInvoice, token, endpoint) + .then(result => { + return result.data.lnNoAmountInvoiceCreate.invoice.paymentRequest + }) + +} + function newInvoice (walletId, cryptoAtoms, token, endpoint) { const createInvoice = { 'operationName': 'lnInvoiceCreate', @@ -244,7 +265,7 @@ function newInvoice (walletId, cryptoAtoms, token, endpoint) { } } }`, - 'variables': { 'input': { 'walletId': `${walletId}`, 'amount': `${cryptoAtoms}` } } + 'variables': { 'input': { walletId, amount: cryptoAtoms.toString() } } } return request(createInvoice, token, endpoint) .then(result => { @@ -263,8 +284,7 @@ function balance (account, cryptoCode, settings, operatorId) { function newAddress (account, info, tx, settings, operatorId) { const { cryptoAtoms, cryptoCode } = tx return checkCryptoCode(cryptoCode) - .then(() => getGaloyWallet(account.apiSecret, account.endpoint, account.walletId)) - .then(wallet => newInvoice(wallet.id, cryptoAtoms, account.apiSecret, account.endpoint)) + .then(() => newInvoice(account.walletId, cryptoAtoms, account.apiSecret, account.endpoint)) } function getInvoiceStatus (token, endpoint, address) { @@ -275,7 +295,7 @@ function getInvoiceStatus (token, endpoint, address) { status } }`, - 'variables': {"input": {"paymentRequest": address}} + 'variables': { input: { paymentRequest: address } } } return request(query, token, endpoint) .then(r => { @@ -307,8 +327,7 @@ function getStatus (account, tx, requested, settings, operatorId) { // On-chain and intra-ledger transactions return getTransactionsByAddress(account.apiSecret, account.endpoint, account.walletId, address) .then(transactions => { - const txEdges = transactions.edges - const { SUCCESS: confirmed, PENDING: pending } = getBalance(txEdges) + const { SUCCESS: confirmed, PENDING: pending } = getBalance(transactions.edges) if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' } if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'authorized' } if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' } @@ -322,7 +341,7 @@ function newFunding (account, cryptoCode, settings, operatorId) { return checkCryptoCode(cryptoCode) .then(() => getGaloyWallet(account.apiSecret, account.endpoint, account.walletId)) .then(wallet => { - return newOnChainAddress(wallet.id, account.apiSecret, account.endpoint) + return newOnChainAddress(account.walletId, account.apiSecret, account.endpoint) .then(onChainAddress => [onChainAddress, wallet.balance]) }) .then(([onChainAddress, balance]) => { From c06b373d5aa4782baad127a40237062979c765ab Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Mon, 11 Mar 2024 12:42:17 +0000 Subject: [PATCH 13/17] chore: beta status on LN --- lib/new-admin/config/index.js | 4 +++- lib/new-admin/graphql/types/currency.type.js | 1 + new-lamassu-admin/src/pages/Locales/Locales.js | 1 + new-lamassu-admin/src/pages/Locales/helper.js | 11 ++++++++--- new-lamassu-admin/src/pages/Wallet/Wallet.js | 1 + new-lamassu-admin/src/pages/Wallet/helper.js | 2 +- 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/new-admin/config/index.js b/lib/new-admin/config/index.js index d64a6246..832945e2 100644 --- a/lib/new-admin/config/index.js +++ b/lib/new-admin/config/index.js @@ -32,10 +32,12 @@ const mapLanguage = lang => { } const massageCryptos = cryptos => { + const betaList = ['LN'] const convert = crypto => ({ code: crypto['cryptoCode'], display: crypto['display'], - codeDisplay: crypto['cryptoCodeDisplay'] ?? crypto['cryptoCode'] + codeDisplay: crypto['cryptoCodeDisplay'] ?? crypto['cryptoCode'], + isBeta: betaList.includes(crypto.cryptoCode) }) return _.map(convert, cryptos) diff --git a/lib/new-admin/graphql/types/currency.type.js b/lib/new-admin/graphql/types/currency.type.js index a2d8afb4..adef4997 100644 --- a/lib/new-admin/graphql/types/currency.type.js +++ b/lib/new-admin/graphql/types/currency.type.js @@ -10,6 +10,7 @@ const typeDef = gql` code: String! display: String! codeDisplay: String! + isBeta: Boolean } type Query { diff --git a/new-lamassu-admin/src/pages/Locales/Locales.js b/new-lamassu-admin/src/pages/Locales/Locales.js index a91459e5..3a820c8a 100644 --- a/new-lamassu-admin/src/pages/Locales/Locales.js +++ b/new-lamassu-admin/src/pages/Locales/Locales.js @@ -47,6 +47,7 @@ const GET_DATA = gql` cryptoCurrencies { code display + isBeta } languages { code diff --git a/new-lamassu-admin/src/pages/Locales/helper.js b/new-lamassu-admin/src/pages/Locales/helper.js index 738fc75f..32b14e4e 100644 --- a/new-lamassu-admin/src/pages/Locales/helper.js +++ b/new-lamassu-admin/src/pages/Locales/helper.js @@ -16,7 +16,7 @@ const allFields = (getData, onChange, auxElements = []) => { if (!data) return '' return R.compose( - R.prop(code), + it => `${R.prop(code)(it)} ${it?.isBeta ? '(Beta)' : ''}`, R.find(R.propEq(compare ?? 'code', it)) )(data) } @@ -36,7 +36,12 @@ const allFields = (getData, onChange, auxElements = []) => { const countryData = getData(['countries']) const currencyData = getData(['currencies']) const languageData = getData(['languages']) - const cryptoData = getData(['cryptoCurrencies']) + const rawCryptoData = getData(['cryptoCurrencies']) + const cryptoData = rawCryptoData?.map(it => { + it.codeLabel = `${it.code}${it.isBeta ? ' (Beta)' : ''}` + return it + }) + const timezonesData = timezoneList const findSuggestion = it => { @@ -104,7 +109,7 @@ const allFields = (getData, onChange, auxElements = []) => { inputProps: { options: cryptoData, valueProp: 'code', - labelProp: 'code', + labelProp: 'codeLabel', multiple: true, optionsLimit: null, onChange diff --git a/new-lamassu-admin/src/pages/Wallet/Wallet.js b/new-lamassu-admin/src/pages/Wallet/Wallet.js index b0a9c0c8..11067cbc 100644 --- a/new-lamassu-admin/src/pages/Wallet/Wallet.js +++ b/new-lamassu-admin/src/pages/Wallet/Wallet.js @@ -45,6 +45,7 @@ const GET_INFO = gql` cryptoCurrencies { code display + isBeta } } ` diff --git a/new-lamassu-admin/src/pages/Wallet/helper.js b/new-lamassu-admin/src/pages/Wallet/helper.js index 14f303e9..cf2871bd 100644 --- a/new-lamassu-admin/src/pages/Wallet/helper.js +++ b/new-lamassu-admin/src/pages/Wallet/helper.js @@ -208,7 +208,7 @@ const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => { const widthAdjust = wizard ? 11 : 0 const viewCryptoCurrency = it => { const currencyDisplay = R.compose( - R.prop(['display']), + it => `${R.prop(['display'])(it)} ${it.isBeta ? '(Beta)' : ''}`, R.find(R.propEq('code', it)) )(cryptoCurrencies) return currencyDisplay From ee90179bd17db97ce137abe2ab716968de8b3471 Mon Sep 17 00:00:00 2001 From: CrypticaScriptura <7396812+CrypticaScriptura@users.noreply.github.com> Date: Thu, 14 Mar 2024 18:19:26 -0400 Subject: [PATCH 14/17] chore: v10.0.0-rc.1 (#1660) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f2a2aaa9..ea8b31f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "10.0.0-beta.13", + "version": "10.0.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 8a3c1231..8a02b123 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-beta.13", + "version": "10.0.0-rc.1", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { From 952cbd661ec106d97dcfc90946c32ce68fe99010 Mon Sep 17 00:00:00 2001 From: CrypticaScriptura <7396812+CrypticaScriptura@users.noreply.github.com> Date: Fri, 15 Mar 2024 16:25:54 -0400 Subject: [PATCH 15/17] chore: v9.0.0-rc.1 (#1661) --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7f57679a..3af6df84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "lamassu-server", - "version": "9.0.0-beta.11", + "version": "9.0.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2290875a..6e868546 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "lamassu-server", "description": "bitcoin atm client server protocol module", "keywords": [], - "version": "9.0.0-beta.11", + "version": "9.0.0-rc.1", "license": "./LICENSE", "author": "Lamassu (https://lamassu.is)", "dependencies": { From 6d0e510d60b9f085bcd42e9221f3e1ed9fc5a9bb Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Mon, 18 Mar 2024 09:48:34 +0000 Subject: [PATCH 16/17] fix: profit display on admin --- .env.sample | 1 - .sample.env | 3 - lib/options-loader.js | 66 ------------------- .../src/pages/Transactions/DetailsCard.js | 4 +- tools/build-dev-env.js | 1 - 5 files changed, 1 insertion(+), 74 deletions(-) delete mode 100644 .env.sample delete mode 100644 lib/options-loader.js diff --git a/.env.sample b/.env.sample deleted file mode 100644 index db93e716..00000000 --- a/.env.sample +++ /dev/null @@ -1 +0,0 @@ -LAMASSU_DB=DEV \ No newline at end of file diff --git a/.sample.env b/.sample.env index 6f867352..c2c02bf5 100644 --- a/.sample.env +++ b/.sample.env @@ -1,8 +1,5 @@ ## Database variables -# Used to describe which database to use. Possible values include: DEV, RELEASE, STRESS_TEST -LAMASSU_DB= - # Postgres related environment variables POSTGRES_USER= POSTGRES_PASSWORD= diff --git a/lib/options-loader.js b/lib/options-loader.js deleted file mode 100644 index ba10ffc7..00000000 --- a/lib/options-loader.js +++ /dev/null @@ -1,66 +0,0 @@ -const fs = require('fs') -const path = require('path') -const os = require('os') -const argv = require('minimist')(process.argv.slice(2)) -const _ = require('lodash/fp') - -require('./environment-helper') - -const DATABASE = process.env.LAMASSU_DB ?? 'PROD' -const dbMapping = psqlConf => ({ - STRESS_TEST: _.replace('lamassu', 'lamassu_stress', psqlConf), - PAZUZ: _.replace('lamassu', 'lamassu_pazuz', psqlConf), - RELEASE: _.replace('lamassu', 'lamassu_release', psqlConf), - DEV: _.replace('lamassu', 'lamassu', psqlConf), - PROD: _.replace('lamassu', 'lamassu', psqlConf) -}) - -/** - * @return {{path: string, opts: any}} - */ -function load () { - if (process.env.LAMASSU_CONFIG) { - const configPath = process.env.LAMASSU_CONFIG - return { - path: configPath, - opts: JSON.parse(fs.readFileSync(configPath)) - } - } - - if (argv.f) { - const configPath = argv.f - return { - path: configPath, - opts: JSON.parse(fs.readFileSync(configPath)) - } - } - - try { - const globalConfigPath = path.resolve('/etc', 'lamassu', 'lamassu.json') - const config = { - path: globalConfigPath, - opts: JSON.parse(fs.readFileSync(globalConfigPath)) - } - - config.opts.postgresql = dbMapping(config.opts.postgresql)[DATABASE] - - return config - } catch (_) { - try { - const homeConfigPath = path.resolve(os.homedir(), '.lamassu', 'lamassu.json') - const config = { - path: homeConfigPath, - opts: JSON.parse(fs.readFileSync(homeConfigPath)) - } - - config.opts.postgresql = dbMapping(config.opts.postgresql)[DATABASE] - - return config - } catch (_) { - console.error("Couldn't open lamassu.json config file.") - process.exit(1) - } - } -} - -module.exports = load diff --git a/new-lamassu-admin/src/pages/Transactions/DetailsCard.js b/new-lamassu-admin/src/pages/Transactions/DetailsCard.js index afd2ad7b..57f07785 100644 --- a/new-lamassu-admin/src/pages/Transactions/DetailsCard.js +++ b/new-lamassu-admin/src/pages/Transactions/DetailsCard.js @@ -130,9 +130,7 @@ const DetailsRow = ({ it: tx, timezone }) => { } ) - const commission = BigNumber(tx.profit) - .abs() - .toFixed(2, 1) // ROUND_DOWN + const commission = BigNumber(tx.profit).toFixed(2, 1) // ROUND_DOWN const commissionPercentage = Number.parseFloat(tx.commissionPercentage, 2) * 100 const cashInFee = isCashIn ? Number.parseFloat(tx.cashInFee) : 0 diff --git a/tools/build-dev-env.js b/tools/build-dev-env.js index ddc89de2..05b45b37 100644 --- a/tools/build-dev-env.js +++ b/tools/build-dev-env.js @@ -6,7 +6,6 @@ const setEnvVariable = require('./set-env-var') fs.copyFileSync(path.resolve(__dirname, '../.sample.env'), path.resolve(__dirname, '../.env')) -setEnvVariable('LAMASSU_DB', 'DEV') setEnvVariable('POSTGRES_USER', 'postgres') setEnvVariable('POSTGRES_PASSWORD', 'postgres123') setEnvVariable('POSTGRES_HOST', 'localhost') From 035a0a3b8ee878ab38fe131c5d36e110d33882f5 Mon Sep 17 00:00:00 2001 From: Rafael Taranto Date: Tue, 19 Mar 2024 02:35:44 +0000 Subject: [PATCH 17/17] fix: recycler counts reset on cash unit update --- lib/cashbox-batches.js | 6 +++++- lib/machine-loader.js | 6 +++++- new-lamassu-admin/src/pages/Maintenance/Wizard/Wizard.js | 4 +++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/cashbox-batches.js b/lib/cashbox-batches.js index 6e723c1a..e0f89ae2 100644 --- a/lib/cashbox-batches.js +++ b/lib/cashbox-batches.js @@ -49,7 +49,11 @@ function updateMachineWithBatch (machineContext, oldCashboxCount) { bills.cashbox_batch_id IS NULL`, [batchId, deviceId]) const q3 = t.none(`UPDATE empty_unit_bills SET cashbox_batch_id=$1 WHERE empty_unit_bills.device_id = $2 AND empty_unit_bills.cashbox_batch_id IS NULL`, [batchId, deviceId]) - const q4 = t.none(`UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, recycler1=$5, recycler2=$6, recycler3=$7, recycler4=$8, recycler5=$9, recycler6=$10 WHERE device_id=$11`, [ + const q4 = t.none(` + UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, + recycler1=coalesce($5, recycler1), recycler2=coalesce($6, recycler2), recycler3=coalesce($7, recycler3), + recycler4=coalesce($8, recycler4), recycler5=coalesce($9, recycler5), recycler6=coalesce($10, recycler6) WHERE device_id=$11 + `, [ cashUnits.cassette1, cashUnits.cassette2, cashUnits.cassette3, diff --git a/lib/machine-loader.js b/lib/machine-loader.js index e106e0f9..578e211e 100644 --- a/lib/machine-loader.js +++ b/lib/machine-loader.js @@ -183,7 +183,11 @@ function setCassetteBills (rec) { .then(machine => { const oldCashboxCount = machine?.cashUnits?.cashbox if (_.isNil(oldCashboxCount) || cashbox.toString() === oldCashboxCount.toString()) { - const sql = 'UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, recycler1=$5, recycler2=$6, recycler3=$7, recycler4=$8, recycler5=$9, recycler6=$10 WHERE device_id=$11' + const sql = ` + UPDATE devices SET cassette1=$1, cassette2=$2, cassette3=$3, cassette4=$4, + recycler1=coalesce($5, recycler1), recycler2=coalesce($6, recycler2), recycler3=coalesce($7, recycler3), + recycler4=coalesce($8, recycler4), recycler5=coalesce($9, recycler5), recycler6=coalesce($10, recycler6) + WHERE device_id=$11` return db.none(sql, [cassette1, cassette2, cassette3, cassette4, recycler1, recycler2, recycler3, recycler4, recycler5, recycler6, rec.deviceId]) } diff --git a/new-lamassu-admin/src/pages/Maintenance/Wizard/Wizard.js b/new-lamassu-admin/src/pages/Maintenance/Wizard/Wizard.js index 214b68aa..c46f4a50 100644 --- a/new-lamassu-admin/src/pages/Maintenance/Wizard/Wizard.js +++ b/new-lamassu-admin/src/pages/Maintenance/Wizard/Wizard.js @@ -64,7 +64,9 @@ const Wizard = ({ machine, cashoutSettings, locale, onClose, save, error }) => { ].includes('YES') const cassettes = buildCashUnitObj(CASSETTE_FIELDS, it) - const recyclers = buildCashUnitObj(RECYCLER_FIELDS, it) + const recyclers = canManuallyLoadRecyclers(machine) + ? buildCashUnitObj(RECYCLER_FIELDS, it) + : [] const cashUnits = { cashbox: wasCashboxEmptied ? 0 : machine?.cashUnits.cashbox,