From 71c239d432c3a618f4b5e8fbfabd94e9f6509c5d Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 28 Sep 2020 11:56:21 -0400 Subject: [PATCH 1/8] invoices boostrap at auth --- src/routes.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/routes.js b/src/routes.js index aa1e00ed..2a1b7182 100644 --- a/src/routes.js +++ b/src/routes.js @@ -695,7 +695,24 @@ module.exports = async ( alias, publicKey }, - follows: await GunGetters.Follows.currentFollows() + follows: await GunGetters.Follows.currentFollows(), + data: { + invoices: await Common.makePromise((res, rej) => { + lightning.listInvoices( + { + reversed: true, + num_max_invoices: 50 + }, + (err, lres) => { + if (err) { + rej(new Error(err.details)) + } else { + res(lres) + } + } + ) + }) + } }) return true From 288ba30a163fe8d70ab94393e5324a2a0222939d Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 28 Sep 2020 11:56:30 -0400 Subject: [PATCH 2/8] catch errors --- src/routes.js | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/routes.js b/src/routes.js index 2a1b7182..46db0778 100644 --- a/src/routes.js +++ b/src/routes.js @@ -3086,22 +3086,32 @@ module.exports = async ( }) ap.post('/api/lnd/cb/:methodName', (req, res) => { - const { lightning } = LightningServices.services - const { methodName } = req.params - const args = req.body + try { + const { lightning } = LightningServices.services + const { methodName } = req.params + const args = req.body - lightning[methodName](args, (err, lres) => { - if (err) { - res.status(500).json({ - errorMessage: err.details - }) - } else if (lres) { - res.status(200).json(lres) - } else { - res.status(500).json({ - errorMessage: 'Unknown error' - }) - } - }) + lightning[methodName](args, (err, lres) => { + if (err) { + res.status(500).json({ + errorMessage: err.details + }) + } else if (lres) { + res.status(200).json(lres) + } else { + res.status(500).json({ + errorMessage: 'Unknown error' + }) + } + }) + } catch (err) { + logger.warn(`Error inside api cb:`) + logger.error(err) + logger.error(err.message) + + return res.status(500).json({ + errorMessage: err.message + }) + } }) } From f184f7be942560e1178a74ca79e1b27de4b0f5bf Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Mon, 28 Sep 2020 14:23:33 -0400 Subject: [PATCH 3/8] remove old socket code --- src/sockets.js | 62 +++++++++++--------------------------------------- 1 file changed, 13 insertions(+), 49 deletions(-) diff --git a/src/sockets.js b/src/sockets.js index 6c5b11df..f7add4d7 100644 --- a/src/sockets.js +++ b/src/sockets.js @@ -1,5 +1,5 @@ /** @prettier */ -// app/sockets.js +// @ts-check const logger = require('winston') const Encryption = require('../utils/encryptionStore') @@ -21,8 +21,6 @@ module.exports = ( /** @type {import('socket.io').Server} */ io ) => { - const Mediator = require('../services/gunDB/Mediator/index.js') - // This should be used for encrypting and emitting your data const emitEncryptedEvent = ({ eventName, data, socket }) => { try { @@ -260,61 +258,27 @@ module.exports = ( logger.info('socket.handshake', socket.handshake) - const isOneTimeUseSocket = !!socket.handshake.query.IS_GUN_AUTH const isLNDSocket = !!socket.handshake.query.IS_LND_SOCKET const isNotificationsSocket = !!socket.handshake.query .IS_NOTIFICATIONS_SOCKET + if (!isLNDSocket) { /** printing out the client who joined */ logger.info('New socket client connected (id=' + socket.id + ').') } - if (isOneTimeUseSocket) { - logger.info('New socket is one time use') - socket.on('IS_GUN_AUTH', () => { - try { - const isGunAuth = Mediator.isAuthenticated() - socket.emit('IS_GUN_AUTH', { - ok: true, - msg: { - isGunAuth - }, - origBody: {} - }) - socket.disconnect() - } catch (err) { - socket.emit('IS_GUN_AUTH', { - ok: false, - msg: err.message, - origBody: {} - }) - socket.disconnect() - } - }) - } else { - if (isLNDSocket) { - const subID = Math.floor(Math.random() * 1000).toString() - const isNotifications = isNotificationsSocket ? 'notifications' : '' - logger.info('[LND] New LND Socket created:' + isNotifications + subID) - const cancelInvoiceStream = onNewInvoice(socket, subID) - const cancelTransactionStream = onNewTransaction(socket, subID) - const cancelPingStream = onPing(socket, subID) - socket.on('disconnect', () => { - logger.info('LND socket disconnected:' + isNotifications + subID) - cancelInvoiceStream() - cancelTransactionStream() - cancelPingStream() - }) - return - } - logger.info('New socket is NOT one time use') - // this is where we create the websocket connection - // with the GunDB service. - Mediator.createMediator(socket) - - /** listening if client has disconnected */ + if (isLNDSocket) { + const subID = Math.floor(Math.random() * 1000).toString() + const isNotifications = isNotificationsSocket ? 'notifications' : '' + logger.info('[LND] New LND Socket created:' + isNotifications + subID) + const cancelInvoiceStream = onNewInvoice(socket, subID) + const cancelTransactionStream = onNewTransaction(socket, subID) + const cancelPingStream = onPing(socket, subID) socket.on('disconnect', () => { - logger.info('client disconnected (id=' + socket.id + ').') + logger.info('LND socket disconnected:' + isNotifications + subID) + cancelInvoiceStream() + cancelTransactionStream() + cancelPingStream() }) } }) From b815a881499f52a8fd62d2cb632509defcb35b65 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 30 Sep 2020 20:10:15 -0400 Subject: [PATCH 4/8] eslint rules --- .eslintrc.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 00f512ef..dd2485bf 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -83,7 +83,12 @@ "no-undefined": "off", - "no-process-env": "off" + "no-process-env": "off", + + // I am now convinced TODO comments closer to the relevant code are better + // than GH issues. Especially when it only concerns a single function / + // routine. + "no-warning-comments": "off" }, "parser": "babel-eslint", "env": { From dcf176429ea1abc45824a3438cac6baf2551e9f2 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 30 Sep 2020 20:50:49 -0400 Subject: [PATCH 5/8] deafult namespace for sockets --- src/sockets.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sockets.js b/src/sockets.js index f7add4d7..5d19a7c2 100644 --- a/src/sockets.js +++ b/src/sockets.js @@ -253,9 +253,8 @@ module.exports = ( } } - io.on('connection', socket => { + io.of('default').on('connection', socket => { logger.info(`io.onconnection`) - logger.info('socket.handshake', socket.handshake) const isLNDSocket = !!socket.handshake.query.IS_LND_SOCKET From 3e059591a9cc1d63079bb2a5c7200540d626f9e4 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Wed, 30 Sep 2020 20:52:17 -0400 Subject: [PATCH 6/8] gun rpc namespace --- src/sockets.js | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/sockets.js b/src/sockets.js index 5d19a7c2..a6bc07ff 100644 --- a/src/sockets.js +++ b/src/sockets.js @@ -4,6 +4,11 @@ const logger = require('winston') const Encryption = require('../utils/encryptionStore') const LightningServices = require('../utils/lightningServices') +const { + getGun, + getUser, + isAuthenticated +} = require('../services/gunDB/Mediator') const onPing = (socket, subID) => { logger.warn('Subscribing to pings socket...' + subID) @@ -282,5 +287,65 @@ module.exports = ( } }) + io.of('gun').on('connect', socket => { + // TODO: off() + + try { + if (!isAuthenticated()) { + socket.emit('$shock', 'NOT_AUTH') + return + } + + const { $shock } = socket.handshake.query + + const [root, path, method] = $shock.split('::') + + // eslint-disable-next-line init-declarations + let node + + if (root === '$gun') { + node = getGun() + } else if (root === '$user') { + node = getUser() + } else { + node = getGun().user(root) + } + + for (const bit of path.split('.')) { + node = node.get(bit) + } + + /** + * @param {unknown} data + * @param {string} key + */ + const listener = (data, key) => { + try { + socket.emit('$shock', data, key) + } catch (err) { + logger.error( + `Error for gun rpc socket, query ${$shock} -> ${err.message}` + ) + } + } + + if (method === 'on') { + node.on(listener) + } else if (method === 'open') { + node.open(listener) + } else if (method === 'map.on') { + node.map().on(listener) + } else if (method === 'map.once') { + node.map().once(listener) + } else { + throw new TypeError( + `Invalid method for gun rpc call : ${method}, query: ${$shock}` + ) + } + } catch (err) { + logger.error('GUNRPC: ' + err.message) + } + }) + return io } From d0af6532a3e827567cd0894af528f0fb14ab0851 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 2 Oct 2020 11:54:51 -0400 Subject: [PATCH 7/8] socket LND RPC --- src/sockets.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/sockets.js b/src/sockets.js index a6bc07ff..52af968e 100644 --- a/src/sockets.js +++ b/src/sockets.js @@ -347,5 +347,46 @@ module.exports = ( } }) + io.of('/lndstreaming').on('connect', socket => { + // TODO: unsubscription + + /** + * Streaming stuff in LND uses these events: data, status, end, error. + */ + + try { + const { services } = LightningServices + + const { service, method, args: unParsed } = socket.handshake.query + + const args = JSON.parse(unParsed) + + const call = services[service][method](args) + + call.on('data', data => { + socket.emit('data', data) + }) + + call.on('status', status => { + socket.emit('status', status) + }) + + call.on('end', () => { + socket.emit('end') + }) + + call.on('error', err => { + socket.emit('error', err) + }) + + // Possibly allow streaming writes such as sendPaymentV2 + socket.on('write', args => { + call.write(args) + }) + } catch (err) { + logger.error('LNDRPC: ' + err.message) + } + }) + return io } From 892890bbfdf70a059be1e7d4866c07608505b135 Mon Sep 17 00:00:00 2001 From: Daniel Lugo Date: Fri, 2 Oct 2020 14:35:25 -0400 Subject: [PATCH 8/8] use non-restricted event name --- src/sockets.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sockets.js b/src/sockets.js index 52af968e..4feecfdc 100644 --- a/src/sockets.js +++ b/src/sockets.js @@ -376,7 +376,8 @@ module.exports = ( }) call.on('error', err => { - socket.emit('error', err) + // 'error' is a reserved event name we can't use it + socket.emit('$error', err) }) // Possibly allow streaming writes such as sendPaymentV2