diff --git a/README.md b/README.md index be7c65a7..f14a7c0f 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ For easy setup on your Laptop/Desktop, [a wizard is available here.](https://git #### Steps: 1) Run [LND](https://github.com/lightningnetwork/lnd/releases) - *Example mainnet startup*: - ```./lnd --bitcoin.active --bitcoin.mainnet --bitcoin.node=neutrino --neutrino.connect=neutrino.shock.network``` + ```./lnd --bitcoin.active --bitcoin.mainnet --bitcoin.node=neutrino --neutrino.connect=neutrino.shock.network --routing.assumechanvalid=1``` 2) Download and Install API diff --git a/services/auth/secrets.json b/services/auth/secrets.json index 0967ef42..9e26dfee 100644 --- a/services/auth/secrets.json +++ b/services/auth/secrets.json @@ -1 +1 @@ -{} +{} \ No newline at end of file diff --git a/services/gunDB/contact-api/actions.js b/services/gunDB/contact-api/actions.js index 722c26e0..b4fe5bed 100644 --- a/services/gunDB/contact-api/actions.js +++ b/services/gunDB/contact-api/actions.js @@ -1164,6 +1164,29 @@ const saveSeedBackup = async (mnemonicPhrase, user, SEA) => { }) } +/** + * @param {string} backups + * @param {UserGUNNode} user + * @param {ISEA} SEA + * @returns {Promise} + */ +const saveChannelsBackup = async (backups, user, SEA) => { + if (backups === '') { + throw new TypeError('cant save an empty channel backup') + } + const mySecret = require('../Mediator').getMySecret() + const encryptBackups = await SEA.encrypt(backups, mySecret) + return new Promise((res, rej) => { + user.get(Key.CHANNELS_BACKUP).put(encryptBackups, ack => { + if (ack.err) { + rej(ack.err) + } else { + res() + } + }) + }) +} + /** * @param {string} pub * @returns {Promise} @@ -1211,6 +1234,7 @@ module.exports = { generateOrderAddress, setBio, saveSeedBackup, + saveChannelsBackup, disconnect, setLastSeenApp } diff --git a/services/gunDB/contact-api/key.js b/services/gunDB/contact-api/key.js index a1b26023..be14b788 100644 --- a/services/gunDB/contact-api/key.js +++ b/services/gunDB/contact-api/key.js @@ -37,6 +37,8 @@ exports.BIO = 'bio' exports.SEED_BACKUP = 'seedBackup' +exports.CHANNELS_BACKUP = 'channelsBackup' + exports.LAST_SEEN_APP = 'lastSeenApp' exports.LAST_SEEN_NODE = 'lastSeenNode' diff --git a/src/routes.js b/src/routes.js index 60134101..06762f2f 100644 --- a/src/routes.js +++ b/src/routes.js @@ -422,6 +422,42 @@ module.exports = async ( // Send an event to update lightning's status mySocketsEvents.emit("updateLightning"); + //get the latest channel backups before subscribing + const user = require('../services/gunDB/Mediator').getUser() + const SEA = require('../services/gunDB/Mediator').mySEA + const { lightning } = LightningServices.services; + lightning.exportAllChannelBackups({}, (err, channelBackups) => { + if (err) { + return handleError(res, err); + } + GunActions.saveChannelsBackup(JSON.stringify(channelBackups),user,SEA) + + }); + + //register to listen for channel backups + const onNewChannelBackup = () => { + logger.warn("Subscribing to channel backup ...") + const stream = lightning.SubscribeChannelBackups({}) + stream.on("data", data => { + logger.info(" New channel backup data") + GunActions.saveChannelsBackup(JSON.stringify(data),user,SEA) + }) + stream.on("end", ()=>{ + logger.info("Channel backup stream ended, starting a new one...") + onNewChannelBackup() + }) + stream.on("error", err => { + logger.error("Channel backup stream error:", err); + }) + stream.on("status", status => { + logger.error("Channel backup stream status:", status); + if (status.code === 14) { + onNewChannelBackup(); + } + }) + } + onNewChannelBackup(); + // Generate auth token and send it as a JSON response const token = await auth.generateToken(); res.json({ @@ -1580,8 +1616,24 @@ module.exports = async ( }); const GunEvent = Common.Constants.Event - const Events = require('../services/gunDB/contact-api/events') const Key = require('../services/gunDB/contact-api/key') + app.get("/api/gun/lndchanbackups", async (req,res) => { + try{ + const user = require('../services/gunDB/Mediator').getUser() + + const SEA = require('../services/gunDB/Mediator').mySEA + const mySecret = require('../services/gunDB/Mediator').getMySecret() + const encBackup = await timeout5(user.get(Key.CHANNELS_BACKUP).then()) + const backup = await SEA.decrypt(encBackup,mySecret) + logger.info(backup) + res.json({data:backup}) + } catch (err) { + res.json({ok:"err"}) + } + }) + + const Events = require('../services/gunDB/contact-api/events') + const {timeout5} = require('../services/gunDB/contact-api/utils') app.get(`/api/gun/${GunEvent.ON_RECEIVED_REQUESTS}`, (_, res) => { diff --git a/src/server.js b/src/server.js index 58e2091c..c55393d6 100644 --- a/src/server.js +++ b/src/server.js @@ -73,11 +73,11 @@ const server = program => { } const dataHash = hashData(args[0]).slice(-8) - res.set('ETag', dataHash) + res.set('shock-cache-hash', dataHash) - logger.debug('ETag:', req.headers.etag) + logger.debug('shock-cache-hash:', req.headers['shock-cache-hash']) logger.debug('Data Hash:', dataHash) - if (req.headers.etag === dataHash) { + if (req.headers['shock-cache-hash'] === dataHash) { logger.debug('Same Hash Detected!') args[0] = null res.status(304) diff --git a/utils/encryptionStore.js b/utils/encryptionStore.js index a946bc2f..c3df0ec1 100644 --- a/utils/encryptionStore.js +++ b/utils/encryptionStore.js @@ -38,6 +38,7 @@ const Encryption = { }, data ) + return encryptedData.toString('base64') }, /** @@ -62,7 +63,7 @@ const Encryption = { /** * @param {{ deviceId: string , message: any , metadata?: any}} arg0 */ - encryptMessage: ({ deviceId, message, metadata }) => { + encryptMessage: ({ deviceId, message, metadata = {} }) => { const parsedMessage = typeof message === 'object' ? JSON.stringify(message) : message const data = Buffer.from(parsedMessage) @@ -79,7 +80,14 @@ const Encryption = { Buffer.from(cipher.final()) ]) const encryptedData = encryptedBuffer.toString('base64') - return { encryptedData, encryptedKey, iv: iv.toString('hex'), metadata } + const encryptedMessage = { + encryptedData, + encryptedKey, + iv: iv.toString('hex'), + metadata + } + + return encryptedMessage }, /** * @param {{ message: string , key: string , iv: string }} arg0