diff --git a/README.md b/README.md index 9e17836..4b08b20 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,12 @@ For running the server, rename the file `sample-cl-rest-config.json` to `cl-rest - LNRPCPATH (Default: ` `) - RPCCOMMANDS (Default: `["*"]`) - DOMAIN (Default: `localhost`) +- BIND (Default: `::`) #### Option 2: With the plugin configuration, if used as a plugin + +NOTE: Node.js plugins might not work with lightningd.service setting `MemoryDenyWriteExecute=true` as it denies the creation of writable and executable memory mappings. Ref: https://github.com/Ride-The-Lightning/c-lightning-REST/issues/116 + If running as a plugin, configure the below options in your c-lightning `config` file: - `rest-port` - `rest-docport` @@ -56,6 +60,7 @@ If running as a plugin, configure the below options in your c-lightning `config` - `rest-lnrpcpath` - `rest-rpc` - `rest-domain` +- `rest-bind` Defaults are the same as in option # 1 with the exception that `rest-rpc` is a comma separated string. @@ -72,7 +77,7 @@ Pass arguments when launching lightningd: `$ lightningd --plugin=PATH_TO_PLUGIN [--rest-port=N] [--rest-protocol=http|https] [--rest-execmode=MODE]` -E.g. `$ lightningd --plugin=/Users//c-lightning-REST/plugin.js --rest-port=3003` +E.g. `$ lightningd --plugin=/Users//c-lightning-REST/clrest.js --rest-port=3003` OR @@ -80,7 +85,7 @@ Set `plugin`, `[rest-port]`, `[rest-docport]`, `[rest-protocol]`, and `[rest-exe E.g. add below to the `config` file in `.lightning` folder ``` -plugin=/Users//c-lightning-REST/plugin.js +plugin=/Users//c-lightning-REST/clrest.js rest-port=3002 rest-docport=4001 rest-protocol=https @@ -128,13 +133,13 @@ Providing a `DOMAIN` to the c-lightning-REST configuration will add the domain a If you are *upgrading* a server which is already configured, you should first backup and your entire `./certs` directory in case you need to restore it later. Following this you should delete *only* the `.certs/certificate.pem` and `.certs/key.pem` files, so that new SSL certificates can be generated which take the `subjectAltName` into consideration. -**WARNING**: Do not delete `access.macaroon`. If you do then your connection to remote applications will be lost, and need to be re-configured. +**WARNING**: Do not delete `access.macaroon` or `rootKey.key`. If you do then your connection to remote applications will be lost, and need to be re-configured. New certificates will be automatically generated as usual next time the program is started up. ### Authentication Authentication has been implemented with macaroons. Macaroons are bearer tokens, which will be verified by the server. -A file `access.macaroon` will be generated in the `certs` folder in the application root. +Two files, `access.macaroon` and `rootKey.key`, will be generated in the `certs` folder in the application root. The `access.macaroon` has to be read by the requesting application, converted to `base64` or `hex`, and passed in the header with key value `macaroon`. Encoding Options for passing macaroon in the header: @@ -179,7 +184,7 @@ C-Lightning commands covered by this API suite is [here](docs/CLTCommandCoverage - disconnect (/v1/peer/disconnect) - `DEL`: Disconnect from a connected network peer ### Channel management - fundchannel (/v1/channel/openChannel) - `POST`: Open channel with a connected peer node -- listchannels (/v1/channel/listChannels) - `GET`: Get the list of channels open on the node +- listchannels (/v1/channel/listChannels) - `GET`: Get the list of channels that are known to the node. - setchannelfee (/v1/channel/setChannelFee) - `POST`: Update the fee policy for a channel - close (/v1/channel/closeChannel) - `DEL`: Close channel - listforwards (/v1/channel/listForwards) - `GET`: Get the list of forwarded htlcs by the node diff --git a/cl-rest.js b/cl-rest.js index 3212aa9..980deec 100644 --- a/cl-rest.js +++ b/cl-rest.js @@ -30,6 +30,7 @@ const PORT = config.PORT; const EXECMODE = config.EXECMODE; const DOCPORT = config.DOCPORT; const DOMAIN = config.DOMAIN || "localhost"; +const BIND = config.BIND || "::"; //Create certs folder try { @@ -46,7 +47,7 @@ if ( ! fs.existsSync( key ) || ! fs.existsSync( certificate ) ) { try { execSync( 'openssl version', execOptions ); execSync( - `openssl req -x509 -newkey rsa:2048 -keyout ./certs/key.tmp.pem -out ${ certificate } -days 365 -nodes -subj "/C=US/ST=Foo/L=Bar/O=Baz/CN=c-lightning-rest" --addext "subjectAltName = DNS:${ DOMAIN }"`, + `openssl req -x509 -newkey rsa:2048 -keyout ./certs/key.tmp.pem -out ${ certificate } -days 365 -nodes -subj "/C=US/ST=Foo/L=Bar/O=Baz/CN=c-lightning-rest" -addext "subjectAltName = DNS:${ DOMAIN }"`, execOptions ); execSync( `openssl rsa -in ./certs/key.tmp.pem -out ${ key }`, execOptions ); @@ -134,13 +135,13 @@ try { docserver = require( 'http' ).createServer( docapp ); //Start the server -server.listen(PORT, function() { - global.logger.warn('--- cl-rest api server is ready and listening on port: ' + PORT + ' ---'); +server.listen(PORT, BIND, function() { + global.logger.warn('--- cl-rest api server is ready and listening on ' + BIND + ':' + PORT + ' ---'); }) //Start the docserver -docserver.listen(DOCPORT, function() { - global.logger.warn('--- cl-rest doc server is ready and listening on port: ' + DOCPORT + ' ---'); +docserver.listen(DOCPORT, BIND, function() { + global.logger.warn('--- cl-rest doc server is ready and listening on ' + BIND + ':' + PORT + ' ---'); }) exports.closeServer = function(){ @@ -158,3 +159,5 @@ process.on('SIGTERM', () => { docserver.close(); process.exit(0); }) + +module.exports = { server, wsServer }; diff --git a/plugin.js b/clrest.js similarity index 87% rename from plugin.js rename to clrest.js index 946c5cd..91b5a63 100755 --- a/plugin.js +++ b/clrest.js @@ -12,6 +12,7 @@ restPlugin.addOption('rest-execmode', 'production', 'rest exec mode', 'string'); restPlugin.addOption('rest-rpc', ' ', 'allowed rpc commands', 'string'); restPlugin.addOption('rest-lnrpcpath', ' ', 'path for lightning-rpc', 'string'); restPlugin.addOption('rest-domain', ' ', 'domain name for self-signed cert', 'string'); +restPlugin.addOption('rest-bind', ' ', 'Binding address', 'string'); restPlugin.onInit = params => { process.env.LN_PATH = `${params.configuration['lightning-dir']}/${params.configuration['rpc-file']}` @@ -24,11 +25,11 @@ restPlugin.onInit = params => { RPCCOMMANDS: params.options['rest-rpc'].trim().split(",").map(s => s.trim()), LNRPCPATH: params.options['rest-lnrpcpath'], DOMAIN: params.options['rest-domain'].trim(), + BIND: params.options['rest-bind'].trim(), PLUGIN: restPlugin } srvr = require('./cl-rest'); - }; const EVENTS = [ @@ -44,9 +45,9 @@ const EVENTS = [ EVENTS.forEach(event => { restPlugin.subscribe(event); restPlugin.notifications[event].on(event, (msg) => { - if(srvr && srvr.broadcastToClients) { + if(srvr && srvr.wsServer && srvr.wsServer.broadcastToClients) { updatedMessage = { event: event, data: msg }; - srvr.broadcastToClients(updatedMessage); + srvr.wsServer.broadcastToClients(updatedMessage); } }); }); diff --git a/controllers/channel.js b/controllers/channel.js index 5620eb5..cc317c6 100644 --- a/controllers/channel.js +++ b/controllers/channel.js @@ -131,7 +131,7 @@ exports.openChannel = (req,res) => { * tags: * - Channel Management * name: listchannel -* summary: Returns a list of channels on the node +* summary: Returns data on channels that are known to the node * description: Core documentation - https://lightning.readthedocs.io/lightning-listchannels.7.html * security: * - MacaroonAuth: [] @@ -478,6 +478,10 @@ exports.listForwards = (req,res) => { * name: maxLen * description: maximum range after the offset you want to forward. * type: integer +* - in: query +* name: sort_by +* description: Sort criteria, 'received_time' or 'resolved_time'. +* type: string * security: * - MacaroonAuth: [] * responses: @@ -534,7 +538,7 @@ exports.listForwards = (req,res) => { */ exports.listForwardsPaginated = (req,res) => { try { - var { status, offset, maxLen } = req.query; + var { status, offset, maxLen, sort_by } = req.query; if (appCache.has('listForwards' + status)) { global.logger.log('Reading ' + status + ' listForwards from cache'); var forwards = appCache.get('listForwards' + status); @@ -547,7 +551,10 @@ exports.listForwardsPaginated = (req,res) => { ln.listforwards(status=status).then(data => { // Deleting failed and local_failed transactions after latest 1000 records const forwards = !data.forwards ? [] : (req.query.status === 'failed' || req.query.status === 'local_failed') ? data.forwards.slice(Math.max(0, data.forwards.length - 1000), Math.max(1000, data.forwards.length)).reverse() : data.forwards.reverse(); - // Caching data for subsequent pages + if (sort_by !== undefined) { + forwards.sort((a, b) => a[sort_by] - b[sort_by]); + } + // Caching data for subsequent pages appCache.set('listForwards' + status, forwards); res.status(200).json(getRequestedPage(forwards, offset, maxLen, status)); }).catch(err => { @@ -599,6 +606,7 @@ getAliasForChannels = (peer) => { our_channel_reserve_satoshis: channel.our_channel_reserve_satoshis, spendable_msatoshi: channel.spendable_msatoshi, funding_allocation_msat: channel.funding_allocation_msat, + opener: channel.opener, direction: channel.direction }); return acc; @@ -623,6 +631,7 @@ getAliasForChannels = (peer) => { our_channel_reserve_satoshis: channel.our_channel_reserve_satoshis, spendable_msatoshi: channel.spendable_msatoshi, funding_allocation_msat: channel.funding_allocation_msat, + opener: channel.opener, direction: channel.direction }); return acc; @@ -818,4 +827,4 @@ exports.funderUpdate = (req,res) => { res.status(500).json({error: err}); }); ln.removeListener('error', connFailed); -} \ No newline at end of file +} diff --git a/controllers/invoice.js b/controllers/invoice.js index 3fc9e74..b22db1c 100644 --- a/controllers/invoice.js +++ b/controllers/invoice.js @@ -42,6 +42,16 @@ var wsServer = require('../utils/webSocketServer'); * name: private * description: Include routing hints for private channels (true or 1) * type: string +* - in: body +* name: fallbacks +* description: The fallbacks array is one or more fallback addresses to include in the invoice (in order from most-preferred to least). +* type: array +* items: +* type: string +* - in: body +* name: preimage +* description: 64-digit hex string to be used as payment preimage for the created invoice. IMPORTANT> if you specify the preimage, you are responsible, to ensure appropriate care for generating using a secure pseudorandom generator seeded with sufficient entropy, and keeping the preimage secret. This parameter is an advanced feature intended for use with cutting-edge cryptographic protocols and should not be used unless explicitly needed. +* type: string * security: * - MacaroonAuth: [] * responses: @@ -65,26 +75,15 @@ var wsServer = require('../utils/webSocketServer'); exports.genInvoice = (req,res) => { function connFailed(err) { throw err } ln.on('error', connFailed); - //Set required params - var amount = req.body.amount; - if(req.body.amount == 0) - amount = 'any'; - var label = req.body.label; - var desc = req.body.description; - //Set optional params - var expiry = (req.body.expiry) ? req.body.expiry : null; - var exposePvt = (req.body.private === '1' || req.body.private === 'true') ? !!req.body.private : null; - //Set unexposed params - var fallback = null; - var preimage = null; - - ln.invoice(msatoshi=amount, - label=label, - description=desc, - expiry=expiry, - fallback=fallback, - preimage=preimage, - exposeprivatechannels=exposePvt).then(data => { + ln.invoice( + msatoshi=((req.body.amount == 0) ? 'any' : req.body.amount), + label=req.body.label, + description=req.body.description, + expiry=(req.body.expiry || null), + fallbacks=(req.body.fallbacks || null), + preimage=(req.body.preimage || null), + exposeprivatechannels=(!!req.body.private || null) + ).then(data => { global.logger.log('bolt11 -> '+ data.bolt11); global.logger.log('genInvoice success'); res.status(201).json(data); diff --git a/controllers/peers.js b/controllers/peers.js index ba111fa..e309717 100644 --- a/controllers/peers.js +++ b/controllers/peers.js @@ -92,13 +92,7 @@ exports.listPeers = (req,res) => { ln.listpeers().then(data => { Promise.all( data.peers.map(peer => { - peerData = {}; - peerData = { - id: peer.id, - connected: peer.connected, - netaddr: peer.netaddr - }; - return getAliasForPeer(peerData); + return getAliasForPeer(peer); }) ).then(function(peerList) { res.status(200).json(peerList); @@ -126,7 +120,7 @@ exports.listPeers = (req,res) => { * parameters: * - in: route * name: pubKey -* description: Pubket of the connected peer +* description: Pubkey of the connected peer * type: string * required: * - pubKey @@ -184,4 +178,4 @@ getAliasForPeer = (peer) => { resolve(peer); }); }); - } \ No newline at end of file + } diff --git a/controllers/peerswap.js b/controllers/peerswap.js index df37307..14d1781 100644 --- a/controllers/peerswap.js +++ b/controllers/peerswap.js @@ -26,6 +26,11 @@ * items: * type: string * description: allowed peers list +* SuspiciousPeerList: +* type: array +* items: +* type: string +* description: suspicious peers list * AcceptAllPeers: * type: boolean * description: accept all peers @@ -392,6 +397,13 @@ exports.listPeers = (req,res) => { * - Peerswap * name: allowswaprequests * summary: Sets peerswap to allow incoming swap requests +* parameters: +* - in: route +* name: isAllowed +* description: allow or deny swap incoming requests +* type: boolean +* required: +* - isAllowed * security: * - MacaroonAuth: [] * responses: @@ -418,7 +430,7 @@ exports.allowSwapRequests = (req,res) => { } //Function # 8 -//Invoke the 'peerswap-addpeer' command to add peer to allowlist +//Invoke the 'peerswap-addpeer'/'peerswap-addsuspeer' command to add peer to allow/suspicious list /** * @swagger * /peerswap/addPeer: @@ -426,12 +438,25 @@ exports.allowSwapRequests = (req,res) => { * tags: * - Peerswap * name: addpeer -* summary: Add peer to allowlist +* summary: Add peer to allow/suspicious list +* parameters: +* - in: route +* name: list +* description: Choose list where the pubkey should be added. Valid values are 'allowed' and 'suspicious'. +* type: string +* required: +* - list +* - in: route +* name: pubkey +* description: Peer pubkey +* type: string +* required: +* - pubkey * security: * - MacaroonAuth: [] * responses: * 200: -* description: Adds peer to allowed list successfully +* description: Adds peer to allowed/suspicious list successfully * schema: * type: object * properties: @@ -443,6 +468,11 @@ exports.allowSwapRequests = (req,res) => { * items: * type: string * description: allowed peers list +* SuspiciousPeerList: +* type: array +* items: +* type: string +* description: suspicious peers list * AcceptAllPeers: * type: boolean * description: accept all peers @@ -453,8 +483,22 @@ exports.addPeer = (req,res) => { function connFailed(err) { throw err } ln.on('error', connFailed); - ln.peerswapAddpeer(req.params.pubkey).then(addPeerRes => { - global.logger.log('peerswap add peer success'); + if (!req.params.list || !req.params.pubkey) { + res.status(500).json({error: 'List and pubkey both are required.'}); + ln.removeListener('error', connFailed); + return; + } + + console.warn(req.params.list); + + if (req.params.list !== 'allowed' && req.params.list !== 'suspicious') { + res.status(500).json({error: 'Invalid list. allowed and suspicious are valid values.'}); + ln.removeListener('error', connFailed); + return; + } + + ln.call((req.params.list === 'suspicious') ? 'peerswap-addsuspeer' : 'peerswap-addpeer', [req.params.pubkey]).then(addPeerRes => { + global.logger.log('peerswap add ' + req.params.list + ' peer success'); res.status(200).json(addPeerRes); }).catch(err => { global.logger.warn(err); @@ -464,7 +508,7 @@ exports.addPeer = (req,res) => { } //Function # 9 -//Invoke the 'peerswap-removepeer' command to remove peer from allowlist +//Invoke the 'peerswap-removepeer'/'peerswap-removesuspeer' command to remove peer from allowed/suspicious list /** * @swagger * /peerswap/removePeer: @@ -472,12 +516,25 @@ exports.addPeer = (req,res) => { * tags: * - Peerswap * name: removepeer -* summary: Remove peer from allowlist +* summary: Remove peer from allow/suspicious list +* parameters: +* - in: route +* name: list +* description: Choose list where the pubkey should be removed from. Valid values are 'allowed' and 'suspicious' +* type: string +* required: +* - list +* - in: route +* name: pubkey +* description: Peer pubkey +* type: string +* required: +* - pubkey * security: * - MacaroonAuth: [] * responses: * 200: -* description: Removes peer from allowed list successfully +* description: Removes peer from allowed/suspicious list successfully * schema: * type: object * properties: @@ -489,6 +546,11 @@ exports.addPeer = (req,res) => { * items: * type: string * description: allowed peers list +* SuspiciousPeerList: +* type: array +* items: +* type: string +* description: suspicious peers list * AcceptAllPeers: * type: boolean * description: accept all peers @@ -499,8 +561,20 @@ exports.removePeer = (req,res) => { function connFailed(err) { throw err } ln.on('error', connFailed); - ln.peerswapRemovepeer(req.params.pubkey).then(removePeerRes => { - global.logger.log('peerswap remove peer success'); + if (!req.params.list || !req.params.pubkey) { + res.status(500).json({error: 'List and pubkey both are required.'}); + ln.removeListener('error', connFailed); + return; + } + + if (req.params.list !== 'allowed' && req.params.list !== 'suspicious') { + res.status(500).json({error: 'Invalid list. allowed and suspicious are valid values.'}); + ln.removeListener('error', connFailed); + return; + } + + ln.call((req.params.list === 'suspicious') ? 'peerswap-removesuspeer' : 'peerswap-removepeer', [req.params.pubkey]).then(removePeerRes => { + global.logger.log('peerswap remove ' + req.params.list + ' peer success'); res.status(200).json(removePeerRes); }).catch(err => { global.logger.warn(err); @@ -519,6 +593,13 @@ exports.removePeer = (req,res) => { * - Peerswap * name: resendmsg * summary: Command to resend last swap message +* parameters: +* - in: route +* name: swapId +* description: swap id to resend last swap message +* type: string +* required: +* - swapId * security: * - MacaroonAuth: [] * responses: @@ -559,7 +640,7 @@ exports.resendMessage = (req,res) => { * parameters: * - in: body * name: amountSats -* description: Amount in milli satoshis +* description: Amount in satoshis * type: integer * required: * - amountSats @@ -575,6 +656,10 @@ exports.resendMessage = (req,res) => { * type: string * required: * - asset +* - in: body +* name: force +* description: Force +* type: boolean * security: * - MacaroonAuth: [] * responses: @@ -626,7 +711,8 @@ exports.swapIn = (req,res) => { ln.peerswapSwapIn( amt_sat=req.body.amountSats, short_channel_id=req.body.shortChannelId, - asset=req.body.asset + asset=req.body.asset, + force=req.body.force ).then(swapInRes => { global.logger.log('peerswap swap in success'); res.status(200).json(swapInRes); @@ -652,7 +738,7 @@ exports.swapIn = (req,res) => { * parameters: * - in: body * name: amountSats -* description: Amount in milli satoshis +* description: Amount in satoshis * type: integer * required: * - amountSats @@ -668,6 +754,10 @@ exports.swapIn = (req,res) => { * type: string * required: * - asset +* - in: body +* name: force +* description: Force +* type: boolean * security: * - MacaroonAuth: [] * responses: @@ -719,7 +809,8 @@ exports.swapOut = (req,res) => { ln.peerswapSwapOut( amt_sat=req.body.amountSats, short_channel_id=req.body.shortChannelId, - asset=req.body.asset + asset=req.body.asset, + force=req.body.force ).then(swapOutRes => { global.logger.log('peerswap swap out success'); res.status(200).json(swapOutRes); diff --git a/lightning-client-js.js b/lightning-client-js.js index 4ca3fde..6d2a062 100644 --- a/lightning-client-js.js +++ b/lightning-client-js.js @@ -72,9 +72,7 @@ class LightningClient extends EventEmitter { }); _self.client.on('end', () => { - global.logger.error('Lightning client connection closed, reconnecting'); - _self.increaseWaitTime(); - _self.reconnect(); + console.log('Lightning client connection closed'); }); _self.client.on('error', error => { diff --git a/package-lock.json b/package-lock.json index e8ae59a..0023050 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "c-lightning-rest", - "version": "0.9.0", + "version": "0.10.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "c-lightning-rest", - "version": "0.8.1", + "version": "0.10.0", "license": "MIT", "dependencies": { "atob": "^2.1.2", diff --git a/package.json b/package.json index 139b565..b4c95d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "c-lightning-rest", - "version": "0.9.0", + "version": "0.10.0", "description": "c-lightning REST API suite", "main": "cl-rest.js", "scripts": { diff --git a/routes/peerswap.js b/routes/peerswap.js index e04799b..bdf5695 100644 --- a/routes/peerswap.js +++ b/routes/peerswap.js @@ -23,11 +23,11 @@ router.get('/listPeers', tasteMacaroon, PeerswapController.listPeers); // Sets peerswap to allow incoming swap requests router.get('/allowSwapRequests/:isAllowed', tasteMacaroon, PeerswapController.allowSwapRequests); -// Add peer to allowlist -router.get('/addPeer/:pubkey', tasteMacaroon, PeerswapController.addPeer); +// Add peer to allowed/suspicious list +router.get('/addPeer/:list/:pubkey?', tasteMacaroon, PeerswapController.addPeer); -// Remove peer from allowlist -router.get('/removePeer/:pubkey', tasteMacaroon, PeerswapController.removePeer); +// Remove peer from allowed/suspicious list +router.get('/removePeer/:list/:pubkey?', tasteMacaroon, PeerswapController.removePeer); // Resends last swap message router.get('/resendMessage/:swapId', tasteMacaroon, PeerswapController.resendMessage); diff --git a/sample-cl-rest-config.json b/sample-cl-rest-config.json index 2a96b8c..846e7f8 100644 --- a/sample-cl-rest-config.json +++ b/sample-cl-rest-config.json @@ -4,5 +4,6 @@ "PROTOCOL": "https", "EXECMODE": "production", "RPCCOMMANDS": ["*"], - "DOMAIN": "localhost" + "DOMAIN": "localhost", + "BIND": "::" } diff --git a/test/mainTest.js b/test/mainTest.js index aa4212a..c36dc67 100644 --- a/test/mainTest.js +++ b/test/mainTest.js @@ -222,19 +222,22 @@ describe('/GET listForwards', () => { expect(res).to.have.status(200); if(body && body.length){ body.forEach( forward => { - console.log("payment_hash: " + forward.payment_hash); - expect(forward).to.contain.property('payment_hash'); + console.log("in_channel: " + forward.in_channel); expect(forward).to.contain.property('in_channel'); - expect(forward).to.contain.property('out_channel'); + if(forward.status == "settled") + expect(forward).to.contain.property('out_channel'); expect(forward).to.contain.property('in_msatoshi'); expect(forward).to.contain.property('in_msat'); + if(forward.status == "settled") { expect(forward).to.contain.property('out_msatoshi'); expect(forward).to.contain.property('out_msat'); expect(forward).to.contain.property('fee'); expect(forward).to.contain.property('fee_msat'); + } expect(forward).to.contain.property('status'); - expect(forward).to.contain.property('received_time'); - expect(forward).to.contain.property('resolved_time'); + //expect(forward).to.contain.property('received_time'); + //if(forward.status == "settled") + // expect(forward).to.contain.property('resolved_time'); }); } done(); @@ -253,6 +256,7 @@ describe('/GET listPays', () => { expect(res).to.have.status(200); if(body && body.length){ body.forEach( pay => { + console.log("bolt11: " + pay.bolt11); expect(pay).to.contain.property('bolt11'); expect(pay).to.contain.property('status'); expect(pay).to.contain.property('amount_sent_msat'); @@ -309,13 +313,16 @@ describe('/GET listInvoices', () => { expect(res).to.have.status(200); if(body && body.length){ body.forEach( invoice => { - console.log("label: " + invoice.label); + let label = invoice.label; + console.log("label: " + label); expect(invoice).to.contain.property('label'); expect(invoice).to.contain.property('bolt11'); expect(invoice).to.contain.property('payment_hash'); + if(label.substr(0,7) != "keysend"){ expect(invoice).to.contain.property('msatoshi'); expect(invoice).to.contain.property('amount_msat'); + } expect(invoice).to.contain.property('status'); expect(invoice).to.contain.property('pay_index'); expect(invoice).to.contain.property('msatoshi_received'); diff --git a/utils/webSocketServer.js b/utils/webSocketServer.js index f10272b..669a440 100644 --- a/utils/webSocketServer.js +++ b/utils/webSocketServer.js @@ -25,14 +25,11 @@ const verifyWSClient = (info, next) => { macaroon.importMacaroon(macaroon.base64ToBytes(mac)).verify(verRootkey, () => null, []); next(true); } catch (error) { - if (config.EXECMODE === 'test') { - return next(true); - } next(false, 401, 'Authentication Failed! Bad Macaroon!'); } }; -const wss = new WebSocket.Server({ noServer: true, path: '/v1/ws', verifyClient: verifyWSClient }); +const wss = new WebSocket.Server({ noServer: true, path: '/v1/ws', verifyClient: () => (config.EXECMODE === 'test') ? true : verifyWSClient }); exports.mountWebServer = (httpServer) => { try {