diff --git a/src/routes.js b/src/routes.js index f8843b3f..a6f5cd75 100644 --- a/src/routes.js +++ b/src/routes.js @@ -1,34 +1,35 @@ -/* eslint-disable no-param-reassign */ -/* eslint-disable prefer-destructuring */ /** * @prettier */ -"use strict"; +'use strict' -const Axios = require("axios"); -const Crypto = require("crypto"); -const logger = require("winston"); -const httpsAgent = require("https"); -const responseTime = require("response-time"); -const uuid = require("uuid/v4"); +const Axios = require('axios') +const Crypto = require('crypto') +const logger = require('winston') +const httpsAgent = require('https') +const responseTime = require('response-time') +const uuid = require('uuid/v4') const Common = require('shock-common') const isARealUsableNumber = require('lodash/isFinite') const Big = require('big.js') const size = require('lodash/size') -const getListPage = require("../utils/paginate"); -const auth = require("../services/auth/auth"); -const FS = require("../utils/fs"); -const Encryption = require("../utils/encryptionStore"); -const LightningServices = require("../utils/lightningServices"); -const GunDB = require("../services/gunDB/Mediator"); -const { unprotectedRoutes, nonEncryptedRoutes } = require("../utils/protectedRoutes"); -const GunActions = require("../services/gunDB/contact-api/actions") +const getListPage = require('../utils/paginate') +const auth = require('../services/auth/auth') +const FS = require('../utils/fs') +const Encryption = require('../utils/encryptionStore') +const LightningServices = require('../utils/lightningServices') +const GunDB = require('../services/gunDB/Mediator') +const { + unprotectedRoutes, + nonEncryptedRoutes +} = require('../utils/protectedRoutes') +const GunActions = require('../services/gunDB/contact-api/actions') const GunGetters = require('../services/gunDB/contact-api/getters') const GunKey = require('../services/gunDB/contact-api/key') -const DEFAULT_MAX_NUM_ROUTES_TO_QUERY = 10; -const SESSION_ID = uuid(); +const DEFAULT_MAX_NUM_ROUTES_TO_QUERY = 10 +const SESSION_ID = uuid() // module.exports = (app) => { module.exports = async ( @@ -37,129 +38,134 @@ module.exports = async ( mySocketsEvents, { serverPort, CA, CA_KEY, usetls } ) => { - const {timeout5} = require('../services/gunDB/contact-api/utils') + const { timeout5 } = require('../services/gunDB/contact-api/utils') const Http = Axios.create({ - httpsAgent: new httpsAgent.Agent({ + httpsAgent: new httpsAgent.Agent({ ca: await FS.readFile(CA) }) }) - - const sanitizeLNDError = (message = "") => { - if (message.toLowerCase().includes("unknown")) { - const splittedMessage = message - .split("UNKNOWN: "); + + const sanitizeLNDError = (message = '') => { + if (message.toLowerCase().includes('unknown')) { + const splittedMessage = message.split('UNKNOWN: ') return splittedMessage.length > 1 - ? splittedMessage.slice(1).join("") - : splittedMessage.join("") + ? splittedMessage.slice(1).join('') + : splittedMessage.join('') } return message } - + const getAvailableService = () => new Promise((resolve, reject) => { - const { lightning } = LightningServices.services; + const { lightning } = LightningServices.services lightning.getInfo({}, (err, response) => { if (err) { - if (err.message.includes("unknown service lnrpc.Lightning")) { + if (err.message.includes('unknown service lnrpc.Lightning')) { resolve({ - service: "walletUnlocker", - message: "Wallet locked", + service: 'walletUnlocker', + message: 'Wallet locked', code: err.code, - walletStatus: "locked", + walletStatus: 'locked', success: true - }); + }) } else if (err.code === 14) { reject({ - service: "unknown", + service: 'unknown', message: "Failed to connect to LND server, make sure it's up and running.", code: 14, - walletStatus: "unknown", + walletStatus: 'unknown', success: false - }); + }) } else { reject({ - service: "lightning", + service: 'lightning', message: sanitizeLNDError(err.message), code: err.code, - walletStatus: "unlocked", + walletStatus: 'unlocked', success: false - }); + }) } } resolve({ - service: "lightning", + service: 'lightning', message: response, code: null, - walletStatus: "unlocked", + walletStatus: 'unlocked', success: true - }); - }); - }); - + }) + }) + }) + const checkHealth = async () => { - logger.info("Getting service status...") - const serviceStatus = await getAvailableService(); - logger.info("Received status:", serviceStatus); - const LNDStatus = serviceStatus; + logger.info('Getting service status...') + const serviceStatus = await getAvailableService() + logger.info('Received status:', serviceStatus) + const LNDStatus = serviceStatus try { - logger.info("Getting API status..."); - const APIHealth = await Http.get(`${usetls ? 'https' : 'http'}://localhost:${serverPort}/ping`); + logger.info('Getting API status...') + const APIHealth = await Http.get( + `${usetls ? 'https' : 'http'}://localhost:${serverPort}/ping` + ) const APIStatus = { message: APIHealth.data, - responseTime: APIHealth.headers["x-response-time"], + responseTime: APIHealth.headers['x-response-time'], success: true - }; - logger.info("Received API status!", APIStatus); + } + logger.info('Received API status!', APIStatus) return { LNDStatus, APIStatus - }; + } } catch (err) { - logger.error(err); + logger.error(err) const APIStatus = { message: err.response.data, - responseTime: err.response.headers["x-response-time"], + responseTime: err.response.headers['x-response-time'], success: false - }; - logger.warn("Failed to retrieve API status", APIStatus); + } + logger.warn('Failed to retrieve API status', APIStatus) return { LNDStatus, APIStatus - }; + } } - }; - + } + const handleError = async (res, err) => { - const health = await checkHealth(); + const health = await checkHealth() if (health.LNDStatus.success) { if (err) { res.json({ errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.sendStatus(403); + res.sendStatus(403) } } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } - }; + } const recreateLnServices = async () => { - await LightningServices.init(); + await LightningServices.init() - return true; - }; + return true + } const lastSeenMiddleware = (req, res, next) => { const { authorization } = req.headers const { path, method } = req - if (!unprotectedRoutes[method][path] && authorization && GunDB.isAuthenticated()) { + if ( + !unprotectedRoutes[method][path] && + authorization && + GunDB.isAuthenticated() + ) { GunActions.setLastSeenApp() } @@ -170,112 +176,128 @@ module.exports = async ( new Promise((resolve, reject) => { try { const args = { - wallet_password: Buffer.from(password, "utf-8") - }; - const { walletUnlocker } = LightningServices.services; + wallet_password: Buffer.from(password, 'utf-8') + } + const { walletUnlocker } = LightningServices.services walletUnlocker.unlockWallet(args, (unlockErr, unlockResponse) => { if (unlockErr) { - reject(unlockErr); - return; + reject(unlockErr) + return } - resolve(unlockResponse); - }); + resolve(unlockResponse) + }) } catch (err) { - logger.error(err); - if (err.message === "unknown service lnrpc.WalletUnlocker") { + logger.error(err) + if (err.message === 'unknown service lnrpc.WalletUnlocker') { resolve({ - message: "Wallet already unlocked" - }); - return; + message: 'Wallet already unlocked' + }) + return } reject({ - field: "wallet", + field: 'wallet', code: err.code, message: sanitizeLNDError(err.message) - }); + }) } - }); - + }) + // Hack to check whether or not a wallet exists const walletExists = async () => { try { - const availableService = await getAvailableService(); - if (availableService.service === "lightning") { - return true; + const availableService = await getAvailableService() + if (availableService.service === 'lightning') { + return true } - - if (availableService.service === "walletUnlocker") { - const randomPassword = Crypto.randomBytes(4).toString('hex'); + + if (availableService.service === 'walletUnlocker') { + const randomPassword = Crypto.randomBytes(4).toString('hex') try { - await unlockWallet(randomPassword); - return true; + await unlockWallet(randomPassword) + return true } catch (err) { - if (err.message.indexOf("invalid passphrase") > -1) { - return true; + if (err.message.indexOf('invalid passphrase') > -1) { + return true } - return false; + return false } } - } catch(err) { - logger.error("LND error:", err); - return false; + } catch (err) { + logger.error('LND error:', err) + return false } - }; + } app.use((req, res, next) => { - res.setHeader("x-session-id", SESSION_ID) + res.setHeader('x-session-id', SESSION_ID) next() }) app.use((req, res, next) => { - const deviceId = req.headers["x-shockwallet-device-id"]; - logger.debug("Decrypting route...") + const deviceId = req.headers['x-shockwallet-device-id'] + logger.debug('Decrypting route...') try { - if (nonEncryptedRoutes.includes(req.path) || process.env.DISABLE_SHOCK_ENCRYPTION === "true") { - return next(); + if ( + nonEncryptedRoutes.includes(req.path) || + process.env.DISABLE_SHOCK_ENCRYPTION === 'true' + ) { + return next() } - + if (!deviceId) { const error = { - field: "deviceId", - message: "Please specify a device ID" - }; - logger.error("Please specify a device ID") - return res.status(401).json(error); + field: 'deviceId', + message: 'Please specify a device ID' + } + logger.error('Please specify a device ID') + return res.status(401).json(error) } if (!Encryption.isAuthorizedDevice({ deviceId })) { const error = { - field: "deviceId", - message: "Please specify a device ID" - }; - logger.error("Unknown Device") - return res.status(401).json(error); + field: 'deviceId', + message: 'Please specify a device ID' + } + logger.error('Unknown Device') + return res.status(401).json(error) } - if (req.method === "GET" || req.method === "DELETE" || !req.body.encryptionKey && !req.body.iv) { - return next(); + if ( + req.method === 'GET' || + req.method === 'DELETE' || + (!req.body.encryptionKey && !req.body.iv) + ) { + return next() } - const decryptedKey = Encryption.decryptKey({ deviceId, message: req.body.encryptionKey }); - const decryptedMessage = Encryption.decryptMessage({ message: req.body.data, key: decryptedKey, iv: req.body.iv }); - const decryptedToken = req.body.token ? Encryption.decryptMessage({ message: req.body.token, key: decryptedKey, iv: req.body.iv }) : null; - req.body = JSON.parse(decryptedMessage); + const decryptedKey = Encryption.decryptKey({ + deviceId, + message: req.body.encryptionKey + }) + const decryptedMessage = Encryption.decryptMessage({ + message: req.body.data, + key: decryptedKey, + iv: req.body.iv + }) + const decryptedToken = req.body.token + ? Encryption.decryptMessage({ + message: req.body.token, + key: decryptedKey, + iv: req.body.iv + }) + : null + req.body = JSON.parse(decryptedMessage) if (decryptedToken) { - req.headers.authorization = decryptedToken; + req.headers.authorization = decryptedToken } - return next(); + return next() } catch (err) { - logger.error(err); - return res - .status(401) - .json( - err - ); + logger.error(err) + return res.status(401).json(err) } }) @@ -293,8 +315,7 @@ module.exports = async ( } else { res.status(401).json({ field: 'authorization', - errorMessage: - "The authorization token you've supplied is invalid" + errorMessage: "The authorization token you've supplied is invalid" }) } } catch (err) { @@ -313,102 +334,98 @@ module.exports = async ( app.use(async (req, res, next) => { try { if (unprotectedRoutes[req.method][req.path]) { - next(); - return; + next() + return } - if (req.path.includes("/api/lnd")) { - const walletStatus = await walletExists(); - const availableService = await getAvailableService(); - const statusMessage = availableService.walletStatus; + if (req.path.includes('/api/lnd')) { + const walletStatus = await walletExists() + const availableService = await getAvailableService() + const statusMessage = availableService.walletStatus if (walletStatus) { - if (statusMessage === "unlocked") { - return next(); + if (statusMessage === 'unlocked') { + return next() } - return res - .status(401) - .json({ - field: "wallet", - errorMessage: statusMessage - ? statusMessage - : "unknown" - }) + return res.status(401).json({ + field: 'wallet', + errorMessage: statusMessage ? statusMessage : 'unknown' + }) } - return res - .status(401) - .json({ - field: "wallet", - errorMessage: "Please create a wallet before using the API" - }); + return res.status(401).json({ + field: 'wallet', + errorMessage: 'Please create a wallet before using the API' + }) } next() } catch (err) { - logger.error(err); - res - .status(500) - .json({ - field: "wallet", - errorMessage: err.message - ? err.message - : err - }); + logger.error(err) + res.status(500).json({ + field: 'wallet', + errorMessage: err.message ? err.message : err + }) } - }); + }) - app.use(lastSeenMiddleware); + app.use(lastSeenMiddleware) - app.use(["/ping"], responseTime()); + app.use(['/ping'], responseTime()) /** * health check */ - app.get("/health", async (req, res) => { - const health = await checkHealth(); - res.json(health); - }); + app.get('/health', async (req, res) => { + const health = await checkHealth() + res.json(health) + }) /** * kubernetes health check */ - app.get("/healthz", async (req, res) => { - const health = await checkHealth(); - logger.info("Healthz response:", health); - res.json(health); - }); + app.get('/healthz', async (req, res) => { + const health = await checkHealth() + logger.info('Healthz response:', health) + res.json(health) + }) - app.get("/ping", (req, res) => { - logger.info("Ping completed!"); - res.json({ message: "OK" }); - }); + app.get('/ping', (req, res) => { + logger.info('Ping completed!') + res.json({ message: 'OK' }) + }) - app.post("/api/mobile/error", (req, res) => { - logger.debug("Mobile error:", JSON.stringify(req.body)); - res.json({ msg: "OK" }); - }); + app.post('/api/mobile/error', (req, res) => { + logger.debug('Mobile error:', JSON.stringify(req.body)) + res.json({ msg: 'OK' }) + }) - app.post("/api/security/exchangeKeys", async (req, res) => { + app.post('/api/security/exchangeKeys', async (req, res) => { try { - const { publicKey, deviceId } = req.body; - + const { publicKey, deviceId } = req.body + if (!publicKey) { return res.status(400).json({ field: 'publicKey', - message: "Please provide a valid public key" + message: 'Please provide a valid public key' }) } - if (!deviceId || - !/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/iu - .test(deviceId)) { + if ( + !deviceId || + !/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/iu.test( + deviceId + ) + ) { return res.status(400).json({ field: 'deviceId', - message: "Please provide a valid device ID" + message: 'Please provide a valid device ID' }) } - - const authorizedDevice = await Encryption.authorizeDevice({ deviceId, publicKey }) + + const authorizedDevice = await Encryption.authorizeDevice({ + deviceId, + publicKey + }) logger.info(authorizedDevice) return res.json(authorizedDevice) } catch (err) { @@ -420,184 +437,201 @@ module.exports = async ( } }) - app.get("/api/lnd/wallet/status", async (req, res) => { + app.get('/api/lnd/wallet/status', async (req, res) => { try { - const walletStatus = await walletExists(); - const availableService = await getAvailableService(); - + const walletStatus = await walletExists() + const availableService = await getAvailableService() + res.json({ walletExists: walletStatus, walletStatus: walletStatus ? availableService.walletStatus : null }) } catch (err) { - logger.error(err); - const sanitizedMessage = sanitizeLNDError(err.message); + logger.error(err) + const sanitizedMessage = sanitizeLNDError(err.message) res.status(500).json({ - field: "LND", - errorMessage: sanitizedMessage ? sanitizedMessage : "An unknown error has occurred, please try restarting your LND and API servers" - }); + field: 'LND', + errorMessage: sanitizedMessage + ? sanitizedMessage + : 'An unknown error has occurred, please try restarting your LND and API servers' + }) } - }); + }) - app.post("/api/lnd/auth", async (req, res) => { + app.post('/api/lnd/auth', async (req, res) => { try { - const health = await checkHealth(); - const walletInitialized = await walletExists(); + const health = await checkHealth() + const walletInitialized = await walletExists() // If we're connected to lnd, unlock the wallet using the password supplied // and generate an auth token if that operation was successful. if (health.LNDStatus.success && walletInitialized) { - const { alias, password } = req.body; + const { alias, password } = req.body - await recreateLnServices(); + await recreateLnServices() if (GunDB.isAuthenticated()) { - GunDB.logoff(); + GunDB.logoff() } - const publicKey = await GunDB.authenticate(alias, password); - if (walletInitialized && health.LNDStatus.walletStatus === "locked" && publicKey) { - await unlockWallet(password); + const publicKey = await GunDB.authenticate(alias, password) + if ( + walletInitialized && + health.LNDStatus.walletStatus === 'locked' && + publicKey + ) { + await unlockWallet(password) } // Send an event to update lightning's status - mySocketsEvents.emit("updateLightning"); + 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; + const { lightning } = LightningServices.services lightning.exportAllChannelBackups({}, (err, channelBackups) => { if (err) { - return handleError(res, err); + return handleError(res, err) } - GunActions.saveChannelsBackup(JSON.stringify(channelBackups),user,SEA) - - }); - + GunActions.saveChannelsBackup( + JSON.stringify(channelBackups), + user, + SEA + ) + }) + //register to listen for channel backups - const onNewChannelBackup = () => { - logger.warn("Subscribing to channel backup ...") + 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('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...") + stream.on('end', () => { + logger.info('Channel backup stream ended, starting a new one...') // Prevents call stack overflow exceptions process.nextTick(onNewChannelBackup) }) - stream.on("error", err => { - logger.error("Channel backup stream error:", err); + stream.on('error', err => { + logger.error('Channel backup stream error:', err) }) - stream.on("status", status => { - logger.error("Channel backup stream status:", status); + stream.on('status', status => { + logger.error('Channel backup stream status:', status) if (status.code === 14) { // Prevents call stack overflow exceptions process.nextTick(onNewChannelBackup) - } }) } - onNewChannelBackup(); + onNewChannelBackup() // Generate auth token and send it as a JSON response - const token = await auth.generateToken(); + const token = await auth.generateToken() res.json({ authorization: token, user: { alias, publicKey } - }); + }) - return true; + return true } if (!walletInitialized) { res.status(500).json({ - field: "wallet", - errorMessage: "Please create a wallet before authenticating", + field: 'wallet', + errorMessage: 'Please create a wallet before authenticating', success: false - }); - return false; + }) + return false } - res.status(500); + res.status(500) res.json({ - field: "health", + field: 'health', errorMessage: sanitizeLNDError(health.LNDStatus.message), success: false - }); - return false; + }) + return false } catch (err) { - logger.error("Unlock Error:", err); - res.status(400); - res.json({ field: "user", errorMessage: err.message ? sanitizeLNDError(err.message) : err, success: false }); - return err; + logger.error('Unlock Error:', err) + res.status(400) + res.json({ + field: 'user', + errorMessage: err.message ? sanitizeLNDError(err.message) : err, + success: false + }) + return err } - }); + }) - app.post("/api/lnd/wallet", async (req, res) => { + app.post('/api/lnd/wallet', async (req, res) => { try { - const { walletUnlocker } = LightningServices.services; - const { password, alias } = req.body; - const healthResponse = await checkHealth(); + const { walletUnlocker } = LightningServices.services + const { password, alias } = req.body + const healthResponse = await checkHealth() if (!alias) { return res.status(400).json({ - field: "alias", - errorMessage: "Please specify an alias for your new wallet" - }); + field: 'alias', + errorMessage: 'Please specify an alias for your new wallet' + }) } - + if (!password) { return res.status(400).json({ - field: "password", - errorMessage: "Please specify a password for your new wallet" - }); + field: 'password', + errorMessage: 'Please specify a password for your new wallet' + }) } - + if (password.length < 8) { return res.status(400).json({ - field: "password", - errorMessage: "Please specify a password that's longer than 8 characters" - }); + field: 'password', + errorMessage: + "Please specify a password that's longer than 8 characters" + }) } - - if (healthResponse.LNDStatus.service !== "walletUnlocker") { + + if (healthResponse.LNDStatus.service !== 'walletUnlocker') { return res.status(400).json({ - field: "wallet", - errorMessage: "Wallet is already unlocked" - }); + field: 'wallet', + errorMessage: 'Wallet is already unlocked' + }) } - + walletUnlocker.genSeed({}, async (genSeedErr, genSeedResponse) => { try { if (genSeedErr) { - logger.debug("GenSeed Error:", genSeedErr); - - const healthResponse = await checkHealth(); + logger.debug('GenSeed Error:', genSeedErr) + + const healthResponse = await checkHealth() if (healthResponse.LNDStatus.success) { - const message = genSeedErr.details; - return res - .status(400) - .json({ field: "GenSeed", errorMessage: message, success: false }); + const message = genSeedErr.details + return res.status(400).json({ + field: 'GenSeed', + errorMessage: message, + success: false + }) } - - return res - .status(500) - .json({ field: "health", errorMessage: "LND is down", success: false }); + + return res.status(500).json({ + field: 'health', + errorMessage: 'LND is down', + success: false + }) } - - logger.debug("GenSeed:", genSeedResponse); - const mnemonicPhrase = genSeedResponse.cipher_seed_mnemonic; + + logger.debug('GenSeed:', genSeedResponse) + const mnemonicPhrase = genSeedResponse.cipher_seed_mnemonic const walletArgs = { - wallet_password: Buffer.from(password, "utf8"), + wallet_password: Buffer.from(password, 'utf8'), cipher_seed_mnemonic: mnemonicPhrase - }; - + } + // Register user before creating wallet - const publicKey = await GunDB.register(alias, password); + const publicKey = await GunDB.register(alias, password) await GunActions.saveSeedBackup( mnemonicPhrase, @@ -610,44 +644,44 @@ module.exports = async ( async (initWalletErr, initWalletResponse) => { try { if (initWalletErr) { - logger.error("initWallet Error:", initWalletErr.message); - const healthResponse = await checkHealth(); + logger.error('initWallet Error:', initWalletErr.message) + const healthResponse = await checkHealth() if (healthResponse.LNDStatus.success) { - const errorMessage = initWalletErr.details; - + const errorMessage = initWalletErr.details + return res.status(400).json({ - field: "initWallet", + field: 'initWallet', errorMessage, success: false - }); + }) } return res.status(500).json({ - field: "health", - errorMessage: "LND is down", + field: 'health', + errorMessage: 'LND is down', success: false - }); + }) } - logger.info("initWallet:", initWalletResponse); - + logger.info('initWallet:', initWalletResponse) + const waitUntilFileExists = seconds => { logger.info( `Waiting for admin.macaroon to be created. Seconds passed: ${seconds} Path: ${LightningServices.servicesConfig.macaroonPath}` - ); + ) setTimeout(async () => { try { const macaroonExists = await FS.access( LightningServices.servicesConfig.macaroonPath - ); + ) if (!macaroonExists) { - return waitUntilFileExists(seconds + 1); + return waitUntilFileExists(seconds + 1) } - - logger.info("admin.macaroon file created"); - - await LightningServices.init(); - const token = await auth.generateToken(); + logger.info('admin.macaroon file created') + + await LightningServices.init() + + const token = await auth.generateToken() return res.json({ mnemonicPhrase, authorization: token, @@ -655,98 +689,100 @@ module.exports = async ( alias, publicKey } - }); + }) } catch (err) { - logger.error(err); + logger.error(err) res.status(400).json({ - field: "unknown", + field: 'unknown', errorMessage: sanitizeLNDError(err.message) - }); + }) } - }, 1000); - }; - - waitUntilFileExists(1); + }, 1000) + } + + waitUntilFileExists(1) } catch (err) { - logger.error(err); + logger.error(err) return res.status(500).json({ - field: "unknown", + field: 'unknown', errorMessage: err }) } } - ); + ) } catch (err) { - logger.error(err); + logger.error(err) return res.status(500).json({ - field: "unknown", + field: 'unknown', errorMessage: err.message || err }) } - }); + }) } catch (err) { - logger.error(err); + logger.error(err) return res.status(500).json({ - field: "unknown", + field: 'unknown', errorMessage: err }) } - }); + }) - app.post("/api/lnd/wallet/existing", async (req, res) => { + app.post('/api/lnd/wallet/existing', async (req, res) => { try { - const { password, alias } = req.body; - const healthResponse = await checkHealth(); - const exists = await walletExists(); + const { password, alias } = req.body + const healthResponse = await checkHealth() + const exists = await walletExists() if (!exists) { return res.status(500).json({ - field: "wallet", - errorMessage: "LND wallet does not exist, please create a new one" - }); + field: 'wallet', + errorMessage: 'LND wallet does not exist, please create a new one' + }) } if (!alias) { return res.status(400).json({ - field: "alias", - errorMessage: "Please specify an alias for your wallet" - }); + field: 'alias', + errorMessage: 'Please specify an alias for your wallet' + }) } if (!password) { return res.status(400).json({ - field: "password", - errorMessage: "Please specify a password for your wallet alias" - }); + field: 'password', + errorMessage: 'Please specify a password for your wallet alias' + }) } if (password.length < 8) { return res.status(400).json({ - field: "password", - errorMessage: "Please specify a password that's longer than 8 characters" - }); + field: 'password', + errorMessage: + "Please specify a password that's longer than 8 characters" + }) } - if (healthResponse.LNDStatus.service !== "walletUnlocker") { + if (healthResponse.LNDStatus.service !== 'walletUnlocker') { return res.status(400).json({ - field: "wallet", - errorMessage: "Wallet is already unlocked. Please restart your LND instance and try again." - }); + field: 'wallet', + errorMessage: + 'Wallet is already unlocked. Please restart your LND instance and try again.' + }) } try { - await unlockWallet(password); - } catch(err) { + await unlockWallet(password) + } catch (err) { return res.status(401).json({ - field: "wallet", - errorMessage: "Invalid LND wallet password" - }); + field: 'wallet', + errorMessage: 'Invalid LND wallet password' + }) } // Register user after verifying wallet password - const publicKey = await GunDB.register(alias, password); + const publicKey = await GunDB.register(alias, password) // Generate Access Token - const token = await auth.generateToken(); + const token = await auth.generateToken() res.json({ authorization: token, @@ -757,255 +793,261 @@ module.exports = async ( }) } catch (err) { return res.status(500).json({ - errorMessage: err.message, + errorMessage: err.message }) } - }); + }) // get lnd info - app.get("/api/lnd/getinfo", (req, res) => { - const { lightning } = LightningServices.services; - + app.get('/api/lnd/getinfo', (req, res) => { + const { lightning } = LightningServices.services + lightning.getInfo({}, async (err, response) => { if (err) { - logger.error("GetInfo Error:", err); - const health = await checkHealth(); + logger.error('GetInfo Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "getInfo", + field: 'getInfo', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.info("GetInfo:", response); + logger.info('GetInfo:', response) if (!response.uris || response.uris.length === 0) { if (config.lndAddress) { - response.uris = [response.identity_pubkey + "@" + config.lndAddress]; + response.uris = [response.identity_pubkey + '@' + config.lndAddress] } } - res.json(response); - }); - }); + res.json(response) + }) + }) // get lnd node info - app.post("/api/lnd/getnodeinfo", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/getnodeinfo', (req, res) => { + const { lightning } = LightningServices.services lightning.getNodeInfo( { pub_key: req.body.pubkey }, async (err, response) => { if (err) { - logger.debug("GetNodeInfo Error:", err); - const health = await checkHealth(); + logger.debug('GetNodeInfo Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(400); + res.status(400) res.json({ - field: "getNodeInfo", + field: 'getNodeInfo', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("GetNodeInfo:", response); - res.json(response); + logger.debug('GetNodeInfo:', response) + res.json(response) } - ); - }); + ) + }) // get lnd chan info - app.post("/api/lnd/getchaninfo", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/getchaninfo', (req, res) => { + const { lightning } = LightningServices.services lightning.getChanInfo( { chan_id: req.body.chan_id }, async (err, response) => { if (err) { - logger.debug("GetChanInfo Error:", err); - const health = await checkHealth(); + logger.debug('GetChanInfo Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(400); + res.status(400) res.json({ - field: "getChanInfo", + field: 'getChanInfo', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("GetChanInfo:", response); - res.json(response); + logger.debug('GetChanInfo:', response) + res.json(response) } - ); - }); + ) + }) - app.get("/api/lnd/getnetworkinfo", (req, res) => { - const { lightning } = LightningServices.services; + app.get('/api/lnd/getnetworkinfo', (req, res) => { + const { lightning } = LightningServices.services lightning.getNetworkInfo({}, async (err, response) => { if (err) { - logger.debug("GetNetworkInfo Error:", err); - const health = await checkHealth(); + logger.debug('GetNetworkInfo Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "getNodeInfo", + field: 'getNodeInfo', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("GetNetworkInfo:", response); - res.json(response); - }); - }); + logger.debug('GetNetworkInfo:', response) + res.json(response) + }) + }) // get lnd node active channels list - app.get("/api/lnd/listpeers", (req, res) => { - const { lightning } = LightningServices.services; + app.get('/api/lnd/listpeers', (req, res) => { + const { lightning } = LightningServices.services lightning.listPeers({}, async (err, response) => { if (err) { - logger.debug("ListPeers Error:", err); - const health = await checkHealth(); + logger.debug('ListPeers Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "listPeers", + field: 'listPeers', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("ListPeers:", response); - res.json(response); - }); - }); + logger.debug('ListPeers:', response) + res.json(response) + }) + }) // newaddress - app.post("/api/lnd/newaddress", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/newaddress', (req, res) => { + const { lightning } = LightningServices.services lightning.newAddress({ type: req.body.type }, async (err, response) => { if (err) { - logger.debug("NewAddress Error:", err); - const health = await checkHealth(); + logger.debug('NewAddress Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "newAddress", + field: 'newAddress', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("NewAddress:", response); - res.json(response); - }); - }); + logger.debug('NewAddress:', response) + res.json(response) + }) + }) // connect peer to lnd node - app.post("/api/lnd/connectpeer", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/connectpeer', (req, res) => { + const { lightning } = LightningServices.services const connectRequest = { addr: { pubkey: req.body.pubkey, host: req.body.host }, perm: true - }; - logger.debug("ConnectPeer Request:", connectRequest); + } + logger.debug('ConnectPeer Request:', connectRequest) lightning.connectPeer(connectRequest, (err, response) => { if (err) { - logger.debug("ConnectPeer Error:", err); - res.status(500).json({ field: "connectPeer", errorMessage: sanitizeLNDError(err.message) }); + logger.debug('ConnectPeer Error:', err) + res.status(500).json({ + field: 'connectPeer', + errorMessage: sanitizeLNDError(err.message) + }) } else { - logger.debug("ConnectPeer:", response); - res.json(response); + logger.debug('ConnectPeer:', response) + res.json(response) } - }); - }); + }) + }) // disconnect peer from lnd node - app.post("/api/lnd/disconnectpeer", (req, res) => { - const { lightning } = LightningServices.services; - const disconnectRequest = { pub_key: req.body.pubkey }; - logger.debug("DisconnectPeer Request:", disconnectRequest); + app.post('/api/lnd/disconnectpeer', (req, res) => { + const { lightning } = LightningServices.services + const disconnectRequest = { pub_key: req.body.pubkey } + logger.debug('DisconnectPeer Request:', disconnectRequest) lightning.disconnectPeer(disconnectRequest, (err, response) => { if (err) { - logger.debug("DisconnectPeer Error:", err); - res.status(400).json({ field: "disconnectPeer", errorMessage: sanitizeLNDError(err.message) }); + logger.debug('DisconnectPeer Error:', err) + res.status(400).json({ + field: 'disconnectPeer', + errorMessage: sanitizeLNDError(err.message) + }) } else { - logger.debug("DisconnectPeer:", response); - res.json(response); + logger.debug('DisconnectPeer:', response) + res.json(response) } - }); - }); + }) + }) // get lnd node opened channels list - app.get("/api/lnd/listchannels", (req, res) => { - const { lightning } = LightningServices.services; + app.get('/api/lnd/listchannels', (req, res) => { + const { lightning } = LightningServices.services lightning.listChannels({}, async (err, response) => { if (err) { - logger.debug("ListChannels Error:", err); - const health = await checkHealth(); + logger.debug('ListChannels Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "listChannels", + field: 'listChannels', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("ListChannels:", response); - res.json(response); - }); - }); + logger.debug('ListChannels:', response) + res.json(response) + }) + }) // get lnd node pending channels list - app.get("/api/lnd/pendingchannels", (req, res) => { - const { lightning } = LightningServices.services; + app.get('/api/lnd/pendingchannels', (req, res) => { + const { lightning } = LightningServices.services lightning.pendingChannels({}, async (err, response) => { if (err) { - logger.debug("PendingChannels Error:", err); - const health = await checkHealth(); + logger.debug('PendingChannels Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "pendingChannels", + field: 'pendingChannels', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("PendingChannels:", response); - res.json(response); - }); - }); + logger.debug('PendingChannels:', response) + res.json(response) + }) + }) - app.get("/api/lnd/unifiedTrx", (req, res) => { - const { lightning } = LightningServices.services; - const { itemsPerPage, page, reversed = true } = req.query; - const offset = (page - 1) * itemsPerPage; + app.get('/api/lnd/unifiedTrx', (req, res) => { + const { lightning } = LightningServices.services + const { itemsPerPage, page, reversed = true } = req.query + const offset = (page - 1) * itemsPerPage lightning.listPayments({}, (err, { payments = [] } = {}) => { if (err) { - return handleError(res, err); + return handleError(res, err) } lightning.listInvoices( { reversed, index_offset: offset, num_max_invoices: itemsPerPage }, (err, { invoices, last_index_offset }) => { if (err) { - return handleError(res, err); + return handleError(res, err) } lightning.getTransactions({}, (err, { transactions = [] } = {}) => { if (err) { - return handleError(res, err); + return handleError(res, err) } res.json({ @@ -1025,51 +1067,57 @@ module.exports = async ( totalPages: Math.ceil(last_index_offset / itemsPerPage), totalItems: last_index_offset } - }); - }); + }) + }) } - ); - }); - }); + ) + }) + }) // get lnd node payments list - app.get("/api/lnd/listpayments", (req, res) => { - const { lightning } = LightningServices.services; - const { itemsPerPage, page, paginate = true } = req.query; - lightning.listPayments({ - include_incomplete: !!req.include_incomplete, - }, (err, { payments = [] } = {}) => { - if (err) { - logger.debug("ListPayments Error:", err); - handleError(res, err); - } else { - logger.debug("ListPayments:", payments); - if (paginate) { - res.json(getListPage({ entries: payments, itemsPerPage, page })); + app.get('/api/lnd/listpayments', (req, res) => { + const { lightning } = LightningServices.services + const { itemsPerPage, page, paginate = true } = req.query + lightning.listPayments( + { + include_incomplete: !!req.include_incomplete + }, + (err, { payments = [] } = {}) => { + if (err) { + logger.debug('ListPayments Error:', err) + handleError(res, err) } else { - res.json({ payments }); + logger.debug('ListPayments:', payments) + if (paginate) { + res.json(getListPage({ entries: payments, itemsPerPage, page })) + } else { + res.json({ payments }) + } } } - }); - }); + ) + }) // get lnd node invoices list - app.get("/api/lnd/listinvoices", (req, res) => { - const { lightning } = LightningServices.services; - const { page, itemsPerPage, reversed = true } = req.query; - const offset = (page - 1) * itemsPerPage; + app.get('/api/lnd/listinvoices', (req, res) => { + const { lightning } = LightningServices.services + const { page, itemsPerPage, reversed = true } = req.query + const offset = (page - 1) * itemsPerPage // const limit = page * itemsPerPage; lightning.listInvoices( { reversed, index_offset: offset, num_max_invoices: itemsPerPage }, async (err, { invoices, last_index_offset } = {}) => { if (err) { - logger.debug("ListInvoices Error:", err); - const health = await checkHealth(); + logger.debug('ListInvoices Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(400).json({ errorMessage: sanitizeLNDError(err.message), success: false }); + res.status(400).json({ + errorMessage: sanitizeLNDError(err.message), + success: false + }) } else { - res.status(500); - res.json({ errorMessage: health.LNDStatus.message, success: false }); + res.status(500) + res.json({ errorMessage: health.LNDStatus.message, success: false }) } } else { // logger.debug("ListInvoices:", response); @@ -1078,527 +1126,542 @@ module.exports = async ( page, totalPages: Math.ceil(last_index_offset / itemsPerPage), success: true - }); + }) } } - ); - }); + ) + }) // get lnd node forwarding history - app.get("/api/lnd/forwardinghistory", (req, res) => { - const { lightning } = LightningServices.services; + app.get('/api/lnd/forwardinghistory', (req, res) => { + const { lightning } = LightningServices.services lightning.forwardingHistory({}, async (err, response) => { if (err) { - logger.debug("ForwardingHistory Error:", err); - const health = await checkHealth(); + logger.debug('ForwardingHistory Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "forwardingHistory", + field: 'forwardingHistory', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("ForwardingHistory:", response); - res.json(response); - }); - }); + logger.debug('ForwardingHistory:', response) + res.json(response) + }) + }) // get the lnd node wallet balance - app.get("/api/lnd/walletbalance", (req, res) => { - const { lightning } = LightningServices.services; + app.get('/api/lnd/walletbalance', (req, res) => { + const { lightning } = LightningServices.services lightning.walletBalance({}, async (err, response) => { if (err) { - logger.debug("WalletBalance Error:", err); - const health = await checkHealth(); + logger.debug('WalletBalance Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "walletBalance", + field: 'walletBalance', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("WalletBalance:", response); - res.json(response); - }); - }); + logger.debug('WalletBalance:', response) + res.json(response) + }) + }) // get the lnd node wallet balance and channel balance - app.get("/api/lnd/balance", async (req, res) => { - const { lightning } = LightningServices.services; - const health = await checkHealth(); + app.get('/api/lnd/balance', async (req, res) => { + const { lightning } = LightningServices.services + const health = await checkHealth() lightning.walletBalance({}, (err, walletBalance) => { if (err) { - logger.debug("WalletBalance Error:", err); + logger.debug('WalletBalance Error:', err) if (health.LNDStatus.success) { res.status(400).json({ - field: "walletBalance", + field: 'walletBalance', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json(health.LNDStatus); + res.status(500) + res.json(health.LNDStatus) } - return err; + return err } lightning.channelBalance({}, (err, channelBalance) => { if (err) { - logger.debug("ChannelBalance Error:", err); + logger.debug('ChannelBalance Error:', err) if (health.LNDStatus.success) { res.status(400).json({ - field: "channelBalance", + field: 'channelBalance', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json(health.LNDStatus); + res.status(500) + res.json(health.LNDStatus) } - return err; + return err } - logger.debug("ChannelBalance:", channelBalance); + logger.debug('ChannelBalance:', channelBalance) res.json({ ...walletBalance, channel_balance: channelBalance.balance, pending_channel_balance: channelBalance.pending_open_balance - }); - }); - }); - }); + }) + }) + }) + }) - app.post("/api/lnd/decodePayReq", (req, res) => { - const { lightning } = LightningServices.services; - const { payReq } = req.body; + app.post('/api/lnd/decodePayReq', (req, res) => { + const { lightning } = LightningServices.services + const { payReq } = req.body lightning.decodePayReq({ pay_req: payReq }, async (err, paymentRequest) => { if (err) { - logger.debug("DecodePayReq Error:", err); - const health = await checkHealth(); + logger.debug('DecodePayReq Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(500).json({ + res.status(500).json({ errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500).json({ errorMessage: "LND is down" }); + res.status(500).json({ errorMessage: 'LND is down' }) } } else { - logger.info("DecodePayReq:", paymentRequest); + logger.info('DecodePayReq:', paymentRequest) res.json({ - decodedRequest: paymentRequest, - }); + decodedRequest: paymentRequest + }) } - }); - }); + }) + }) - app.get("/api/lnd/channelbalance", (req, res) => { - const { lightning } = LightningServices.services; + app.get('/api/lnd/channelbalance', (req, res) => { + const { lightning } = LightningServices.services lightning.channelBalance({}, async (err, response) => { if (err) { - logger.debug("ChannelBalance Error:", err); - const health = await checkHealth(); + logger.debug('ChannelBalance Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "channelBalance", + field: 'channelBalance', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("ChannelBalance:", response); - res.json(response); - }); - }); + logger.debug('ChannelBalance:', response) + res.json(response) + }) + }) // openchannel - app.post("/api/lnd/openchannel", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/openchannel', (req, res) => { + const { lightning } = LightningServices.services - const { pubkey, channelCapacity, channelPushAmount,satPerByte } = req.body; + const { pubkey, channelCapacity, channelPushAmount, satPerByte } = req.body const openChannelRequest = { node_pubkey: Buffer.from(pubkey, 'hex'), local_funding_amount: channelCapacity, push_sat: channelPushAmount === '' ? '0' : channelPushAmount, - sat_per_byte:satPerByte, - }; - logger.info("OpenChannelRequest", openChannelRequest); + sat_per_byte: satPerByte + } + logger.info('OpenChannelRequest', openChannelRequest) let finalEvent = null //Object to send to the socket, depends on final event from the stream - const openedChannel = lightning.openChannel(openChannelRequest); - openedChannel.on("data", response => { - logger.debug("OpenChannelRequest:", response); - if(res.headersSent){//if res was already sent - if(response.update === 'chan_open'){ - finalEvent = {status:'chan_open'} + const openedChannel = lightning.openChannel(openChannelRequest) + openedChannel.on('data', response => { + logger.debug('OpenChannelRequest:', response) + if (res.headersSent) { + //if res was already sent + if (response.update === 'chan_open') { + finalEvent = { status: 'chan_open' } } } else { - res.json(response); + res.json(response) } - - }); - openedChannel.on("error", async err => { - logger.info("OpenChannelRequest Error:", err); - if(res.headersSent){ - finalEvent = {error:err.details}//send error on socket if http has already finished + }) + openedChannel.on('error', async err => { + logger.info('OpenChannelRequest Error:', err) + if (res.headersSent) { + finalEvent = { error: err.details } //send error on socket if http has already finished } else { - const health = await checkHealth(); + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(500).json({ field: "openChannelRequest", errorMessage: sanitizeLNDError(err.details) }); + res.status(500).json({ + field: 'openChannelRequest', + errorMessage: sanitizeLNDError(err.details) + }) } else if (!res.headersSent) { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - }); - openedChannel.on('end',()=> { - if(finalEvent !== null){//send the last event got from the stream + }) + openedChannel.on('end', () => { + if (finalEvent !== null) { + //send the last event got from the stream //TO DO send finalEvent on socket } }) - }); + }) // closechannel - app.post("/api/lnd/closechannel", (req, res) => { - const { lightning } = LightningServices.services; - const { channelPoint, outputIndex, force,satPerByte } = req.body; + app.post('/api/lnd/closechannel', (req, res) => { + const { lightning } = LightningServices.services + const { channelPoint, outputIndex, force, satPerByte } = req.body const closeChannelRequest = { channel_point: { - funding_txid_bytes: Buffer.from(channelPoint, "hex"), + funding_txid_bytes: Buffer.from(channelPoint, 'hex'), funding_txid_str: channelPoint, output_index: outputIndex, - sat_per_byte:satPerByte, + sat_per_byte: satPerByte }, force - }; - logger.info("CloseChannelRequest", closeChannelRequest); - const closedChannel = lightning.closeChannel(closeChannelRequest); + } + logger.info('CloseChannelRequest', closeChannelRequest) + const closedChannel = lightning.closeChannel(closeChannelRequest) - closedChannel.on('data', (response) => { + closedChannel.on('data', response => { if (!res.headersSent) { - logger.info("CloseChannelRequest:", response); - res.json(response); + logger.info('CloseChannelRequest:', response) + res.json(response) } }) - closedChannel.on('error', async (err) => { - logger.error("CloseChannelRequest Error:", err); - const health = await checkHealth(); + closedChannel.on('error', async err => { + logger.error('CloseChannelRequest Error:', err) + const health = await checkHealth() if (!res.headersSent) { if (health.LNDStatus.success) { - logger.debug("CloseChannelRequest Error:", err); + logger.debug('CloseChannelRequest Error:', err) res.status(400).json({ - field: "closeChannel", + field: 'closeChannel', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - }); - }); + }) + }) // sendpayment - app.post("/api/lnd/sendpayment", (req, res) => { - const { router } = LightningServices.services; + app.post('/api/lnd/sendpayment', (req, res) => { + const { router } = LightningServices.services // this is the recommended value from lightning labs - const { maxParts = 3, payreq } = req.body; + const { maxParts = 3, payreq } = req.body - const paymentRequest = { - payment_request: payreq, + const paymentRequest = { + payment_request: payreq, max_parts: maxParts, - timeout_seconds:5 - }; - - if (req.body.amt) { - paymentRequest.amt = req.body.amt; + timeout_seconds: 5 } - logger.info("Sending payment", paymentRequest); - const sentPayment = router.sendPaymentV2(paymentRequest); + if (req.body.amt) { + paymentRequest.amt = req.body.amt + } + + logger.info('Sending payment', paymentRequest) + const sentPayment = router.sendPaymentV2(paymentRequest) let finalEvent = null //Object to send to the socket, depends on final event from the stream - sentPayment.on("data", response => { - if(res.headersSent){//if res was already sent - if(response.failure_reason !== 'FAILURE_REASON_NONE'){//if the operation failed - finalEvent = {error:response.failure_reason} + sentPayment.on('data', response => { + if (res.headersSent) { + //if res was already sent + if (response.failure_reason !== 'FAILURE_REASON_NONE') { + //if the operation failed + finalEvent = { error: response.failure_reason } } else { - finalEvent = {status:response.status} + finalEvent = { status: response.status } } } else { if (response.failure_reason !== 'FAILURE_REASON_NONE') { - logger.error("SendPayment Info:", response) + logger.error('SendPayment Info:', response) return res.status(500).json({ errorMessage: response.failure_reason - }); - } - logger.info("SendPayment Data:", response); - return res.json(response); + }) + } + logger.info('SendPayment Data:', response) + return res.json(response) } - }); + }) - sentPayment.on("status", status => { - logger.info("SendPayment Status:", status); - }); + sentPayment.on('status', status => { + logger.info('SendPayment Status:', status) + }) - sentPayment.on("error", async err => { - logger.error("SendPayment Error:", err); - if(res.headersSent){ - finalEvent = {error:err.details}//send error on socket if http has already finished + sentPayment.on('error', async err => { + logger.error('SendPayment Error:', err) + if (res.headersSent) { + finalEvent = { error: err.details } //send error on socket if http has already finished } else { - const health = await checkHealth(); + const health = await checkHealth() if (health.LNDStatus.success) { res.status(500).json({ errorMessage: sanitizeLNDError(err.details) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - }); - sentPayment.on('end',()=>{ - if(finalEvent !== null){//send the last event got from the stream + }) + sentPayment.on('end', () => { + if (finalEvent !== null) { + //send the last event got from the stream //TO DO send finalEvent on socket } }) - }); + }) - app.post("/api/lnd/trackpayment", (req, res) => { - const { router } = LightningServices.services; - const { paymentHash, inflightUpdates = true } = req.body; + app.post('/api/lnd/trackpayment', (req, res) => { + const { router } = LightningServices.services + const { paymentHash, inflightUpdates = true } = req.body - logger.info("Tracking payment payment", { paymentHash, inflightUpdates }); + logger.info('Tracking payment payment', { paymentHash, inflightUpdates }) const trackedPayment = router.trackPaymentV2({ payment_hash: paymentHash, no_inflight_updates: !inflightUpdates - }); + }) // only emits one event - trackedPayment.on("data", response => { + trackedPayment.on('data', response => { if (response.payment_error) { - logger.error("TrackPayment Info:", response) + logger.error('TrackPayment Info:', response) return res.status(500).json({ errorMessage: response.payment_error - }); + }) } - - logger.info("TrackPayment Data:", response); - return res.json(response); - }); - trackedPayment.on("status", status => { - logger.info("TrackPayment Status:", status); - }); + logger.info('TrackPayment Data:', response) + return res.json(response) + }) - trackedPayment.on("error", async err => { - logger.error("TrackPayment Error:", err); - const health = await checkHealth(); + trackedPayment.on('status', status => { + logger.info('TrackPayment Status:', status) + }) + + trackedPayment.on('error', async err => { + logger.error('TrackPayment Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(500).json({ errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } - }); - }); + }) + }) - app.post("/api/lnd/sendtoroute", (req, res) => { - const { router } = LightningServices.services; - const { paymentHash, route } = req.body; + app.post('/api/lnd/sendtoroute', (req, res) => { + const { router } = LightningServices.services + const { paymentHash, route } = req.body router.sendToRoute({ payment_hash: paymentHash, route }, (err, data) => { if (err) { - logger.error("SendToRoute Error:", err); - return res.status(400).json(err); + logger.error('SendToRoute Error:', err) + return res.status(400).json(err) } - return res.json(data); - }); - }); + return res.json(data) + }) + }) - app.post("/api/lnd/estimateroutefee", (req, res) => { - const { router } = LightningServices.services; - const { dest, amount } = req.body; + app.post('/api/lnd/estimateroutefee', (req, res) => { + const { router } = LightningServices.services + const { dest, amount } = req.body router.estimateRouteFee({ dest, amt_sat: amount }, (err, data) => { if (err) { - logger.error("EstimateRouteFee Error:", err); - return res.status(400).json(err); + logger.error('EstimateRouteFee Error:', err) + return res.status(400).json(err) } - return res.json(data); - }); - }); + return res.json(data) + }) + }) // addinvoice - app.post("/api/lnd/addinvoice", (req, res) => { - const { lightning } = LightningServices.services; - const invoiceRequest = { memo: req.body.memo, private: true }; + app.post('/api/lnd/addinvoice', (req, res) => { + const { lightning } = LightningServices.services + const invoiceRequest = { memo: req.body.memo, private: true } if (req.body.value) { - invoiceRequest.value = req.body.value; + invoiceRequest.value = req.body.value } if (req.body.expiry) { - invoiceRequest.expiry = req.body.expiry; + invoiceRequest.expiry = req.body.expiry } lightning.addInvoice(invoiceRequest, async (err, newInvoice) => { if (err) { - logger.debug("AddInvoice Error:", err); - const health = await checkHealth(); + logger.debug('AddInvoice Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "addInvoice", + field: 'addInvoice', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } - return err; + return err } - logger.debug("AddInvoice:", newInvoice); + logger.debug('AddInvoice:', newInvoice) if (req.body.value) { - logger.debug("AddInvoice liquidity check:"); - lightning.listChannels({active_only:true}, async (err, response) => { + logger.debug('AddInvoice liquidity check:') + lightning.listChannels({ active_only: true }, async (err, response) => { if (err) { - logger.debug("ListChannels Error:", err); - const health = await checkHealth(); + logger.debug('ListChannels Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "listChannels", + field: 'listChannels', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("ListChannels:", response); + logger.debug('ListChannels:', response) const channelsList = response.channels let remoteBalance = Big(0) - channelsList.forEach(element=>{ + channelsList.forEach(element => { const remB = Big(element.remote_balance) - if(remB.gt(remoteBalance)){ + if (remB.gt(remoteBalance)) { remoteBalance = remB } }) newInvoice.liquidityCheck = remoteBalance > req.body.value - //newInvoice.remoteBalance = remoteBalance - res.json(newInvoice); - }); + //newInvoice.remoteBalance = remoteBalance + res.json(newInvoice) + }) } else { - res.json(newInvoice); + res.json(newInvoice) } - - }); - }); + }) + }) // signmessage - app.post("/api/lnd/signmessage", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/signmessage', (req, res) => { + const { lightning } = LightningServices.services lightning.signMessage( - { msg: Buffer.from(req.body.msg, "utf8") }, + { msg: Buffer.from(req.body.msg, 'utf8') }, async (err, response) => { if (err) { - logger.debug("SignMessage Error:", err); - const health = await checkHealth(); + logger.debug('SignMessage Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(400).json({ field: "signMessage", errorMessage: sanitizeLNDError(err.message) }); + res.status(400).json({ + field: 'signMessage', + errorMessage: sanitizeLNDError(err.message) + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("SignMessage:", response); - res.json(response); + logger.debug('SignMessage:', response) + res.json(response) } - ); - }); + ) + }) // verifymessage - app.post("/api/lnd/verifymessage", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/verifymessage', (req, res) => { + const { lightning } = LightningServices.services lightning.verifyMessage( - { msg: Buffer.from(req.body.msg, "utf8"), signature: req.body.signature }, + { msg: Buffer.from(req.body.msg, 'utf8'), signature: req.body.signature }, async (err, response) => { if (err) { - logger.debug("VerifyMessage Error:", err); - const health = await checkHealth(); + logger.debug('VerifyMessage Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(400).json({ field: "verifyMessage", errorMessage: sanitizeLNDError(err.message) }); + res.status(400).json({ + field: 'verifyMessage', + errorMessage: sanitizeLNDError(err.message) + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("VerifyMessage:", response); - res.json(response); + logger.debug('VerifyMessage:', response) + res.json(response) } - ); - }); + ) + }) // sendcoins - app.post("/api/lnd/sendcoins", (req, res) => { - const { lightning } = LightningServices.services; - const sendCoinsRequest = { - addr: req.body.addr, + app.post('/api/lnd/sendcoins', (req, res) => { + const { lightning } = LightningServices.services + const sendCoinsRequest = { + addr: req.body.addr, amount: req.body.amount, - sat_per_byte:req.body.satPerByte - }; - logger.debug("SendCoins", sendCoinsRequest); + sat_per_byte: req.body.satPerByte + } + logger.debug('SendCoins', sendCoinsRequest) lightning.sendCoins(sendCoinsRequest, async (err, response) => { if (err) { - logger.debug("SendCoins Error:", err); - const health = await checkHealth(); + logger.debug('SendCoins Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ - field: "sendCoins", + field: 'sendCoins', errorMessage: sanitizeLNDError(err.message) - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("SendCoins:", response); - res.json(response); - }); - }); + logger.debug('SendCoins:', response) + res.json(response) + }) + }) // queryroute - app.post("/api/lnd/queryroute", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/queryroute', (req, res) => { + const { lightning } = LightningServices.services const numRoutes = - config.maxNumRoutesToQuery || DEFAULT_MAX_NUM_ROUTES_TO_QUERY; + config.maxNumRoutesToQuery || DEFAULT_MAX_NUM_ROUTES_TO_QUERY lightning.queryRoutes( { pub_key: req.body.pubkey, amt: req.body.amt, num_routes: numRoutes }, async (err, response) => { if (err) { - logger.debug("QueryRoute Error:", err); - const health = await checkHealth(); + logger.debug('QueryRoute Error:', err) + const health = await checkHealth() if (health.LNDStatus.success) { - res.status(400).json({ field: "queryRoute", errorMessage: sanitizeLNDError(err.message) }); + res.status(400).json({ + field: 'queryRoute', + errorMessage: sanitizeLNDError(err.message) + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } - logger.debug("QueryRoute:", response); - res.json(response); + logger.debug('QueryRoute:', response) + res.json(response) } - ); - }); + ) + }) - app.post("/api/lnd/estimatefee", (req, res) => { - const { lightning } = LightningServices.services; - const { amount, confirmationBlocks } = req.body; + app.post('/api/lnd/estimatefee', (req, res) => { + const { lightning } = LightningServices.services + const { amount, confirmationBlocks } = req.body lightning.estimateFee( { AddrToAmount: { @@ -1608,26 +1671,26 @@ module.exports = async ( }, async (err, fee) => { if (err) { - const health = await checkHealth(); + const health = await checkHealth() if (health.LNDStatus.success) { res.status(400).json({ error: err.message - }); + }) } else { - res.status(500); - res.json({ errorMessage: "LND is down" }); + res.status(500) + res.json({ errorMessage: 'LND is down' }) } } else { - logger.debug("EstimateFee:", fee); - res.json(fee); + logger.debug('EstimateFee:', fee) + res.json(fee) } } - ); - }); + ) + }) - app.post("/api/lnd/listunspent", (req, res) => { - const { lightning } = LightningServices.services; - const { minConfirmations = 3, maxConfirmations = 6 } = req.body; + app.post('/api/lnd/listunspent', (req, res) => { + const { lightning } = LightningServices.services + const { minConfirmations = 3, maxConfirmations = 6 } = req.body lightning.listUnspent( { min_confs: minConfirmations, @@ -1635,121 +1698,124 @@ module.exports = async ( }, (err, unspent) => { if (err) { - return handleError(res, err); + return handleError(res, err) } - logger.debug("ListUnspent:", unspent); - res.json(unspent); + logger.debug('ListUnspent:', unspent) + res.json(unspent) } - ); - }); + ) + }) - app.get("/api/lnd/transactions", (req, res) => { - const { lightning } = LightningServices.services; - const { page, paginate = true, itemsPerPage } = req.query; + app.get('/api/lnd/transactions', (req, res) => { + const { lightning } = LightningServices.services + const { page, paginate = true, itemsPerPage } = req.query lightning.getTransactions({}, (err, { transactions = [] } = {}) => { if (err) { - return handleError(res, err); + return handleError(res, err) } - logger.debug("Transactions:", transactions); + logger.debug('Transactions:', transactions) if (paginate) { - res.json(getListPage({ entries: transactions, itemsPerPage, page })); + res.json(getListPage({ entries: transactions, itemsPerPage, page })) } else { - res.json({ transactions }); + res.json({ transactions }) } - }); - }); + }) + }) - app.post("/api/lnd/sendmany", (req, res) => { - const { lightning } = LightningServices.services; - const { addresses,satPerByte } = req.body; - lightning.sendMany({ AddrToAmount: addresses,sat_per_byte:satPerByte }, (err, transactions) => { - if (err) { - return handleError(res, err); + app.post('/api/lnd/sendmany', (req, res) => { + const { lightning } = LightningServices.services + const { addresses, satPerByte } = req.body + lightning.sendMany( + { AddrToAmount: addresses, sat_per_byte: satPerByte }, + (err, transactions) => { + if (err) { + return handleError(res, err) + } + logger.debug('Transactions:', transactions) + res.json(transactions) } - logger.debug("Transactions:", transactions); - res.json(transactions); - }); - }); + ) + }) - app.get("/api/lnd/closedchannels", (req, res) => { - const { lightning } = LightningServices.services; - const { closeTypeFilters = [] } = req.query; + app.get('/api/lnd/closedchannels', (req, res) => { + const { lightning } = LightningServices.services + const { closeTypeFilters = [] } = req.query const lndFilters = closeTypeFilters.reduce( (filters, filter) => ({ ...filters, [filter]: true }), {} - ); + ) lightning.closedChannels(lndFilters, (err, channels) => { if (err) { - return handleError(res, err); + return handleError(res, err) } - logger.debug("Channels:", channels); - res.json(channels); - }); - }); + logger.debug('Channels:', channels) + res.json(channels) + }) + }) - app.post("/api/lnd/exportchanbackup", (req, res) => { - const { lightning } = LightningServices.services; - const { channelPoint } = req.body; + app.post('/api/lnd/exportchanbackup', (req, res) => { + const { lightning } = LightningServices.services + const { channelPoint } = req.body lightning.exportChannelBackup( { chan_point: { funding_txid_str: channelPoint } }, (err, backup) => { if (err) { - return handleError(res, err); + return handleError(res, err) } - logger.debug("ExportChannelBackup:", backup); - res.json(backup); + logger.debug('ExportChannelBackup:', backup) + res.json(backup) } - ); - }); + ) + }) - app.post("/api/lnd/exportallchanbackups", (req, res) => { - const { lightning } = LightningServices.services; + app.post('/api/lnd/exportallchanbackups', (req, res) => { + const { lightning } = LightningServices.services lightning.exportAllChannelBackups({}, (err, channelBackups) => { if (err) { - return handleError(res, err); + return handleError(res, err) } - logger.debug("ExportAllChannelBackups:", channelBackups); - res.json(channelBackups); - }); - }); - + logger.debug('ExportAllChannelBackups:', channelBackups) + res.json(channelBackups) + }) + }) + const GunEvent = Common.Constants.Event const Key = require('../services/gunDB/contact-api/key') - app.get("/api/gun/lndchanbackups", async (req,res) => { - try{ + 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) + const backup = await SEA.decrypt(encBackup, mySecret) logger.info(backup) - res.json({data:backup}) + res.json({ data: backup }) } catch (err) { - res.json({ok:"err"}) + res.json({ ok: 'err' }) } }) - app.get("/api/gun/feedpoc", async (req,res) =>{ - try{ - logger.warn("FEED POC") + app.get('/api/gun/feedpoc', async (req, res) => { + try { + logger.warn('FEED POC') const user = require('../services/gunDB/Mediator').getUser() - const feedObj = await timeout5(user.get("FEED_POC").then()) + const feedObj = await timeout5(user.get('FEED_POC').then()) logger.warn(feedObj) - - res.json({data:feedObj}) + + res.json({ data: feedObj }) } catch (err) { //res.json({ok:"err"}) } }) const Events = require('../services/gunDB/contact-api/events') - + app.get(`/api/gun/${GunEvent.ON_CHATS}`, (_, res) => { try { - const data = Events.getChats() + const data = Events.getChats() logger.info(`Chats polled: ${data.length}`) res.json({ - data, + data }) } catch (err) { logger.info('Error in Chats poll:') @@ -1763,7 +1829,12 @@ module.exports = async ( app.get(`/api/gun/${GunEvent.ON_AVATAR}`, async (_, res) => { try { const user = require('../services/gunDB/Mediator').getUser() - const data = await timeout5(user.get(Key.PROFILE).get(Key.AVATAR).then()) + const data = await timeout5( + user + .get(Key.PROFILE) + .get(Key.AVATAR) + .then() + ) logger.info(`avatar poll:${(data || '').length} chars`) res.json({ data @@ -1780,7 +1851,12 @@ module.exports = async ( app.get(`/api/gun/${GunEvent.ON_DISPLAY_NAME}`, async (_, res) => { try { const user = require('../services/gunDB/Mediator').getUser() - const data = await timeout5(user.get(Key.PROFILE).get(Key.DISPLAY_NAME).then()) + const data = await timeout5( + user + .get(Key.PROFILE) + .get(Key.DISPLAY_NAME) + .then() + ) logger.info(`display name poll:${data}`) res.json({ data @@ -1797,7 +1873,9 @@ module.exports = async ( app.get(`/api/gun/${GunEvent.ON_HANDSHAKE_ADDRESS}`, async (_, res) => { try { const user = require('../services/gunDB/Mediator').getUser() - const data = await timeout5(user.get(Key.CURRENT_HANDSHAKE_ADDRESS).then()) + const data = await timeout5( + user.get(Key.CURRENT_HANDSHAKE_ADDRESS).then() + ) logger.info(`handshake address poll:${data}`) res.json({ data @@ -1827,12 +1905,12 @@ module.exports = async ( }) } }) -//////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////// app.get(`/api/gun/wall/:publicKey?`, async (req, res) => { try { - const { page } = req.query; - const {publicKey} = req.params + const { page } = req.query + const { publicKey } = req.params const pageNum = Number(page) @@ -1855,7 +1933,7 @@ module.exports = async ( return res.status(200).json({ ...fetchedPage, - totalPages, + totalPages }) } catch (err) { return res.status(500).json({ @@ -1864,44 +1942,42 @@ module.exports = async ( } }) - app.post(`/api/gun/wall/`, async (req,res) => { - try{ - const {tags,title,contentItems} = req.body - return res.status(200).json(await GunActions.createPost( - tags, - title, - contentItems - )) - } catch(e) { + app.post(`/api/gun/wall/`, async (req, res) => { + try { + const { tags, title, contentItems } = req.body + return res + .status(200) + .json(await GunActions.createPost(tags, title, contentItems)) + } catch (e) { return res.status(500).json({ - errorMessage: (typeof e === 'string' ? e : e.message) - || 'Unknown error.' + errorMessage: + (typeof e === 'string' ? e : e.message) || 'Unknown error.' }) } }) - app.delete(`/api/gun/wall/:postID`, (_, res) => res.status(200).json({ - ok: 'true' - })) + app.delete(`/api/gun/wall/:postID`, (_, res) => + res.status(200).json({ + ok: 'true' + }) + ) ///////////////////////////////// /** * @template P * @typedef {import('express-serve-static-core').RequestHandler

} RequestHandler */ - - const ap = /** @type {Application} */ (app); + const ap = /** @type {Application} */ (app) /** * @typedef {object} FollowsRouteParams * @prop {(string|undefined)=} publicKey */ - /** * @type {RequestHandler} */ - const apiGunFollowsGet = async (_, res) => { + const apiGunFollowsGet = async (_, res) => { try { const currFollows = await GunGetters.Follows.currentFollows() @@ -1912,14 +1988,13 @@ module.exports = async ( }) } } - - + /** * @type {RequestHandler} */ const apiGunFollowsPut = async (req, res) => { try { - const { publicKey } = req.params; + const { publicKey } = req.params if (!publicKey) { throw new Error(`Missing publicKey route param.`) } @@ -1938,11 +2013,11 @@ module.exports = async ( } /** - * @type {RequestHandler} - */ + * @type {RequestHandler} + */ const apiGunFollowsDelete = async (req, res) => { try { - const { publicKey } = req.params; + const { publicKey } = req.params if (!publicKey) { throw new Error(`Missing publicKey route param.`) } @@ -1961,15 +2036,15 @@ module.exports = async ( ap.get('/api/gun/follows/', apiGunFollowsGet) ap.get('/api/gun/follows/:publicKey', apiGunFollowsGet) - ap.put(`/api/gun/follows/:publicKey`,apiGunFollowsPut) + ap.put(`/api/gun/follows/:publicKey`, apiGunFollowsPut) ap.delete(`/api/gun/follows/:publicKey`, apiGunFollowsDelete) /** - * @type {RequestHandler<{}>} - */ - const apiGunFeedGet = async (req, res) => { + * @type {RequestHandler<{}>} + */ + const apiGunFeedGet = async (req, res) => { try { - const { page: pageStr } = req.query; + const { page: pageStr } = req.query const page = Number(pageStr) if (!isARealUsableNumber(page)) { @@ -1998,7 +2073,7 @@ module.exports = async ( ap.get(`/api/gun/feed`, apiGunFeedGet) - /** + /** * @type {RequestHandler<{}>} */ const apiGunMeGet = async (_, res) => { @@ -2012,7 +2087,6 @@ module.exports = async ( } } - /** * @type {RequestHandler<{}>} */ @@ -2023,27 +2097,41 @@ module.exports = async ( * @typedef {UserWithoutPK & HasHandshakeAddress} MePutBody */ try { - const { avatar, bio , displayName, handshakeAddress } = /** @type {Partial} */ (req.body) + const { + avatar, + bio, + displayName, + handshakeAddress + } = /** @type {Partial} */ (req.body) - if (avatar) { - await GunActions.setAvatar(avatar, require('../services/gunDB/Mediator').getUser()) - } + if (avatar) { + await GunActions.setAvatar( + avatar, + require('../services/gunDB/Mediator').getUser() + ) + } - if (bio) { - await GunActions.setBio(bio, require('../services/gunDB/Mediator').getUser()) - } + if (bio) { + await GunActions.setBio( + bio, + require('../services/gunDB/Mediator').getUser() + ) + } - if (displayName) { - await GunActions.setDisplayName(displayName, require('../services/gunDB/Mediator').getUser()) - } + if (displayName) { + await GunActions.setDisplayName( + displayName, + require('../services/gunDB/Mediator').getUser() + ) + } - if (handshakeAddress) { - await GunActions.generateHandshakeAddress(); - } + if (handshakeAddress) { + await GunActions.generateHandshakeAddress() + } - return res.status(200).json({ - ok: true - }) + return res.status(200).json({ + ok: true + }) } catch (err) { logger.error(err) return res.status(500).json({ @@ -2077,9 +2165,9 @@ module.exports = async ( const user = GunDB.getUser() const SEA = GunDB.mySEA - return res.status(200).json( - await GunActions.sendMessageNew(publicKey,body, user, SEA) - ) + return res + .status(200) + .json(await GunActions.sendMessageNew(publicKey, body, user, SEA)) } catch (err) { logger.error(err) return res.status(500).json({ @@ -2125,11 +2213,11 @@ module.exports = async ( /** * @type {RequestHandler<{}>} */ - const apiGunRequestsReceivedGet = (_, res) => { + const apiGunRequestsReceivedGet = (_, res) => { try { const data = Events.getCurrentReceivedReqs() res.json({ - data, + data }) } catch (err) { logger.error(err) @@ -2146,7 +2234,7 @@ module.exports = async ( try { const data = Events.getCurrentSentReqs() res.json({ - data, + data }) } catch (err) { logger.error(err) @@ -2166,7 +2254,10 @@ module.exports = async ( * @type {RequestHandler<{}>} */ const apiGunRequestsPost = async (req, res) => { - const { initialMsg, publicKey } = /** @type {RequestsRoutePOSTBody} */(req.body) + const { + initialMsg, + publicKey + } = /** @type {RequestsRoutePOSTBody} */ (req.body) if (!publicKey) { return res.status(400).json({ @@ -2180,7 +2271,13 @@ module.exports = async ( const SEA = require('../services/gunDB/Mediator').mySEA if (initialMsg) { - await GunActions.sendHRWithInitialMsg(initialMsg, publicKey, gun, user, SEA) + await GunActions.sendHRWithInitialMsg( + initialMsg, + publicKey, + gun, + user, + SEA + ) } else { await GunActions.sendHandshakeRequest(publicKey, gun, user, SEA) } @@ -2189,7 +2286,7 @@ module.exports = async ( ok: true }) } catch (err) { - logger.error(err); + logger.error(err) return res.status(500).json({ errorMessage: err.message }) @@ -2206,7 +2303,7 @@ module.exports = async ( */ const apiGunRequestsPut = async (req, res) => { const { requestID } = req.params - const { accept } = /** @type {RequestsRoutePUTBody} */(req.body) + const { accept } = /** @type {RequestsRoutePUTBody} */ (req.body) if (!requestID) { return res.status(400).json({ @@ -2231,7 +2328,7 @@ module.exports = async ( ok: true }) } catch (err) { - logger.error(err); + logger.error(err) return res.status(500).json({ errorMessage: err.message }) @@ -2245,28 +2342,30 @@ module.exports = async ( ap.post('/api/gun/requests/', apiGunRequestsPost) ap.put(`/api/gun/requests/:requestID?`, apiGunRequestsPut) - - ap.get(`/api/gun/dev/userToIncoming`, async (_, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((_, u) => new Promise(res => { - u.get(GunKey.USER_TO_INCOMING).load(data => { - res(data) - }) - }), v => { - if (typeof v !== 'object') { - return true + const data = await tryAndWait( + (_, u) => + new Promise(res => { + u.get(GunKey.USER_TO_INCOMING).load(data => { + res(data) + }) + }), + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - }) + ) return res.status(200).json({ data @@ -2280,24 +2379,28 @@ module.exports = async ( ap.get(`/api/gun/dev/recipientToOutgoing`, async (_, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((_, u) => new Promise(res => { - u.get(GunKey.RECIPIENT_TO_OUTGOING).load(data => { - res(data) - }) - }), v => { - if (typeof v !== 'object') { - return true + const data = await tryAndWait( + (_, u) => + new Promise(res => { + u.get(GunKey.RECIPIENT_TO_OUTGOING).load(data => { + res(data) + }) + }), + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - }) + ) return res.status(200).json({ data @@ -2311,24 +2414,28 @@ module.exports = async ( ap.get(`/api/gun/dev/outgoings`, async (_, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((_, u) => new Promise(res => { - u.get(GunKey.OUTGOINGS).load(data => { - res(data) - }) - }), v => { - if (typeof v !== 'object') { - return true + const data = await tryAndWait( + (_, u) => + new Promise(res => { + u.get(GunKey.OUTGOINGS).load(data => { + res(data) + }) + }), + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - }) + ) return res.status(200).json({ data @@ -2340,12 +2447,13 @@ module.exports = async ( } }) - ap.get(`/api/gun/dev/currentHandshakeAddress`, async (_, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((_, u) => u.get(GunKey.CURRENT_HANDSHAKE_ADDRESS).then()) + const data = await tryAndWait((_, u) => + u.get(GunKey.CURRENT_HANDSHAKE_ADDRESS).then() + ) return res.status(200).json({ data @@ -2359,26 +2467,30 @@ module.exports = async ( ap.get(`/api/gun/dev/handshakeNodes/:handshakeAddress`, async (req, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((g) => - new Promise((res) => { - g.get(GunKey.HANDSHAKE_NODES).get(req.params.handshakeAddress).load(data => { - res(data) - }) - }) - , v => { - if (typeof v !== 'object') { - return true + const data = await tryAndWait( + g => + new Promise(res => { + g.get(GunKey.HANDSHAKE_NODES) + .get(req.params.handshakeAddress) + .load(data => { + res(data) + }) + }), + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - }) + ) return res.status(200).json({ data @@ -2392,26 +2504,28 @@ module.exports = async ( ap.get(`/api/gun/dev/user/:publicKey`, async (req, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((g) => - new Promise((res) => { - g.user(req.params.publicKey).load(data => { - res(data) - }) - }) - , v => { - if (typeof v !== 'object') { - return true + const data = await tryAndWait( + g => + new Promise(res => { + g.user(req.params.publicKey).load(data => { + res(data) + }) + }), + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - }) + ) return res.status(200).json({ data @@ -2423,25 +2537,25 @@ module.exports = async ( } }) - - ap.get(`/api/gun/dev/storedReqs`, async (req, res) => { + ap.get(`/api/gun/dev/storedReqs`, async (req, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((_, u) => - new Promise((res) => u.get(Key.STORED_REQS).load(res)) - , v => { - if (typeof v !== 'object') { - return true + const data = await tryAndWait( + (_, u) => new Promise(res => u.get(Key.STORED_REQS).load(res)), + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - }) + ) return res.status(200).json({ data @@ -2455,22 +2569,24 @@ module.exports = async ( ap.get(`/api/gun/dev/userToLastReqSent`, async (req, res) => { try { - const {tryAndWait} = require('../services/gunDB/contact-api/utils') + const { tryAndWait } = require('../services/gunDB/contact-api/utils') - const data = await tryAndWait((_, u) => - new Promise((res) => u.get(Key.USER_TO_LAST_REQUEST_SENT).load(res)) - , v => { - if (typeof v !== 'object') { - return true + const data = await tryAndWait( + (_, u) => + new Promise(res => u.get(Key.USER_TO_LAST_REQUEST_SENT).load(res)), + v => { + if (typeof v !== 'object') { + return true + } + + if (v === null) { + return true + } + + // load sometimes returns an empty set on the first try + return size(v) === 0 } - - if (v === null) { - return true - } - - // load sometimes returns an empty set on the first try - return size(v) === 0 - }) + ) return res.status(200).json({ data