mirror of
https://github.com/Ride-The-Lightning/RTL.git
synced 2024-11-19 01:40:29 +01:00
Release 0.15.1 (#1406)
* rm .DS_Store * Add watchfrontenddev command for npm * Fix toggle issues in sidenav (pinning and on page refresh) * Add copy-to-clipboard fallback if navigator.clipboard is not available (#1336) * add copy-to-clipboard fallback if navigator.clipboard is not available * amend copy fallback * clipboard copy lint fixes and frontend build * fix: add missing boltz state `transaction.lockupFailed` (#1349) * fix: boltzd docs link (#1354) * exit gracefully (#1356) * allow for eclair updated relayed audit format (#1363) * feat: add boltz service to cln (#1352) * lint fix * Request Params Cleanup * cln: Boltz auto-send (#1366) * Bug-fix (CLN Boltz): Hide claim tx id and routing fee for non-zero conf reverse swap * cln: Boltz auto-send - Added auto send option for Swap In - Checking compatiblity with v2.0.0 and above * Test import fixes * Update help.component.ts (#1379) Fixed broken link under "Help" -> "Node Settings" * Backend config fix (#1382) * Updating Common Application Configuration * Fixed get RTL Conf * Update Application Settings * application and settings case change * Unified config models * Default node update * 2FA and Password reset * Final application settings update * Config Settings and Authentication case fixed * Node Setting Fix * Fiat currency Symbol fix * CLN: Fiat symbol fix * All: Fiat symbol fix * Update node settings * Services UI fix * CLN: Removed child node settings * All: Removed child node settings * Test fixes * mempool links for onchain information (#1383) * Tests fix Tests fix * UI for Block Explorer Configuration (#1385) * Bump fee with mempool information (#1386) * Mempool openchannel minfee (#1388) Open channel model block if min fee is higher * Show error on login screen if rune is incorrect and getinfo throws error (#1391) * cln: Removed channel lookup call for update policy (#1392) * ECL: On-chain Transactions, Invoice and Payments pagination (#1393) Done most of the UI changes to accommodate pagination on transactions, payments and invoices tables but true pagination cannot be implemented till total number of records are missing from the API response. Once the issue https://github.com/ACINQ/eclair/issues/2855 is fixed, I will uncomment pagination changes in the frontend. * lnd: Onchain CPFP (#1394) - UTXO label bug fix - Warning on utxo label for "sweep" in text. * Bug fixes after testing * Testing bug fixes (#1401) * Bug fix 2: lnd: Link channel point to explorer and show fee on close channel too * lnd: explorer link on pending channels * Node lookup link on view channel peer pubkey * Testing bug fixes (#1402) * Bug fix 2: lnd: Link channel point to explorer and show fee on close channel too * lnd: explorer link on pending channels * Node lookup link on view channel peer pubkey * test fixes * ng update to v18.0.x * Updating install with --legacy-peer-deps --------- Co-authored-by: Grzegorz Kućmierz <gkucmierz@gmail.com> Co-authored-by: lacksfish <lacksfish@gmail.com> Co-authored-by: jackstar12 <62219658+jackstar12@users.noreply.github.com> Co-authored-by: Kilian <19181985+kilrau@users.noreply.github.com> Co-authored-by: Taylor King <taylorbradleyking@gmail.com> Co-authored-by: Fishcake <128653975+fishcakeday@users.noreply.github.com> Co-authored-by: Ant <72945059+2140data@users.noreply.github.com>
This commit is contained in:
parent
ea7f300360
commit
22ab6d1154
11
.github/README.md
vendored
11
.github/README.md
vendored
@ -55,7 +55,7 @@ To download from master (*not recommended*):
|
|||||||
```
|
```
|
||||||
$ git clone https://github.com/Ride-The-Lightning/RTL.git
|
$ git clone https://github.com/Ride-The-Lightning/RTL.git
|
||||||
$ cd RTL
|
$ cd RTL
|
||||||
$ npm install --omit=dev
|
$ npm install --omit=dev --legacy-peer-deps
|
||||||
```
|
```
|
||||||
#### Or: Update existing dependencies
|
#### Or: Update existing dependencies
|
||||||
```
|
```
|
||||||
@ -63,7 +63,7 @@ $ cd RTL
|
|||||||
$ git reset --hard HEAD
|
$ git reset --hard HEAD
|
||||||
$ git clean -f -d
|
$ git clean -f -d
|
||||||
$ git pull
|
$ git pull
|
||||||
$ npm install --omit=dev
|
$ npm install --omit=dev --legacy-peer-deps
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Error on npm install
|
#### Error on npm install
|
||||||
@ -95,7 +95,7 @@ Example RTL-Config.json:
|
|||||||
"index": 1,
|
"index": 1,
|
||||||
"lnNode": "LND Testnet",
|
"lnNode": "LND Testnet",
|
||||||
"lnImplementation": "LND",
|
"lnImplementation": "LND",
|
||||||
"Authentication": {
|
"authentication": {
|
||||||
"macaroonPath": "<Complete path of the folder containing LND admin.macaroon for the node>",
|
"macaroonPath": "<Complete path of the folder containing LND admin.macaroon for the node>",
|
||||||
"runePath": "<Complete path including filename for CLN rune for the node, rune format 'LIGHTNING_RUNE="your-rune"'>",
|
"runePath": "<Complete path including filename for CLN rune for the node, rune format 'LIGHTNING_RUNE="your-rune"'>",
|
||||||
"lnApiPassword": "<Can be used to provide password in ECL implementation>",
|
"lnApiPassword": "<Can be used to provide password in ECL implementation>",
|
||||||
@ -103,7 +103,7 @@ Example RTL-Config.json:
|
|||||||
"boltzMacaroonPath": "<Complete path of the folder containing Boltz admin.macaroon for the node>",
|
"boltzMacaroonPath": "<Complete path of the folder containing Boltz admin.macaroon for the node>",
|
||||||
"configPath": "<Optional:Path of the .conf if present locally or empty>",
|
"configPath": "<Optional:Path of the .conf if present locally or empty>",
|
||||||
},
|
},
|
||||||
"Settings": {
|
"settings": {
|
||||||
"userPersona": "OPERATOR",
|
"userPersona": "OPERATOR",
|
||||||
"themeMode": "DAY",
|
"themeMode": "DAY",
|
||||||
"themeColor": "PURPLE",
|
"themeColor": "PURPLE",
|
||||||
@ -114,7 +114,8 @@ Example RTL-Config.json:
|
|||||||
"unannouncedChannels": false,
|
"unannouncedChannels": false,
|
||||||
"lnServerUrl": "<url for LND REST APIs for node #1 e.g. https://192.168.0.1:8080>",
|
"lnServerUrl": "<url for LND REST APIs for node #1 e.g. https://192.168.0.1:8080>",
|
||||||
"swapServerUrl": "<url for swap server REST APIs for the node. e.g. https://127.0.0.1:8081>",
|
"swapServerUrl": "<url for swap server REST APIs for the node. e.g. https://127.0.0.1:8081>",
|
||||||
"boltzServerUrl": "<url for boltz server REST APIs for the node. e.g. https://127.0.0.1:9003>"
|
"boltzServerUrl": "<url for boltz server REST APIs for the node. e.g. https://127.0.0.1:9003>",
|
||||||
|
"blockExplorerUrl": "<url for local or centralized block explorer. e.g. https://mempool.space>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
7
.github/docs/Application_configurations.md
vendored
7
.github/docs/Application_configurations.md
vendored
@ -20,7 +20,7 @@ parameters have `default` values for initial setup and can be updated after RTL
|
|||||||
"index": <Incremental node indices starting from 1, Required>,
|
"index": <Incremental node indices starting from 1, Required>,
|
||||||
"lnNode": "<Node name to uniquely identify the node in the UI, Required>",
|
"lnNode": "<Node name to uniquely identify the node in the UI, Required>",
|
||||||
"lnImplementation": "<LNP implementation, Allowed values LND/CLN/ECL, Required>",
|
"lnImplementation": "<LNP implementation, Allowed values LND/CLN/ECL, Required>",
|
||||||
"Authentication": {
|
"authentication": {
|
||||||
"macaroonPath": "<Path for the folder containing 'admin.macaroon' for LND node, Required for LND>",
|
"macaroonPath": "<Path for the folder containing 'admin.macaroon' for LND node, Required for LND>",
|
||||||
"runePath": "<Complete path including filename for CLN rune for the node, Required for CLN>",
|
"runePath": "<Complete path including filename for CLN rune for the node, Required for CLN>",
|
||||||
"lnApiPassword": "<Password to be used for ECL API authentication. Mandatory only for ECL if the configPath is missing>"
|
"lnApiPassword": "<Password to be used for ECL API authentication. Mandatory only for ECL if the configPath is missing>"
|
||||||
@ -28,7 +28,7 @@ parameters have `default` values for initial setup and can be updated after RTL
|
|||||||
"boltzMacaroonPath": "<Path for the folder containing 'admin.macaroon' (Boltz), Required for Boltz Swaps>",
|
"boltzMacaroonPath": "<Path for the folder containing 'admin.macaroon' (Boltz), Required for Boltz Swaps>",
|
||||||
"configPath": "<Full path of the lnd.conf/core lightning config/eclair.conf file including the file name, if present locally, Optional, only mandatory for ECL if the lnApiPassword is missing>",
|
"configPath": "<Full path of the lnd.conf/core lightning config/eclair.conf file including the file name, if present locally, Optional, only mandatory for ECL if the lnApiPassword is missing>",
|
||||||
},
|
},
|
||||||
"Settings": {
|
"settings": {
|
||||||
"userPersona": "<User persona to tailor the data on UI. Allowed values MERCHANT/OPERATOR. Default MERCHANT, Optional>",
|
"userPersona": "<User persona to tailor the data on UI. Allowed values MERCHANT/OPERATOR. Default MERCHANT, Optional>",
|
||||||
"themeMode": "<Theme modes, Allowed values DAY, NIGHT. Default DAY, Optional>",
|
"themeMode": "<Theme modes, Allowed values DAY, NIGHT. Default DAY, Optional>",
|
||||||
"themeColor": "<Theme colors, Allowed values PURPLE, TEAL, INDIGO, PINK, YELLOW. Default PURPLE, Optional>",
|
"themeColor": "<Theme colors, Allowed values PURPLE, TEAL, INDIGO, PINK, YELLOW. Default PURPLE, Optional>",
|
||||||
@ -40,7 +40,8 @@ parameters have `default` values for initial setup and can be updated after RTL
|
|||||||
"unannouncedChannels": <parameter to turn off/on setting for opening announced Channels, default false, Optional>
|
"unannouncedChannels": <parameter to turn off/on setting for opening announced Channels, default false, Optional>
|
||||||
"lnServerUrl": "<Service url for LND/Core Lightning REST APIs for the node, e.g. https://192.168.0.1:8080 OR https://192.168.0.1:3001 OR http://192.168.0.1:8080. Default 'https://127.0.0.1:8080', Optional>
|
"lnServerUrl": "<Service url for LND/Core Lightning REST APIs for the node, e.g. https://192.168.0.1:8080 OR https://192.168.0.1:3001 OR http://192.168.0.1:8080. Default 'https://127.0.0.1:8080', Optional>
|
||||||
"swapServerUrl": "<Service url for swap server REST APIs for the node, e.g. https://127.0.0.1:8081, Optional>",
|
"swapServerUrl": "<Service url for swap server REST APIs for the node, e.g. https://127.0.0.1:8081, Optional>",
|
||||||
"boltzServerUrl": "<Service url for boltz server REST APIs for the node, e.g. https://127.0.0.1:9003, Optional>"
|
"boltzServerUrl": "<Service url for boltz server REST APIs for the node, e.g. https://127.0.0.1:9003, Optional>",
|
||||||
|
"blockExplorerUrl": "<url for local or centralized block explorer. e.g. https://mempool.space>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
11
.github/docs/Core_lightning_setup.md
vendored
11
.github/docs/Core_lightning_setup.md
vendored
@ -33,7 +33,7 @@ To download from master (*not recommended*):
|
|||||||
```
|
```
|
||||||
$ git clone https://github.com/Ride-The-Lightning/RTL.git
|
$ git clone https://github.com/Ride-The-Lightning/RTL.git
|
||||||
$ cd RTL
|
$ cd RTL
|
||||||
$ npm install --omit=dev
|
$ npm install --omit=dev --legacy-peer-deps
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Or: Update existing build
|
#### Or: Update existing build
|
||||||
@ -42,7 +42,7 @@ $ cd RTL
|
|||||||
$ git reset --hard HEAD
|
$ git reset --hard HEAD
|
||||||
$ git clean -f -d
|
$ git clean -f -d
|
||||||
$ git pull
|
$ git pull
|
||||||
$ npm install --omit=dev
|
$ npm install --omit=dev --legacy-peer-deps
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Error on npm install
|
#### Error on npm install
|
||||||
@ -77,11 +77,11 @@ Ensure that the follow values are correct per your config:
|
|||||||
"index": 1,
|
"index": 1,
|
||||||
"lnNode": "Core Lightning Testnet # 1",
|
"lnNode": "Core Lightning Testnet # 1",
|
||||||
"lnImplementation": "CLN",
|
"lnImplementation": "CLN",
|
||||||
"Authentication": {
|
"authentication": {
|
||||||
"runePath": "<Modify to include the path of the folder including filename which contains `rune`>",
|
"runePath": "<Modify to include the path of the folder including filename which contains `rune`>",
|
||||||
"configPath": "<Optional - Config file path for core lightning>"
|
"configPath": "<Optional - Config file path for core lightning>"
|
||||||
},
|
},
|
||||||
"Settings": {
|
"settings": {
|
||||||
"userPersona": "OPERATOR",
|
"userPersona": "OPERATOR",
|
||||||
"themeMode": "DAY",
|
"themeMode": "DAY",
|
||||||
"themeColor": "PURPLE",
|
"themeColor": "PURPLE",
|
||||||
@ -89,7 +89,8 @@ Ensure that the follow values are correct per your config:
|
|||||||
"logLevel": "INFO",
|
"logLevel": "INFO",
|
||||||
"fiatConversion": false,
|
"fiatConversion": false,
|
||||||
"unannouncedChannels": false,
|
"unannouncedChannels": false,
|
||||||
"lnServerUrl": "https://<CLNRest api server ip address>:3001"
|
"lnServerUrl": "https://<CLNRest api server ip address>:3001",
|
||||||
|
"blockExplorerUrl": "<Default: https://mempool.space>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
11
.github/docs/Eclair_setup.md
vendored
11
.github/docs/Eclair_setup.md
vendored
@ -28,7 +28,7 @@ To download from master (*not recommended*) follow the below instructions:
|
|||||||
```
|
```
|
||||||
$ git clone https://github.com/Ride-The-Lightning/RTL.git
|
$ git clone https://github.com/Ride-The-Lightning/RTL.git
|
||||||
$ cd RTL
|
$ cd RTL
|
||||||
$ npm install --omit=dev
|
$ npm install --omit=dev --legacy-peer-deps
|
||||||
```
|
```
|
||||||
#### Or: Update existing build
|
#### Or: Update existing build
|
||||||
```
|
```
|
||||||
@ -36,7 +36,7 @@ $ cd RTL
|
|||||||
$ git reset --hard HEAD
|
$ git reset --hard HEAD
|
||||||
$ git clean -f -d
|
$ git clean -f -d
|
||||||
$ git pull
|
$ git pull
|
||||||
$ npm install --omit=dev
|
$ npm install --omit=dev --legacy-peer-deps
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Error on npm install
|
#### Error on npm install
|
||||||
@ -71,11 +71,11 @@ Ensure that the follow values are correct per your config:
|
|||||||
"index": 1,
|
"index": 1,
|
||||||
"lnNode": "Eclair Testnet # 1",
|
"lnNode": "Eclair Testnet # 1",
|
||||||
"lnImplementation": "ECL",
|
"lnImplementation": "ECL",
|
||||||
"Authentication": {
|
"authentication": {
|
||||||
"configPath": "<Optional - Config file path, including .conf file>",
|
"configPath": "<Optional - Config file path, including .conf file>",
|
||||||
"lnApiPassword": "<Mandatory if the configPath is missing - Password used for API authentication>",
|
"lnApiPassword": "<Mandatory if the configPath is missing - Password used for API authentication>",
|
||||||
},
|
},
|
||||||
"Settings": {
|
"settings": {
|
||||||
"userPersona": "OPERATOR",
|
"userPersona": "OPERATOR",
|
||||||
"themeMode": "DAY",
|
"themeMode": "DAY",
|
||||||
"themeColor": "PURPLE",
|
"themeColor": "PURPLE",
|
||||||
@ -83,7 +83,8 @@ Ensure that the follow values are correct per your config:
|
|||||||
"logLevel": "INFO",
|
"logLevel": "INFO",
|
||||||
"fiatConversion": false,
|
"fiatConversion": false,
|
||||||
"unannouncedChannels": false,
|
"unannouncedChannels": false,
|
||||||
"lnServerUrl": "http://<eclair api server ip address>:port"
|
"lnServerUrl": "http://<eclair api server ip address>:port",
|
||||||
|
"blockExplorerUrl": "<Default: https://mempool.space>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
7
.github/docs/RTL_setups.md
vendored
7
.github/docs/RTL_setups.md
vendored
@ -26,13 +26,13 @@ If your running RTL and LND on different devices on your local LAN, certain conf
|
|||||||
"index": 1,
|
"index": 1,
|
||||||
"lnNode": "LND Testnet",
|
"lnNode": "LND Testnet",
|
||||||
"lnImplementation": "LND",
|
"lnImplementation": "LND",
|
||||||
"Authentication": {
|
"authentication": {
|
||||||
"macaroonPath": "<Path of the folder containing 'admin.macaroon' on the device running RTL>",
|
"macaroonPath": "<Path of the folder containing 'admin.macaroon' on the device running RTL>",
|
||||||
"swapMacaroonPath": "<Path of the folder containing 'loop.macaroon' on the device running RTL>",
|
"swapMacaroonPath": "<Path of the folder containing 'loop.macaroon' on the device running RTL>",
|
||||||
"boltzMacaroonPath": "<Path of the folder containing 'admin.macaroon' on the device running RTL>",
|
"boltzMacaroonPath": "<Path of the folder containing 'admin.macaroon' on the device running RTL>",
|
||||||
"configPath": "<Optional:Path of the lnd.conf if present locally or empty>"
|
"configPath": "<Optional:Path of the lnd.conf if present locally or empty>"
|
||||||
},
|
},
|
||||||
"Settings": {
|
"settings": {
|
||||||
"userPersona": "OPERATOR",
|
"userPersona": "OPERATOR",
|
||||||
"themeMode": "DAY",
|
"themeMode": "DAY",
|
||||||
"themeColor": "PURPLE",
|
"themeColor": "PURPLE",
|
||||||
@ -43,7 +43,8 @@ If your running RTL and LND on different devices on your local LAN, certain conf
|
|||||||
"unannouncedChannels": false,
|
"unannouncedChannels": false,
|
||||||
"lnServerUrl": "<https://<ip-address-of-device-running-lnd>:8080; e.g. https://192.168.0.1:8080>",
|
"lnServerUrl": "<https://<ip-address-of-device-running-lnd>:8080; e.g. https://192.168.0.1:8080>",
|
||||||
"swapServerUrl": "<https://<localhost>:8081>",
|
"swapServerUrl": "<https://<localhost>:8081>",
|
||||||
"boltzServerUrl": "<https://<localhost>:9003>"
|
"boltzServerUrl": "<https://<localhost>:9003>",
|
||||||
|
"blockExplorerUrl": "<Default: https://mempool.space>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
6
.github/workflows/checks.yml
vendored
6
.github/workflows/checks.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install NPM dependencies
|
- name: Install NPM dependencies
|
||||||
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
||||||
run: npm ci
|
run: npm ci --legacy-peer-deps
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
name: Lint
|
name: Lint
|
||||||
@ -57,7 +57,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install NPM dependencies
|
- name: Install NPM dependencies
|
||||||
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
||||||
run: npm ci
|
run: npm ci --legacy-peer-deps
|
||||||
|
|
||||||
- name: Lint Scripts
|
- name: Lint Scripts
|
||||||
run: npm run lint
|
run: npm run lint
|
||||||
@ -89,7 +89,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install NPM dependencies
|
- name: Install NPM dependencies
|
||||||
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
||||||
run: npm ci
|
run: npm ci --legacy-peer-deps
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: npm run test
|
run: npm run test
|
||||||
|
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -34,7 +34,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install NPM dependencies
|
- name: Install NPM dependencies
|
||||||
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
if: steps.cache-npm-packages.outputs.cache-hit != 'true'
|
||||||
run: npm ci
|
run: npm ci --legacy-peer-deps
|
||||||
|
|
||||||
- name: Cache build frontend
|
- name: Cache build frontend
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
"index": 1,
|
"index": 1,
|
||||||
"lnNode": "Node 1",
|
"lnNode": "Node 1",
|
||||||
"lnImplementation": "LND",
|
"lnImplementation": "LND",
|
||||||
"Authentication": {
|
"authentication": {
|
||||||
"macaroonPath": "C:\\Users\\xyz\\AppData\\Local\\Lnd\\data\\chain\\bitcoin\\mainnet",
|
"macaroonPath": "C:\\Users\\xyz\\AppData\\Local\\Lnd\\data\\chain\\bitcoin\\mainnet",
|
||||||
"configPath": "C:\\Users\\xyz\\AppData\\Local\\Lnd\\lnd.conf",
|
"configPath": "C:\\Users\\xyz\\AppData\\Local\\Lnd\\lnd.conf",
|
||||||
"swapMacaroonPath": "C:\\Users\\xyz\\AppData\\Local\\Loop\\mainnet",
|
"swapMacaroonPath": "C:\\Users\\xyz\\AppData\\Local\\Loop\\mainnet",
|
||||||
"boltzMacaroonPath": "C:\\Users\\xyz\\AppData\\Boltz\\mainnet"
|
"boltzMacaroonPath": "C:\\Users\\xyz\\AppData\\Boltz\\mainnet"
|
||||||
},
|
},
|
||||||
"Settings": {
|
"settings": {
|
||||||
"userPersona": "MERCHANT",
|
"userPersona": "MERCHANT",
|
||||||
"themeMode": "DAY",
|
"themeMode": "DAY",
|
||||||
"themeColor": "PURPLE",
|
"themeColor": "PURPLE",
|
||||||
@ -29,7 +29,8 @@
|
|||||||
"swapServerUrl": "https://127.0.0.1:8081",
|
"swapServerUrl": "https://127.0.0.1:8081",
|
||||||
"boltzServerUrl": "https://127.0.0.1:9003",
|
"boltzServerUrl": "https://127.0.0.1:9003",
|
||||||
"fiatConversion": false,
|
"fiatConversion": false,
|
||||||
"unannouncedChannels": false
|
"unannouncedChannels": false,
|
||||||
|
"blockExplorerUrl": "https://mempool.space"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -11,7 +11,7 @@ export const listPeerChannels = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeerchannels';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels });
|
||||||
return Promise.all(body.channels?.map((channel) => {
|
return Promise.all(body.channels?.map((channel) => {
|
||||||
@ -33,7 +33,7 @@ export const openChannel = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/fundchannel';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fundchannel';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -50,7 +50,7 @@ export const setChannelFee = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/setchannel';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/setchannel';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -68,7 +68,7 @@ export const closeChannel = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/close';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/close';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -80,16 +80,17 @@ export const closeChannel = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const listForwards = (req, res, next) => {
|
export const listForwards = (req, res, next) => {
|
||||||
|
const { status } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listforwards';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listforwards';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + req.body.status, data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body });
|
||||||
body.forwards = !body.forwards ? [] : (req.body.status === 'failed' || req.body.status === 'local_failed') ? body.forwards.slice(Math.max(0, body.forwards.length - 1000), Math.max(1000, body.forwards.length)).reverse() : body.forwards.reverse();
|
body.forwards = !body.forwards ? [] : (status === 'failed' || status === 'local_failed') ? body.forwards.slice(Math.max(0, body.forwards.length - 1000), Math.max(1000, body.forwards.length)).reverse() : body.forwards.reverse();
|
||||||
res.status(200).json(body.forwards);
|
res.status(200).json(body.forwards);
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
const err = common.handleError(errRes, 'Channels', 'Forwarding History Error', req.session.selectedNode);
|
const err = common.handleError(errRes, 'Channels', 'Forwarding History Error', req.session.selectedNode);
|
||||||
@ -102,7 +103,7 @@ export const funderUpdatePolicy = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/funderupdate';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/funderupdate';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import request from 'request-promise';
|
|
||||||
import { Logger } from '../../utils/logger.js';
|
|
||||||
import { Common } from '../../utils/common.js';
|
|
||||||
let options = null;
|
|
||||||
const logger = Logger;
|
|
||||||
const common = Common;
|
|
||||||
export const getFees = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' });
|
|
||||||
options = common.getOptions(req);
|
|
||||||
if (options.error) {
|
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
|
||||||
}
|
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo';
|
|
||||||
request.post(options).then((body) => {
|
|
||||||
const versionCompatible = common.isVersionCompatible(req.session.selectedNode.ln_version, '23.02');
|
|
||||||
const feeData = { feeCollected: ((versionCompatible ? body.fees_collected_msat : body.msatoshi_fees_collected) || 0) };
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: feeData });
|
|
||||||
res.status(200).json(feeData);
|
|
||||||
}).catch((errRes) => {
|
|
||||||
const err = common.handleError(errRes, 'Fees', 'Get Fees Error', req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
|
||||||
});
|
|
||||||
};
|
|
@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url });
|
||||||
if (!options.headers || !options.headers.rune) {
|
if (!options.headers || !options.headers.rune) {
|
||||||
const errMsg = 'Core lightning get info failed due to missing rune!';
|
const errMsg = 'Core lightning get info failed due to missing rune!';
|
||||||
@ -48,7 +48,7 @@ export const getInfo = (req, res, next) => {
|
|||||||
body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
|
body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
req.session.selectedNode.ln_version = body.version || '';
|
req.session.selectedNode.lnVersion = body.version || '';
|
||||||
req.session.selectedNode.api_version = body.api_version || '';
|
req.session.selectedNode.api_version = body.api_version || '';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' });
|
||||||
clWsClient.updateSelectedNode(req.session.selectedNode);
|
clWsClient.updateSelectedNode(req.session.selectedNode);
|
||||||
|
@ -10,7 +10,7 @@ export const deleteExpiredInvoice = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/delexpiredinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/delexpiredinvoice';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body });
|
||||||
@ -26,7 +26,7 @@ export const listInvoices = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listinvoices';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listinvoices';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -43,7 +43,7 @@ export const addInvoice = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/invoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoice';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body });
|
||||||
|
@ -10,7 +10,7 @@ export const getRoute = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/getroute';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getroute';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body });
|
||||||
@ -29,7 +29,7 @@ export const listChannels = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listchannels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listchannels';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body });
|
||||||
@ -40,15 +40,16 @@ export const listChannels = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const feeRates = (req, res, next) => {
|
export const feeRates = (req, res, next) => {
|
||||||
|
const { style } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Fee Rates..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Fee Rates..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/feerates';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/feerates';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + req.body.style, data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
const err = common.handleError(errRes, 'Network', 'Fee Rates Error', req.session.selectedNode);
|
const err = common.handleError(errRes, 'Network', 'Fee Rates Error', req.session.selectedNode);
|
||||||
@ -56,14 +57,14 @@ export const feeRates = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const listNodes = (req, res, next) => {
|
export const listNodes = (req, res, next) => {
|
||||||
|
const filter_liquidity_ads = !!req.body.liquidity_ads;
|
||||||
|
delete req.body.liquidity_ads;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listnodes';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listnodes';
|
||||||
const filter_liquidity_ads = !!req.body.liquidity_ads;
|
|
||||||
delete req.body.liquidity_ads;
|
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -79,7 +80,7 @@ export const listNodes = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const getAlias = (selNode, peer, id) => {
|
export const getAlias = (selNode, peer, id) => {
|
||||||
options.url = selNode.ln_server_url + '/v1/listnodes';
|
options.url = selNode.settings.lnServerUrl + '/v1/listnodes';
|
||||||
if (!peer[id]) {
|
if (!peer[id]) {
|
||||||
logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' });
|
logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' });
|
||||||
peer.alias = '';
|
peer.alias = '';
|
||||||
|
@ -18,10 +18,11 @@ export const listOfferBookmarks = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const deleteOfferBookmark = (req, res, next) => {
|
export const deleteOfferBookmark = (req, res, next) => {
|
||||||
|
const { offer_str } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Deleting Offer Bookmark..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Deleting Offer Bookmark..' });
|
||||||
databaseService.remove(req.session.selectedNode, CollectionsEnum.OFFERS, CollectionFieldsEnum.BOLT12, req.body.offer_str).then((deleteRes) => {
|
databaseService.remove(req.session.selectedNode, CollectionsEnum.OFFERS, CollectionFieldsEnum.BOLT12, offer_str).then((deleteRes) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmark Deleted', data: deleteRes });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmark Deleted', data: deleteRes });
|
||||||
res.status(204).json(req.body.offer_str);
|
res.status(204).json(offer_str);
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
const err = common.handleError(errRes, 'Offers', 'Offer Bookmark Delete Error', req.session.selectedNode);
|
const err = common.handleError(errRes, 'Offers', 'Offer Bookmark Delete Error', req.session.selectedNode);
|
||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
@ -33,7 +34,7 @@ export const listOffers = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listoffers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listoffers';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body });
|
||||||
@ -49,7 +50,7 @@ export const createOffer = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/offer';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/offer';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body });
|
||||||
@ -65,7 +66,7 @@ export const fetchOfferInvoice = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/fetchinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fetchinvoice';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -82,7 +83,7 @@ export const disableOffer = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/disableOffer';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disableOffer';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body });
|
||||||
|
@ -10,7 +10,7 @@ export const getNewAddress = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/newaddr';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddr';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
|
||||||
@ -26,7 +26,7 @@ export const onChainWithdraw = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/withdraw';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/withdraw';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -43,7 +43,7 @@ export const getUTXOs = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listfunds';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listfunds';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
|
||||||
// Local Remote Balance Calculation
|
// Local Remote Balance Calculation
|
||||||
|
@ -8,7 +8,7 @@ const logger = Logger;
|
|||||||
const common = Common;
|
const common = Common;
|
||||||
const databaseService = Database;
|
const databaseService = Database;
|
||||||
export const getMemo = (selNode, payment) => {
|
export const getMemo = (selNode, payment) => {
|
||||||
options.url = selNode.ln_server_url + '/v1/decode';
|
options.url = selNode.settings.lnServerUrl + '/v1/decode';
|
||||||
options.body = { string: payment.bolt11 };
|
options.body = { string: payment.bolt11 };
|
||||||
return request.post(options).then((res) => {
|
return request.post(options).then((res) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
|
||||||
@ -81,7 +81,7 @@ export const listPayments = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listsendpays';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listsendpays';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments });
|
||||||
body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : [];
|
body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : [];
|
||||||
@ -95,14 +95,15 @@ export const listPayments = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const postPayment = (req, res, next) => {
|
export const postPayment = (req, res, next) => {
|
||||||
|
const { paymentType, saveToDB, bolt12, zeroAmtOffer, amount_msat, title, issuer, description } = req.body;
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
const options_body = JSON.parse(JSON.stringify(req.body));
|
const options_body = JSON.parse(JSON.stringify(req.body));
|
||||||
if (req.body.paymentType === 'KEYSEND') {
|
if (paymentType === 'KEYSEND') {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/keysend';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/keysend';
|
||||||
delete options_body.uiMessage;
|
delete options_body.uiMessage;
|
||||||
delete options_body.fromDialog;
|
delete options_body.fromDialog;
|
||||||
delete options_body.paymentType;
|
delete options_body.paymentType;
|
||||||
@ -121,13 +122,13 @@ export const postPayment = (req, res, next) => {
|
|||||||
options.body = options_body;
|
options.body = options_body;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (req.body.paymentType === 'OFFER') {
|
if (paymentType === 'OFFER') {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Offer Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Offer Payment..' });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' });
|
||||||
}
|
}
|
||||||
if (req.body.paymentType === 'OFFER') {
|
if (paymentType === 'OFFER') {
|
||||||
// delete amount for zero amt offer also as fetchinvoice already has amount information
|
// delete amount for zero amt offer also as fetchinvoice already has amount information
|
||||||
delete options_body.amount_msat;
|
delete options_body.amount_msat;
|
||||||
}
|
}
|
||||||
@ -143,22 +144,22 @@ export const postPayment = (req, res, next) => {
|
|||||||
delete options_body.pubkey;
|
delete options_body.pubkey;
|
||||||
delete options_body.saveToDB;
|
delete options_body.saveToDB;
|
||||||
options.body = options_body;
|
options.body = options_body;
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/pay';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/pay';
|
||||||
}
|
}
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body });
|
||||||
if (req.body.paymentType === 'OFFER') {
|
if (paymentType === 'OFFER') {
|
||||||
if (req.body.saveToDB && req.body.bolt12) {
|
if (saveToDB && bolt12) {
|
||||||
const offerToUpdate = { bolt12: req.body.bolt12, amountMSat: (req.body.zeroAmtOffer ? 0 : req.body.amount_msat), title: req.body.title, lastUpdatedAt: new Date(Date.now()).getTime() };
|
const offerToUpdate = { bolt12: bolt12, amountMSat: (zeroAmtOffer ? 0 : amount_msat), title: title, lastUpdatedAt: new Date(Date.now()).getTime() };
|
||||||
if (req.body.issuer) {
|
if (issuer) {
|
||||||
offerToUpdate['issuer'] = req.body.issuer;
|
offerToUpdate['issuer'] = issuer;
|
||||||
}
|
}
|
||||||
if (req.body.description) {
|
if (description) {
|
||||||
offerToUpdate['description'] = req.body.description;
|
offerToUpdate['description'] = description;
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line arrow-body-style
|
// eslint-disable-next-line arrow-body-style
|
||||||
return databaseService.validateDocument(CollectionsEnum.OFFERS, offerToUpdate).then((validated) => {
|
return databaseService.validateDocument(CollectionsEnum.OFFERS, offerToUpdate).then((validated) => {
|
||||||
return databaseService.update(req.session.selectedNode, CollectionsEnum.OFFERS, offerToUpdate, CollectionFieldsEnum.BOLT12, req.body.bolt12).then((updatedOffer) => {
|
return databaseService.update(req.session.selectedNode, CollectionsEnum.OFFERS, offerToUpdate, CollectionFieldsEnum.BOLT12, bolt12).then((updatedOffer) => {
|
||||||
logger.log({ level: 'DEBUG', fileName: 'Payments', msg: 'Offer Updated', data: updatedOffer });
|
logger.log({ level: 'DEBUG', fileName: 'Payments', msg: 'Offer Updated', data: updatedOffer });
|
||||||
return res.status(201).json({ paymentResponse: body, saveToDBResponse: updatedOffer });
|
return res.status(201).json({ paymentResponse: body, saveToDBResponse: updatedOffer });
|
||||||
}).catch((errDB) => {
|
}).catch((errDB) => {
|
||||||
@ -174,10 +175,10 @@ export const postPayment = (req, res, next) => {
|
|||||||
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (req.body.paymentType === 'INVOICE') {
|
if (paymentType === 'INVOICE') {
|
||||||
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
||||||
}
|
}
|
||||||
if (req.body.paymentType === 'KEYSEND') {
|
if (paymentType === 'KEYSEND') {
|
||||||
return res.status(201).json(body);
|
return res.status(201).json(body);
|
||||||
}
|
}
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
|
@ -11,7 +11,7 @@ export const getPeers = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
|
||||||
const peers = !body.peers ? [] : body.peers;
|
const peers = !body.peers ? [] : body.peers;
|
||||||
@ -30,12 +30,12 @@ export const postPeer = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/connect';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/connect';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((connectRes) => {
|
request.post(options).then((connectRes) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes });
|
||||||
const listOptions = common.getOptions(req);
|
const listOptions = common.getOptions(req);
|
||||||
listOptions.url = req.session.selectedNode.ln_server_url + '/v1/listpeers';
|
listOptions.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
|
||||||
request.post(listOptions).then((listPeersRes) => {
|
request.post(listOptions).then((listPeersRes) => {
|
||||||
const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : [];
|
const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : [];
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers });
|
||||||
@ -55,7 +55,7 @@ export const deletePeer = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/disconnect';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disconnect';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body });
|
||||||
|
@ -10,7 +10,7 @@ export const decodePayment = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/decode';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/decode';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
|
||||||
@ -26,7 +26,7 @@ export const signMessage = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
|
||||||
@ -42,7 +42,7 @@ export const verifyMessage = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/checkmessage';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/checkmessage';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options, (error, response, body) => {
|
request.post(options, (error, response, body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
|
||||||
@ -58,7 +58,7 @@ export const listConfigs = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listconfigs';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listconfigs';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
|
@ -27,14 +27,14 @@ export class CLWebSocketClient {
|
|||||||
try {
|
try {
|
||||||
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
||||||
if (!clientExists) {
|
if (!clientExists) {
|
||||||
if (selectedNode.ln_server_url) {
|
if (selectedNode.settings.lnServerUrl) {
|
||||||
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
|
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
|
||||||
this.connectWithClient(newWebSocketClient);
|
this.connectWithClient(newWebSocketClient);
|
||||||
this.webSocketClients.push(newWebSocketClient);
|
this.webSocketClients.push(newWebSocketClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.ln_server_url) {
|
if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.settings.lnServerUrl) {
|
||||||
clientExists.reConnect = true;
|
clientExists.reConnect = true;
|
||||||
this.connectWithClient(clientExists);
|
this.connectWithClient(clientExists);
|
||||||
}
|
}
|
||||||
@ -47,11 +47,11 @@ export class CLWebSocketClient {
|
|||||||
this.connectWithClient = (clWsClt) => {
|
this.connectWithClient = (clWsClt) => {
|
||||||
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' });
|
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' });
|
||||||
try {
|
try {
|
||||||
if (!clWsClt.selectedNode.rune_value) {
|
if (!clWsClt.selectedNode.authentication.runeValue) {
|
||||||
clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path);
|
clWsClt.selectedNode.authentication.runeValue = this.common.getRuneValue(clWsClt.selectedNode.authentication.runePath);
|
||||||
}
|
}
|
||||||
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, {
|
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.settings.lnServerUrl, {
|
||||||
extraHeaders: { rune: clWsClt.selectedNode.rune_value },
|
extraHeaders: { rune: clWsClt.selectedNode.authentication.runeValue },
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
secure: true,
|
secure: true,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
@ -65,7 +65,7 @@ export class CLWebSocketClient {
|
|||||||
this.waitTime = 0.5;
|
this.waitTime = 0.5;
|
||||||
});
|
});
|
||||||
clWsClt.webSocketClient.on('disconnect', (reason) => {
|
clWsClt.webSocketClient.on('disconnect', (reason) => {
|
||||||
if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.ln_implementation === 'CLN') {
|
if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.lnImplementation === 'CLN') {
|
||||||
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason });
|
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason });
|
||||||
clWsClt.webSocketClient.close();
|
clWsClt.webSocketClient.close();
|
||||||
if (clWsClt.reConnect) {
|
if (clWsClt.reConnect) {
|
||||||
|
@ -27,7 +27,7 @@ export const simplifyAllChannels = (selNode, channels) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
channelNodeIds = channelNodeIds.substring(1);
|
channelNodeIds = channelNodeIds.substring(1);
|
||||||
options.url = selNode.ln_server_url + '/nodes';
|
options.url = selNode.settings.lnServerUrl + '/nodes';
|
||||||
options.form = { nodeIds: channelNodeIds };
|
options.form = { nodeIds: channelNodeIds };
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds });
|
||||||
return request.post(options).then((nodes) => {
|
return request.post(options).then((nodes) => {
|
||||||
@ -47,7 +47,7 @@ export const getChannels = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/channels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/channels';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
if (req.query && req.query.nodeId) {
|
if (req.query && req.query.nodeId) {
|
||||||
options.form = req.query;
|
options.form = req.query;
|
||||||
@ -55,7 +55,7 @@ export const getChannels = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options });
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('Channels', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); });
|
common.getDummyData('Channels', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -83,7 +83,7 @@ export const getChannelStats = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/channelstats';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/channelstats';
|
||||||
const today = new Date(Date.now());
|
const today = new Date(Date.now());
|
||||||
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
||||||
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
||||||
@ -105,7 +105,7 @@ export const openChannel = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/open';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/open';
|
||||||
options.form = req.body;
|
options.form = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -122,7 +122,7 @@ export const updateChannelRelayFee = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/updaterelayfee';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/updaterelayfee';
|
||||||
options.form = req.query;
|
options.form = req.query;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -140,11 +140,11 @@ export const closeChannel = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
if (req.query.force !== 'true') {
|
if (req.query.force !== 'true') {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/close';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/close';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/forceclose';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/forceclose';
|
||||||
}
|
}
|
||||||
options.form = { channelId: req.query.channelId };
|
options.form = { channelId: req.query.channelId };
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url });
|
||||||
@ -158,7 +158,8 @@ export const closeChannel = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const circularRebalance = (req, res, next) => {
|
export const circularRebalance = (req, res, next) => {
|
||||||
const crInvDescription = 'Circular rebalancing invoice for ' + (req.body.amountMsat / 1000) + ' Sats';
|
const { amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format, sourceShortChannelId, targetShortChannelId } = req.body;
|
||||||
|
const crInvDescription = 'Circular rebalancing invoice for ' + (amountMsat / 1000) + ' Sats';
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
@ -168,22 +169,22 @@ export const circularRebalance = (req, res, next) => {
|
|||||||
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
||||||
// Check if unpaid Invoice exists already
|
// Check if unpaid Invoice exists already
|
||||||
listPendingInvoicesRequestCall(req.session.selectedNode).then((callRes) => {
|
listPendingInvoicesRequestCall(req.session.selectedNode).then((callRes) => {
|
||||||
const foundExistingInvoice = callRes.find((inv) => inv.description.includes(crInvDescription) && inv.amount === req.body.amountMsat && inv.expiry && inv.timestamp && ((inv.expiry + inv.timestamp) >= tillToday));
|
const foundExistingInvoice = callRes.find((inv) => inv.description.includes(crInvDescription) && inv.amount === amountMsat && inv.expiry && inv.timestamp && ((inv.expiry + inv.timestamp) >= tillToday));
|
||||||
// Create new invoice if doesn't exist already
|
// Create new invoice if doesn't exist already
|
||||||
const requestCalls = foundExistingInvoice && foundExistingInvoice.serialized ?
|
const requestCalls = foundExistingInvoice && foundExistingInvoice.serialized ?
|
||||||
[findRouteBetweenNodesRequestCall(req.session.selectedNode, req.body.amountMsat, req.body.sourceNodeId, req.body.targetNodeId, req.body.ignoreNodeIds, req.body.format)] :
|
[findRouteBetweenNodesRequestCall(req.session.selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format)] :
|
||||||
[findRouteBetweenNodesRequestCall(req.session.selectedNode, req.body.amountMsat, req.body.sourceNodeId, req.body.targetNodeId, req.body.ignoreNodeIds, req.body.format), createInvoiceRequestCall(req.session.selectedNode, crInvDescription, req.body.amountMsat)];
|
[findRouteBetweenNodesRequestCall(req.session.selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format), createInvoiceRequestCall(req.session.selectedNode, crInvDescription, amountMsat)];
|
||||||
Promise.all(requestCalls).then((values) => {
|
Promise.all(requestCalls).then((values) => {
|
||||||
// eslint-disable-next-line arrow-body-style
|
// eslint-disable-next-line arrow-body-style
|
||||||
const routes = values[0]?.routes?.filter((route) => {
|
const routes = values[0]?.routes?.filter((route) => {
|
||||||
return !((route.shortChannelIds[0] === req.body.sourceShortChannelId && route.shortChannelIds[1] === req.body.targetShortChannelId) ||
|
return !((route.shortChannelIds[0] === sourceShortChannelId && route.shortChannelIds[1] === targetShortChannelId) ||
|
||||||
(route.shortChannelIds[1] === req.body.sourceShortChannelId && route.shortChannelIds[0] === req.body.targetShortChannelId));
|
(route.shortChannelIds[1] === sourceShortChannelId && route.shortChannelIds[0] === targetShortChannelId));
|
||||||
});
|
});
|
||||||
const firstRoute = routes[0].shortChannelIds.join() || '';
|
const firstRoute = routes[0].shortChannelIds.join() || '';
|
||||||
const shortChannelIds = req.body.sourceShortChannelId + ',' + firstRoute + ',' + req.body.targetShortChannelId;
|
const shortChannelIds = sourceShortChannelId + ',' + firstRoute + ',' + targetShortChannelId;
|
||||||
const invoice = (foundExistingInvoice && foundExistingInvoice.serialized ? foundExistingInvoice.serialized : (values[1] ? values[1].serialized : '')) || '';
|
const invoice = (foundExistingInvoice && foundExistingInvoice.serialized ? foundExistingInvoice.serialized : (values[1] ? values[1].serialized : '')) || '';
|
||||||
const paymentHash = (foundExistingInvoice && foundExistingInvoice.paymentHash ? foundExistingInvoice.paymentHash : (values[1] ? values[1].paymentHash : '') || '');
|
const paymentHash = (foundExistingInvoice && foundExistingInvoice.paymentHash ? foundExistingInvoice.paymentHash : (values[1] ? values[1].paymentHash : '') || '');
|
||||||
return sendPaymentToRouteRequestCall(req.session.selectedNode, shortChannelIds, invoice, req.body.amountMsat).then((payToRouteCallRes) => {
|
return sendPaymentToRouteRequestCall(req.session.selectedNode, shortChannelIds, invoice, amountMsat).then((payToRouteCallRes) => {
|
||||||
// eslint-disable-next-line arrow-body-style
|
// eslint-disable-next-line arrow-body-style
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
return getSentInfoFromPaymentRequest(req.session.selectedNode, paymentHash).then((sentInfoCallRes) => {
|
return getSentInfoFromPaymentRequest(req.session.selectedNode, paymentHash).then((sentInfoCallRes) => {
|
||||||
|
@ -11,23 +11,24 @@ export const arrangeFees = (selNode, body, current_time) => {
|
|||||||
let fee = 0;
|
let fee = 0;
|
||||||
body.relayed.forEach((relayedEle) => {
|
body.relayed.forEach((relayedEle) => {
|
||||||
fee = Math.round((relayedEle.amountIn - relayedEle.amountOut) / 1000);
|
fee = Math.round((relayedEle.amountIn - relayedEle.amountOut) / 1000);
|
||||||
if (relayedEle.timestamp) {
|
const relayedEleTimestamp = relayedEle.settledAt ? relayedEle.settledAt : relayedEle.timestamp;
|
||||||
if (relayedEle.timestamp.unix) {
|
if (relayedEleTimestamp) {
|
||||||
if ((relayedEle.timestamp.unix * 1000) >= day_start_time) {
|
if (relayedEleTimestamp.unix) {
|
||||||
|
if ((relayedEleTimestamp.unix * 1000) >= day_start_time) {
|
||||||
fees.daily_fee = fees.daily_fee + fee;
|
fees.daily_fee = fees.daily_fee + fee;
|
||||||
fees.daily_txs = fees.daily_txs + 1;
|
fees.daily_txs = fees.daily_txs + 1;
|
||||||
}
|
}
|
||||||
if ((relayedEle.timestamp.unix * 1000) >= week_start_time) {
|
if ((relayedEleTimestamp.unix * 1000) >= week_start_time) {
|
||||||
fees.weekly_fee = fees.weekly_fee + fee;
|
fees.weekly_fee = fees.weekly_fee + fee;
|
||||||
fees.weekly_txs = fees.weekly_txs + 1;
|
fees.weekly_txs = fees.weekly_txs + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (relayedEle.timestamp >= day_start_time) {
|
if (relayedEleTimestamp >= day_start_time) {
|
||||||
fees.daily_fee = fees.daily_fee + fee;
|
fees.daily_fee = fees.daily_fee + fee;
|
||||||
fees.daily_txs = fees.daily_txs + 1;
|
fees.daily_txs = fees.daily_txs + 1;
|
||||||
}
|
}
|
||||||
if (relayedEle.timestamp >= week_start_time) {
|
if (relayedEleTimestamp >= week_start_time) {
|
||||||
fees.weekly_fee = fees.weekly_fee + fee;
|
fees.weekly_fee = fees.weekly_fee + fee;
|
||||||
fees.weekly_txs = fees.weekly_txs + 1;
|
fees.weekly_txs = fees.weekly_txs + 1;
|
||||||
}
|
}
|
||||||
@ -78,9 +79,10 @@ export const arrangePayments = (selNode, body) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
payments.relayed.forEach((relayedEle) => {
|
payments.relayed.forEach((relayedEle) => {
|
||||||
if (relayedEle.timestamp.unix) {
|
// Changing the timestamp value to keep the response backward compatible.
|
||||||
relayedEle.timestamp = relayedEle.timestamp.unix * 1000;
|
// ECL < 0.7.0 sent timestamp in unix milliseconds, then in {"iso", "unix"} object.
|
||||||
}
|
// From v0.10.0, it sends settledAt in {"iso", "unix"} object too.
|
||||||
|
relayedEle.timestamp = relayedEle.settledAt && relayedEle.settledAt.unix ? relayedEle.settledAt.unix * 1000 : relayedEle.timestamp && relayedEle.timestamp.unix ? relayedEle.timestamp.unix * 1000 : relayedEle.timestamp;
|
||||||
if (relayedEle.amountIn) {
|
if (relayedEle.amountIn) {
|
||||||
relayedEle.amountIn = Math.round(relayedEle.amountIn / 1000);
|
relayedEle.amountIn = Math.round(relayedEle.amountIn / 1000);
|
||||||
}
|
}
|
||||||
@ -97,7 +99,7 @@ export const getFees = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/audit';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
|
||||||
const today = new Date(Date.now());
|
const today = new Date(Date.now());
|
||||||
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
||||||
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
||||||
@ -107,7 +109,7 @@ export const getFees = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form });
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('Fees', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); });
|
common.getDummyData('Fees', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -125,11 +127,17 @@ export const getPayments = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/audit';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
|
||||||
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
||||||
options.form = { from: 0, to: tillToday };
|
options.form = { from: 0, to: tillToday };
|
||||||
|
if (req.query.count) {
|
||||||
|
options.form.count = req.query.count;
|
||||||
|
}
|
||||||
|
if (req.query.skip) {
|
||||||
|
options.form.skip = req.query.skip;
|
||||||
|
}
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('Payments', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
|
common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
|
@ -16,12 +16,12 @@ export const getInfo = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/getinfo';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/getinfo';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url });
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('GetInfo', req.session.selectedNode.ln_implementation).then((data) => {
|
common.getDummyData('GetInfo', req.session.selectedNode.lnImplementation).then((data) => {
|
||||||
data.lnImplementation = 'Eclair';
|
data.lnImplementation = 'Eclair';
|
||||||
return res.status(200).json(data);
|
return res.status(200).json(data);
|
||||||
});
|
});
|
||||||
@ -36,7 +36,7 @@ export const getInfo = (req, res, next) => {
|
|||||||
return request.post(options).then((body) => {
|
return request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' });
|
||||||
body.lnImplementation = 'Eclair';
|
body.lnImplementation = 'Eclair';
|
||||||
req.session.selectedNode.ln_version = body.version.split('-')[0] || '';
|
req.session.selectedNode.lnVersion = body.version.split('-')[0] || '';
|
||||||
eclWsClient.updateSelectedNode(req.session.selectedNode);
|
eclWsClient.updateSelectedNode(req.session.selectedNode);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
|
||||||
return res.status(200).json(body);
|
return res.status(200).json(body);
|
||||||
|
@ -39,7 +39,7 @@ export const getInvoice = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/getinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/getinvoice';
|
||||||
options.form = { paymentHash: req.params.paymentHash };
|
options.form = { paymentHash: req.params.paymentHash };
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body });
|
||||||
@ -53,11 +53,18 @@ export const getInvoice = (req, res, next) => {
|
|||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const listPendingInvoicesRequestCall = (selectedNode) => {
|
export const listPendingInvoicesRequestCall = (selectedNode, count, skip) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
|
||||||
options = selectedNode.options;
|
options = selectedNode.authentication.options;
|
||||||
options.url = selectedNode.ln_server_url + '/listpendinginvoices';
|
options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices';
|
||||||
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
|
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
|
||||||
|
// Limit the number of invoices till provided count
|
||||||
|
if (count) {
|
||||||
|
options.form.count = count;
|
||||||
|
}
|
||||||
|
if (skip) {
|
||||||
|
options.form.skip = skip;
|
||||||
|
}
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request.post(options).then((pendingInvoicesResponse) => {
|
request.post(options).then((pendingInvoicesResponse) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Pending Invoices List ', data: pendingInvoicesResponse });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Pending Invoices List ', data: pendingInvoicesResponse });
|
||||||
@ -74,29 +81,33 @@ export const listInvoices = (req, res, next) => {
|
|||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
||||||
options.form = { from: 0, to: tillToday };
|
|
||||||
const options1 = JSON.parse(JSON.stringify(options));
|
const options1 = JSON.parse(JSON.stringify(options));
|
||||||
options1.url = req.session.selectedNode.ln_server_url + '/listinvoices';
|
options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices';
|
||||||
options1.form = { from: 0, to: tillToday };
|
options1.form = { from: 0, to: tillToday };
|
||||||
|
if (req.query.count) {
|
||||||
|
options1.form.count = req.query.count;
|
||||||
|
}
|
||||||
|
if (req.query.skip) {
|
||||||
|
options1.form.skip = req.query.skip;
|
||||||
|
}
|
||||||
const options2 = JSON.parse(JSON.stringify(options));
|
const options2 = JSON.parse(JSON.stringify(options));
|
||||||
options2.url = req.session.selectedNode.ln_server_url + '/listpendinginvoices';
|
options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices';
|
||||||
options2.form = { from: 0, to: tillToday };
|
options2.form = { from: 0, to: tillToday };
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => {
|
return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then(([invoices, pendingInvoicesRes]) => {
|
||||||
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
|
pendingInvoices = pendingInvoicesRes;
|
||||||
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
|
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
|
||||||
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
|
|
||||||
then((values) => res.status(200).json(invoices));
|
then((values) => res.status(200).json(invoices));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Promise.all([request(options1), request(options2)]).
|
return Promise.all([request(options1), request(options2)]).
|
||||||
then((body) => {
|
then(([invoices, pendingInvoicesRes]) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: invoices });
|
||||||
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
|
// pendingInvoices will be used to get the status (paid/unpaid) of the invoice via getReceivedPaymentInfo
|
||||||
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
|
pendingInvoices = pendingInvoicesRes;
|
||||||
if (invoices && invoices.length > 0) {
|
if (invoices && invoices.length > 0) {
|
||||||
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
|
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
|
||||||
then((values) => {
|
then((values) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices });
|
||||||
return res.status(200).json(invoices);
|
return res.status(200).json(invoices);
|
||||||
@ -119,8 +130,8 @@ export const listInvoices = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
export const createInvoiceRequestCall = (selectedNode, description, amount) => {
|
export const createInvoiceRequestCall = (selectedNode, description, amount) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
||||||
options = selectedNode.options;
|
options = selectedNode.authentication.options;
|
||||||
options.url = selectedNode.ln_server_url + '/createinvoice';
|
options.url = selectedNode.settings.lnServerUrl + '/createinvoice';
|
||||||
options.form = { description: description, amountMsat: amount };
|
options.form = { description: description, amountMsat: amount };
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request.post(options).then((invResponse) => {
|
request.post(options).then((invResponse) => {
|
||||||
@ -135,12 +146,13 @@ export const createInvoiceRequestCall = (selectedNode, description, amount) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const createInvoice = (req, res, next) => {
|
export const createInvoice = (req, res, next) => {
|
||||||
|
const { description, amountMsat } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
createInvoiceRequestCall(req.session.selectedNode, req.body.description, req.body.amountMsat).then((invRes) => {
|
createInvoiceRequestCall(req.session.selectedNode, description, amountMsat).then((invRes) => {
|
||||||
res.status(201).json(invRes);
|
res.status(201).json(invRes);
|
||||||
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
||||||
};
|
};
|
||||||
|
@ -10,7 +10,7 @@ export const getNodes = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/nodes';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/nodes';
|
||||||
options.form = { nodeIds: req.params.id };
|
options.form = { nodeIds: req.params.id };
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body });
|
||||||
@ -22,8 +22,8 @@ export const getNodes = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
export const findRouteBetweenNodesRequestCall = (selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds = [], format = 'shortChannelId') => {
|
export const findRouteBetweenNodesRequestCall = (selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds = [], format = 'shortChannelId') => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' });
|
||||||
options = selectedNode.options;
|
options = selectedNode.authentication.options;
|
||||||
options.url = selectedNode.ln_server_url + '/findroutebetweennodes';
|
options.url = selectedNode.settings.lnServerUrl + '/findroutebetweennodes';
|
||||||
options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format };
|
options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format };
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -35,11 +35,12 @@ export const findRouteBetweenNodesRequestCall = (selectedNode, amountMsat, sourc
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const findRouteBetweenNodes = (req, res, next) => {
|
export const findRouteBetweenNodes = (req, res, next) => {
|
||||||
|
const { amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format } = req.body;
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
findRouteBetweenNodesRequestCall(req.session.selectedNode, req.body.amountMsat, req.body.sourceNodeId, req.body.targetNodeId, req.body.ignoreNodeIds, req.body.format).then((callRes) => {
|
findRouteBetweenNodesRequestCall(req.session.selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format).then((callRes) => {
|
||||||
res.status(200).json(callRes);
|
res.status(200).json(callRes);
|
||||||
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
||||||
};
|
};
|
||||||
|
@ -21,7 +21,7 @@ export const getNewAddress = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/getnewaddress';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/getnewaddress';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
|
||||||
@ -37,10 +37,10 @@ export const getBalance = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/onchainbalance';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/onchainbalance';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('OnChainBalance', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeBalances(data)); });
|
common.getDummyData('OnChainBalance', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeBalances(data)); });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -59,7 +59,7 @@ export const getTransactions = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/onchaintransactions';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/onchaintransactions';
|
||||||
options.form = {
|
options.form = {
|
||||||
count: req.query.count,
|
count: req.query.count,
|
||||||
skip: req.query.skip
|
skip: req.query.skip
|
||||||
@ -74,17 +74,14 @@ export const getTransactions = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const sendFunds = (req, res, next) => {
|
export const sendFunds = (req, res, next) => {
|
||||||
|
const { address, amount, blocks } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Sending On Chain Funds..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Sending On Chain Funds..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/sendonchain';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/sendonchain';
|
||||||
options.form = {
|
options.form = { address: address, amountSatoshis: amount, confirmationTarget: blocks };
|
||||||
address: req.body.address,
|
|
||||||
amountSatoshis: req.body.amount,
|
|
||||||
confirmationTarget: req.body.blocks
|
|
||||||
};
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Onchain', msg: 'Send Funds Options', data: options.form });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Onchain', msg: 'On Chain Funds Sent', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Onchain', msg: 'On Chain Funds Sent', data: body });
|
||||||
|
@ -5,7 +5,7 @@ let options = null;
|
|||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
export const getSentInfoFromPaymentRequest = (selNode, payment) => {
|
export const getSentInfoFromPaymentRequest = (selNode, payment) => {
|
||||||
options.url = selNode.ln_server_url + '/getsentinfo';
|
options.url = selNode.settings.lnServerUrl + '/getsentinfo';
|
||||||
options.form = { paymentHash: payment };
|
options.form = { paymentHash: payment };
|
||||||
return request.post(options).then((body) => {
|
return request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Information Received', data: body });
|
||||||
@ -21,7 +21,7 @@ export const getSentInfoFromPaymentRequest = (selNode, payment) => {
|
|||||||
}).catch((err) => err);
|
}).catch((err) => err);
|
||||||
};
|
};
|
||||||
export const getQueryNodes = (selNode, nodeIds) => {
|
export const getQueryNodes = (selNode, nodeIds) => {
|
||||||
options.url = selNode.ln_server_url + '/nodes';
|
options.url = selNode.settings.lnServerUrl + '/nodes';
|
||||||
options.form = { nodeIds: nodeIds?.reduce((acc, curr) => acc + ',' + curr) };
|
options.form = { nodeIds: nodeIds?.reduce((acc, curr) => acc + ',' + curr) };
|
||||||
return request.post(options).then((nodes) => {
|
return request.post(options).then((nodes) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Query Nodes Received', data: nodes });
|
||||||
@ -34,7 +34,7 @@ export const decodePayment = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/parseinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/parseinvoice';
|
||||||
options.form = { invoice: req.params.invoice };
|
options.form = { invoice: req.params.invoice };
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
|
||||||
@ -53,7 +53,7 @@ export const postPayment = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/payinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/payinvoice';
|
||||||
options.form = req.body;
|
options.form = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Options', data: options.form });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -70,7 +70,7 @@ export const queryPaymentRoute = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/findroutetonode';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/findroutetonode';
|
||||||
options.form = {
|
options.form = {
|
||||||
nodeId: req.query.nodeId,
|
nodeId: req.query.nodeId,
|
||||||
amountMsat: req.query.amountMsat
|
amountMsat: req.query.amountMsat
|
||||||
@ -104,13 +104,14 @@ export const queryPaymentRoute = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const getSentPaymentsInformation = (req, res, next) => {
|
export const getSentPaymentsInformation = (req, res, next) => {
|
||||||
|
const { payments } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting Sent Payment Information..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting Sent Payment Information..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
if (req.body.payments) {
|
if (payments) {
|
||||||
const paymentsArr = req.body.payments.split(',');
|
const paymentsArr = payments.split(',');
|
||||||
return Promise.all(paymentsArr?.map((payment) => getSentInfoFromPaymentRequest(req.session.selectedNode, payment))).
|
return Promise.all(paymentsArr?.map((payment) => getSentInfoFromPaymentRequest(req.session.selectedNode, payment))).
|
||||||
then((values) => {
|
then((values) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent Information Received', data: values });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent Information Received', data: values });
|
||||||
@ -128,8 +129,8 @@ export const getSentPaymentsInformation = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
export const sendPaymentToRouteRequestCall = (selectedNode, shortChannelIds, invoice, amountMsat) => {
|
export const sendPaymentToRouteRequestCall = (selectedNode, shortChannelIds, invoice, amountMsat) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
||||||
options = selectedNode.options;
|
options = selectedNode.authentication.options;
|
||||||
options.url = selectedNode.ln_server_url + '/sendtoroute';
|
options.url = selectedNode.settings.lnServerUrl + '/sendtoroute';
|
||||||
options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice };
|
options.form = { shortChannelIds: shortChannelIds, amountMsat: amountMsat, invoice: invoice };
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form });
|
logger.log({ selectedNode: selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment To Route Options', data: options.form });
|
||||||
@ -142,12 +143,13 @@ export const sendPaymentToRouteRequestCall = (selectedNode, shortChannelIds, inv
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const sendPaymentToRoute = (req, res, next) => {
|
export const sendPaymentToRoute = (req, res, next) => {
|
||||||
|
const { shortChannelIds, invoice, amountMsat } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Send Payment To Route..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Send Payment To Route..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
sendPaymentToRouteRequestCall(req.session.selectedNode, req.body.shortChannelIds, req.body.invoice, req.body.amountMsat).then((callRes) => {
|
sendPaymentToRouteRequestCall(req.session.selectedNode, shortChannelIds, invoice, amountMsat).then((callRes) => {
|
||||||
res.status(200).json(callRes);
|
res.status(200).json(callRes);
|
||||||
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@ let options = null;
|
|||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
export const getFilteredNodes = (selNode, peersNodeIds) => {
|
export const getFilteredNodes = (selNode, peersNodeIds) => {
|
||||||
options.url = selNode.ln_server_url + '/nodes';
|
options.url = selNode.settings.lnServerUrl + '/nodes';
|
||||||
options.form = { nodeIds: peersNodeIds };
|
options.form = { nodeIds: peersNodeIds };
|
||||||
return request.post(options).then((nodes) => {
|
return request.post(options).then((nodes) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Filtered Nodes Received', data: nodes });
|
||||||
@ -18,10 +18,10 @@ export const getPeers = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/peers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/peers';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('Peers', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); });
|
common.getDummyData('Peers', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -58,7 +58,7 @@ export const connectPeer = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/connect';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/connect';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
if (req.query) {
|
if (req.query) {
|
||||||
options.form = req.query;
|
options.form = req.query;
|
||||||
@ -74,7 +74,7 @@ export const connectPeer = (req, res, next) => {
|
|||||||
const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, req.session.selectedNode);
|
const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body, req.session.selectedNode);
|
||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/peers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/peers';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List after Connect', data: body });
|
||||||
@ -112,7 +112,7 @@ export const deletePeer = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/disconnect';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/disconnect';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
if (req.params.nodeId) {
|
if (req.params.nodeId) {
|
||||||
options.form = { nodeId: req.params.nodeId };
|
options.form = { nodeId: req.params.nodeId };
|
||||||
|
@ -28,14 +28,14 @@ export class ECLWebSocketClient {
|
|||||||
try {
|
try {
|
||||||
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
||||||
if (!clientExists) {
|
if (!clientExists) {
|
||||||
if (selectedNode.ln_server_url) {
|
if (selectedNode.settings.lnServerUrl) {
|
||||||
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
|
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
|
||||||
this.connectWithClient(newWebSocketClient);
|
this.connectWithClient(newWebSocketClient);
|
||||||
this.webSocketClients.push(newWebSocketClient);
|
this.webSocketClients.push(newWebSocketClient);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.ln_server_url) {
|
if ((!clientExists.webSocketClient || clientExists.webSocketClient.readyState !== WebSocket.OPEN) && selectedNode.settings.lnServerUrl) {
|
||||||
clientExists.reConnect = true;
|
clientExists.reConnect = true;
|
||||||
this.connectWithClient(clientExists);
|
this.connectWithClient(clientExists);
|
||||||
}
|
}
|
||||||
@ -47,9 +47,9 @@ export class ECLWebSocketClient {
|
|||||||
};
|
};
|
||||||
this.connectWithClient = (eclWsClt) => {
|
this.connectWithClient = (eclWsClt) => {
|
||||||
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' });
|
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connecting to the Eclair\'s Websocket Server..' });
|
||||||
const UpdatedLNServerURL = (eclWsClt.selectedNode.ln_server_url)?.replace(/^http/, 'ws');
|
const UpdatedLNServerURL = (eclWsClt.selectedNode.settings.lnServerUrl)?.replace(/^http/, 'ws');
|
||||||
const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2);
|
const firstSubStrIndex = (UpdatedLNServerURL.indexOf('//') + 2);
|
||||||
const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.ln_api_password + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws';
|
const WS_LINK = UpdatedLNServerURL.slice(0, firstSubStrIndex) + ':' + eclWsClt.selectedNode.authentication.lnApiPassword + '@' + UpdatedLNServerURL.slice(firstSubStrIndex) + '/ws';
|
||||||
eclWsClt.webSocketClient = new WebSocket(WS_LINK);
|
eclWsClt.webSocketClient = new WebSocket(WS_LINK);
|
||||||
eclWsClt.webSocketClient.onopen = () => {
|
eclWsClt.webSocketClient.onopen = () => {
|
||||||
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' });
|
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Connected to the Eclair\'s Websocket Server..' });
|
||||||
@ -57,7 +57,7 @@ export class ECLWebSocketClient {
|
|||||||
this.heartbeat(eclWsClt);
|
this.heartbeat(eclWsClt);
|
||||||
};
|
};
|
||||||
eclWsClt.webSocketClient.onclose = (e) => {
|
eclWsClt.webSocketClient.onclose = (e) => {
|
||||||
if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.ln_implementation === 'ECL') {
|
if (eclWsClt && eclWsClt.selectedNode && eclWsClt.selectedNode.lnImplementation === 'ECL') {
|
||||||
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' });
|
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'INFO', fileName: 'ECLWebSocket', msg: 'Web socket disconnected, will reconnect again...' });
|
||||||
eclWsClt.webSocketClient.close();
|
eclWsClt.webSocketClient.close();
|
||||||
if (eclWsClt.reConnect) {
|
if (eclWsClt.reConnect) {
|
||||||
@ -75,7 +75,7 @@ export class ECLWebSocketClient {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
eclWsClt.webSocketClient.onerror = (err) => {
|
eclWsClt.webSocketClient.onerror = (err) => {
|
||||||
if (eclWsClt.selectedNode.ln_version === '' || !eclWsClt.selectedNode.ln_version || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) {
|
if (eclWsClt.selectedNode.lnVersion === '' || !eclWsClt.selectedNode.lnVersion || this.common.isVersionCompatible(eclWsClt.selectedNode.ln, '0.5.0')) {
|
||||||
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err });
|
this.logger.log({ selectedNode: eclWsClt.selectedNode, level: 'ERROR', fileName: 'ECLWebSocket', msg: 'Web socket error', error: err });
|
||||||
const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }'));
|
const errStr = ((typeof err === 'object' && err.message) ? JSON.stringify({ error: err.message }) : (typeof err === 'object') ? JSON.stringify({ error: err }) : ('{ "error": ' + err + ' }'));
|
||||||
this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode);
|
this.wsServer.sendErrorToAllLNClients(errStr, eclWsClt.selectedNode);
|
||||||
|
@ -10,7 +10,7 @@ export const getBlockchainBalance = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/balance/blockchain';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/balance/blockchain';
|
||||||
options.qs = req.query;
|
options.qs = req.query;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request params', data: req.params });
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Balance', msg: 'Request Query', data: req.query });
|
||||||
|
@ -6,7 +6,7 @@ const logger = Logger;
|
|||||||
const common = Common;
|
const common = Common;
|
||||||
export const getAliasForChannel = (selNode, channel) => {
|
export const getAliasForChannel = (selNode, channel) => {
|
||||||
const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : '';
|
const pubkey = (channel.remote_pubkey) ? channel.remote_pubkey : (channel.remote_node_pub) ? channel.remote_node_pub : '';
|
||||||
options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey;
|
options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey;
|
||||||
return request(options).then((aliasBody) => {
|
return request(options).then((aliasBody) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Alias Received', data: aliasBody.node.alias });
|
||||||
channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20);
|
channel.remote_alias = aliasBody.node.alias && aliasBody.node.alias !== '' ? aliasBody.node.alias : aliasBody.node.pub_key.slice(0, 20);
|
||||||
@ -22,7 +22,7 @@ export const getAllChannels = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels';
|
||||||
options.qs = req.query;
|
options.qs = req.query;
|
||||||
let local = 0;
|
let local = 0;
|
||||||
let remote = 0;
|
let remote = 0;
|
||||||
@ -60,7 +60,7 @@ export const getPendingChannels = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/pending';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/pending';
|
||||||
options.qs = req.query;
|
options.qs = req.query;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
if (!body.total_limbo_balance) {
|
if (!body.total_limbo_balance) {
|
||||||
@ -98,7 +98,7 @@ export const getClosedChannels = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/closed';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/closed';
|
||||||
options.qs = req.query;
|
options.qs = req.query;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
if (body.channels && body.channels.length > 0) {
|
if (body.channels && body.channels.length > 0) {
|
||||||
@ -123,26 +123,27 @@ export const getClosedChannels = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const postChannel = (req, res, next) => {
|
export const postChannel = (req, res, next) => {
|
||||||
|
const { node_pubkey, private: privateChannel, spend_unconfirmed, local_funding_amount, trans_type, trans_type_value, commitment_type } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels';
|
||||||
options.form = {
|
options.form = {
|
||||||
node_pubkey_string: req.body.node_pubkey,
|
node_pubkey_string: node_pubkey,
|
||||||
local_funding_amount: req.body.local_funding_amount,
|
local_funding_amount: local_funding_amount,
|
||||||
private: req.body.private,
|
private: privateChannel,
|
||||||
spend_unconfirmed: req.body.spend_unconfirmed
|
spend_unconfirmed: spend_unconfirmed
|
||||||
};
|
};
|
||||||
if (req.body.trans_type === '1') {
|
if (trans_type === '1') {
|
||||||
options.form.target_conf = req.body.trans_type_value;
|
options.form.target_conf = trans_type_value;
|
||||||
}
|
}
|
||||||
else if (req.body.trans_type === '2') {
|
else if (trans_type === '2') {
|
||||||
options.form.sat_per_byte = req.body.trans_type_value;
|
options.form.sat_per_byte = trans_type_value;
|
||||||
}
|
}
|
||||||
if (req.body.commitment_type) {
|
if (commitment_type) {
|
||||||
options.form.commitment_type = req.body.commitment_type;
|
options.form.commitment_type = commitment_type;
|
||||||
}
|
}
|
||||||
options.form = JSON.stringify(options.form);
|
options.form = JSON.stringify(options.form);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channel Open Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channel Open Options', data: options.form });
|
||||||
@ -155,27 +156,28 @@ export const postChannel = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const postTransactions = (req, res, next) => {
|
export const postTransactions = (req, res, next) => {
|
||||||
|
const { paymentReq, paymentAmount, feeLimit, outgoingChannel, allowSelfPayment, lastHopPubkey } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Sending Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Sending Payment..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/transaction-stream';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/transaction-stream';
|
||||||
options.form = { payment_request: req.body.paymentReq };
|
options.form = { payment_request: paymentReq };
|
||||||
if (req.body.paymentAmount) {
|
if (paymentAmount) {
|
||||||
options.form.amt = req.body.paymentAmount;
|
options.form.amt = paymentAmount;
|
||||||
}
|
}
|
||||||
if (req.body.feeLimit) {
|
if (feeLimit) {
|
||||||
options.form.fee_limit = req.body.feeLimit;
|
options.form.fee_limit = feeLimit;
|
||||||
}
|
}
|
||||||
if (req.body.outgoingChannel) {
|
if (outgoingChannel) {
|
||||||
options.form.outgoing_chan_id = req.body.outgoingChannel;
|
options.form.outgoing_chan_id = outgoingChannel;
|
||||||
}
|
}
|
||||||
if (req.body.allowSelfPayment) {
|
if (allowSelfPayment) {
|
||||||
options.form.allow_self_payment = req.body.allowSelfPayment;
|
options.form.allow_self_payment = allowSelfPayment;
|
||||||
}
|
}
|
||||||
if (req.body.lastHopPubkey) {
|
if (lastHopPubkey) {
|
||||||
options.form.last_hop_pubkey = Buffer.from(req.body.lastHopPubkey, 'hex').toString('base64');
|
options.form.last_hop_pubkey = Buffer.from(lastHopPubkey, 'hex').toString('base64');
|
||||||
}
|
}
|
||||||
options.form = JSON.stringify(options.form);
|
options.form = JSON.stringify(options.form);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Send Payment Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Send Payment Options', data: options.form });
|
||||||
@ -206,7 +208,7 @@ export const closeChannel = (req, res, next) => {
|
|||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
const channelpoint = req.params.channelPoint?.replace(':', '/');
|
const channelpoint = req.params.channelPoint?.replace(':', '/');
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/' + channelpoint + '?force=' + req.query.force;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/' + channelpoint + '?force=' + req.query.force;
|
||||||
if (req.query.target_conf) {
|
if (req.query.target_conf) {
|
||||||
options.url = options.url + '&target_conf=' + req.query.target_conf;
|
options.url = options.url + '&target_conf=' + req.query.target_conf;
|
||||||
}
|
}
|
||||||
@ -224,35 +226,36 @@ export const closeChannel = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const postChanPolicy = (req, res, next) => {
|
export const postChanPolicy = (req, res, next) => {
|
||||||
|
const { chanPoint, baseFeeMsat, feeRate, timeLockDelta, max_htlc_msat, min_htlc_msat } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Policy..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Policy..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/chanpolicy';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/chanpolicy';
|
||||||
if (req.body.chanPoint === 'all') {
|
if (chanPoint === 'all') {
|
||||||
options.form = JSON.stringify({
|
options.form = JSON.stringify({
|
||||||
global: true,
|
global: true,
|
||||||
base_fee_msat: req.body.baseFeeMsat,
|
base_fee_msat: baseFeeMsat,
|
||||||
fee_rate: parseFloat((req.body.feeRate / 1000000).toString()),
|
fee_rate: parseFloat((feeRate / 1000000).toString()),
|
||||||
time_lock_delta: parseInt(req.body.timeLockDelta)
|
time_lock_delta: parseInt(timeLockDelta)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const breakPoint = req.body.chanPoint.indexOf(':');
|
const breakPoint = chanPoint.indexOf(':');
|
||||||
const txid_str = req.body.chanPoint.substring(0, breakPoint);
|
const txid_str = chanPoint.substring(0, breakPoint);
|
||||||
const output_idx = req.body.chanPoint.substring(breakPoint + 1, req.body.chanPoint.length);
|
const output_idx = chanPoint.substring(breakPoint + 1, chanPoint.length);
|
||||||
const optionsBody = {
|
const optionsBody = {
|
||||||
base_fee_msat: req.body.baseFeeMsat,
|
base_fee_msat: baseFeeMsat,
|
||||||
fee_rate: parseFloat((req.body.feeRate / 1000000).toString()),
|
fee_rate: parseFloat((feeRate / 1000000).toString()),
|
||||||
time_lock_delta: parseInt(req.body.timeLockDelta),
|
time_lock_delta: parseInt(timeLockDelta),
|
||||||
chan_point: { funding_txid_str: txid_str, output_index: parseInt(output_idx) }
|
chan_point: { funding_txid_str: txid_str, output_index: parseInt(output_idx) }
|
||||||
};
|
};
|
||||||
if (req.body.max_htlc_msat) {
|
if (max_htlc_msat) {
|
||||||
optionsBody['max_htlc_msat'] = req.body.max_htlc_msat;
|
optionsBody['max_htlc_msat'] = max_htlc_msat;
|
||||||
}
|
}
|
||||||
if (req.body.min_htlc_msat) {
|
if (min_htlc_msat) {
|
||||||
optionsBody['min_htlc_msat'] = req.body.min_htlc_msat;
|
optionsBody['min_htlc_msat'] = min_htlc_msat;
|
||||||
optionsBody['min_htlc_msat_specified'] = true;
|
optionsBody['min_htlc_msat_specified'] = true;
|
||||||
}
|
}
|
||||||
options.form = JSON.stringify(optionsBody);
|
options.form = JSON.stringify(optionsBody);
|
||||||
|
@ -39,15 +39,15 @@ export const getBackup = (req, res, next) => {
|
|||||||
let channel_backup_file = '';
|
let channel_backup_file = '';
|
||||||
let message = '';
|
let message = '';
|
||||||
if (req.params.channelPoint === 'ALL') {
|
if (req.params.channelPoint === 'ALL') {
|
||||||
channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak';
|
channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak';
|
||||||
message = 'All Channels Backup Successful.';
|
message = 'All Channels Backup Successful.';
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
channel_backup_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
|
channel_backup_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
|
||||||
message = 'Channel Backup Successful.';
|
message = 'Channel Backup Successful.';
|
||||||
const channelpoint = req.params.channelPoint?.replace(':', '/');
|
const channelpoint = req.params.channelPoint?.replace(':', '/');
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/' + channelpoint;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/' + channelpoint;
|
||||||
const exists = fs.existsSync(channel_backup_file);
|
const exists = fs.existsSync(channel_backup_file);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
fs.writeFile(channel_backup_file, '', () => { });
|
fs.writeFile(channel_backup_file, '', () => { });
|
||||||
@ -86,13 +86,13 @@ export const postBackupVerify = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/verify';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/verify';
|
||||||
let channel_verify_file = '';
|
let channel_verify_file = '';
|
||||||
let message = '';
|
let message = '';
|
||||||
let verify_backup = '';
|
let verify_backup = '';
|
||||||
if (req.params.channelPoint === 'ALL') {
|
if (req.params.channelPoint === 'ALL') {
|
||||||
message = 'All Channels Verify Successful.';
|
message = 'All Channels Verify Successful.';
|
||||||
channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-all.bak';
|
channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-all.bak';
|
||||||
const exists = fs.existsSync(channel_verify_file);
|
const exists = fs.existsSync(channel_verify_file);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
verify_backup = fs.readFileSync(channel_verify_file, 'utf-8');
|
verify_backup = fs.readFileSync(channel_verify_file, 'utf-8');
|
||||||
@ -116,7 +116,7 @@ export const postBackupVerify = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = 'Channel Verify Successful.';
|
message = 'Channel Verify Successful.';
|
||||||
channel_verify_file = req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
|
channel_verify_file = req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
|
||||||
const exists = fs.existsSync(channel_verify_file);
|
const exists = fs.existsSync(channel_verify_file);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
verify_backup = fs.readFileSync(channel_verify_file, 'utf-8');
|
verify_backup = fs.readFileSync(channel_verify_file, 'utf-8');
|
||||||
@ -146,13 +146,13 @@ export const postRestore = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/channels/backup/restore';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/channels/backup/restore';
|
||||||
let channel_restore_file = '';
|
let channel_restore_file = '';
|
||||||
let message = '';
|
let message = '';
|
||||||
let restore_backup = '';
|
let restore_backup = '';
|
||||||
if (req.params.channelPoint === 'ALL') {
|
if (req.params.channelPoint === 'ALL') {
|
||||||
message = 'All Channels Restore Successful.';
|
message = 'All Channels Restore Successful.';
|
||||||
channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep;
|
channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep;
|
||||||
const exists = fs.existsSync(channel_restore_file + 'channel-all.bak');
|
const exists = fs.existsSync(channel_restore_file + 'channel-all.bak');
|
||||||
const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak');
|
const downloaded_exists = fs.existsSync(channel_restore_file + 'backup-channel-all.bak');
|
||||||
if (exists) {
|
if (exists) {
|
||||||
@ -188,7 +188,7 @@ export const postRestore = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
message = 'Channel Restore Successful.';
|
message = 'Channel Restore Successful.';
|
||||||
channel_restore_file = req.session.selectedNode.channel_backup_path + sep + 'restore' + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
|
channel_restore_file = req.session.selectedNode.settings.channelBackupPath + sep + 'restore' + sep + 'channel-' + req.params.channelPoint?.replace(':', '-') + '.bak';
|
||||||
const exists = fs.existsSync(channel_restore_file);
|
const exists = fs.existsSync(channel_restore_file);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
restore_backup = fs.readFileSync(channel_restore_file, 'utf-8');
|
restore_backup = fs.readFileSync(channel_restore_file, 'utf-8');
|
||||||
@ -208,7 +208,7 @@ export const postRestore = (req, res, next) => {
|
|||||||
channel_restore_file = channel_restore_file + 'channel-all.bak';
|
channel_restore_file = channel_restore_file + 'channel-all.bak';
|
||||||
}
|
}
|
||||||
fs.rename(channel_restore_file, channel_restore_file + '.restored', () => {
|
fs.rename(channel_restore_file, channel_restore_file + '.restored', () => {
|
||||||
getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => {
|
getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => {
|
||||||
if (getFilesListRes.error) {
|
if (getFilesListRes.error) {
|
||||||
const errMsg = getFilesListRes.error;
|
const errMsg = getFilesListRes.error;
|
||||||
const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode);
|
const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg, req.session.selectedNode);
|
||||||
@ -228,7 +228,7 @@ export const postRestore = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const getRestoreList = (req, res, next) => {
|
export const getRestoreList = (req, res, next) => {
|
||||||
getFilesList(req.session.selectedNode.channel_backup_path, (getFilesListRes) => {
|
getFilesList(req.session.selectedNode.settings.channelBackupPath, (getFilesListRes) => {
|
||||||
if (getFilesListRes.error) {
|
if (getFilesListRes.error) {
|
||||||
return res.status(getFilesListRes.statusCode).json(getFilesListRes);
|
return res.status(getFilesListRes.statusCode).json(getFilesListRes);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ export const getFees = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/fees';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fees';
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body });
|
||||||
const today = new Date(Date.now());
|
const today = new Date(Date.now());
|
||||||
|
@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from LND server url ' + options.url });
|
||||||
if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) {
|
if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) {
|
||||||
const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!';
|
const errMsg = 'LND Get info failed due to bad or missing macaroon! Please check RTL-Config.json to verify the setup!';
|
||||||
@ -26,7 +26,7 @@ export const getInfo = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
common.nodes?.map((node) => {
|
common.nodes?.map((node) => {
|
||||||
if (node.ln_implementation === 'LND') {
|
if (node.lnImplementation === 'LND') {
|
||||||
common.getAllNodeAllChannelBackup(node);
|
common.getAllNodeAllChannelBackup(node);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
@ -42,7 +42,7 @@ export const getInfo = (req, res, next) => {
|
|||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
req.session.selectedNode.ln_version = body.version.split('-')[0] || '';
|
req.session.selectedNode.lnVersion = body.version.split('-')[0] || '';
|
||||||
lndWsClient.updateSelectedNode(req.session.selectedNode);
|
lndWsClient.updateSelectedNode(req.session.selectedNode);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
|
||||||
return res.status(200).json(body);
|
return res.status(200).json(body);
|
||||||
|
@ -5,7 +5,7 @@ let options = null;
|
|||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
export const getAliasFromPubkey = (selNode, pubkey) => {
|
export const getAliasFromPubkey = (selNode, pubkey) => {
|
||||||
options.url = selNode.ln_server_url + '/v1/graph/node/' + pubkey;
|
options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + pubkey;
|
||||||
return request(options).then((res) => {
|
return request(options).then((res) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Graph', msg: 'Alias Received', data: res.node.alias });
|
||||||
return res.node.alias;
|
return res.node.alias;
|
||||||
@ -18,7 +18,7 @@ export const getDescribeGraph = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/graph';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph';
|
||||||
request.get(options).then((body) => {
|
request.get(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
@ -33,7 +33,7 @@ export const getGraphInfo = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/info';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/info';
|
||||||
request.get(options).then((body) => {
|
request.get(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
@ -48,7 +48,7 @@ export const getGraphNode = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/node/' + req.params.pubKey;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/node/' + req.params.pubKey;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
@ -63,7 +63,7 @@ export const getGraphEdge = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
@ -78,7 +78,7 @@ export const getQueryRoutes = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/routes/' + req.params.destPubkey + '/' + req.params.amount;
|
||||||
if (req.query.outgoing_chan_id) {
|
if (req.query.outgoing_chan_id) {
|
||||||
options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id;
|
options.url = options.url + '?outgoing_chan_id=' + req.query.outgoing_chan_id;
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ export const getRemoteFeePolicy = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/graph/edge/' + req.params.chanid;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/graph/edge/' + req.params.chanid;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body });
|
||||||
let remoteNodeFee = {};
|
let remoteNodeFee = {};
|
||||||
|
@ -12,7 +12,7 @@ export const invoiceLookup = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v2/invoices/lookup';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/invoices/lookup';
|
||||||
if (req.query.payment_addr) {
|
if (req.query.payment_addr) {
|
||||||
options.url = options.url + '?payment_addr=' + req.query.payment_addr;
|
options.url = options.url + '?payment_addr=' + req.query.payment_addr;
|
||||||
}
|
}
|
||||||
@ -36,7 +36,7 @@ export const listInvoices = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset +
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset +
|
||||||
'&reversed=' + req.query.reversed;
|
'&reversed=' + req.query.reversed;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
|
||||||
@ -60,7 +60,7 @@ export const addInvoice = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/invoices';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices';
|
||||||
options.form = JSON.stringify(req.body);
|
options.form = JSON.stringify(req.body);
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added', data: body });
|
||||||
|
@ -5,14 +5,15 @@ let options = null;
|
|||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
export const signMessage = (req, res, next) => {
|
export const signMessage = (req, res, next) => {
|
||||||
|
const { message } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage';
|
||||||
options.form = JSON.stringify({
|
options.form = JSON.stringify({
|
||||||
msg: Buffer.from(req.body.message).toString('base64')
|
msg: Buffer.from(message).toString('base64')
|
||||||
});
|
});
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
|
||||||
@ -23,15 +24,16 @@ export const signMessage = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const verifyMessage = (req, res, next) => {
|
export const verifyMessage = (req, res, next) => {
|
||||||
|
const { message, signature } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/verifymessage';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/verifymessage';
|
||||||
options.form = JSON.stringify({
|
options.form = JSON.stringify({
|
||||||
msg: Buffer.from(req.body.message).toString('base64'),
|
msg: Buffer.from(message).toString('base64'),
|
||||||
signature: req.body.signature
|
signature: signature
|
||||||
});
|
});
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
|
||||||
|
@ -10,7 +10,7 @@ export const getNewAddress = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/newaddress?type=' + req.query.type;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddress?type=' + req.query.type;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'NewAddress', msg: 'New Address Generated', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
|
@ -5,7 +5,7 @@ let options = null;
|
|||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
export const decodePaymentFromPaymentRequest = (selNode, payment) => {
|
export const decodePaymentFromPaymentRequest = (selNode, payment) => {
|
||||||
options.url = selNode.ln_server_url + '/v1/payreq/' + payment;
|
options.url = selNode.settings.lnServerUrl + '/v1/payreq/' + payment;
|
||||||
return request(options).then((res) => {
|
return request(options).then((res) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'PayReq', msg: 'Description Received', data: res.description });
|
||||||
return res;
|
return res;
|
||||||
@ -17,7 +17,7 @@ export const decodePayment = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/payreq/' + req.params.payRequest;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payreq/' + req.params.payRequest;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
@ -27,13 +27,14 @@ export const decodePayment = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const decodePayments = (req, res, next) => {
|
export const decodePayments = (req, res, next) => {
|
||||||
|
const { payments } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Decoding Payments List..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Decoding Payments List..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
if (req.body.payments) {
|
if (payments) {
|
||||||
const paymentsArr = req.body.payments.split(',');
|
const paymentsArr = payments.split(',');
|
||||||
return Promise.all(paymentsArr?.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
|
return Promise.all(paymentsArr?.map((payment) => decodePaymentFromPaymentRequest(req.session.selectedNode, payment))).
|
||||||
then((values) => {
|
then((values) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment List Decoded', data: values });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'PayRequest', msg: 'Payment List Decoded', data: values });
|
||||||
@ -55,7 +56,7 @@ export const getPayments = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
@ -68,8 +69,8 @@ export const getAllLightningTransactions = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Getting All Lightning Transactions..' });
|
||||||
const options1 = JSON.parse(JSON.stringify(common.getOptions(req)));
|
const options1 = JSON.parse(JSON.stringify(common.getOptions(req)));
|
||||||
const options2 = JSON.parse(JSON.stringify(common.getOptions(req)));
|
const options2 = JSON.parse(JSON.stringify(common.getOptions(req)));
|
||||||
// options1.url = req.session.selectedNode.ln_server_url + '/v1/payments?max_payments=100000&index_offset=0&reversed=true';
|
// options1.url = req.session.selectedNode.settings.lnServerUrl + '/v1/payments?max_payments=100000&index_offset=0&reversed=true';
|
||||||
options2.url = req.session.selectedNode.ln_server_url + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true';
|
options2.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoices?num_max_invoices=100000&index_offset=0&reversed=true';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Payments Options', data: options1 });
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'All Invoices Options', data: options2 });
|
||||||
// return Promise.all([request(options1), request(options2)]).then((values) => {
|
// return Promise.all([request(options1), request(options2)]).then((values) => {
|
||||||
@ -87,7 +88,7 @@ export const paymentLookup = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v2/router/track/' + req.params.paymentHash;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/router/track/' + req.params.paymentHash;
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Information Received for ' + req.params.paymentHash, data: body });
|
||||||
res.status(200).json(body.result || body);
|
res.status(200).json(body.result || body);
|
||||||
|
@ -5,7 +5,7 @@ let options = null;
|
|||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
export const getAliasForPeers = (selNode, peer) => {
|
export const getAliasForPeers = (selNode, peer) => {
|
||||||
options.url = selNode.ln_server_url + '/v1/graph/node/' + peer.pub_key;
|
options.url = selNode.settings.lnServerUrl + '/v1/graph/node/' + peer.pub_key;
|
||||||
return request(options).then((aliasBody) => {
|
return request(options).then((aliasBody) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Peers', msg: 'Alias Received', data: aliasBody.node.alias });
|
||||||
peer.alias = aliasBody.node.alias;
|
peer.alias = aliasBody.node.alias;
|
||||||
@ -21,7 +21,7 @@ export const getPeers = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/peers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers';
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
|
||||||
const peers = !body.peers ? [] : body.peers;
|
const peers = !body.peers ? [] : body.peers;
|
||||||
@ -35,24 +35,25 @@ export const getPeers = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const postPeer = (req, res, next) => {
|
export const postPeer = (req, res, next) => {
|
||||||
|
const { host, pubkey, perm } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/peers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers';
|
||||||
options.form = JSON.stringify({
|
options.form = JSON.stringify({
|
||||||
addr: { host: req.body.host, pubkey: req.body.pubkey },
|
addr: { host: host, pubkey: pubkey },
|
||||||
perm: req.body.perm
|
perm: perm
|
||||||
});
|
});
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: body });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/peers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers';
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
const peers = (!body.peers) ? [] : body.peers;
|
const peers = (!body.peers) ? [] : body.peers;
|
||||||
return Promise.all(peers?.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => {
|
return Promise.all(peers?.map((peer) => getAliasForPeers(req.session.selectedNode, peer))).then((values) => {
|
||||||
if (body.peers) {
|
if (body.peers) {
|
||||||
body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey);
|
body.peers = common.newestOnTop(body.peers, 'pub_key', pubkey);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: body });
|
||||||
}
|
}
|
||||||
res.status(201).json(body.peers);
|
res.status(201).json(body.peers);
|
||||||
@ -75,7 +76,7 @@ export const deletePeer = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/peers/' + req.params.peerPubKey;
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/peers/' + req.params.peerPubKey;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnect Pubkey', data: req.params.peerPubKey });
|
||||||
request.delete(options).then((body) => {
|
request.delete(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconneted', data: body });
|
||||||
|
@ -7,7 +7,8 @@ const common = Common;
|
|||||||
const responseData = { switch: { forwarding_events: [], last_offset_index: 0 }, fees: { forwarding_events: [], last_offset_index: 0 } };
|
const responseData = { switch: { forwarding_events: [], last_offset_index: 0 }, fees: { forwarding_events: [], last_offset_index: 0 } };
|
||||||
const num_max_events = 100;
|
const num_max_events = 100;
|
||||||
export const forwardingHistory = (req, res, next) => {
|
export const forwardingHistory = (req, res, next) => {
|
||||||
getAllForwardingEvents(req, req.body.start_time, req.body.end_time, 0, 'switch', (eventsResponse) => {
|
const { start_time, end_time } = req.body;
|
||||||
|
getAllForwardingEvents(req, start_time, end_time, 0, 'switch', (eventsResponse) => {
|
||||||
if (eventsResponse.error) {
|
if (eventsResponse.error) {
|
||||||
res.status(eventsResponse.error.statusCode).json(eventsResponse);
|
res.status(eventsResponse.error.statusCode).json(eventsResponse);
|
||||||
}
|
}
|
||||||
@ -26,7 +27,7 @@ export const getAllForwardingEvents = (req, start, end, offset, caller, callback
|
|||||||
return callback({ message: err.message, error: err.error, statusCode: err.statusCode });
|
return callback({ message: err.message, error: err.error, statusCode: err.statusCode });
|
||||||
}
|
}
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/switch';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/switch';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
if (start) {
|
if (start) {
|
||||||
options.form.start_time = start;
|
options.form.start_time = start;
|
||||||
|
@ -10,7 +10,7 @@ export const getTransactions = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/transactions';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions';
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Transactions', msg: 'Transactions List Received', data: body });
|
||||||
res.status(200).json(body.transactions);
|
res.status(200).json(body.transactions);
|
||||||
@ -20,20 +20,21 @@ export const getTransactions = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const postTransactions = (req, res, next) => {
|
export const postTransactions = (req, res, next) => {
|
||||||
|
const { amount, address, fees, blocks, sendAll } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Sending Transaction..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Transactions', msg: 'Sending Transaction..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/transactions';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/transactions';
|
||||||
options.form = {
|
options.form = {
|
||||||
amount: req.body.amount,
|
amount: amount,
|
||||||
addr: req.body.address,
|
addr: address,
|
||||||
sat_per_byte: req.body.fees,
|
sat_per_byte: fees,
|
||||||
target_conf: req.body.blocks
|
target_conf: blocks
|
||||||
};
|
};
|
||||||
if (req.body.sendAll) {
|
if (sendAll) {
|
||||||
options.form.send_all = req.body.sendAll;
|
options.form.send_all = sendAll;
|
||||||
}
|
}
|
||||||
options.form = JSON.stringify(options.form);
|
options.form = JSON.stringify(options.form);
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
|
@ -12,10 +12,10 @@ export const genSeed = (req, res, next) => {
|
|||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
if (req.params.passphrase) {
|
if (req.params.passphrase) {
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64');
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed?aezeed_passphrase=' + Buffer.from(atob(req.params.passphrase)).toString('base64');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/genseed';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/genseed';
|
||||||
}
|
}
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated', data: body });
|
||||||
@ -26,6 +26,7 @@ export const genSeed = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const operateWallet = (req, res, next) => {
|
export const operateWallet = (req, res, next) => {
|
||||||
|
const { wallet_password, aezeed_passphrase, cipher_seed_mnemonic } = req.body;
|
||||||
let err_message = '';
|
let err_message = '';
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
@ -34,26 +35,26 @@ export const operateWallet = (req, res, next) => {
|
|||||||
options.method = 'POST';
|
options.method = 'POST';
|
||||||
if (!req.params.operation || req.params.operation === 'unlockwallet') {
|
if (!req.params.operation || req.params.operation === 'unlockwallet') {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Unlocking Wallet..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/unlockwallet';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/unlockwallet';
|
||||||
options.form = JSON.stringify({
|
options.form = JSON.stringify({
|
||||||
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64')
|
wallet_password: Buffer.from(atob(wallet_password)).toString('base64')
|
||||||
});
|
});
|
||||||
err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!';
|
err_message = 'Unlocking wallet failed! Verify that lnd is running and the wallet is locked!';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Initializing Wallet..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/initwallet';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/initwallet';
|
||||||
if (req.body.aezeed_passphrase && req.body.aezeed_passphrase !== '') {
|
if (aezeed_passphrase && aezeed_passphrase !== '') {
|
||||||
options.form = JSON.stringify({
|
options.form = JSON.stringify({
|
||||||
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64'),
|
wallet_password: Buffer.from(atob(wallet_password)).toString('base64'),
|
||||||
cipher_seed_mnemonic: req.body.cipher_seed_mnemonic,
|
cipher_seed_mnemonic: cipher_seed_mnemonic,
|
||||||
aezeed_passphrase: Buffer.from(atob(req.body.aezeed_passphrase)).toString('base64')
|
aezeed_passphrase: Buffer.from(atob(aezeed_passphrase)).toString('base64')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
options.form = JSON.stringify({
|
options.form = JSON.stringify({
|
||||||
wallet_password: Buffer.from(atob(req.body.wallet_password)).toString('base64'),
|
wallet_password: Buffer.from(atob(wallet_password)).toString('base64'),
|
||||||
cipher_seed_mnemonic: req.body.cipher_seed_mnemonic
|
cipher_seed_mnemonic: cipher_seed_mnemonic
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
err_message = 'Initializing wallet failed!';
|
err_message = 'Initializing wallet failed!';
|
||||||
@ -103,8 +104,8 @@ export const getUTXOs = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos';
|
||||||
if (common.isVersionCompatible(req.session.selectedNode.ln_version, '0.14.0')) {
|
if (common.isVersionCompatible(req.session.selectedNode.lnVersion, '0.14.0')) {
|
||||||
options.form = JSON.stringify({ max_confs: req.query.max_confs });
|
options.form = JSON.stringify({ max_confs: req.query.max_confs });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -119,22 +120,23 @@ export const getUTXOs = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const bumpFee = (req, res, next) => {
|
export const bumpFee = (req, res, next) => {
|
||||||
|
const { txid, outputIndex, targetConf, satPerByte } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Bumping Fee..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Bumping Fee..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/bumpfee';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/bumpfee';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
options.form.outpoint = {
|
options.form.outpoint = {
|
||||||
txid_str: req.body.txid,
|
txid_str: txid,
|
||||||
output_index: req.body.outputIndex
|
output_index: outputIndex
|
||||||
};
|
};
|
||||||
if (req.body.targetConf) {
|
if (targetConf) {
|
||||||
options.form.target_conf = req.body.targetConf;
|
options.form.target_conf = targetConf;
|
||||||
}
|
}
|
||||||
else if (req.body.satPerByte) {
|
else if (satPerByte) {
|
||||||
options.form.sat_per_byte = req.body.satPerByte;
|
options.form.sat_per_byte = satPerByte;
|
||||||
}
|
}
|
||||||
options.form = JSON.stringify(options.form);
|
options.form = JSON.stringify(options.form);
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -151,12 +153,8 @@ export const labelTransaction = (req, res, next) => {
|
|||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/tx/label';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/tx/label';
|
||||||
options.form = {};
|
options.form = JSON.stringify(req.body);
|
||||||
options.form.txid = req.body.txid;
|
|
||||||
options.form.label = req.body.label;
|
|
||||||
options.form.overwrite = req.body.overwrite;
|
|
||||||
options.form = JSON.stringify(options.form);
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'Label Transaction Options', data: options.form });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Transaction Labelled', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Transaction Labelled', data: body });
|
||||||
@ -167,17 +165,18 @@ export const labelTransaction = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const leaseUTXO = (req, res, next) => {
|
export const leaseUTXO = (req, res, next) => {
|
||||||
|
const { txid, outputIndex } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Leasing UTXO..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Leasing UTXO..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/lease';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/lease';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
options.form.id = req.body.txid;
|
options.form.id = txid;
|
||||||
options.form.outpoint = {
|
options.form.outpoint = {
|
||||||
txid_bytes: req.body.txid,
|
txid_bytes: txid,
|
||||||
output_index: req.body.outputIndex
|
output_index: outputIndex
|
||||||
};
|
};
|
||||||
options.form = JSON.stringify(options.form);
|
options.form = JSON.stringify(options.form);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'UTXO Lease Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Wallet', msg: 'UTXO Lease Options', data: options.form });
|
||||||
@ -190,17 +189,18 @@ export const leaseUTXO = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const releaseUTXO = (req, res, next) => {
|
export const releaseUTXO = (req, res, next) => {
|
||||||
|
const { txid, outputIndex } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Releasing UTXO..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Wallet', msg: 'Releasing UTXO..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) {
|
if (options.error) {
|
||||||
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
return res.status(options.statusCode).json({ message: options.message, error: options.error });
|
||||||
}
|
}
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v2/wallet/utxos/release';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v2/wallet/utxos/release';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
options.form.id = req.body.txid;
|
options.form.id = txid;
|
||||||
options.form.outpoint = {
|
options.form.outpoint = {
|
||||||
txid_bytes: req.body.txid,
|
txid_bytes: txid,
|
||||||
output_index: req.body.outputIndex
|
output_index: outputIndex
|
||||||
};
|
};
|
||||||
options.form = JSON.stringify(options.form);
|
options.form = JSON.stringify(options.form);
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
|
@ -13,7 +13,7 @@ export class LNDWebSocketClient {
|
|||||||
this.connect = (selectedNode) => {
|
this.connect = (selectedNode) => {
|
||||||
try {
|
try {
|
||||||
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
||||||
if (!clientExists && selectedNode.ln_server_url) {
|
if (!clientExists && selectedNode.settings.lnServerUrl) {
|
||||||
const newWebSocketClient = { selectedNode: selectedNode };
|
const newWebSocketClient = { selectedNode: selectedNode };
|
||||||
this.webSocketClients.push(newWebSocketClient);
|
this.webSocketClients.push(newWebSocketClient);
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ export class LNDWebSocketClient {
|
|||||||
this.fetchUnpaidInvoices = (selectedNode) => {
|
this.fetchUnpaidInvoices = (selectedNode) => {
|
||||||
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' });
|
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Getting Unpaid Invoices..' });
|
||||||
const options = this.setOptionsForSelNode(selectedNode);
|
const options = this.setOptionsForSelNode(selectedNode);
|
||||||
options.url = selectedNode.ln_server_url + '/v1/invoices?pending_only=true';
|
options.url = selectedNode.settings.lnServerUrl + '/v1/invoices?pending_only=true';
|
||||||
return request(options).then((body) => {
|
return request(options).then((body) => {
|
||||||
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body });
|
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Unpaid Invoices Received', data: body });
|
||||||
if (body.invoices && body.invoices.length > 0) {
|
if (body.invoices && body.invoices.length > 0) {
|
||||||
@ -44,7 +44,7 @@ export class LNDWebSocketClient {
|
|||||||
this.subscribeToInvoice = (options, selectedNode, rHash) => {
|
this.subscribeToInvoice = (options, selectedNode, rHash) => {
|
||||||
rHash = rHash?.replace(/\+/g, '-')?.replace(/[/]/g, '_');
|
rHash = rHash?.replace(/\+/g, '-')?.replace(/[/]/g, '_');
|
||||||
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' });
|
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Invoice ' + rHash + ' ..' });
|
||||||
options.url = selectedNode.ln_server_url + '/v2/invoices/subscribe/' + rHash;
|
options.url = selectedNode.settings.lnServerUrl + '/v2/invoices/subscribe/' + rHash;
|
||||||
request(options).then((msg) => {
|
request(options).then((msg) => {
|
||||||
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash });
|
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Invoice Information Received for ' + rHash });
|
||||||
if (typeof msg === 'string') {
|
if (typeof msg === 'string') {
|
||||||
@ -67,7 +67,7 @@ export class LNDWebSocketClient {
|
|||||||
};
|
};
|
||||||
this.subscribeToPayment = (options, selectedNode, paymentHash) => {
|
this.subscribeToPayment = (options, selectedNode, paymentHash) => {
|
||||||
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' });
|
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Subscribing to Payment ' + paymentHash + ' ..' });
|
||||||
options.url = selectedNode.ln_server_url + '/v2/router/track/' + paymentHash;
|
options.url = selectedNode.settings.lnServerUrl + '/v2/router/track/' + paymentHash;
|
||||||
request(options).then((msg) => {
|
request(options).then((msg) => {
|
||||||
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash });
|
this.logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'WebSocketClient', msg: 'Payment Information Received for ' + paymentHash });
|
||||||
msg['type'] = 'payment';
|
msg['type'] = 'payment';
|
||||||
@ -84,7 +84,7 @@ export class LNDWebSocketClient {
|
|||||||
this.setOptionsForSelNode = (selectedNode) => {
|
this.setOptionsForSelNode = (selectedNode) => {
|
||||||
const options = { url: '', rejectUnauthorized: false, json: true, form: null };
|
const options = { url: '', rejectUnauthorized: false, json: true, form: null };
|
||||||
try {
|
try {
|
||||||
options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') };
|
options['headers'] = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) });
|
this.logger.log({ selectedNode: selectedNode, level: 'ERROR', fileName: 'WebSocketClient', msg: 'Set Options Error', error: JSON.stringify(err) });
|
||||||
@ -107,7 +107,7 @@ export class LNDWebSocketClient {
|
|||||||
}
|
}
|
||||||
newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode));
|
newClient.selectedNode = JSON.parse(JSON.stringify(newSelectedNode));
|
||||||
this.webSocketClients[clientIdx] = newClient;
|
this.webSocketClients[clientIdx] = newClient;
|
||||||
if (this.webSocketClients[clientIdx].selectedNode.ln_version === '' || !this.webSocketClients[clientIdx].selectedNode.ln_version || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.ln_version, '0.11.0')) {
|
if (this.webSocketClients[clientIdx].selectedNode.lnVersion === '' || !this.webSocketClients[clientIdx].selectedNode.lnVersion || this.common.isVersionCompatible(this.webSocketClients[clientIdx].selectedNode.lnVersion, '0.11.0')) {
|
||||||
this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode);
|
this.fetchUnpaidInvoices(this.webSocketClients[clientIdx].selectedNode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import jwt from 'jsonwebtoken';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import { sep } from 'path';
|
import { sep } from 'path';
|
||||||
import ini from 'ini';
|
import ini from 'ini';
|
||||||
@ -7,15 +8,136 @@ import { Database } from '../../utils/database.js';
|
|||||||
import { Logger } from '../../utils/logger.js';
|
import { Logger } from '../../utils/logger.js';
|
||||||
import { Common } from '../../utils/common.js';
|
import { Common } from '../../utils/common.js';
|
||||||
import { WSServer } from '../../utils/webSocketServer.js';
|
import { WSServer } from '../../utils/webSocketServer.js';
|
||||||
|
import { Authentication, SSO } from '../../models/config.model.js';
|
||||||
const options = { url: '' };
|
const options = { url: '' };
|
||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
const wsServer = WSServer;
|
const wsServer = WSServer;
|
||||||
const databaseService = Database;
|
const databaseService = Database;
|
||||||
|
// Set local block explorer URL after first API call
|
||||||
|
// if the selected node block explorer has working REST API suite
|
||||||
|
// otherwise set it to mempool.space
|
||||||
|
let blockExplorerUrl = '';
|
||||||
|
export const getExplorerFeesRecommended = (req, res, next) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Recommended Fee Rates..' });
|
||||||
|
options.url = (blockExplorerUrl === '') ?
|
||||||
|
req.session.selectedNode.settings.blockExplorerUrl + '/api/v1/fees/recommended' :
|
||||||
|
blockExplorerUrl + '/api/v1/fees/recommended';
|
||||||
|
request(options).then((body) => {
|
||||||
|
blockExplorerUrl = req.session.selectedNode.settings.blockExplorerUrl;
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Recommended Fee Rates Received', data: body });
|
||||||
|
res.status(200).json(JSON.parse(body));
|
||||||
|
}).catch((errRes) => {
|
||||||
|
blockExplorerUrl = 'https://mempool.space';
|
||||||
|
options.url = blockExplorerUrl + '/api/v1/fees/recommended';
|
||||||
|
return request(options).then((body) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Recommended Fee Rates Received', data: body });
|
||||||
|
res.status(200).json(JSON.parse(body));
|
||||||
|
}).catch((errRes) => {
|
||||||
|
const errMsg = 'Get Recommended Fee Rates Error';
|
||||||
|
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
||||||
|
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const getExplorerTransaction = (req, res, next) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Transaction From Block Explorer..' });
|
||||||
|
options.url = (blockExplorerUrl === '') ?
|
||||||
|
req.session.selectedNode.settings.blockExplorerUrl + '/api/tx/' + req.params.txid :
|
||||||
|
blockExplorerUrl + '/api/tx/' + req.params.txid;
|
||||||
|
request(options).then((body) => {
|
||||||
|
blockExplorerUrl = req.session.selectedNode.settings.blockExplorerUrl;
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Transaction From Block Explorer Received', data: body });
|
||||||
|
res.status(200).json(JSON.parse(body));
|
||||||
|
}).catch((errRes) => {
|
||||||
|
blockExplorerUrl = 'https://mempool.space';
|
||||||
|
options.url = blockExplorerUrl + '/api/tx/' + req.params.txid;
|
||||||
|
return request(options).then((body) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Transaction From Block Explorer Received', data: body });
|
||||||
|
res.status(200).json(JSON.parse(body));
|
||||||
|
}).catch((errRes) => {
|
||||||
|
const errMsg = 'Get Transaction From Block Explorer Error';
|
||||||
|
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
||||||
|
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const getCurrencyRates = (req, res, next) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' });
|
||||||
|
options.url = 'https://blockchain.info/ticker';
|
||||||
|
request(options).then((body) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body });
|
||||||
|
res.status(200).json(JSON.parse(body));
|
||||||
|
}).catch((errRes) => {
|
||||||
|
const errMsg = 'Get Rates Error';
|
||||||
|
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
||||||
|
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const getFile = (req, res, next) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' });
|
||||||
|
const file = req.query.path ? req.query.path : (req.session.selectedNode.settings.channelBackupPath + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak');
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel });
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file });
|
||||||
|
fs.readFile(file, 'utf8', (errRes, data) => {
|
||||||
|
if (errRes) {
|
||||||
|
if (errRes.code && errRes.code === 'ENOENT') {
|
||||||
|
errRes.code = 'File Not Found!';
|
||||||
|
}
|
||||||
|
const errMsg = 'Reading File Error';
|
||||||
|
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
||||||
|
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data });
|
||||||
|
res.status(200).json(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const getApplicationSettings = (req, res, next) => {
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' });
|
||||||
|
const confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
||||||
|
fs.readFile(confFile, 'utf8', (errRes, data) => {
|
||||||
|
if (errRes) {
|
||||||
|
const errMsg = 'Get Node Config Error';
|
||||||
|
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
||||||
|
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const appConfData = common.removeSecureData(JSON.parse(data));
|
||||||
|
appConfData.allowPasswordUpdate = common.appConfig.allowPasswordUpdate;
|
||||||
|
appConfData.enable2FA = common.appConfig.enable2FA;
|
||||||
|
appConfData.selectedNodeIndex = (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.selectedNode.index);
|
||||||
|
common.appConfig.selectedNodeIndex = appConfData.selectedNodeIndex;
|
||||||
|
const token = req.headers.authorization ? req.headers.authorization.split(' ')[1] : '';
|
||||||
|
jwt.verify(token, common.secret_key, (err, user) => {
|
||||||
|
if (err) {
|
||||||
|
// Delete unnecessary data for initial response (without security token)
|
||||||
|
const selNodeIdx = appConfData.nodes.findIndex((node) => node.index === appConfData.selectedNodeIndex) || 0;
|
||||||
|
appConfData.SSO = new SSO();
|
||||||
|
appConfData.secret2FA = '';
|
||||||
|
appConfData.dbDirectoryPath = '';
|
||||||
|
appConfData.nodes[selNodeIdx].authentication = new Authentication();
|
||||||
|
delete appConfData.nodes[selNodeIdx].settings.bitcoindConfigPath;
|
||||||
|
delete appConfData.nodes[selNodeIdx].settings.lnServerUrl;
|
||||||
|
delete appConfData.nodes[selNodeIdx].settings.swapServerUrl;
|
||||||
|
delete appConfData.nodes[selNodeIdx].settings.boltzServerUrl;
|
||||||
|
delete appConfData.nodes[selNodeIdx].settings.enableOffers;
|
||||||
|
delete appConfData.nodes[selNodeIdx].settings.enablePeerswap;
|
||||||
|
delete appConfData.nodes[selNodeIdx].settings.channelBackupPath;
|
||||||
|
appConfData.nodes = [appConfData.nodes[selNodeIdx]];
|
||||||
|
}
|
||||||
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: appConfData });
|
||||||
|
res.status(200).json(appConfData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
export const updateSelectedNode = (req, res, next) => {
|
export const updateSelectedNode = (req, res, next) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Selected Node..' });
|
||||||
const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.initSelectedNode ? +common.initSelectedNode.index : 1;
|
const selNodeIndex = req.params.currNodeIndex ? +req.params.currNodeIndex : common.selectedNode ? +common.selectedNode.index : 1;
|
||||||
req.session.selectedNode = common.findNode(selNodeIndex);
|
req.session.selectedNode = common.findNode(selNodeIndex);
|
||||||
|
common.selectedNode = req.session.selectedNode;
|
||||||
if (req.headers && req.headers.authorization && req.headers.authorization !== '') {
|
if (req.headers && req.headers.authorization && req.headers.authorization !== '') {
|
||||||
wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex);
|
wsServer.updateLNWSClientDetails(req.session.id, +req.session.selectedNode.index, +req.params.prevNodeIndex);
|
||||||
if (req.params.prevNodeIndex !== '-1') {
|
if (req.params.prevNodeIndex !== '-1') {
|
||||||
@ -25,192 +147,9 @@ export const updateSelectedNode = (req, res, next) => {
|
|||||||
databaseService.loadDatabase(req.session);
|
databaseService.loadDatabase(req.session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const responseVal = !req.session.selectedNode.ln_node ? '' : req.session.selectedNode.ln_node;
|
blockExplorerUrl = '';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + responseVal });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Selected Node Updated To ' + req.session.selectedNode.lnNode || '' });
|
||||||
res.status(200).json({ status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!' });
|
res.status(200).json(common.removeAuthSecureData(JSON.parse(JSON.stringify(req.session.selectedNode))));
|
||||||
};
|
|
||||||
export const getRTLConfigInitial = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Initial RTL Configuration..' });
|
|
||||||
const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
fs.readFile(confFile, 'utf8', (errRes, data) => {
|
|
||||||
if (errRes) {
|
|
||||||
if (errRes.code === 'ENOENT') {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } });
|
|
||||||
res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const errMsg = 'Get Node Config Error';
|
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const nodeConfData = JSON.parse(data);
|
|
||||||
const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link };
|
|
||||||
const enable2FA = !!common.rtl_secret2fa;
|
|
||||||
const allowPasswordUpdate = common.flg_allow_password_update;
|
|
||||||
const nodesArr = [];
|
|
||||||
if (common.nodes && common.nodes.length > 0) {
|
|
||||||
common.nodes.forEach((node, i) => {
|
|
||||||
const settings = { unannouncedChannels: false };
|
|
||||||
settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT';
|
|
||||||
settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY';
|
|
||||||
settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE';
|
|
||||||
settings.unannouncedChannels = !!node.unannounced_channels || false;
|
|
||||||
settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false;
|
|
||||||
settings.currencyUnit = node.currency_unit;
|
|
||||||
nodesArr.push({
|
|
||||||
index: node.index,
|
|
||||||
lnNode: node.ln_node,
|
|
||||||
lnImplementation: node.ln_implementation,
|
|
||||||
settings: settings,
|
|
||||||
authentication: {}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr };
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Initial RTL Configuration Received', data: body });
|
|
||||||
res.status(200).json(body);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export const getRTLConfig = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..' });
|
|
||||||
const confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
fs.readFile(confFile, 'utf8', (errRes, data) => {
|
|
||||||
if (errRes) {
|
|
||||||
if (errRes.code === 'ENOENT') {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'RTLConf', msg: 'Node config does not exist!', error: { error: 'Node config does not exist.' } });
|
|
||||||
res.status(200).json({ defaultNodeIndex: 0, selectedNodeIndex: 0, sso: {}, nodes: [] });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const errMsg = 'Get Node Config Error';
|
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const nodeConfData = JSON.parse(data);
|
|
||||||
const sso = { rtlSSO: common.rtl_sso, logoutRedirectLink: common.logout_redirect_link };
|
|
||||||
const enable2FA = !!common.rtl_secret2fa;
|
|
||||||
const allowPasswordUpdate = common.flg_allow_password_update;
|
|
||||||
const nodesArr = [];
|
|
||||||
if (common.nodes && common.nodes.length > 0) {
|
|
||||||
common.nodes.forEach((node, i) => {
|
|
||||||
const authentication = {};
|
|
||||||
authentication.configPath = (node.config_path) ? node.config_path : '';
|
|
||||||
authentication.swapMacaroonPath = (node.swap_macaroon_path) ? node.swap_macaroon_path : '';
|
|
||||||
authentication.boltzMacaroonPath = (node.boltz_macaroon_path) ? node.boltz_macaroon_path : '';
|
|
||||||
const settings = { unannouncedChannels: false };
|
|
||||||
settings.userPersona = node.user_persona ? node.user_persona : 'MERCHANT';
|
|
||||||
settings.themeMode = (node.theme_mode) ? node.theme_mode : 'DAY';
|
|
||||||
settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE';
|
|
||||||
settings.unannouncedChannels = !!node.unannounced_channels || false;
|
|
||||||
settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false;
|
|
||||||
settings.bitcoindConfigPath = node.bitcoind_config_path;
|
|
||||||
settings.logLevel = node.log_level ? node.log_level : 'ERROR';
|
|
||||||
settings.lnServerUrl = node.ln_server_url;
|
|
||||||
settings.swapServerUrl = node.swap_server_url;
|
|
||||||
settings.boltzServerUrl = node.boltz_server_url;
|
|
||||||
settings.enableOffers = node.enable_offers;
|
|
||||||
settings.enablePeerswap = node.enable_peerswap;
|
|
||||||
settings.channelBackupPath = node.channel_backup_path;
|
|
||||||
settings.currencyUnit = node.currency_unit;
|
|
||||||
nodesArr.push({
|
|
||||||
index: node.index,
|
|
||||||
lnNode: node.ln_node,
|
|
||||||
lnImplementation: node.ln_implementation,
|
|
||||||
settings: settings,
|
|
||||||
authentication: authentication
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const body = { defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: (req.session.selectedNode && req.session.selectedNode.index ? req.session.selectedNode.index : common.initSelectedNode.index), sso: sso, enable2FA: enable2FA, allowPasswordUpdate: allowPasswordUpdate, nodes: nodesArr };
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'RTL Configuration Received', data: body });
|
|
||||||
res.status(200).json(body);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export const updateUISettings = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating UI Settings..' });
|
|
||||||
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
|
||||||
const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index));
|
|
||||||
if (node && node.Settings) {
|
|
||||||
node.Settings.userPersona = req.body.updatedSettings.userPersona;
|
|
||||||
node.Settings.themeMode = req.body.updatedSettings.themeMode;
|
|
||||||
node.Settings.themeColor = req.body.updatedSettings.themeColor;
|
|
||||||
node.Settings.unannouncedChannels = req.body.updatedSettings.unannouncedChannels;
|
|
||||||
node.Settings.fiatConversion = req.body.updatedSettings.fiatConversion;
|
|
||||||
if (req.body.updatedSettings.fiatConversion) {
|
|
||||||
node.Settings.currencyUnit = req.body.updatedSettings.currencyUnit ? req.body.updatedSettings.currencyUnit : 'USD';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete node.Settings.currencyUnit;
|
|
||||||
}
|
|
||||||
const selectedNode = common.findNode(req.session.selectedNode.index);
|
|
||||||
selectedNode.user_persona = req.body.updatedSettings.userPersona;
|
|
||||||
selectedNode.theme_mode = req.body.updatedSettings.themeMode;
|
|
||||||
selectedNode.theme_color = req.body.updatedSettings.themeColor;
|
|
||||||
selectedNode.unannounced_channels = req.body.updatedSettings.unannouncedChannels;
|
|
||||||
selectedNode.fiat_conversion = req.body.updatedSettings.fiatConversion;
|
|
||||||
if (req.body.updatedSettings.fiatConversion) {
|
|
||||||
selectedNode.currency_unit = req.body.updatedSettings.currencyUnit ? req.body.updatedSettings.currencyUnit : 'USD';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete selectedNode.currency_unit;
|
|
||||||
}
|
|
||||||
common.replaceNode(req, selectedNode);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated', data: maskPasswords(config) });
|
|
||||||
res.status(201).json({ message: 'Node Settings Updated Successfully' });
|
|
||||||
}
|
|
||||||
catch (errRes) {
|
|
||||||
const errMsg = 'Update Node Settings Error';
|
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export const update2FASettings = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating 2FA Settings..' });
|
|
||||||
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
|
||||||
if (req.body.secret2fa && req.body.secret2fa.trim() !== '') {
|
|
||||||
config.secret2fa = req.body.secret2fa;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete config.secret2fa;
|
|
||||||
}
|
|
||||||
const message = req.body.secret2fa.trim() === '' ? 'Two factor authentication disabled successfully.' : 'Two factor authentication enabled successfully.';
|
|
||||||
try {
|
|
||||||
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
|
||||||
common.rtl_secret2fa = config.secret2fa;
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: message });
|
|
||||||
res.status(201).json({ message: message });
|
|
||||||
}
|
|
||||||
catch (errRes) {
|
|
||||||
const errMsg = 'Update 2FA Settings Error';
|
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export const updateDefaultNode = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Default Node..' });
|
|
||||||
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
|
||||||
config.defaultNodeIndex = req.body.defaultNodeIndex;
|
|
||||||
try {
|
|
||||||
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated', data: maskPasswords(config) });
|
|
||||||
res.status(201).json({ message: 'Default Node Updated Successfully' });
|
|
||||||
}
|
|
||||||
catch (errRes) {
|
|
||||||
const errMsg = 'Update Default Node Error';
|
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
export const getConfig = (req, res, next) => {
|
export const getConfig = (req, res, next) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Reading Configuration File..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Reading Configuration File..' });
|
||||||
@ -218,14 +157,14 @@ export const getConfig = (req, res, next) => {
|
|||||||
let fileFormat = 'INI';
|
let fileFormat = 'INI';
|
||||||
switch (req.params.nodeType) {
|
switch (req.params.nodeType) {
|
||||||
case 'ln':
|
case 'ln':
|
||||||
confFile = req.session.selectedNode.config_path;
|
confFile = req.session.selectedNode.authentication.configPath;
|
||||||
break;
|
break;
|
||||||
case 'bitcoind':
|
case 'bitcoind':
|
||||||
confFile = req.session.selectedNode.bitcoind_config_path;
|
confFile = req.session.selectedNode.settings.bitcoindConfigPath;
|
||||||
break;
|
break;
|
||||||
case 'rtl':
|
case 'rtl':
|
||||||
fileFormat = 'JSON';
|
fileFormat = 'JSON';
|
||||||
confFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
confFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
confFile = '';
|
confFile = '';
|
||||||
@ -251,144 +190,77 @@ export const getConfig = (req, res, next) => {
|
|||||||
if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) {
|
if (jsonConfig['Application Options'] && jsonConfig['Application Options'].color) {
|
||||||
jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color;
|
jsonConfig['Application Options'].color = '#' + jsonConfig['Application Options'].color;
|
||||||
}
|
}
|
||||||
if (req.params.nodeType === 'ln' && req.session.selectedNode.ln_implementation === 'ECL' && !jsonConfig['eclair.api.password']) {
|
if (req.params.nodeType === 'ln' && req.session.selectedNode.lnImplementation === 'ECL' && !jsonConfig['eclair.api.password']) {
|
||||||
fileFormat = 'HOCON';
|
fileFormat = 'HOCON';
|
||||||
jsonConfig = parseHocon(data);
|
jsonConfig = parseHocon(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsonConfig = maskPasswords(jsonConfig);
|
jsonConfig = common.maskPasswords(jsonConfig);
|
||||||
const responseJSON = (fileFormat === 'JSON') ? jsonConfig : ini.stringify(jsonConfig)?.replace('color=\\#', 'color=#');
|
const responseJSON = (fileFormat === 'JSON') ? jsonConfig : ini.stringify(jsonConfig)?.replace('color=\\#', 'color=#');
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Configuration File Data Received', data: responseJSON });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Configuration File Data Received', data: responseJSON });
|
||||||
res.status(200).json({ format: fileFormat, data: responseJSON });
|
res.status(200).json({ format: fileFormat, data: responseJSON });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const getFile = (req, res, next) => {
|
export const updateNodeSettings = (req, res, next) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Node Settings..' });
|
||||||
const file = req.query.path ? req.query.path : (req.session.selectedNode.channel_backup_path + sep + 'channel-' + req.query.channel?.replace(':', '-') + '.bak');
|
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'Channel Point', data: req.query.channel });
|
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'RTLConf', msg: 'File Path', data: file });
|
const node = config.nodes.find((node) => (node.index === req.session.selectedNode.index));
|
||||||
fs.readFile(file, 'utf8', (errRes, data) => {
|
if (node && node.settings) {
|
||||||
if (errRes) {
|
node.settings = req.body.settings;
|
||||||
if (errRes.code && errRes.code === 'ENOENT') {
|
if (req.body.authentication.boltzMacaroonPath) {
|
||||||
errRes.code = 'File Not Found!';
|
node.authentication.boltzMacaroonPath = req.body.authentication.boltzMacaroonPath;
|
||||||
}
|
|
||||||
const errMsg = 'Reading File Error';
|
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received', data: data });
|
delete node.authentication.boltzMacaroonPath;
|
||||||
res.status(200).json(data);
|
|
||||||
}
|
}
|
||||||
});
|
if (req.body.authentication.swapMacaroonPath) {
|
||||||
};
|
node.authentication.swapMacaroonPath = req.body.authentication.swapMacaroonPath;
|
||||||
export const getCurrencyRates = (req, res, next) => {
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..' });
|
else {
|
||||||
options.url = 'https://blockchain.info/ticker';
|
delete node.authentication.swapMacaroonPath;
|
||||||
request(options).then((body) => {
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received', data: body });
|
}
|
||||||
res.status(200).json(JSON.parse(body));
|
|
||||||
}).catch((errRes) => {
|
|
||||||
const errMsg = 'Get Rates Error';
|
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
export const updateSSO = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating SSO Settings..' });
|
|
||||||
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
|
||||||
delete config.SSO;
|
|
||||||
config.SSO = req.body.SSO;
|
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'SSO Setting Updated', data: maskPasswords(config) });
|
const selectedNode = common.findNode(req.session.selectedNode.index);
|
||||||
res.status(201).json({ message: 'SSO Updated Successfully' });
|
if (selectedNode && selectedNode.settings) {
|
||||||
}
|
selectedNode.settings = req.body.settings;
|
||||||
catch (errRes) {
|
selectedNode.authentication.boltzMacaroonPath = req.body.authentication.boltzMacaroonPath;
|
||||||
const errMsg = 'Update SSO Error';
|
selectedNode.authentication.swapMacaroonPath = req.body.authentication.swapMacaroonPath;
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
export const updateServiceSettings = (req, res, next) => {
|
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Service Settings..' });
|
|
||||||
const RTLConfFile = common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
|
||||||
const selectedNode = common.findNode(req.session.selectedNode.index);
|
|
||||||
config.nodes.forEach((node) => {
|
|
||||||
if (node.index === req.session.selectedNode.index) {
|
|
||||||
switch (req.body.service) {
|
|
||||||
case 'LOOP':
|
|
||||||
if (req.body.settings.enable) {
|
|
||||||
node.Settings.swapServerUrl = req.body.settings.serverUrl;
|
|
||||||
node.Authentication.swapMacaroonPath = req.body.settings.macaroonPath;
|
|
||||||
selectedNode.swap_server_url = req.body.settings.serverUrl;
|
|
||||||
selectedNode.swap_macaroon_path = req.body.settings.macaroonPath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete node.Settings.swapServerUrl;
|
|
||||||
delete node.Authentication.swapMacaroonPath;
|
|
||||||
delete selectedNode.swap_server_url;
|
|
||||||
delete selectedNode.swap_macaroon_path;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'BOLTZ':
|
|
||||||
if (req.body.settings.enable) {
|
|
||||||
node.Settings.boltzServerUrl = req.body.settings.serverUrl;
|
|
||||||
node.Authentication.boltzMacaroonPath = req.body.settings.macaroonPath;
|
|
||||||
selectedNode.boltz_server_url = req.body.settings.serverUrl;
|
|
||||||
selectedNode.boltz_macaroon_path = req.body.settings.macaroonPath;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
delete node.Settings.boltzServerUrl;
|
|
||||||
delete node.Authentication.boltzMacaroonPath;
|
|
||||||
delete selectedNode.boltz_server_url;
|
|
||||||
delete selectedNode.boltz_macaroon_path;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'OFFERS':
|
|
||||||
node.Settings.enableOffers = req.body.settings.enableOffers;
|
|
||||||
selectedNode.enable_offers = req.body.settings.enableOffers;
|
|
||||||
break;
|
|
||||||
case 'PEERSWAP':
|
|
||||||
node.Settings.enablePeerswap = req.body.settings.enablePeerswap;
|
|
||||||
selectedNode.enable_peerswap = req.body.settings.enablePeerswap;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
common.replaceNode(req, selectedNode);
|
common.replaceNode(req, selectedNode);
|
||||||
}
|
}
|
||||||
return node;
|
let responseNode = JSON.parse(JSON.stringify(common.selectedNode));
|
||||||
});
|
responseNode = common.removeAuthSecureData(responseNode);
|
||||||
try {
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Node Settings Updated', data: responseNode });
|
||||||
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
res.status(201).json(responseNode);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Service Settings Updated', data: maskPasswords(config) });
|
|
||||||
res.status(201).json({ message: 'Service Settings Updated Successfully' });
|
|
||||||
}
|
}
|
||||||
catch (errRes) {
|
catch (errRes) {
|
||||||
const errMsg = 'Update Service Settings Error';
|
const errMsg = 'Update Node Settings Error';
|
||||||
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
||||||
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const maskPasswords = (obj) => {
|
export const updateApplicationSettings = (req, res, next) => {
|
||||||
const keys = Object.keys(obj);
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Updating Application Settings..' });
|
||||||
const length = keys.length;
|
const RTLConfFile = common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
||||||
if (length !== 0) {
|
try {
|
||||||
for (let i = 0; i < length; i++) {
|
const config = common.addSecureData(req.body);
|
||||||
if (typeof obj[keys[i]] === 'object') {
|
common.appConfig = JSON.parse(JSON.stringify(config));
|
||||||
keys[keys[i]] = maskPasswords(obj[keys[i]]);
|
delete config.selectedNodeIndex;
|
||||||
}
|
delete config.enable2FA;
|
||||||
if (typeof keys[i] === 'string' &&
|
delete config.allowPasswordUpdate;
|
||||||
(keys[i].toLowerCase().includes('password') || keys[i].toLowerCase().includes('multipass') ||
|
delete config.rtlConfFilePath;
|
||||||
keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') ||
|
delete config.rtlPass;
|
||||||
keys[i].toLowerCase().includes('rpcuser'))) {
|
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
||||||
obj[keys[i]] = '********************';
|
const newConfig = JSON.parse(JSON.stringify(common.appConfig));
|
||||||
}
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'RTLConf', msg: 'Application Settings Updated', data: common.maskPasswords(newConfig) });
|
||||||
}
|
res.status(201).json(common.removeSecureData(newConfig));
|
||||||
|
}
|
||||||
|
catch (errRes) {
|
||||||
|
const errMsg = 'Update Default Node Error';
|
||||||
|
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg, req.session.selectedNode);
|
||||||
|
return res.status(err.statusCode).json({ message: err.error, error: err.error });
|
||||||
}
|
}
|
||||||
return obj;
|
|
||||||
};
|
};
|
||||||
|
@ -44,19 +44,20 @@ const handleMultipleFailedAttemptsError = (failed, currentTime, errMsg) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const verifyToken = (twoFAToken) => !!(common.rtl_secret2fa && common.rtl_secret2fa !== '' && otplib.authenticator.check(twoFAToken, common.rtl_secret2fa));
|
export const verifyToken = (twoFAToken) => !!(common.appConfig.secret2FA && common.appConfig.secret2FA !== '' && otplib.authenticator.check(twoFAToken, common.appConfig.secret2FA));
|
||||||
export const authenticateUser = (req, res, next) => {
|
export const authenticateUser = (req, res, next) => {
|
||||||
|
const { authenticateWith, authenticationValue, twoFAToken } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..' });
|
||||||
if (+common.rtl_sso) {
|
if (+common.appConfig.SSO.rtlSso) {
|
||||||
if (req.body.authenticateWith === 'JWT' && jwt.verify(req.body.authenticationValue, common.secret_key)) {
|
if (authenticateWith === 'JWT' && jwt.verify(authenticationValue, common.secret_key)) {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
|
||||||
res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' });
|
res.status(406).json({ message: 'SSO Authentication Error', error: 'Login with Password is not allowed with SSO.' });
|
||||||
}
|
}
|
||||||
else if (req.body.authenticateWith === 'PASSWORD') {
|
else if (authenticateWith === 'PASSWORD') {
|
||||||
if (common.cookie_value.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.cookie_value).digest('hex'), 'utf-8'), Buffer.from(req.body.authenticationValue, 'utf-8'))) {
|
if (common.appConfig.SSO.cookieValue.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.appConfig.SSO.cookieValue).digest('hex'), 'utf-8'), Buffer.from(authenticationValue, 'utf-8'))) {
|
||||||
common.refreshCookie();
|
common.refreshCookie();
|
||||||
if (!req.session.selectedNode) {
|
if (!req.session.selectedNode) {
|
||||||
req.session.selectedNode = common.initSelectedNode;
|
req.session.selectedNode = common.selectedNode;
|
||||||
}
|
}
|
||||||
const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key);
|
const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated' });
|
||||||
@ -73,10 +74,10 @@ export const authenticateUser = (req, res, next) => {
|
|||||||
const currentTime = new Date().getTime();
|
const currentTime = new Date().getTime();
|
||||||
const reqIP = common.getRequestIP(req);
|
const reqIP = common.getRequestIP(req);
|
||||||
const failed = getFailedInfo(reqIP, currentTime);
|
const failed = getFailedInfo(reqIP, currentTime);
|
||||||
const password = req.body.authenticationValue;
|
const password = authenticationValue;
|
||||||
if (common.rtl_pass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) {
|
if (common.appConfig.rtlPass === password && failed.count < ALLOWED_LOGIN_ATTEMPTS) {
|
||||||
if (req.body.twoFAToken && req.body.twoFAToken !== '') {
|
if (twoFAToken && twoFAToken !== '') {
|
||||||
if (!verifyToken(req.body.twoFAToken)) {
|
if (!verifyToken(twoFAToken)) {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: { error: 'Invalid token.' } });
|
||||||
failed.count = failed.count + 1;
|
failed.count = failed.count + 1;
|
||||||
failed.lastTried = currentTime;
|
failed.lastTried = currentTime;
|
||||||
@ -84,7 +85,7 @@ export const authenticateUser = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!req.session.selectedNode) {
|
if (!req.session.selectedNode) {
|
||||||
req.session.selectedNode = common.initSelectedNode;
|
req.session.selectedNode = common.selectedNode;
|
||||||
}
|
}
|
||||||
delete failedLoginAttempts[reqIP];
|
delete failedLoginAttempts[reqIP];
|
||||||
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
|
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
|
||||||
@ -93,23 +94,23 @@ export const authenticateUser = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: { error: 'Invalid password.' } });
|
||||||
failed.count = common.rtl_pass !== password ? (failed.count + 1) : failed.count;
|
failed.count = common.appConfig.rtlPass !== password ? (failed.count + 1) : failed.count;
|
||||||
failed.lastTried = common.rtl_pass !== password ? currentTime : failed.lastTried;
|
failed.lastTried = common.appConfig.rtlPass !== password ? currentTime : failed.lastTried;
|
||||||
return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!'));
|
return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
export const resetPassword = (req, res, next) => {
|
export const resetPassword = (req, res, next) => {
|
||||||
|
const { currPassword, newPassword } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..' });
|
||||||
if (+common.rtl_sso) {
|
if (+common.appConfig.SSO.rtlSso) {
|
||||||
const errMsg = 'Password cannot be reset for SSO authentication';
|
const errMsg = 'Password cannot be reset for SSO authentication';
|
||||||
const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg, req.session.selectedNode);
|
const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg, req.session.selectedNode);
|
||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const currPassword = req.body.currPassword;
|
if (common.appConfig.rtlPass === currPassword) {
|
||||||
if (common.rtl_pass === currPassword) {
|
common.appConfig.rtlPass = common.replacePasswordWithHash(newPassword);
|
||||||
common.rtl_pass = common.replacePasswordWithHash(req.body.newPassword);
|
|
||||||
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
|
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful' });
|
||||||
res.status(200).json({ token: token });
|
res.status(200).json({ token: token });
|
||||||
|
@ -79,6 +79,7 @@ export const getSwapInfo = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const createSwap = (req, res, next) => {
|
export const createSwap = (req, res, next) => {
|
||||||
|
const { amount, sendFromInternal, address } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Boltz', msg: 'Creating Swap..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Boltz', msg: 'Creating Swap..' });
|
||||||
options = common.getBoltzServerOptions(req);
|
options = common.getBoltzServerOptions(req);
|
||||||
if (options.url === '') {
|
if (options.url === '') {
|
||||||
@ -87,9 +88,12 @@ export const createSwap = (req, res, next) => {
|
|||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
}
|
}
|
||||||
options.url = options.url + '/v1/createswap';
|
options.url = options.url + '/v1/createswap';
|
||||||
options.body = { amount: req.body.amount };
|
options.body = { amount: amount };
|
||||||
if (req.body.address !== '') {
|
if (sendFromInternal) {
|
||||||
options.body.address = req.body.address;
|
options.body.send_from_internal = sendFromInternal;
|
||||||
|
}
|
||||||
|
if (address && address !== '') {
|
||||||
|
options.body.address = address;
|
||||||
}
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Boltz', msg: 'Create Swap Options Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Boltz', msg: 'Create Swap Options Body', data: options.body });
|
||||||
request.post(options).then((createSwapRes) => {
|
request.post(options).then((createSwapRes) => {
|
||||||
@ -101,6 +105,7 @@ export const createSwap = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const createReverseSwap = (req, res, next) => {
|
export const createReverseSwap = (req, res, next) => {
|
||||||
|
const { amount, acceptZeroConf, address } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Boltz', msg: 'Creating Reverse Swap..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Boltz', msg: 'Creating Reverse Swap..' });
|
||||||
options = common.getBoltzServerOptions(req);
|
options = common.getBoltzServerOptions(req);
|
||||||
if (options.url === '') {
|
if (options.url === '') {
|
||||||
@ -109,9 +114,9 @@ export const createReverseSwap = (req, res, next) => {
|
|||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
}
|
}
|
||||||
options.url = options.url + '/v1/createreverseswap';
|
options.url = options.url + '/v1/createreverseswap';
|
||||||
options.body = { amount: req.body.amount };
|
options.body = { amount: amount, accept_zero_conf: acceptZeroConf || false };
|
||||||
if (req.body.address !== '') {
|
if (address && address !== '') {
|
||||||
options.body.address = req.body.address;
|
options.body.address = address;
|
||||||
}
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Boltz', msg: 'Create Reverse Swap Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Boltz', msg: 'Create Reverse Swap Body', data: options.body });
|
||||||
request.post(options).then((createReverseSwapRes) => {
|
request.post(options).then((createReverseSwapRes) => {
|
||||||
@ -123,6 +128,7 @@ export const createReverseSwap = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const createChannel = (req, res, next) => {
|
export const createChannel = (req, res, next) => {
|
||||||
|
const { amount, address } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Boltz', msg: 'Creating Boltz Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Boltz', msg: 'Creating Boltz Channel..' });
|
||||||
options = common.getBoltzServerOptions(req);
|
options = common.getBoltzServerOptions(req);
|
||||||
if (options.url === '') {
|
if (options.url === '') {
|
||||||
@ -131,9 +137,9 @@ export const createChannel = (req, res, next) => {
|
|||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
}
|
}
|
||||||
options.url = options.url + '/v1/createchannel';
|
options.url = options.url + '/v1/createchannel';
|
||||||
options.body = { amount: req.body.amount };
|
options.body = { amount: amount };
|
||||||
if (req.body.address !== '') {
|
if (address && address !== '') {
|
||||||
options.body.address = req.body.address;
|
options.body.address = address;
|
||||||
}
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Boltz', msg: 'Create Channel Options Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Boltz', msg: 'Create Channel Options Body', data: options.body });
|
||||||
request.post(options).then((createChannelRes) => {
|
request.post(options).then((createChannelRes) => {
|
||||||
|
@ -5,24 +5,25 @@ let options = null;
|
|||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
export const loopOut = (req, res, next) => {
|
export const loopOut = (req, res, next) => {
|
||||||
|
const { amount, targetConf, swapRoutingFee, minerFee, prepayRoutingFee, prepayAmt, swapFee, swapPublicationDeadline, chanId, destAddress } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Loop', msg: 'Looping Out..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Loop', msg: 'Looping Out..' });
|
||||||
options.uri = '/v1/loop/out';
|
options.uri = '/v1/loop/out';
|
||||||
options.body = {
|
options.body = {
|
||||||
amt: req.body.amount,
|
amt: amount,
|
||||||
sweep_conf_target: req.body.targetConf,
|
sweep_conf_target: targetConf,
|
||||||
max_swap_routing_fee: req.body.swapRoutingFee,
|
max_swap_routing_fee: swapRoutingFee,
|
||||||
max_miner_fee: req.body.minerFee,
|
max_miner_fee: minerFee,
|
||||||
max_prepay_routing_fee: req.body.prepayRoutingFee,
|
max_prepay_routing_fee: prepayRoutingFee,
|
||||||
max_prepay_amt: req.body.prepayAmt,
|
max_prepay_amt: prepayAmt,
|
||||||
max_swap_fee: req.body.swapFee,
|
max_swap_fee: swapFee,
|
||||||
swap_publication_deadline: req.body.swapPublicationDeadline,
|
swap_publication_deadline: swapPublicationDeadline,
|
||||||
initiator: 'RTL'
|
initiator: 'RTL'
|
||||||
};
|
};
|
||||||
if (req.body.chanId !== '') {
|
if (chanId !== '') {
|
||||||
options.body['loop_out_channel'] = req.body.chanId;
|
options.body['loop_out_channel'] = chanId;
|
||||||
}
|
}
|
||||||
if (req.body.destAddress !== '') {
|
if (destAddress !== '') {
|
||||||
options.body['dest'] = req.body.destAddress;
|
options.body['dest'] = destAddress;
|
||||||
}
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Body', data: options.body });
|
||||||
request.post(options).then((loopOutRes) => {
|
request.post(options).then((loopOutRes) => {
|
||||||
@ -87,12 +88,13 @@ export const loopOutTermsAndQuotes = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
export const loopIn = (req, res, next) => {
|
export const loopIn = (req, res, next) => {
|
||||||
|
const { amount, swapFee, minerFee } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Loop', msg: 'Looping In..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Loop', msg: 'Looping In..' });
|
||||||
options.uri = '/v1/loop/in';
|
options.uri = '/v1/loop/in';
|
||||||
options.body = {
|
options.body = {
|
||||||
amt: req.body.amount,
|
amt: amount,
|
||||||
max_swap_fee: req.body.swapFee,
|
max_swap_fee: swapFee,
|
||||||
max_miner_fee: req.body.minerFee,
|
max_miner_fee: minerFee,
|
||||||
initiator: 'RTL'
|
initiator: 'RTL'
|
||||||
};
|
};
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Loop', msg: 'Loop In Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Loop', msg: 'Loop In Body', data: options.body });
|
||||||
|
@ -1,62 +1,72 @@
|
|||||||
export class CommonSelectedNode {
|
export class SSO {
|
||||||
constructor(options, ln_server_url, macaroon_path, macaroon_value, rune_path, rune_value, ln_api_password, swap_server_url, boltz_server_url, config_path, rtl_conf_file_path, swap_macaroon_path, boltz_macaroon_path, bitcoind_config_path, channel_backup_path, log_level, log_file, index, ln_node, ln_implementation, user_persona, theme_mode, theme_color, unannounced_channels, fiat_conversion, currency_unit, ln_version, api_version, enable_offers, enable_peerswap) {
|
constructor(rtlSso, rtlCookiePath, logoutRedirectLink, cookieValue) {
|
||||||
this.options = options;
|
this.rtlSso = rtlSso;
|
||||||
this.ln_server_url = ln_server_url;
|
this.rtlCookiePath = rtlCookiePath;
|
||||||
this.macaroon_path = macaroon_path;
|
this.logoutRedirectLink = logoutRedirectLink;
|
||||||
this.macaroon_value = macaroon_value;
|
this.cookieValue = cookieValue;
|
||||||
this.rune_path = rune_path;
|
|
||||||
this.rune_value = rune_value;
|
|
||||||
this.ln_api_password = ln_api_password;
|
|
||||||
this.swap_server_url = swap_server_url;
|
|
||||||
this.boltz_server_url = boltz_server_url;
|
|
||||||
this.config_path = config_path;
|
|
||||||
this.rtl_conf_file_path = rtl_conf_file_path;
|
|
||||||
this.swap_macaroon_path = swap_macaroon_path;
|
|
||||||
this.boltz_macaroon_path = boltz_macaroon_path;
|
|
||||||
this.bitcoind_config_path = bitcoind_config_path;
|
|
||||||
this.channel_backup_path = channel_backup_path;
|
|
||||||
this.log_level = log_level;
|
|
||||||
this.log_file = log_file;
|
|
||||||
this.index = index;
|
|
||||||
this.ln_node = ln_node;
|
|
||||||
this.ln_implementation = ln_implementation;
|
|
||||||
this.user_persona = user_persona;
|
|
||||||
this.theme_mode = theme_mode;
|
|
||||||
this.theme_color = theme_color;
|
|
||||||
this.unannounced_channels = unannounced_channels;
|
|
||||||
this.fiat_conversion = fiat_conversion;
|
|
||||||
this.currency_unit = currency_unit;
|
|
||||||
this.ln_version = ln_version;
|
|
||||||
this.api_version = api_version;
|
|
||||||
this.enable_offers = enable_offers;
|
|
||||||
this.enable_peerswap = enable_peerswap;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export class AuthenticationConfiguration {
|
export class Settings {
|
||||||
constructor(configPath, swapMacaroonPath, boltzMacaroonPath) {
|
constructor(blockExplorerUrl, lnServerUrl, swapServerUrl, boltzServerUrl, bitcoindConfigPath, channelBackupPath, logLevel, logFile, userPersona, themeMode, themeColor, unannouncedChannels, fiatConversion, currencyUnit, enableOffers, enablePeerswap) {
|
||||||
this.configPath = configPath;
|
this.blockExplorerUrl = blockExplorerUrl;
|
||||||
this.swapMacaroonPath = swapMacaroonPath;
|
this.lnServerUrl = lnServerUrl;
|
||||||
this.boltzMacaroonPath = boltzMacaroonPath;
|
this.swapServerUrl = swapServerUrl;
|
||||||
}
|
this.boltzServerUrl = boltzServerUrl;
|
||||||
}
|
this.bitcoindConfigPath = bitcoindConfigPath;
|
||||||
export class NodeSettingsConfiguration {
|
this.channelBackupPath = channelBackupPath;
|
||||||
constructor(userPersona, themeMode, themeColor, unannouncedChannels, fiatConversion, currencyUnit, bitcoindConfigPath, logLevel, lnServerUrl, swapServerUrl, boltzServerUrl, channelBackupPath, enableOffers, enablePeerswap) {
|
this.logLevel = logLevel;
|
||||||
|
this.logFile = logFile;
|
||||||
this.userPersona = userPersona;
|
this.userPersona = userPersona;
|
||||||
this.themeMode = themeMode;
|
this.themeMode = themeMode;
|
||||||
this.themeColor = themeColor;
|
this.themeColor = themeColor;
|
||||||
this.unannouncedChannels = unannouncedChannels;
|
this.unannouncedChannels = unannouncedChannels;
|
||||||
this.fiatConversion = fiatConversion;
|
this.fiatConversion = fiatConversion;
|
||||||
this.currencyUnit = currencyUnit;
|
this.currencyUnit = currencyUnit;
|
||||||
this.bitcoindConfigPath = bitcoindConfigPath;
|
|
||||||
this.logLevel = logLevel;
|
|
||||||
this.lnServerUrl = lnServerUrl;
|
|
||||||
this.swapServerUrl = swapServerUrl;
|
|
||||||
this.boltzServerUrl = boltzServerUrl;
|
|
||||||
this.channelBackupPath = channelBackupPath;
|
|
||||||
this.enableOffers = enableOffers;
|
this.enableOffers = enableOffers;
|
||||||
this.enablePeerswap = enablePeerswap;
|
this.enablePeerswap = enablePeerswap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export class Authentication {
|
||||||
|
constructor(options, configPath, macaroonPath, macaroonValue, runePath, runeValue, lnApiPassword, swapMacaroonPath, boltzMacaroonPath) {
|
||||||
|
this.options = options;
|
||||||
|
this.configPath = configPath;
|
||||||
|
this.macaroonPath = macaroonPath;
|
||||||
|
this.macaroonValue = macaroonValue;
|
||||||
|
this.runePath = runePath;
|
||||||
|
this.runeValue = runeValue;
|
||||||
|
this.lnApiPassword = lnApiPassword;
|
||||||
|
this.swapMacaroonPath = swapMacaroonPath;
|
||||||
|
this.boltzMacaroonPath = boltzMacaroonPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class ApplicationConfig {
|
||||||
|
constructor(defaultNodeIndex, selectedNodeIndex, dbDirectoryPath, rtlConfFilePath, rtlPass, multiPass, multiPassHashed, allowPasswordUpdate, enable2FA, secret2FA, SSO, nodes) {
|
||||||
|
this.defaultNodeIndex = defaultNodeIndex;
|
||||||
|
this.selectedNodeIndex = selectedNodeIndex;
|
||||||
|
this.dbDirectoryPath = dbDirectoryPath;
|
||||||
|
this.rtlConfFilePath = rtlConfFilePath;
|
||||||
|
this.rtlPass = rtlPass;
|
||||||
|
this.multiPass = multiPass;
|
||||||
|
this.multiPassHashed = multiPassHashed;
|
||||||
|
this.allowPasswordUpdate = allowPasswordUpdate;
|
||||||
|
this.enable2FA = enable2FA;
|
||||||
|
this.secret2FA = secret2FA;
|
||||||
|
this.SSO = SSO;
|
||||||
|
this.nodes = nodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class SelectedNode {
|
||||||
|
constructor(logLevel, logFile, index, lnNode, lnImplementation, lnVersion, settings, authentication) {
|
||||||
|
this.logLevel = logLevel;
|
||||||
|
this.logFile = logFile;
|
||||||
|
this.index = index;
|
||||||
|
this.lnNode = lnNode;
|
||||||
|
this.lnImplementation = lnImplementation;
|
||||||
|
this.lnVersion = lnVersion;
|
||||||
|
this.settings = settings;
|
||||||
|
this.authentication = authentication;
|
||||||
|
}
|
||||||
|
}
|
||||||
export class LogJSONObj {
|
export class LogJSONObj {
|
||||||
constructor(level, msg, data, error, fileName, selectedNode) {
|
constructor(level, msg, data, error, fileName, selectedNode) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
import exprs from 'express';
|
|
||||||
const { Router } = exprs;
|
|
||||||
import { isAuthenticated } from '../../utils/authCheck.js';
|
|
||||||
import { getBalance } from '../../controllers/cln/balance.js';
|
|
||||||
const router = Router();
|
|
||||||
router.get('/', isAuthenticated, getBalance);
|
|
||||||
export default router;
|
|
@ -1,7 +0,0 @@
|
|||||||
import exprs from 'express';
|
|
||||||
const { Router } = exprs;
|
|
||||||
import { isAuthenticated } from '../../utils/authCheck.js';
|
|
||||||
import { getFees } from '../../controllers/cln/fees.js';
|
|
||||||
const router = Router();
|
|
||||||
router.get('/', isAuthenticated, getFees);
|
|
||||||
export default router;
|
|
@ -1,17 +1,15 @@
|
|||||||
import exprs from 'express';
|
import exprs from 'express';
|
||||||
const { Router } = exprs;
|
const { Router } = exprs;
|
||||||
import { isAuthenticated } from '../../utils/authCheck.js';
|
import { isAuthenticated } from '../../utils/authCheck.js';
|
||||||
import { getRTLConfigInitial, getRTLConfig, updateUISettings, update2FASettings, getConfig, getFile, updateSelectedNode, updateDefaultNode, updateServiceSettings, updateSSO, getCurrencyRates } from '../../controllers/shared/RTLConf.js';
|
import { updateNodeSettings, getConfig, getFile, updateSelectedNode, updateApplicationSettings, getCurrencyRates, getApplicationSettings, getExplorerFeesRecommended, getExplorerTransaction } from '../../controllers/shared/RTLConf.js';
|
||||||
const router = Router();
|
const router = Router();
|
||||||
router.get('/rtlconfinit', getRTLConfigInitial);
|
router.get('/', getApplicationSettings);
|
||||||
router.get('/rtlconf', isAuthenticated, getRTLConfig);
|
router.get('/rates', getCurrencyRates);
|
||||||
router.post('/', isAuthenticated, updateUISettings);
|
|
||||||
router.post('/update2FA', isAuthenticated, update2FASettings);
|
|
||||||
router.get('/config/:nodeType', isAuthenticated, getConfig);
|
|
||||||
router.get('/file', isAuthenticated, getFile);
|
router.get('/file', isAuthenticated, getFile);
|
||||||
router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode);
|
router.get('/updateSelNode/:currNodeIndex/:prevNodeIndex', updateSelectedNode);
|
||||||
router.post('/updateDefaultNode', updateDefaultNode);
|
router.get('/config/:nodeType', isAuthenticated, getConfig);
|
||||||
router.post('/updateServiceSettings', updateServiceSettings);
|
router.post('/node', isAuthenticated, updateNodeSettings);
|
||||||
router.post('/updateSSO', updateSSO);
|
router.post('/application', isAuthenticated, updateApplicationSettings);
|
||||||
router.get('/rates', getCurrencyRates);
|
router.get('/explorerFeesRecommended', getExplorerFeesRecommended);
|
||||||
|
router.get('/explorerTransaction/:txid', getExplorerTransaction);
|
||||||
export default router;
|
export default router;
|
||||||
|
@ -30,7 +30,7 @@ export class ExpressApplication {
|
|||||||
this.setCORS = () => { CORS.mount(this.app); };
|
this.setCORS = () => { CORS.mount(this.app); };
|
||||||
this.setCSRF = () => { CSRF.mount(this.app); };
|
this.setCSRF = () => { CSRF.mount(this.app); };
|
||||||
this.setApplicationRoutes = () => {
|
this.setApplicationRoutes = () => {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Setting up Application Routes..' });
|
||||||
this.app.use(this.common.baseHref + '/api', sharedRoutes);
|
this.app.use(this.common.baseHref + '/api', sharedRoutes);
|
||||||
this.app.use(this.common.baseHref + '/api/lnd', lndRoutes);
|
this.app.use(this.common.baseHref + '/api/lnd', lndRoutes);
|
||||||
this.app.use(this.common.baseHref + '/api/cln', clnRoutes);
|
this.app.use(this.common.baseHref + '/api/cln', clnRoutes);
|
||||||
@ -45,33 +45,33 @@ export class ExpressApplication {
|
|||||||
this.handleApplicationErrors(err, res);
|
this.handleApplicationErrors(err, res);
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Application Routes Set' });
|
||||||
};
|
};
|
||||||
this.handleApplicationErrors = (err, res) => {
|
this.handleApplicationErrors = (err, res) => {
|
||||||
switch (err.code) {
|
switch (err.code) {
|
||||||
case 'EACCES':
|
case 'EACCES':
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server requires elevated privileges' });
|
||||||
res.status(406).send('Server requires elevated privileges.');
|
res.status(406).send('Server requires elevated privileges.');
|
||||||
break;
|
break;
|
||||||
case 'EADDRINUSE':
|
case 'EADDRINUSE':
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is already in use' });
|
||||||
res.status(409).send('Server is already in use.');
|
res.status(409).send('Server is already in use.');
|
||||||
break;
|
break;
|
||||||
case 'ECONNREFUSED':
|
case 'ECONNREFUSED':
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Server is down/locked' });
|
||||||
res.status(401).send('Server is down/locked.');
|
res.status(401).send('Server is down/locked.');
|
||||||
break;
|
break;
|
||||||
case 'EBADCSRFTOKEN':
|
case 'EBADCSRFTOKEN':
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'Invalid CSRF token. Form tempered.' });
|
||||||
res.status(403).send('Invalid CSRF token, form tempered.');
|
res.status(403).send('Invalid CSRF token, form tempered.');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'App', msg: 'DEFUALT ERROR', error: err });
|
||||||
res.status(400).send(JSON.stringify(err));
|
res.status(400).send(JSON.stringify(err));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'App', msg: 'Starting Express Application..' });
|
||||||
this.app.set('trust proxy', true);
|
this.app.set('trust proxy', true);
|
||||||
this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false }));
|
this.app.use(sessions({ secret: this.common.secret_key, saveUninitialized: true, cookie: { secure: false, maxAge: ONE_DAY }, resave: false }));
|
||||||
this.app.use(cookieParser(this.common.secret_key));
|
this.app.use(cookieParser(this.common.secret_key));
|
||||||
|
@ -46,7 +46,7 @@ export const verifyWSUser = (info, next) => {
|
|||||||
catch (err) {
|
catch (err) {
|
||||||
cookies = {};
|
cookies = {};
|
||||||
updatedReq['cookies'] = JSON.parse(cookies);
|
updatedReq['cookies'] = JSON.parse(cookies);
|
||||||
logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err });
|
logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to read CSRF token cookie', data: err });
|
||||||
}
|
}
|
||||||
csurfProtection(updatedReq, null, (err) => {
|
csurfProtection(updatedReq, null, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -58,7 +58,7 @@ export const verifyWSUser = (info, next) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
logger.log({ selectedNode: common.initSelectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err });
|
logger.log({ selectedNode: common.selectedNode, level: 'WARN', fileName: 'AuthCheck', msg: '403 Unable to verify CSRF token', data: err });
|
||||||
next(true);
|
next(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,20 +8,11 @@ export class CommonService {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.logger = Logger;
|
this.logger = Logger;
|
||||||
this.nodes = [];
|
this.nodes = [];
|
||||||
this.initSelectedNode = null;
|
this.selectedNode = null;
|
||||||
this.rtl_conf_file_path = '';
|
this.ssoInit = { rtlSso: 0, rtlCookiePath: '', logoutRedirectLink: '', cookieValue: '' };
|
||||||
|
this.appConfig = { defaultNodeIndex: 0, selectedNodeIndex: 0, rtlConfFilePath: '', dbDirectoryPath: join(dirname(fileURLToPath(import.meta.url)), '..', '..'), rtlPass: '', allowPasswordUpdate: true, enable2FA: false, secret2FA: '', SSO: this.ssoInit, nodes: [] };
|
||||||
this.port = 3000;
|
this.port = 3000;
|
||||||
this.host = '';
|
this.host = '';
|
||||||
this.db_directory_path = join(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
||||||
this.rtl_pass = '';
|
|
||||||
this.flg_allow_password_update = true;
|
|
||||||
this.rtl_secret2fa = '';
|
|
||||||
this.rtl_sso = 0;
|
|
||||||
this.rtl_cookie_path = '';
|
|
||||||
this.logout_redirect_link = '';
|
|
||||||
this.cookie_value = '';
|
|
||||||
this.ln_version = '';
|
|
||||||
this.api_version = '';
|
|
||||||
this.secret_key = crypto.randomBytes(64).toString('hex');
|
this.secret_key = crypto.randomBytes(64).toString('hex');
|
||||||
this.read_dummy_data = false;
|
this.read_dummy_data = false;
|
||||||
this.baseHref = '/rtl';
|
this.baseHref = '/rtl';
|
||||||
@ -30,98 +21,160 @@ export class CommonService {
|
|||||||
{ name: 'JAN', days: 31 }, { name: 'FEB', days: 28 }, { name: 'MAR', days: 31 }, { name: 'APR', days: 30 }, { name: 'MAY', days: 31 }, { name: 'JUN', days: 30 },
|
{ name: 'JAN', days: 31 }, { name: 'FEB', days: 28 }, { name: 'MAR', days: 31 }, { name: 'APR', days: 30 }, { name: 'MAY', days: 31 }, { name: 'JUN', days: 30 },
|
||||||
{ name: 'JUL', days: 31 }, { name: 'AUG', days: 31 }, { name: 'SEP', days: 30 }, { name: 'OCT', days: 31 }, { name: 'NOV', days: 30 }, { name: 'DEC', days: 31 }
|
{ name: 'JUL', days: 31 }, { name: 'AUG', days: 31 }, { name: 'SEP', days: 30 }, { name: 'OCT', days: 31 }, { name: 'NOV', days: 30 }, { name: 'DEC', days: 31 }
|
||||||
];
|
];
|
||||||
|
this.maskPasswords = (obj) => {
|
||||||
|
const keys = Object.keys(obj);
|
||||||
|
const length = keys.length;
|
||||||
|
if (length !== 0) {
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
if (typeof obj[keys[i]] === 'object') {
|
||||||
|
keys[keys[i]] = this.maskPasswords(obj[keys[i]]);
|
||||||
|
}
|
||||||
|
if (typeof keys[i] === 'string' &&
|
||||||
|
((keys[i].toLowerCase().includes('password') && keys[i] !== 'allowPasswordUpdate') || keys[i].toLowerCase().includes('multipass') ||
|
||||||
|
keys[i].toLowerCase().includes('rpcpass') || keys[i].toLowerCase().includes('rpcpassword') ||
|
||||||
|
keys[i].toLowerCase().includes('rpcuser'))) {
|
||||||
|
obj[keys[i]] = '*'.repeat(20);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
};
|
||||||
|
this.removeAuthSecureData = (node) => {
|
||||||
|
delete node.authentication.macaroonPath;
|
||||||
|
delete node.authentication.runePath;
|
||||||
|
delete node.authentication.runeValue;
|
||||||
|
delete node.authentication.lnApiPassword;
|
||||||
|
delete node.authentication.options;
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
this.removeSecureData = (config) => {
|
||||||
|
delete config.rtlConfFilePath;
|
||||||
|
delete config.rtlPass;
|
||||||
|
delete config.multiPass;
|
||||||
|
delete config.multiPassHashed;
|
||||||
|
delete config.secret2FA;
|
||||||
|
config.nodes?.map((node) => this.removeAuthSecureData(node));
|
||||||
|
return config;
|
||||||
|
};
|
||||||
|
this.addSecureData = (config) => {
|
||||||
|
config.rtlConfFilePath = this.appConfig.rtlConfFilePath;
|
||||||
|
config.rtlPass = this.appConfig.rtlPass;
|
||||||
|
config.multiPassHashed = this.appConfig.multiPassHashed;
|
||||||
|
config.SSO.rtlCookiePath = this.appConfig.SSO.rtlCookiePath;
|
||||||
|
if (this.appConfig.multiPass) {
|
||||||
|
config.multiPass = this.appConfig.multiPass;
|
||||||
|
}
|
||||||
|
if (config.secret2FA === this.appConfig.secret2FA) {
|
||||||
|
config.secret2FA = this.appConfig.secret2FA;
|
||||||
|
}
|
||||||
|
config.nodes.map((node, i) => {
|
||||||
|
if (this.appConfig && this.appConfig.nodes && this.appConfig.nodes.length > i && this.appConfig.nodes[i].authentication) {
|
||||||
|
if (this.appConfig.nodes[i].authentication.macaroonPath) {
|
||||||
|
node.authentication.macaroonPath = this.appConfig.nodes[i].authentication.macaroonPath;
|
||||||
|
}
|
||||||
|
if (this.appConfig.nodes[i].authentication.runePath) {
|
||||||
|
node.authentication.runePath = this.appConfig.nodes[i].authentication.runePath;
|
||||||
|
}
|
||||||
|
if (this.appConfig.nodes[i].authentication.lnApiPassword) {
|
||||||
|
node.authentication.lnApiPassword = this.appConfig.nodes[i].authentication.lnApiPassword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
return config;
|
||||||
|
};
|
||||||
this.setSwapServerOptions = (req) => {
|
this.setSwapServerOptions = (req) => {
|
||||||
const swapOptions = {
|
const swapOptions = {
|
||||||
baseUrl: req.session.selectedNode.swap_server_url,
|
baseUrl: req.session.selectedNode.settings.swapServerUrl,
|
||||||
uri: '',
|
uri: '',
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
json: true,
|
json: true,
|
||||||
headers: { 'Grpc-Metadata-macaroon': '' }
|
headers: { 'Grpc-Metadata-macaroon': '' }
|
||||||
};
|
};
|
||||||
if (req.session.selectedNode.swap_macaroon_path) {
|
if (req.session.selectedNode.authentication.swapMacaroonPath) {
|
||||||
try {
|
try {
|
||||||
swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.swap_macaroon_path, 'loop.macaroon')).toString('hex') };
|
swapOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.swapMacaroonPath, 'loop.macaroon')).toString('hex') };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Loop macaroon Error', error: err });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Swap Options', data: swapOptions });
|
||||||
return swapOptions;
|
return swapOptions;
|
||||||
};
|
};
|
||||||
this.getBoltzServerOptions = (req) => {
|
this.getBoltzServerOptions = (req) => {
|
||||||
const boltzOptions = {
|
const boltzOptions = {
|
||||||
url: req.session.selectedNode.boltz_server_url,
|
url: req.session.selectedNode.settings.boltzServerUrl,
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
json: true,
|
json: true,
|
||||||
headers: { 'Grpc-Metadata-macaroon': '' }
|
headers: { 'Grpc-Metadata-macaroon': '' }
|
||||||
};
|
};
|
||||||
if (req.session.selectedNode.boltz_macaroon_path) {
|
if (req.session.selectedNode.authentication.boltzMacaroonPath) {
|
||||||
try {
|
try {
|
||||||
boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.boltz_macaroon_path, 'admin.macaroon')).toString('hex') };
|
boltzOptions.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.boltzMacaroonPath, 'admin.macaroon')).toString('hex') };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Boltz macaroon Error', error: err });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Boltz Options', data: boltzOptions });
|
||||||
return boltzOptions;
|
return boltzOptions;
|
||||||
};
|
};
|
||||||
this.getOptions = (req) => {
|
this.getOptions = (req) => {
|
||||||
if (req.session.selectedNode && req.session.selectedNode.options) {
|
if (req.session.selectedNode && req.session.selectedNode.authentication.options) {
|
||||||
req.session.selectedNode.options.method = (req.session.selectedNode.ln_implementation && req.session.selectedNode.ln_implementation.toUpperCase() === 'LND') ? 'GET' : 'POST';
|
req.session.selectedNode.authentication.options.method = (req.session.selectedNode.lnImplementation && req.session.selectedNode.lnImplementation.toUpperCase() === 'LND') ? 'GET' : 'POST';
|
||||||
delete req.session.selectedNode.options.form;
|
delete req.session.selectedNode.authentication.options.form;
|
||||||
delete req.session.selectedNode.options.body;
|
delete req.session.selectedNode.authentication.options.body;
|
||||||
req.session.selectedNode.options.qs = {};
|
req.session.selectedNode.authentication.options.qs = {};
|
||||||
return req.session.selectedNode.options;
|
return req.session.selectedNode.authentication.options;
|
||||||
}
|
}
|
||||||
return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.initSelectedNode);
|
return this.handleError({ statusCode: 401, message: 'Session expired after a day\'s inactivity' }, 'Session Expired', 'Session Expiry Error', this.selectedNode);
|
||||||
};
|
};
|
||||||
this.updateSelectedNodeOptions = (req) => {
|
this.updateSelectedNodeOptions = (req) => {
|
||||||
if (!req.session.selectedNode) {
|
if (!req.session.selectedNode) {
|
||||||
req.session.selectedNode = {};
|
req.session.selectedNode = {};
|
||||||
}
|
}
|
||||||
req.session.selectedNode.options = {
|
req.session.selectedNode.authentication.options = {
|
||||||
url: '',
|
url: '',
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
json: true,
|
json: true,
|
||||||
form: null
|
form: null
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
if (req.session.selectedNode && req.session.selectedNode.ln_implementation) {
|
if (req.session.selectedNode && req.session.selectedNode.lnImplementation) {
|
||||||
switch (req.session.selectedNode.ln_implementation.toUpperCase()) {
|
switch (req.session.selectedNode.lnImplementation.toUpperCase()) {
|
||||||
case 'CLN':
|
case 'CLN':
|
||||||
try {
|
try {
|
||||||
if (!req.session.selectedNode.rune_value) {
|
if (!req.session.selectedNode.authentication.runeValue) {
|
||||||
req.session.selectedNode.rune_value = this.getRuneValue(req.session.selectedNode.rune_path);
|
req.session.selectedNode.authentication.runeValue = this.getRuneValue(req.session.selectedNode.authentication.runePath);
|
||||||
}
|
}
|
||||||
req.session.selectedNode.options.headers = { rune: req.session.selectedNode.rune_value };
|
req.session.selectedNode.authentication.options.headers = { rune: req.session.selectedNode.authentication.runeValue };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ECL':
|
case 'ECL':
|
||||||
req.session.selectedNode.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.ln_api_password).toString('base64') };
|
req.session.selectedNode.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + req.session.selectedNode.authentication.lnApiPassword).toString('base64') };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
req.session.selectedNode.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.macaroon_path, 'admin.macaroon')).toString('hex') };
|
req.session.selectedNode.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(req.session.selectedNode.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (req.session.selectedNode) {
|
if (req.session.selectedNode) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.ln_node, data: req.session.selectedNode.options });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Updated Node Options for ' + req.session.selectedNode.lnNode, data: req.session.selectedNode.authentication.options });
|
||||||
}
|
}
|
||||||
return { status: 200, message: 'Updated Successfully' };
|
return { status: 200, message: 'Updated Successfully' };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
req.session.selectedNode.options = {
|
req.session.selectedNode.authentication.options = {
|
||||||
url: '',
|
url: '',
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
json: true,
|
json: true,
|
||||||
form: null
|
form: null
|
||||||
};
|
};
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Update Selected Node Options Error', error: err });
|
||||||
return { status: 502, message: err };
|
return { status: 502, message: err };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -137,50 +190,50 @@ export class CommonService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.setOptions = (req) => {
|
this.setOptions = (req) => {
|
||||||
if (this.nodes[0].options && this.nodes[0].options.headers) {
|
if (this.nodes[0].authentication.options && this.nodes[0].authentication.options.headers) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.nodes && this.nodes.length > 0) {
|
if (this.nodes && this.nodes.length > 0) {
|
||||||
this.nodes.forEach((node) => {
|
this.nodes.forEach((node) => {
|
||||||
node.options = {
|
node.authentication.options = {
|
||||||
url: '',
|
url: '',
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
json: true,
|
json: true,
|
||||||
form: null
|
form: null
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
if (node.ln_implementation) {
|
if (node.lnImplementation) {
|
||||||
switch (node.ln_implementation.toUpperCase()) {
|
switch (node.lnImplementation.toUpperCase()) {
|
||||||
case 'CLN':
|
case 'CLN':
|
||||||
try {
|
try {
|
||||||
if (!node.rune_value) {
|
if (!node.authentication.runeValue) {
|
||||||
node.rune_value = this.getRuneValue(node.rune_path);
|
node.authentication.runeValue = this.getRuneValue(node.authentication.runePath);
|
||||||
}
|
}
|
||||||
node.options.headers = { rune: node.rune_value };
|
node.authentication.options.headers = { rune: node.authentication.runeValue };
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ECL':
|
case 'ECL':
|
||||||
node.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.ln_api_password).toString('base64') };
|
node.authentication.options.headers = { authorization: 'Basic ' + Buffer.from(':' + node.authentication.lnApiPassword).toString('base64') };
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
node.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.macaroon_path, 'admin.macaroon')).toString('hex') };
|
node.authentication.options.headers = { 'Grpc-Metadata-macaroon': fs.readFileSync(join(node.authentication.macaroonPath, 'admin.macaroon')).toString('hex') };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Common Set Options Error', error: err });
|
||||||
node.options = {
|
node.authentication.options = {
|
||||||
url: '',
|
url: '',
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
json: true,
|
json: true,
|
||||||
form: ''
|
form: ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.ln_node, data: node.options });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Set Node Options for ' + node.lnNode, data: node.authentication.options });
|
||||||
});
|
});
|
||||||
this.updateSelectedNodeOptions(req);
|
this.updateSelectedNodeOptions(req);
|
||||||
}
|
}
|
||||||
@ -250,19 +303,11 @@ export class CommonService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.handleError = (errRes, fileName, errMsg, selectedNode) => {
|
this.handleError = (errRes, fileName, errMsg, selectedNode) => {
|
||||||
let err = JSON.parse(JSON.stringify(errRes));
|
const err = JSON.parse(JSON.stringify(errRes));
|
||||||
if (err && err.error && Object.keys(err.error).length === 0 && errRes.error && (errRes.error.stack || errRes.error.message)) {
|
|
||||||
errRes.error = errRes.error.stack || errRes.error.message;
|
|
||||||
err = JSON.parse(JSON.stringify(errRes));
|
|
||||||
}
|
|
||||||
else if (errRes.message || errRes.stack) {
|
|
||||||
errRes.error = errRes.message || errRes.stack;
|
|
||||||
err = JSON.parse(JSON.stringify(errRes));
|
|
||||||
}
|
|
||||||
if (!selectedNode) {
|
if (!selectedNode) {
|
||||||
selectedNode = this.initSelectedNode;
|
selectedNode = this.selectedNode;
|
||||||
}
|
}
|
||||||
switch (selectedNode.ln_implementation) {
|
switch (selectedNode.lnImplementation) {
|
||||||
case 'LND':
|
case 'LND':
|
||||||
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
|
||||||
delete err.options.headers['Grpc-Metadata-macaroon'];
|
delete err.options.headers['Grpc-Metadata-macaroon'];
|
||||||
@ -272,11 +317,11 @@ export class CommonService {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'CLN':
|
case 'CLN':
|
||||||
if (err.options && err.options.headers && err.options.headers.macaroon) {
|
if (err.options && err.options.headers && err.options.headers.rune) {
|
||||||
delete err.options.headers.macaroon;
|
delete err.options.headers.rune;
|
||||||
}
|
}
|
||||||
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
|
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.rune) {
|
||||||
delete err.response.request.headers.macaroon;
|
delete err.response.request.headers.rune;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'ECL':
|
case 'ECL':
|
||||||
@ -314,7 +359,7 @@ export class CommonService {
|
|||||||
(err.message && typeof err.message === 'string') ? err.message : (typeof err === 'string') ? err : 'Unknown Error')
|
(err.message && typeof err.message === 'string') ? err.message : (typeof err === 'string') ? err : 'Unknown Error')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (selectedNode.ln_implementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') {
|
if (selectedNode.lnImplementation === 'ECL' && err.message && err.message.indexOf('Authentication Error') < 0 && err.name && err.name === 'StatusCodeError') {
|
||||||
newErrorObj.statusCode = 500;
|
newErrorObj.statusCode = 500;
|
||||||
}
|
}
|
||||||
return newErrorObj;
|
return newErrorObj;
|
||||||
@ -325,16 +370,16 @@ export class CommonService {
|
|||||||
req.socket.remoteAddress ||
|
req.socket.remoteAddress ||
|
||||||
(req.connection.socket ? req.connection.socket.remoteAddress : null));
|
(req.connection.socket ? req.connection.socket.remoteAddress : null));
|
||||||
this.getDummyData = (dataKey, lnImplementation) => {
|
this.getDummyData = (dataKey, lnImplementation) => {
|
||||||
const dummyDataFile = this.rtl_conf_file_path + sep + 'ECLDummyData.log';
|
const dummyDataFile = this.appConfig.rtlConfFilePath + sep + 'ECLDummyData.log';
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (this.dummy_data_array_from_file.length === 0) {
|
if (this.dummy_data_array_from_file.length === 0) {
|
||||||
fs.readFile(dummyDataFile, 'utf8', (err, data) => {
|
fs.readFile(dummyDataFile, 'utf8', (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.code === 'ENOENT') {
|
if (err.code === 'ENOENT') {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Dummy data file does not exist' });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Getting dummy data failed' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -349,36 +394,36 @@ export class CommonService {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.readCookie = () => {
|
this.readCookie = () => {
|
||||||
const exists = fs.existsSync(this.rtl_cookie_path);
|
const exists = fs.existsSync(this.appConfig.SSO.rtlCookiePath);
|
||||||
if (exists) {
|
if (exists) {
|
||||||
try {
|
try {
|
||||||
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8');
|
this.appConfig.SSO.cookieValue = fs.readFileSync(this.appConfig.SSO.rtlCookiePath, 'utf-8');
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading cookie: \n' + err });
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
const directoryName = dirname(this.rtl_cookie_path);
|
const directoryName = dirname(this.appConfig.SSO.rtlCookiePath);
|
||||||
this.createDirectory(directoryName);
|
this.createDirectory(directoryName);
|
||||||
fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex'));
|
fs.writeFileSync(this.appConfig.SSO.rtlCookiePath, crypto.randomBytes(64).toString('hex'));
|
||||||
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8');
|
this.appConfig.SSO.cookieValue = fs.readFileSync(this.appConfig.SSO.rtlCookiePath, 'utf-8');
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while reading the cookie: \n' + err });
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.refreshCookie = () => {
|
this.refreshCookie = () => {
|
||||||
try {
|
try {
|
||||||
fs.writeFileSync(this.rtl_cookie_path, crypto.randomBytes(64).toString('hex'));
|
fs.writeFileSync(this.appConfig.SSO.rtlCookiePath, crypto.randomBytes(64).toString('hex'));
|
||||||
this.cookie_value = fs.readFileSync(this.rtl_cookie_path, 'utf-8');
|
this.appConfig.SSO.cookieValue = fs.readFileSync(this.appConfig.SSO.rtlCookiePath, 'utf-8');
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Something went wrong while refreshing cookie', error: err });
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -405,50 +450,50 @@ export class CommonService {
|
|||||||
}, initDir);
|
}, initDir);
|
||||||
};
|
};
|
||||||
this.replacePasswordWithHash = (multiPassHashed) => {
|
this.replacePasswordWithHash = (multiPassHashed) => {
|
||||||
this.rtl_conf_file_path = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..');
|
this.appConfig.rtlConfFilePath = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : join(dirname(fileURLToPath(import.meta.url)), '../..');
|
||||||
try {
|
try {
|
||||||
const RTLConfFile = this.rtl_conf_file_path + sep + 'RTL-Config.json';
|
const RTLConfFile = this.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
||||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
||||||
config.multiPassHashed = multiPassHashed;
|
config.multiPassHashed = multiPassHashed;
|
||||||
delete config.multiPass;
|
delete config.multiPass;
|
||||||
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Please note that, RTL has encrypted the plaintext password into its corresponding hash' });
|
||||||
return config.multiPassHashed;
|
return config.multiPassHashed;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Password hashing failed', error: err });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.getAllNodeAllChannelBackup = (node) => {
|
this.getAllNodeAllChannelBackup = (node) => {
|
||||||
const channel_backup_file = node.channel_backup_path + sep + 'channel-all.bak';
|
const channel_backup_file = node.settings.channelBackupPath + sep + 'channel-all.bak';
|
||||||
const options = {
|
const options = {
|
||||||
url: node.ln_server_url + '/v1/channels/backup',
|
url: node.settings.lnServerUrl + '/v1/channels/backup',
|
||||||
rejectUnauthorized: false,
|
rejectUnauthorized: false,
|
||||||
json: true,
|
json: true,
|
||||||
headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex') }
|
headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.authentication.macaroonPath + '/admin.macaroon').toString('hex') }
|
||||||
};
|
};
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.ln_node + '..' });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Getting Channel Backup for Node ' + node.lnNode + '..' });
|
||||||
request(options).then((body) => {
|
request(options).then((body) => {
|
||||||
fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => {
|
fs.writeFile(channel_backup_file, JSON.stringify(body), (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
if (node.ln_node) {
|
if (node.lnNode) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for File ' + channel_backup_file, error: err });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (node.ln_node) {
|
if (node.lnNode) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.ln_node, data: body });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for Node ' + node.lnNode, data: body });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Successful in Channel Backup for File ' + channel_backup_file, data: body });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.ln_node, error: err });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Error in Channel Backup for Node ' + node.lnNode, error: err });
|
||||||
fs.writeFile(channel_backup_file, '', () => { });
|
fs.writeFile(channel_backup_file, '', () => { });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -458,8 +503,8 @@ export class CommonService {
|
|||||||
const pattern = /v?(\d+(\.\d+)*)/;
|
const pattern = /v?(\d+(\.\d+)*)/;
|
||||||
const match = currentVersion.match(pattern);
|
const match = currentVersion.match(pattern);
|
||||||
if (match && match.length && match.length > 1) {
|
if (match && match.length && match.length > 1) {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Global Version ' + match[1] });
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'INFO', fileName: 'Common', msg: 'Checking Compatiblility with Version ' + checkVersion });
|
||||||
const currentVersionArr = match[1].split('.') || [];
|
const currentVersionArr = match[1].split('.') || [];
|
||||||
currentVersionArr[1] = currentVersionArr[1].substring(0, 2);
|
currentVersionArr[1] = currentVersionArr[1].substring(0, 2);
|
||||||
const checkVersionsArr = checkVersion.split('.');
|
const checkVersionsArr = checkVersion.split('.');
|
||||||
@ -469,7 +514,7 @@ export class CommonService {
|
|||||||
(+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]);
|
(+currentVersionArr[0] === +checkVersionsArr[0] && +currentVersionArr[1] === +checkVersionsArr[1] && +currentVersionArr[2] >= +checkVersionsArr[2]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.logger.log({ selectedNode: this.initSelectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion });
|
this.logger.log({ selectedNode: this.selectedNode, level: 'ERROR', fileName: 'Common', msg: 'Invalid Version String ' + currentVersion });
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -479,18 +524,8 @@ export class CommonService {
|
|||||||
this.logEnvVariables = (req) => {
|
this.logEnvVariables = (req) => {
|
||||||
const selNode = req.session.selectedNode;
|
const selNode = req.session.selectedNode;
|
||||||
if (selNode && selNode.index) {
|
if (selNode && selNode.index) {
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'PORT: ' + this.port });
|
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup:', msg: JSON.stringify(this.removeSecureData(JSON.parse(JSON.stringify(this.appConfig)))) });
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'HOST: ' + this.host });
|
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.appConfig.SSO.rtlSso });
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DB_DIRECTORY_PATH: ' + this.db_directory_path });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'SSO: ' + this.rtl_sso });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + selNode.index });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'INDEX: ' + selNode.index });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + selNode.ln_node });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + selNode.ln_implementation });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + selNode.fiat_conversion });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + selNode.currency_unit });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + selNode.ln_server_url });
|
|
||||||
this.logger.log({ selectedNode: selNode, level: 'INFO', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + this.logout_redirect_link + '\r\n' });
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.filterData = (dataKey, lnImplementation) => {
|
this.filterData = (dataKey, lnImplementation) => {
|
||||||
|
@ -61,11 +61,11 @@ export class ConfigService {
|
|||||||
index: 1,
|
index: 1,
|
||||||
lnNode: 'Node 1',
|
lnNode: 'Node 1',
|
||||||
lnImplementation: 'LND',
|
lnImplementation: 'LND',
|
||||||
Authentication: {
|
authentication: {
|
||||||
macaroonPath: macaroonPath,
|
macaroonPath: macaroonPath,
|
||||||
configPath: configPath
|
configPath: configPath
|
||||||
},
|
},
|
||||||
Settings: {
|
settings: {
|
||||||
userPersona: 'MERCHANT',
|
userPersona: 'MERCHANT',
|
||||||
themeMode: 'DAY',
|
themeMode: 'DAY',
|
||||||
themeColor: 'PURPLE',
|
themeColor: 'PURPLE',
|
||||||
@ -73,7 +73,8 @@ export class ConfigService {
|
|||||||
logLevel: 'ERROR',
|
logLevel: 'ERROR',
|
||||||
lnServerUrl: 'https://127.0.0.1:8080',
|
lnServerUrl: 'https://127.0.0.1:8080',
|
||||||
fiatConversion: false,
|
fiatConversion: false,
|
||||||
unannouncedChannels: false
|
unannouncedChannels: false,
|
||||||
|
blockExplorerUrl: 'https://mempool.space'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -95,15 +96,15 @@ export class ConfigService {
|
|||||||
};
|
};
|
||||||
this.updateLogByLevel = () => {
|
this.updateLogByLevel = () => {
|
||||||
let updateLogFlag = false;
|
let updateLogFlag = false;
|
||||||
this.common.rtl_conf_file_path = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
|
this.common.appConfig.rtlConfFilePath = process?.env?.RTL_CONFIG_PATH ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
|
||||||
try {
|
try {
|
||||||
const RTLConfFile = this.common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
const RTLConfFile = this.common.appConfig.rtlConfFilePath + sep + 'RTL-Config.json';
|
||||||
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
const config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
|
||||||
config.nodes.forEach((node) => {
|
config.nodes.forEach((node) => {
|
||||||
if (node.Settings.hasOwnProperty('enableLogging')) {
|
if (node.settings.hasOwnProperty('enableLogging')) {
|
||||||
updateLogFlag = true;
|
updateLogFlag = true;
|
||||||
node.Settings.logLevel = node.Settings.enableLogging ? 'INFO' : 'ERROR';
|
node.settings.logLevel = node.settings.enableLogging ? 'INFO' : 'ERROR';
|
||||||
delete node.Settings.enableLogging;
|
delete node.settings.enableLogging;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (updateLogFlag) {
|
if (updateLogFlag) {
|
||||||
@ -115,21 +116,22 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.validateNodeConfig = (config) => {
|
this.validateNodeConfig = (config) => {
|
||||||
|
config.allowPasswordUpdate = true;
|
||||||
if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
|
if ((process?.env?.RTL_SSO && +process?.env?.RTL_SSO === 0) || (typeof process?.env?.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
|
||||||
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
|
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
|
||||||
this.common.rtl_pass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex');
|
config.rtlPass = this.hash.update(process?.env?.APP_PASSWORD).digest('hex');
|
||||||
this.common.flg_allow_password_update = false;
|
config.allowPasswordUpdate = false;
|
||||||
}
|
}
|
||||||
else if (config.multiPassHashed && config.multiPassHashed !== '') {
|
else if (config.multiPassHashed && config.multiPassHashed !== '') {
|
||||||
this.common.rtl_pass = config.multiPassHashed;
|
config.rtlPass = config.multiPassHashed;
|
||||||
}
|
}
|
||||||
else if (config.multiPass && config.multiPass !== '') {
|
else if (config.multiPass && config.multiPass !== '') {
|
||||||
this.common.rtl_pass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex'));
|
config.rtlPass = this.common.replacePasswordWithHash(this.hash.update(config.multiPass).digest('hex'));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json';
|
this.errMsg = this.errMsg + '\nNode Authentication can be set with multiPass only. Please set multiPass in RTL-Config.json';
|
||||||
}
|
}
|
||||||
this.common.rtl_secret2fa = config.secret2fa;
|
config.enable2FA = !!config.secret2FA;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
|
if (process?.env?.APP_PASSWORD && process?.env?.APP_PASSWORD.trim() !== '') {
|
||||||
@ -138,23 +140,23 @@ export class ConfigService {
|
|||||||
}
|
}
|
||||||
this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000;
|
this.common.port = (process?.env?.PORT) ? this.normalizePort(process?.env?.PORT) : (config.port) ? this.normalizePort(config.port) : 3000;
|
||||||
this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null;
|
this.common.host = (process?.env?.HOST) ? process?.env?.HOST : (config.host) ? config.host : null;
|
||||||
this.common.db_directory_path = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
config.dbDirectoryPath = (process?.env?.DB_DIRECTORY_PATH) ? process?.env?.DB_DIRECTORY_PATH : (config.dbDirectoryPath) ? config.dbDirectoryPath : join(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
||||||
if (config.nodes && config.nodes.length > 0) {
|
if (config.nodes && config.nodes.length > 0) {
|
||||||
config.nodes.forEach((node, idx) => {
|
config.nodes.forEach((node, idx) => {
|
||||||
this.common.nodes[idx] = {};
|
this.common.nodes[idx] = { settings: { blockExplorerUrl: '' }, authentication: {} };
|
||||||
this.common.nodes[idx].index = node.index;
|
this.common.nodes[idx].index = node.index;
|
||||||
this.common.nodes[idx].ln_node = node.lnNode;
|
this.common.nodes[idx].lnNode = node.lnNode;
|
||||||
this.common.nodes[idx].ln_implementation = (process?.env?.LN_IMPLEMENTATION) ? process?.env?.LN_IMPLEMENTATION : node.lnImplementation ? node.lnImplementation : 'LND';
|
this.common.nodes[idx].lnImplementation = (process?.env?.lnImplementation) ? process?.env?.lnImplementation : node.lnImplementation ? node.lnImplementation : 'LND';
|
||||||
if (this.common.nodes[idx].ln_implementation === 'CLT') {
|
if (this.common.nodes[idx].lnImplementation === 'CLT') {
|
||||||
this.common.nodes[idx].ln_implementation = 'CLN';
|
this.common.nodes[idx].lnImplementation = 'CLN';
|
||||||
}
|
}
|
||||||
switch (this.common.nodes[idx].ln_implementation) {
|
switch (this.common.nodes[idx].lnImplementation) {
|
||||||
case 'CLN':
|
case 'CLN':
|
||||||
if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') {
|
if (process?.env?.RUNE_PATH && process?.env?.RUNE_PATH.trim() !== '') {
|
||||||
this.common.nodes[idx].rune_path = process?.env?.RUNE_PATH;
|
this.common.nodes[idx].authentication.runePath = process?.env?.RUNE_PATH;
|
||||||
}
|
}
|
||||||
else if (node.Authentication && node.Authentication.runePath && node.Authentication.runePath.trim() !== '') {
|
else if (node.authentication && node.authentication.runePath && node.authentication.runePath.trim() !== '') {
|
||||||
this.common.nodes[idx].rune_path = node.Authentication.runePath;
|
this.common.nodes[idx].authentication.runePath = node.authentication.runePath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!';
|
this.errMsg = 'Please set rune path for node index ' + node.index + ' in RTL-Config.json!';
|
||||||
@ -162,21 +164,21 @@ export class ConfigService {
|
|||||||
break;
|
break;
|
||||||
case 'ECL':
|
case 'ECL':
|
||||||
if (process?.env?.LN_API_PASSWORD) {
|
if (process?.env?.LN_API_PASSWORD) {
|
||||||
this.common.nodes[idx].ln_api_password = process?.env?.LN_API_PASSWORD;
|
this.common.nodes[idx].authentication.lnApiPassword = process?.env?.LN_API_PASSWORD;
|
||||||
}
|
}
|
||||||
else if (node.Authentication && node.Authentication.lnApiPassword) {
|
else if (node.authentication && node.authentication.lnApiPassword) {
|
||||||
this.common.nodes[idx].ln_api_password = node.Authentication.lnApiPassword;
|
this.common.nodes[idx].authentication.lnApiPassword = node.authentication.lnApiPassword;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.common.nodes[idx].ln_api_password = '';
|
this.common.nodes[idx].authentication.lnApiPassword = '';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') {
|
if (process?.env?.MACAROON_PATH && process?.env?.MACAROON_PATH.trim() !== '') {
|
||||||
this.common.nodes[idx].macaroon_path = process?.env?.MACAROON_PATH;
|
this.common.nodes[idx].authentication.macaroonPath = process?.env?.MACAROON_PATH;
|
||||||
}
|
}
|
||||||
else if (node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') {
|
else if (node.authentication && node.authentication.macaroonPath && node.authentication.macaroonPath.trim() !== '') {
|
||||||
this.common.nodes[idx].macaroon_path = node.Authentication.macaroonPath;
|
this.common.nodes[idx].authentication.macaroonPath = node.authentication.macaroonPath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!';
|
this.errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!';
|
||||||
@ -184,114 +186,115 @@ export class ConfigService {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (process?.env?.CONFIG_PATH) {
|
if (process?.env?.CONFIG_PATH) {
|
||||||
this.common.nodes[idx].config_path = process?.env?.CONFIG_PATH;
|
this.common.nodes[idx].authentication.configPath = process?.env?.CONFIG_PATH;
|
||||||
}
|
}
|
||||||
else if (node.Authentication && node.Authentication.configPath) {
|
else if (node.authentication && node.authentication.configPath) {
|
||||||
this.common.nodes[idx].config_path = node.Authentication.configPath;
|
this.common.nodes[idx].authentication.configPath = node.authentication.configPath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.common.nodes[idx].config_path = '';
|
this.common.nodes[idx].authentication.configPath = '';
|
||||||
}
|
}
|
||||||
if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '' && this.common.nodes[idx].config_path !== '') {
|
if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '' && this.common.nodes[idx].authentication.configPath !== '') {
|
||||||
try {
|
try {
|
||||||
const exists = fs.existsSync(this.common.nodes[idx].config_path || '');
|
const exists = fs.existsSync(this.common.nodes[idx].authentication.configPath || '');
|
||||||
if (exists) {
|
if (exists) {
|
||||||
try {
|
try {
|
||||||
const configFile = fs.readFileSync((this.common.nodes[idx].config_path || ''), 'utf-8');
|
const configFile = fs.readFileSync((this.common.nodes[idx].authentication.configPath || ''), 'utf-8');
|
||||||
const iniParsed = ini.parse(configFile);
|
const iniParsed = ini.parse(configFile);
|
||||||
this.common.nodes[idx].ln_api_password = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password;
|
this.common.nodes[idx].authentication.lnApiPassword = iniParsed['eclair.api.password'] ? iniParsed['eclair.api.password'] : parseHocon(configFile).eclair.api.password;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err;
|
this.errMsg = this.errMsg + '\nSomething went wrong while reading config file: \n' + err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].config_path;
|
this.errMsg = this.errMsg + '\nInvalid config path: ' + this.common.nodes[idx].authentication.configPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err;
|
this.errMsg = this.errMsg + '\nUnable to read config file: \n' + err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.common.nodes[idx].ln_implementation === 'ECL' && this.common.nodes[idx].ln_api_password === '') {
|
if (this.common.nodes[idx].lnImplementation === 'ECL' && this.common.nodes[idx].authentication.lnApiPassword === '') {
|
||||||
this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!';
|
this.errMsg = this.errMsg + '\nPlease set config path Or api password for node index ' + node.index + ' in RTL-Config.json! It is mandatory for Eclair authentication!';
|
||||||
}
|
}
|
||||||
if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') {
|
if (process?.env?.LN_SERVER_URL && process?.env?.LN_SERVER_URL.trim() !== '') {
|
||||||
this.common.nodes[idx].ln_server_url = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL;
|
this.common.nodes[idx].settings.lnServerUrl = process?.env?.LN_SERVER_URL.endsWith('/v1') ? process?.env?.LN_SERVER_URL.slice(0, -3) : process?.env?.LN_SERVER_URL;
|
||||||
}
|
}
|
||||||
else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') {
|
else if (process?.env?.LND_SERVER_URL && process?.env?.LND_SERVER_URL.trim() !== '') {
|
||||||
this.common.nodes[idx].ln_server_url = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL;
|
this.common.nodes[idx].settings.lnServerUrl = process?.env?.LND_SERVER_URL.endsWith('/v1') ? process?.env?.LND_SERVER_URL.slice(0, -3) : process?.env?.LND_SERVER_URL;
|
||||||
}
|
}
|
||||||
else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') {
|
else if (node.settings.lnServerUrl && node.settings.lnServerUrl.trim() !== '') {
|
||||||
this.common.nodes[idx].ln_server_url = node.Settings.lnServerUrl.endsWith('/v1') ? node.Settings.lnServerUrl.slice(0, -3) : node.Settings.lnServerUrl;
|
this.common.nodes[idx].settings.lnServerUrl = node.settings.lnServerUrl.endsWith('/v1') ? node.settings.lnServerUrl.slice(0, -3) : node.settings.lnServerUrl;
|
||||||
}
|
}
|
||||||
else if (node.Settings.lndServerUrl && node.Settings.lndServerUrl.trim() !== '') {
|
else if (node.settings.lndServerUrl && node.settings.lndServerUrl.trim() !== '') {
|
||||||
this.common.nodes[idx].ln_server_url = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl;
|
this.common.nodes[idx].settings.lnServerUrl = node.settings.lndServerUrl.endsWith('/v1') ? node.settings.lndServerUrl.slice(0, -3) : node.settings.lndServerUrl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!';
|
this.errMsg = this.errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!';
|
||||||
}
|
}
|
||||||
this.common.nodes[idx].user_persona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT';
|
this.common.nodes[idx].settings.userPersona = node.settings.userPersona ? node.settings.userPersona : 'MERCHANT';
|
||||||
this.common.nodes[idx].theme_mode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY';
|
this.common.nodes[idx].settings.themeMode = node.settings.themeMode ? node.settings.themeMode : 'DAY';
|
||||||
this.common.nodes[idx].theme_color = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE';
|
this.common.nodes[idx].settings.themeColor = node.settings.themeColor ? node.settings.themeColor : 'PURPLE';
|
||||||
this.common.nodes[idx].unannounced_channels = node.Settings.unannouncedChannels ? !!node.Settings.unannouncedChannels : false;
|
this.common.nodes[idx].settings.unannouncedChannels = node.settings.unannouncedChannels ? !!node.settings.unannouncedChannels : false;
|
||||||
this.common.nodes[idx].log_level = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR';
|
this.common.nodes[idx].settings.logLevel = node.settings.logLevel ? node.settings.logLevel : 'ERROR';
|
||||||
this.common.nodes[idx].fiat_conversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false;
|
this.common.nodes[idx].settings.fiatConversion = node.settings.fiatConversion ? !!node.settings.fiatConversion : false;
|
||||||
if (this.common.nodes[idx].fiat_conversion) {
|
if (this.common.nodes[idx].settings.fiatConversion) {
|
||||||
this.common.nodes[idx].currency_unit = node.Settings.currencyUnit ? node.Settings.currencyUnit : 'USD';
|
this.common.nodes[idx].settings.currencyUnit = node.settings.currencyUnit ? node.settings.currencyUnit : 'USD';
|
||||||
}
|
}
|
||||||
if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') {
|
if (process?.env?.SWAP_SERVER_URL && process?.env?.SWAP_SERVER_URL.trim() !== '') {
|
||||||
this.common.nodes[idx].swap_server_url = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL;
|
this.common.nodes[idx].settings.swapServerUrl = process?.env?.SWAP_SERVER_URL.endsWith('/v1') ? process?.env?.SWAP_SERVER_URL.slice(0, -3) : process?.env?.SWAP_SERVER_URL;
|
||||||
this.common.nodes[idx].swap_macaroon_path = process?.env?.SWAP_MACAROON_PATH;
|
this.common.nodes[idx].authentication.swapMacaroonPath = process?.env?.SWAP_MACAROON_PATH;
|
||||||
}
|
}
|
||||||
else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') {
|
else if (node.settings.swapServerUrl && node.settings.swapServerUrl.trim() !== '') {
|
||||||
this.common.nodes[idx].swap_server_url = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl;
|
this.common.nodes[idx].settings.swapServerUrl = node.settings.swapServerUrl.endsWith('/v1') ? node.settings.swapServerUrl.slice(0, -3) : node.settings.swapServerUrl;
|
||||||
this.common.nodes[idx].swap_macaroon_path = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : '';
|
this.common.nodes[idx].authentication.swapMacaroonPath = node.authentication.swapMacaroonPath ? node.authentication.swapMacaroonPath : '';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.common.nodes[idx].swap_server_url = '';
|
this.common.nodes[idx].settings.swapServerUrl = '';
|
||||||
this.common.nodes[idx].swap_macaroon_path = '';
|
this.common.nodes[idx].authentication.swapMacaroonPath = '';
|
||||||
}
|
}
|
||||||
if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') {
|
if (process?.env?.BOLTZ_SERVER_URL && process?.env?.BOLTZ_SERVER_URL.trim() !== '') {
|
||||||
this.common.nodes[idx].boltz_server_url = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL;
|
this.common.nodes[idx].settings.boltzServerUrl = process?.env?.BOLTZ_SERVER_URL.endsWith('/v1') ? process?.env?.BOLTZ_SERVER_URL.slice(0, -3) : process?.env?.BOLTZ_SERVER_URL;
|
||||||
this.common.nodes[idx].boltz_macaroon_path = process?.env?.BOLTZ_MACAROON_PATH;
|
this.common.nodes[idx].authentication.boltzMacaroonPath = process?.env?.BOLTZ_MACAROON_PATH;
|
||||||
}
|
}
|
||||||
else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') {
|
else if (node.settings.boltzServerUrl && node.settings.boltzServerUrl.trim() !== '') {
|
||||||
this.common.nodes[idx].boltz_server_url = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl;
|
this.common.nodes[idx].settings.boltzServerUrl = node.settings.boltzServerUrl.endsWith('/v1') ? node.settings.boltzServerUrl.slice(0, -3) : node.settings.boltzServerUrl;
|
||||||
this.common.nodes[idx].boltz_macaroon_path = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : '';
|
this.common.nodes[idx].authentication.boltzMacaroonPath = node.authentication.boltzMacaroonPath ? node.authentication.boltzMacaroonPath : '';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.common.nodes[idx].boltz_server_url = '';
|
this.common.nodes[idx].settings.boltzServerUrl = '';
|
||||||
this.common.nodes[idx].boltz_macaroon_path = '';
|
this.common.nodes[idx].authentication.boltzMacaroonPath = '';
|
||||||
}
|
}
|
||||||
this.common.nodes[idx].enable_offers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.Settings.enableOffers) ? node.Settings.enableOffers : false;
|
this.common.nodes[idx].settings.enableOffers = process?.env?.ENABLE_OFFERS ? process?.env?.ENABLE_OFFERS : (node.settings.enableOffers) ? node.settings.enableOffers : false;
|
||||||
this.common.nodes[idx].enable_peerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.Settings.enablePeerswap) ? node.Settings.enablePeerswap : false;
|
this.common.nodes[idx].settings.enablePeerswap = process?.env?.ENABLE_PEERSWAP ? process?.env?.ENABLE_PEERSWAP : (node.settings.enablePeerswap) ? node.settings.enablePeerswap : false;
|
||||||
this.common.nodes[idx].bitcoind_config_path = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : '';
|
this.common.nodes[idx].settings.bitcoindConfigPath = process?.env?.BITCOIND_CONFIG_PATH ? process?.env?.BITCOIND_CONFIG_PATH : (node.settings.bitcoindConfigPath) ? node.settings.bitcoindConfigPath : '';
|
||||||
this.common.nodes[idx].channel_backup_path = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : this.common.rtl_conf_file_path + sep + 'channels-backup' + sep + 'node-' + node.index;
|
this.common.nodes[idx].settings.channelBackupPath = process?.env?.CHANNEL_BACKUP_PATH ? process?.env?.CHANNEL_BACKUP_PATH : (node.settings.channelBackupPath) ? node.settings.channelBackupPath : this.common.appConfig.rtlConfFilePath + sep + 'channels-backup' + sep + 'node-' + node.index;
|
||||||
|
this.common.nodes[idx].settings.blockExplorerUrl = process?.env?.BLOCK_EXPLORER_URL ? process.env.BLOCK_EXPLORER_URL : (node.settings.blockExplorerUrl) ? node.settings.blockExplorerUrl : 'https://mempool.space';
|
||||||
try {
|
try {
|
||||||
this.common.createDirectory(this.common.nodes[idx].channel_backup_path);
|
this.common.createDirectory(this.common.nodes[idx].settings.channelBackupPath);
|
||||||
const exists = fs.existsSync(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak');
|
const exists = fs.existsSync(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak');
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
try {
|
try {
|
||||||
if (this.common.nodes[idx].ln_implementation === 'LND') {
|
if (this.common.nodes[idx].lnImplementation === 'LND') {
|
||||||
this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]);
|
this.common.getAllNodeAllChannelBackup(this.common.nodes[idx]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const createStream = fs.createWriteStream(this.common.nodes[idx].channel_backup_path + sep + 'channel-all.bak');
|
const createStream = fs.createWriteStream(this.common.nodes[idx].settings.channelBackupPath + sep + 'channel-all.bak');
|
||||||
createStream.end();
|
createStream.end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating backup file: \n' + err });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating the backup directory: \n' + err });
|
||||||
}
|
}
|
||||||
this.common.nodes[idx].log_file = this.common.rtl_conf_file_path + '/logs/RTL-Node-' + node.index + '.log';
|
this.common.nodes[idx].settings.logFile = config.rtlConfFilePath + '/logs/RTL-Node-' + node.index + '.log';
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'Config', msg: 'Node Config: ' + JSON.stringify(this.common.nodes[idx]) });
|
||||||
const log_file = this.common.nodes[idx].log_file;
|
const log_file = this.common.nodes[idx].settings.logFile;
|
||||||
if (fs.existsSync(log_file || '')) {
|
if (fs.existsSync(log_file || '')) {
|
||||||
fs.writeFile((log_file || ''), '', () => { });
|
fs.writeFile((log_file || ''), '', () => { });
|
||||||
}
|
}
|
||||||
@ -303,7 +306,7 @@ export class ConfigService {
|
|||||||
createStream.end();
|
createStream.end();
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while creating log file ' + log_file + ': \n' + err });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -315,28 +318,28 @@ export class ConfigService {
|
|||||||
};
|
};
|
||||||
this.setSSOParams = (config) => {
|
this.setSSOParams = (config) => {
|
||||||
if (process?.env?.RTL_SSO) {
|
if (process?.env?.RTL_SSO) {
|
||||||
this.common.rtl_sso = +process?.env?.RTL_SSO;
|
config.SSO.rtlSso = +process?.env?.RTL_SSO;
|
||||||
}
|
}
|
||||||
else if (config.SSO && config.SSO.rtlSSO) {
|
else if (config.SSO && config.SSO.rtlSSO) {
|
||||||
this.common.rtl_sso = config.SSO.rtlSSO;
|
config.SSO.rtlSso = config.SSO.rtlSSO;
|
||||||
}
|
}
|
||||||
if (process?.env?.RTL_COOKIE_PATH) {
|
if (process?.env?.RTL_COOKIE_PATH) {
|
||||||
this.common.rtl_cookie_path = process?.env?.RTL_COOKIE_PATH;
|
config.SSO.rtlCookiePath = process?.env?.RTL_COOKIE_PATH;
|
||||||
}
|
}
|
||||||
else if (config.SSO && config.SSO.rtlCookiePath) {
|
else if (config.SSO && config.SSO.rtlCookiePath) {
|
||||||
this.common.rtl_cookie_path = config.SSO.rtlCookiePath;
|
config.SSO.rtlCookiePath = config.SSO.rtlCookiePath;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.common.rtl_cookie_path = '';
|
config.SSO.rtlCookiePath = '';
|
||||||
}
|
}
|
||||||
if (process?.env?.LOGOUT_REDIRECT_LINK) {
|
if (process?.env?.LOGOUT_REDIRECT_LINK) {
|
||||||
this.common.logout_redirect_link = process?.env?.LOGOUT_REDIRECT_LINK;
|
config.SSO.logoutRedirectLink = process?.env?.LOGOUT_REDIRECT_LINK;
|
||||||
}
|
}
|
||||||
else if (config.SSO && config.SSO.logoutRedirectLink) {
|
else if (config.SSO && config.SSO.logoutRedirectLink) {
|
||||||
this.common.logout_redirect_link = config.SSO.logoutRedirectLink;
|
config.SSO.logoutRedirectLink = config.SSO.logoutRedirectLink;
|
||||||
}
|
}
|
||||||
if (+this.common.rtl_sso) {
|
if (+config.SSO.rtlSso) {
|
||||||
if (!this.common.rtl_cookie_path || this.common.rtl_cookie_path.trim() === '') {
|
if (!config.SSO.rtlCookiePath || config.SSO.rtlCookiePath.trim() === '') {
|
||||||
this.errMsg = 'Please set rtlCookiePath value for single sign on option!';
|
this.errMsg = 'Please set rtlCookiePath value for single sign on option!';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -346,26 +349,49 @@ export class ConfigService {
|
|||||||
};
|
};
|
||||||
this.setSelectedNode = (config) => {
|
this.setSelectedNode = (config) => {
|
||||||
if (config.defaultNodeIndex) {
|
if (config.defaultNodeIndex) {
|
||||||
this.common.initSelectedNode = this.common.findNode(config.defaultNodeIndex) || {};
|
this.common.selectedNode = this.common.findNode(config.defaultNodeIndex) || {};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.common.initSelectedNode = this.common.findNode(this.common.nodes[0].index) || {};
|
this.common.selectedNode = this.common.findNode(this.common.nodes[0].index) || {};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.updateConfig = (confFileFullPath, config) => {
|
||||||
|
// Update Config file to change Settings to settings and Authentication to authentication
|
||||||
|
// Added in v0.15.1, remove in a year?
|
||||||
|
if (!config.nodes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config.nodes.map((node) => {
|
||||||
|
if (node.Authentication) {
|
||||||
|
node.authentication = JSON.parse(JSON.stringify(node.Authentication));
|
||||||
|
delete node.Authentication;
|
||||||
|
}
|
||||||
|
if (node.Settings) {
|
||||||
|
node.settings = JSON.parse(JSON.stringify(node.Settings));
|
||||||
|
delete node.Settings;
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
fs.writeFileSync(confFileFullPath, JSON.stringify(config, null, 2), 'utf-8');
|
||||||
|
};
|
||||||
this.setServerConfiguration = () => {
|
this.setServerConfiguration = () => {
|
||||||
|
const rtlConfFilePath = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
|
||||||
|
const confFileFullPath = rtlConfFilePath + sep + 'RTL-Config.json';
|
||||||
try {
|
try {
|
||||||
this.common.rtl_conf_file_path = (process?.env?.RTL_CONFIG_PATH) ? process?.env?.RTL_CONFIG_PATH : join(this.directoryName, '../..');
|
|
||||||
const confFileFullPath = this.common.rtl_conf_file_path + sep + 'RTL-Config.json';
|
|
||||||
if (!fs.existsSync(confFileFullPath)) {
|
if (!fs.existsSync(confFileFullPath)) {
|
||||||
fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig()));
|
fs.writeFileSync(confFileFullPath, JSON.stringify(this.setDefaultConfig(), null, 2), 'utf-8');
|
||||||
}
|
}
|
||||||
const config = JSON.parse(fs.readFileSync(confFileFullPath, 'utf-8'));
|
const config = JSON.parse(fs.readFileSync(confFileFullPath, 'utf-8'));
|
||||||
|
this.updateConfig(confFileFullPath, config);
|
||||||
|
config.rtlConfFilePath = rtlConfFilePath;
|
||||||
this.updateLogByLevel();
|
this.updateLogByLevel();
|
||||||
this.validateNodeConfig(config);
|
this.validateNodeConfig(config);
|
||||||
this.setSelectedNode(config);
|
this.setSelectedNode(config);
|
||||||
|
this.common.appConfig = config;
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Config file path: ' + confFileFullPath });
|
||||||
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'ERROR', fileName: 'Config', msg: 'Something went wrong while configuring the node server: \n' + err });
|
||||||
throw new Error(err);
|
throw new Error(err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ class CORS {
|
|||||||
this.common = Common;
|
this.common = Common;
|
||||||
}
|
}
|
||||||
mount(app) {
|
mount(app) {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'Setting up CORS..' });
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
res.setHeader('Cache-Control', 'no-cache');
|
res.setHeader('Cache-Control', 'no-cache');
|
||||||
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath');
|
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization, filePath');
|
||||||
@ -17,7 +17,7 @@ class CORS {
|
|||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CORS', msg: 'CORS Set' });
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -8,11 +8,11 @@ class CSRF {
|
|||||||
this.common = Common;
|
this.common = Common;
|
||||||
}
|
}
|
||||||
mount(app) {
|
mount(app) {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'Setting up CSRF..' });
|
||||||
if (process.env.NODE_ENV !== 'development') {
|
if (process.env.NODE_ENV !== 'development') {
|
||||||
app.use((req, res, next) => this.csrfProtection(req, res, next));
|
app.use((req, res, next) => this.csrfProtection(req, res, next));
|
||||||
}
|
}
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'CSRF', msg: 'CSRF Set' });
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -7,12 +7,12 @@ export class DatabaseService {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.common = Common;
|
this.common = Common;
|
||||||
this.logger = Logger;
|
this.logger = Logger;
|
||||||
this.dbDirectory = join(this.common.db_directory_path, 'database');
|
this.dbDirectory = join(this.common.appConfig.dbDirectoryPath, 'database');
|
||||||
this.nodeDatabase = {};
|
this.nodeDatabase = {};
|
||||||
}
|
}
|
||||||
migrateDatabase() {
|
migrateDatabase() {
|
||||||
this.common.nodes?.map((node) => {
|
this.common.nodes?.map((node) => {
|
||||||
if (node.ln_implementation === 'ECL') {
|
if (node.lnImplementation === 'ECL') {
|
||||||
this.nodeDatabase[node.index] = { adapter: null, data: {} };
|
this.nodeDatabase[node.index] = { adapter: null, data: {} };
|
||||||
this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node);
|
this.nodeDatabase[node.index].adapter = new DatabaseAdapter(this.dbDirectory, node);
|
||||||
this.fetchNodeData(node);
|
this.fetchNodeData(node);
|
||||||
@ -80,7 +80,7 @@ export class DatabaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fetchNodeData(selectedNode) {
|
fetchNodeData(selectedNode) {
|
||||||
switch (selectedNode.ln_implementation) {
|
switch (selectedNode.lnImplementation) {
|
||||||
case 'CLN':
|
case 'CLN':
|
||||||
for (const collectionName in CLNCollection) {
|
for (const collectionName in CLNCollection) {
|
||||||
if (CLNCollection.hasOwnProperty(collectionName)) {
|
if (CLNCollection.hasOwnProperty(collectionName)) {
|
||||||
@ -250,14 +250,14 @@ export class DatabaseAdapter {
|
|||||||
this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index;
|
this.dbFilePath = dbDirectoryPath + sep + 'node-' + selNode.index;
|
||||||
// For backward compatibility Start
|
// For backward compatibility Start
|
||||||
const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json';
|
const oldFilePath = dbDirectoryPath + sep + 'rtldb-node-' + selNode.index + '.json';
|
||||||
if (selNode.ln_implementation === 'CLN' && fs.existsSync(oldFilePath)) {
|
if (selNode.lnImplementation === 'CLN' && fs.existsSync(oldFilePath)) {
|
||||||
this.renameOldDB(oldFilePath, selNode);
|
this.renameOldDB(oldFilePath, selNode);
|
||||||
}
|
}
|
||||||
// For backward compatibility End
|
// For backward compatibility End
|
||||||
this.insertSession(id);
|
this.insertSession(id);
|
||||||
}
|
}
|
||||||
renameOldDB(oldFilePath, selNode = null) {
|
renameOldDB(oldFilePath, selNode = null) {
|
||||||
const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.ln_implementation + '-Offers.json';
|
const newFilePath = this.dbFilePath + sep + 'rtldb-' + selNode.lnImplementation + '-Offers.json';
|
||||||
try {
|
try {
|
||||||
this.common.createDirectory(this.dbFilePath);
|
this.common.createDirectory(this.dbFilePath);
|
||||||
const oldOffers = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8'));
|
const oldOffers = JSON.parse(fs.readFileSync(oldFilePath, 'utf-8'));
|
||||||
@ -277,7 +277,7 @@ export class DatabaseAdapter {
|
|||||||
catch (err) {
|
catch (err) {
|
||||||
throw new Error(JSON.stringify(err));
|
throw new Error(JSON.stringify(err));
|
||||||
}
|
}
|
||||||
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json';
|
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json';
|
||||||
try {
|
try {
|
||||||
if (!fs.existsSync(collectionFilePath)) {
|
if (!fs.existsSync(collectionFilePath)) {
|
||||||
fs.writeFileSync(collectionFilePath, '[]');
|
fs.writeFileSync(collectionFilePath, '[]');
|
||||||
@ -290,15 +290,15 @@ export class DatabaseAdapter {
|
|||||||
const otherFiles = fs.readdirSync(this.dbFilePath);
|
const otherFiles = fs.readdirSync(this.dbFilePath);
|
||||||
otherFiles.forEach((oFileName) => {
|
otherFiles.forEach((oFileName) => {
|
||||||
let collectionValid = false;
|
let collectionValid = false;
|
||||||
switch (this.selNode.ln_implementation) {
|
switch (this.selNode.lnImplementation) {
|
||||||
case 'CLN':
|
case 'CLN':
|
||||||
collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false);
|
collectionValid = CLNCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
|
||||||
break;
|
break;
|
||||||
case 'ECL':
|
case 'ECL':
|
||||||
collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false);
|
collectionValid = ECLCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.ln_implementation + '-' + collection + '.json'), false);
|
collectionValid = LNDCollection.reduce((acc, collection) => acc || oFileName === ('rtldb-' + this.selNode.lnImplementation + '-' + collection + '.json'), false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (oFileName.endsWith('.json') && !collectionValid) {
|
if (oFileName.endsWith('.json') && !collectionValid) {
|
||||||
@ -324,7 +324,7 @@ export class DatabaseAdapter {
|
|||||||
saveData(collectionName, collectionData) {
|
saveData(collectionName, collectionData) {
|
||||||
try {
|
try {
|
||||||
if (collectionData) {
|
if (collectionData) {
|
||||||
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.ln_implementation + '-' + collectionName + '.json';
|
const collectionFilePath = this.dbFilePath + sep + 'rtldb-' + this.selNode.lnImplementation + '-' + collectionName + '.json';
|
||||||
const tempFile = collectionFilePath + '.tmp';
|
const tempFile = collectionFilePath + '.tmp';
|
||||||
fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2));
|
fs.writeFileSync(tempFile, JSON.stringify(collectionData, null, 2));
|
||||||
fs.renameSync(tempFile, collectionFilePath);
|
fs.renameSync(tempFile, collectionFilePath);
|
||||||
|
@ -16,15 +16,15 @@ export class LoggerService {
|
|||||||
msgStr = msgStr + '.\r\n';
|
msgStr = msgStr + '.\r\n';
|
||||||
}
|
}
|
||||||
console.error(msgStr);
|
console.error(msgStr);
|
||||||
if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) {
|
if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) {
|
||||||
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { });
|
fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'WARN':
|
case 'WARN':
|
||||||
msgStr = prepMsgData(msgJSON, msgStr);
|
msgStr = prepMsgData(msgJSON, msgStr);
|
||||||
if (!msgJSON.selectedNode || msgJSON.selectedNode.log_level === 'WARN' || msgJSON.selectedNode.log_level === 'INFO' || msgJSON.selectedNode.log_level === 'DEBUG') {
|
if (!msgJSON.selectedNode || msgJSON.selectedNode.settings.logLevel === 'WARN' || msgJSON.selectedNode.settings.logLevel === 'INFO' || msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
|
||||||
if (msgJSON.selectedNode && msgJSON.selectedNode.log_file) {
|
if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logFile) {
|
||||||
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { });
|
fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -32,18 +32,18 @@ export class LoggerService {
|
|||||||
if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') {
|
if (!msgJSON.selectedNode && msgJSON.fileName === 'RTL') {
|
||||||
console.log(msgStr + '.\r\n');
|
console.log(msgStr + '.\r\n');
|
||||||
}
|
}
|
||||||
else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'INFO') {
|
else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'INFO') {
|
||||||
msgStr = msgStr + '.\r\n';
|
msgStr = msgStr + '.\r\n';
|
||||||
console.log(msgStr);
|
console.log(msgStr);
|
||||||
if (msgJSON.selectedNode.log_file) {
|
if (msgJSON.selectedNode.settings.logFile) {
|
||||||
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { });
|
fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') {
|
else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
|
||||||
msgStr = prepMsgData(msgJSON, msgStr);
|
msgStr = prepMsgData(msgJSON, msgStr);
|
||||||
console.log(msgStr);
|
console.log(msgStr);
|
||||||
if (msgJSON.selectedNode.log_file) {
|
if (msgJSON.selectedNode.settings.logFile) {
|
||||||
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { });
|
fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -51,11 +51,11 @@ export class LoggerService {
|
|||||||
if (!msgJSON.selectedNode) {
|
if (!msgJSON.selectedNode) {
|
||||||
console.log(msgStr + '.\r\n');
|
console.log(msgStr + '.\r\n');
|
||||||
}
|
}
|
||||||
else if (msgJSON.selectedNode && msgJSON.selectedNode.log_level === 'DEBUG') {
|
else if (msgJSON.selectedNode && msgJSON.selectedNode.settings.logLevel === 'DEBUG') {
|
||||||
msgStr = prepMsgData(msgJSON, msgStr);
|
msgStr = prepMsgData(msgJSON, msgStr);
|
||||||
console.log(msgStr);
|
console.log(msgStr);
|
||||||
if (msgJSON.selectedNode.log_file) {
|
if (msgJSON.selectedNode.settings.logFile) {
|
||||||
fs.appendFile(msgJSON.selectedNode.log_file, msgStr, () => { });
|
fs.appendFile(msgJSON.selectedNode.settings.logFile, msgStr, () => { });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -28,7 +28,7 @@ export class RTLWebSocketServer {
|
|||||||
}
|
}
|
||||||
}, 1000 * 60 * 60); // Terminate broken connections every hour
|
}, 1000 * 60 * 60); // Terminate broken connections every hour
|
||||||
this.mount = (httpServer) => {
|
this.mount = (httpServer) => {
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connecting Websocket Server..' });
|
||||||
this.webSocketServer = new WebSocketServer({ noServer: true, path: this.common.baseHref + '/api/ws', verifyClient: (process.env.NODE_ENV === 'development') ? null : verifyWSUser });
|
this.webSocketServer = new WebSocketServer({ noServer: true, path: this.common.baseHref + '/api/ws', verifyClient: (process.env.NODE_ENV === 'development') ? null : verifyWSUser });
|
||||||
httpServer.on('upgrade', (request, socket, head) => {
|
httpServer.on('upgrade', (request, socket, head) => {
|
||||||
if (request.headers['upgrade'] !== 'websocket') {
|
if (request.headers['upgrade'] !== 'websocket') {
|
||||||
@ -46,7 +46,7 @@ export class RTLWebSocketServer {
|
|||||||
});
|
});
|
||||||
this.webSocketServer.on('connection', this.mountEventsOnConnection);
|
this.webSocketServer.on('connection', this.mountEventsOnConnection);
|
||||||
this.webSocketServer.on('close', () => clearInterval(this.pingInterval));
|
this.webSocketServer.on('close', () => clearInterval(this.pingInterval));
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Websocket Server Connected' });
|
||||||
};
|
};
|
||||||
this.upgradeCallback = (websocket, request) => {
|
this.upgradeCallback = (websocket, request) => {
|
||||||
this.webSocketServer.emit('connection', websocket, request);
|
this.webSocketServer.emit('connection', websocket, request);
|
||||||
@ -58,13 +58,13 @@ export class RTLWebSocketServer {
|
|||||||
websocket.isAlive = true;
|
websocket.isAlive = true;
|
||||||
websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null;
|
websocket.sessionId = cookies && cookies['connect.sid'] ? cookieParser.signedCookie(cookies['connect.sid'], this.common.secret_key) : null;
|
||||||
websocket.clientNodeIndex = +protocols[1];
|
websocket.clientNodeIndex = +protocols[1];
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Connected: ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
|
||||||
websocket.on('error', this.sendErrorToAllLNClients);
|
websocket.on('error', this.sendErrorToAllLNClients);
|
||||||
websocket.on('message', this.sendEventsToAllLNClients);
|
websocket.on('message', this.sendEventsToAllLNClients);
|
||||||
websocket.on('pong', () => { websocket.isAlive = true; });
|
websocket.on('pong', () => { websocket.isAlive = true; });
|
||||||
websocket.on('close', (code, reason) => {
|
websocket.on('close', (code, reason) => {
|
||||||
this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex);
|
this.updateLNWSClientDetails(websocket.sessionId, -1, websocket.clientNodeIndex);
|
||||||
this.logger.log({ selectedNode: this.common.initSelectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
|
this.logger.log({ selectedNode: this.common.selectedNode, level: 'INFO', fileName: 'WebSocketServer', msg: 'Disconnected due to ' + code + ' : ' + websocket.clientId + ', Total WS clients: ' + this.webSocketServer.clients.size });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
this.updateLNWSClientDetails = (sessionId, currNodeIndex, prevNodeIndex) => {
|
this.updateLNWSClientDetails = (sessionId, currNodeIndex, prevNodeIndex) => {
|
||||||
@ -85,7 +85,7 @@ export class RTLWebSocketServer {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const selectedNode = this.common.findNode(currNodeIndex);
|
const selectedNode = this.common.findNode(currNodeIndex);
|
||||||
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' });
|
this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Invalid Node Selection. Previous and current node indices can not be less than zero.' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.disconnectFromNodeClient = (sessionId, prevNodeIndex) => {
|
this.disconnectFromNodeClient = (sessionId, prevNodeIndex) => {
|
||||||
@ -99,8 +99,8 @@ export class RTLWebSocketServer {
|
|||||||
const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex);
|
const foundClientIdx = this.clientDetails.findIndex((clientDetail) => clientDetail.index === +prevNodeIndex);
|
||||||
this.clientDetails.splice(foundClientIdx, 1);
|
this.clientDetails.splice(foundClientIdx, 1);
|
||||||
const prevSelectedNode = this.common.findNode(prevNodeIndex);
|
const prevSelectedNode = this.common.findNode(prevNodeIndex);
|
||||||
if (prevSelectedNode && prevSelectedNode.ln_implementation) {
|
if (prevSelectedNode && prevSelectedNode.lnImplementation) {
|
||||||
switch (prevSelectedNode.ln_implementation) {
|
switch (prevSelectedNode.lnImplementation) {
|
||||||
case 'LND':
|
case 'LND':
|
||||||
this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex);
|
this.eventEmitterLND.emit('DISCONNECT', prevNodeIndex);
|
||||||
break;
|
break;
|
||||||
@ -129,8 +129,8 @@ export class RTLWebSocketServer {
|
|||||||
const currSelectedNode = this.common.findNode(currNodeIndex);
|
const currSelectedNode = this.common.findNode(currNodeIndex);
|
||||||
foundClient = { index: currNodeIndex, sessionIds: [sessionId] };
|
foundClient = { index: currNodeIndex, sessionIds: [sessionId] };
|
||||||
this.clientDetails.push(foundClient);
|
this.clientDetails.push(foundClient);
|
||||||
if (currSelectedNode && currSelectedNode.ln_implementation) {
|
if (currSelectedNode && currSelectedNode.lnImplementation) {
|
||||||
switch (currSelectedNode.ln_implementation) {
|
switch (currSelectedNode.lnImplementation) {
|
||||||
case 'LND':
|
case 'LND':
|
||||||
this.eventEmitterLND.emit('CONNECT', currNodeIndex);
|
this.eventEmitterLND.emit('CONNECT', currNodeIndex);
|
||||||
break;
|
break;
|
||||||
@ -149,27 +149,27 @@ export class RTLWebSocketServer {
|
|||||||
this.sendErrorToAllLNClients = (serverError, selectedNode) => {
|
this.sendErrorToAllLNClients = (serverError, selectedNode) => {
|
||||||
try {
|
try {
|
||||||
this.webSocketServer.clients.forEach((client) => {
|
this.webSocketServer.clients.forEach((client) => {
|
||||||
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError });
|
this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Broadcasting error to clients...: ' + serverError });
|
||||||
if (+client.clientNodeIndex === +selectedNode.index) {
|
if (+client.clientNodeIndex === +selectedNode.index) {
|
||||||
client.send(serverError);
|
client.send(serverError);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
|
this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.sendEventsToAllLNClients = (newMessage, selectedNode) => {
|
this.sendEventsToAllLNClients = (newMessage, selectedNode) => {
|
||||||
try {
|
try {
|
||||||
this.webSocketServer.clients.forEach((client) => {
|
this.webSocketServer.clients.forEach((client) => {
|
||||||
if (+client.clientNodeIndex === +selectedNode.index) {
|
if (+client.clientNodeIndex === +selectedNode.index) {
|
||||||
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage });
|
this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage });
|
||||||
client.send(newMessage);
|
client.send(newMessage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
|
this.logger.log({ selectedNode: !selectedNode ? this.common.selectedNode : selectedNode, level: 'ERROR', fileName: 'WebSocketServer', msg: 'Error while broadcasting message: ' + JSON.stringify(err) });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.generateAcceptValue = (acceptKey) => crypto.createHash('sha1').update(acceptKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary').digest('base64');
|
this.generateAcceptValue = (acceptKey) => crypto.createHash('sha1').update(acceptKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary').digest('base64');
|
||||||
|
@ -8,7 +8,7 @@ WORKDIR /RTL
|
|||||||
COPY package.json /RTL/package.json
|
COPY package.json /RTL/package.json
|
||||||
COPY package-lock.json /RTL/package-lock.json
|
COPY package-lock.json /RTL/package-lock.json
|
||||||
|
|
||||||
RUN npm install
|
RUN npm install --legacy-peer-deps
|
||||||
|
|
||||||
# ---------------
|
# ---------------
|
||||||
# Build App
|
# Build App
|
||||||
|
@ -12,7 +12,7 @@ WORKDIR /RTL
|
|||||||
COPY package.json /RTL/package.json
|
COPY package.json /RTL/package.json
|
||||||
COPY package-lock.json /RTL/package-lock.json
|
COPY package-lock.json /RTL/package-lock.json
|
||||||
|
|
||||||
RUN npm install
|
RUN npm install --legacy-peer-deps
|
||||||
|
|
||||||
# ---------------
|
# ---------------
|
||||||
# Build App
|
# Build App
|
||||||
|
@ -11,7 +11,7 @@ WORKDIR /RTL
|
|||||||
COPY package.json /RTL/package.json
|
COPY package.json /RTL/package.json
|
||||||
COPY package-lock.json /RTL/package-lock.json
|
COPY package-lock.json /RTL/package-lock.json
|
||||||
|
|
||||||
RUN npm install
|
RUN npm install --legacy-peer-deps
|
||||||
|
|
||||||
# ---------------
|
# ---------------
|
||||||
# Build App
|
# Build App
|
||||||
|
File diff suppressed because one or more lines are too long
1
frontend/17.d00d31d08d7bad32.js
Normal file
1
frontend/17.d00d31d08d7bad32.js
Normal file
File diff suppressed because one or more lines are too long
1
frontend/190.88ca997666a3998a.js
Normal file
1
frontend/190.88ca997666a3998a.js
Normal file
File diff suppressed because one or more lines are too long
1
frontend/193.b1206fbf24aa1327.js
Normal file
1
frontend/193.b1206fbf24aa1327.js
Normal file
File diff suppressed because one or more lines are too long
@ -5,7 +5,7 @@ MIT
|
|||||||
MIT
|
MIT
|
||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Google LLC.
|
Copyright (c) 2024 Google LLC.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -42,7 +42,7 @@ MIT
|
|||||||
MIT
|
MIT
|
||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Google LLC.
|
Copyright (c) 2024 Google LLC.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@ -147,7 +147,7 @@ as SVG and JS file types.
|
|||||||
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
||||||
packaged as web and desktop font files.
|
packaged as web and desktop font files.
|
||||||
|
|
||||||
Copyright (c) 2023 Fonticons, Inc. (https://fontawesome.com)
|
Copyright (c) 2024 Fonticons, Inc. (https://fontawesome.com)
|
||||||
with Reserved Font Name: "Font Awesome".
|
with Reserved Font Name: "Font Awesome".
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
@ -247,7 +247,7 @@ OTHER DEALINGS IN THE FONT SOFTWARE.
|
|||||||
In the Font Awesome Free download, the MIT license applies to all non-font and
|
In the Font Awesome Free download, the MIT license applies to all non-font and
|
||||||
non-icon files.
|
non-icon files.
|
||||||
|
|
||||||
Copyright 2023 Fonticons, Inc.
|
Copyright 2024 Fonticons, Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in the
|
this software and associated documentation files (the "Software"), to deal in the
|
||||||
@ -316,7 +316,7 @@ as SVG and JS file types.
|
|||||||
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
||||||
packaged as web and desktop font files.
|
packaged as web and desktop font files.
|
||||||
|
|
||||||
Copyright (c) 2023 Fonticons, Inc. (https://fontawesome.com)
|
Copyright (c) 2024 Fonticons, Inc. (https://fontawesome.com)
|
||||||
with Reserved Font Name: "Font Awesome".
|
with Reserved Font Name: "Font Awesome".
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
@ -416,7 +416,7 @@ OTHER DEALINGS IN THE FONT SOFTWARE.
|
|||||||
In the Font Awesome Free download, the MIT license applies to all non-font and
|
In the Font Awesome Free download, the MIT license applies to all non-font and
|
||||||
non-icon files.
|
non-icon files.
|
||||||
|
|
||||||
Copyright 2023 Fonticons, Inc.
|
Copyright 2024 Fonticons, Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in the
|
this software and associated documentation files (the "Software"), to deal in the
|
||||||
@ -485,7 +485,7 @@ as SVG and JS file types.
|
|||||||
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
In the Font Awesome Free download, the SIL OFL license applies to all icons
|
||||||
packaged as web and desktop font files.
|
packaged as web and desktop font files.
|
||||||
|
|
||||||
Copyright (c) 2023 Fonticons, Inc. (https://fontawesome.com)
|
Copyright (c) 2024 Fonticons, Inc. (https://fontawesome.com)
|
||||||
with Reserved Font Name: "Font Awesome".
|
with Reserved Font Name: "Font Awesome".
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
@ -585,7 +585,7 @@ OTHER DEALINGS IN THE FONT SOFTWARE.
|
|||||||
In the Font Awesome Free download, the MIT license applies to all non-font and
|
In the Font Awesome Free download, the MIT license applies to all non-font and
|
||||||
non-icon files.
|
non-icon files.
|
||||||
|
|
||||||
Copyright 2023 Fonticons, Inc.
|
Copyright 2024 Fonticons, Inc.
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in the
|
this software and associated documentation files (the "Software"), to deal in the
|
||||||
@ -656,6 +656,35 @@ https://github.com/cartant/rxjs-etc by Nicholas Jamieson, MIT licensed. See the
|
|||||||
file header for details.
|
file header for details.
|
||||||
|
|
||||||
|
|
||||||
|
@ngrx/operators
|
||||||
|
MIT
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2017-2023 Brandon Roberts, Mike Ryan, Victor Savkin, Rob Wormald
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
This repository includes a file "debounceSync.ts" originially copied from
|
||||||
|
https://github.com/cartant/rxjs-etc by Nicholas Jamieson, MIT licensed. See the
|
||||||
|
file header for details.
|
||||||
|
|
||||||
|
|
||||||
@ngrx/store
|
@ngrx/store
|
||||||
MIT
|
MIT
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
@ -844,28 +873,6 @@ MIT
|
|||||||
|
|
||||||
asn1.js
|
asn1.js
|
||||||
MIT
|
MIT
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2017 Fedor Indutny
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
base64-js
|
base64-js
|
||||||
MIT
|
MIT
|
||||||
@ -1114,6 +1121,29 @@ convert-hex
|
|||||||
|
|
||||||
convert-string
|
convert-string
|
||||||
|
|
||||||
|
core-util-is
|
||||||
|
MIT
|
||||||
|
Copyright Node.js contributors. All rights reserved.
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to
|
||||||
|
deal in the Software without restriction, including without limitation the
|
||||||
|
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
create-ecdh
|
create-ecdh
|
||||||
MIT
|
MIT
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
@ -1672,6 +1702,9 @@ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
|||||||
THIS SOFTWARE.
|
THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
isarray
|
||||||
|
MIT
|
||||||
|
|
||||||
material-icons
|
material-icons
|
||||||
Apache-2.0
|
Apache-2.0
|
||||||
|
|
||||||
@ -2025,7 +2058,7 @@ MIT
|
|||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
||||||
Copyright (c) 2014-2015 bpampuch
|
Copyright (c) 2014-2015 bpampuch
|
||||||
2016-2022 liborm85
|
2016-2024 liborm85
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
@ -2070,6 +2103,55 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
process
|
||||||
|
MIT
|
||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2013 Roman Shtylman <shtylman@gmail.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
'Software'), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
process-nextick-args
|
||||||
|
MIT
|
||||||
|
# Copyright (c) 2015 Calvin Metcalf
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.**
|
||||||
|
|
||||||
|
|
||||||
public-encrypt
|
public-encrypt
|
||||||
MIT
|
MIT
|
||||||
Copyright (c) 2017 Calvin Metcalf
|
Copyright (c) 2017 Calvin Metcalf
|
||||||
@ -2713,31 +2795,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
safer-buffer
|
|
||||||
MIT
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2018 Nikita Skovoroda <chalkerx@gmail.com>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
sha.js
|
sha.js
|
||||||
(MIT AND BSD-3-Clause)
|
(MIT AND BSD-3-Clause)
|
||||||
Copyright (c) 2013-2018 sha.js contributors
|
Copyright (c) 2013-2018 sha.js contributors
|
||||||
@ -2933,11 +2990,33 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|||||||
OTHER DEALINGS IN THE SOFTWARE.
|
OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
vm-browserify
|
||||||
|
MIT
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
zone.js
|
zone.js
|
||||||
MIT
|
MIT
|
||||||
The MIT License
|
The MIT License
|
||||||
|
|
||||||
Copyright (c) 2010-2023 Google LLC. https://angular.io/license
|
Copyright (c) 2010-2024 Google LLC. https://angular.io/license
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
frontend/853.c4ce8a9a0bef2bb7.js
Normal file
1
frontend/853.c4ce8a9a0bef2bb7.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
frontend/main.4d0b488c417a90c1.js
Normal file
1
frontend/main.4d0b488c417a90c1.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
frontend/polyfills.277648f7b3e820e3.js
Normal file
1
frontend/polyfills.277648f7b3e820e3.js
Normal file
File diff suppressed because one or more lines are too long
@ -1 +0,0 @@
|
|||||||
(()=>{"use strict";var e,v={},m={};function r(e){var o=m[e];if(void 0!==o)return o.exports;var t=m[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(o,t,i,f)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,i,f]=e[n],s=!0,d=0;d<t.length;d++)(!1&f||a>=f)&&Object.keys(r.O).every(b=>r.O[b](t[d]))?t.splice(d--,1):(s=!1,f<a&&(a=f));if(s){e.splice(n--,1);var u=i();void 0!==u&&(o=u)}}return o}f=f||0;for(var n=e.length;n>0&&e[n-1][2]>f;n--)e[n]=e[n-1];e[n]=[t,i,f]},r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((o,t)=>(r.f[t](e,o),o),[])),r.u=e=>e+"."+{125:"708b87b4f08ae30f",456:"21f2112ce22ca275",570:"1e18345ecab5f7fe",758:"8736aa34f95f1235"}[e]+".js",r.miniCssF=e=>{},r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),(()=>{var e={},o="RTLApp:";r.l=(t,i,f,n)=>{if(e[t])e[t].push(i);else{var a,s;if(void 0!==f)for(var d=document.getElementsByTagName("script"),u=0;u<d.length;u++){var l=d[u];if(l.getAttribute("src")==t||l.getAttribute("data-webpack")==o+f){a=l;break}}a||(s=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",o+f),a.src=r.tu(t)),e[t]=[i];var c=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:o=>o},typeof trustedTypes<"u"&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(i,f)=>{var n=r.o(e,i)?e[i]:void 0;if(0!==n)if(n)f.push(n[2]);else if(666!=i){var a=new Promise((l,c)=>n=e[i]=[l,c]);f.push(n[2]=a);var s=r.p+r.u(i),d=new Error;r.l(s,l=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var c=l&&("load"===l.type?"missing":l.type),p=l&&l.target&&l.target.src;d.message="Loading chunk "+i+" failed.\n("+c+": "+p+")",d.name="ChunkLoadError",d.type=c,d.request=p,n[1](d)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var o=(i,f)=>{var d,u,[n,a,s]=f,l=0;if(n.some(p=>0!==e[p])){for(d in a)r.o(a,d)&&(r.m[d]=a[d]);if(s)var c=s(r)}for(i&&i(f);l<n.length;l++)r.o(e,u=n[l])&&e[u]&&e[u][0](),e[u]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))})()})();
|
|
1
frontend/runtime.738cba8440999ebd.js
Normal file
1
frontend/runtime.738cba8440999ebd.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
(()=>{"use strict";var e,v={},m={};function r(e){var o=m[e];if(void 0!==o)return o.exports;var t=m[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(o,t,i,f)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,i,f]=e[n],c=!0,l=0;l<t.length;l++)(!1&f||a>=f)&&Object.keys(r.O).every(b=>r.O[b](t[l]))?t.splice(l--,1):(c=!1,f<a&&(a=f));if(c){e.splice(n--,1);var d=i();void 0!==d&&(o=d)}}return o}f=f||0;for(var n=e.length;n>0&&e[n-1][2]>f;n--)e[n]=e[n-1];e[n]=[t,i,f]},r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((o,t)=>(r.f[t](e,o),o),[])),r.u=e=>e+"."+{17:"d00d31d08d7bad32",190:"88ca997666a3998a",193:"b1206fbf24aa1327",853:"c4ce8a9a0bef2bb7"}[e]+".js",r.miniCssF=e=>{},r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),(()=>{var e={},o="RTLApp:";r.l=(t,i,f,n)=>{if(e[t])e[t].push(i);else{var a,c;if(void 0!==f)for(var l=document.getElementsByTagName("script"),d=0;d<l.length;d++){var u=l[d];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==o+f){a=u;break}}a||(c=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",o+f),a.src=r.tu(t)),e[t]=[i];var s=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),c&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:o=>o},typeof trustedTypes<"u"&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={121:0};r.f.j=(i,f)=>{var n=r.o(e,i)?e[i]:void 0;if(0!==n)if(n)f.push(n[2]);else if(121!=i){var a=new Promise((u,s)=>n=e[i]=[u,s]);f.push(n[2]=a);var c=r.p+r.u(i),l=new Error;r.l(c,u=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var s=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;l.message="Loading chunk "+i+" failed.\n("+s+": "+p+")",l.name="ChunkLoadError",l.type=s,l.request=p,n[1](l)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var o=(i,f)=>{var l,d,[n,a,c]=f,u=0;if(n.some(p=>0!==e[p])){for(l in a)r.o(a,l)&&(r.m[l]=a[l]);if(c)var s=c(r)}for(i&&i(f);u<n.length;u++)r.o(e,d=n[u])&&e[d]&&e[d][0](),e[d]=0;return r.O(s)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))})()})();
|
File diff suppressed because one or more lines are too long
1
frontend/styles.e57f489d97a0d3fc.css
Normal file
1
frontend/styles.e57f489d97a0d3fc.css
Normal file
File diff suppressed because one or more lines are too long
9713
package-lock.json
generated
9713
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
89
package.json
89
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "rtl",
|
"name": "rtl",
|
||||||
"version": "0.15.0-beta",
|
"version": "0.15.1-beta",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -8,6 +8,7 @@
|
|||||||
"start": "ng serve --open",
|
"start": "ng serve --open",
|
||||||
"prebuildfrontendtest": "node src/prebuild.cjs",
|
"prebuildfrontendtest": "node src/prebuild.cjs",
|
||||||
"prebuildfrontend": "node src/prebuild.cjs",
|
"prebuildfrontend": "node src/prebuild.cjs",
|
||||||
|
"watchfrontenddev": "ng build --configuration development --optimization false --watch",
|
||||||
"buildfrontendtest": "ng test --watch=false && ng build",
|
"buildfrontendtest": "ng test --watch=false && ng build",
|
||||||
"buildfrontend": "ng build --configuration production",
|
"buildfrontend": "ng build --configuration production",
|
||||||
"buildbackend": "tsc --project ./server/tsconfig.server.json",
|
"buildbackend": "tsc --project ./server/tsconfig.server.json",
|
||||||
@ -21,77 +22,79 @@
|
|||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ngrx/effects": "^17.0.0",
|
"@ngrx/effects": "^17.2.0",
|
||||||
"@ngrx/store": "^17.0.0",
|
"@ngrx/store": "^17.2.0",
|
||||||
"@swimlane/ngx-charts": "^20.5.0",
|
"@swimlane/ngx-charts": "^20.5.0",
|
||||||
"angular-user-idle": "^4.0.0",
|
"angular-user-idle": "^4.0.0",
|
||||||
"atob": "^2.1.2",
|
"atob": "^2.1.2",
|
||||||
"cookie-parser": "^1.4.6",
|
"cookie-parser": "^1.4.6",
|
||||||
"crypto-browserify": "^3.12.0",
|
"crypto-browserify": "^3.12.0",
|
||||||
"csurf": "^1.11.0",
|
"csurf": "^1.11.0",
|
||||||
"express": "^4.18.2",
|
"express": "^4.19.2",
|
||||||
"express-session": "^1.17.3",
|
"express-session": "^1.18.0",
|
||||||
"hocon-parser": "^1.0.1",
|
"hocon-parser": "^1.0.1",
|
||||||
"ini": "^4.1.1",
|
"ini": "^4.1.3",
|
||||||
"jsonwebtoken": "^9.0.2",
|
"jsonwebtoken": "^9.0.2",
|
||||||
"ng-qrcode": "^17.0.0",
|
"ng-qrcode": "^18.0.0",
|
||||||
"ngx-perfect-scrollbar-next": "^10.1.1",
|
"ngx-perfect-scrollbar-next": "^10.1.1",
|
||||||
"otplib": "^12.0.1",
|
"otplib": "^12.0.1",
|
||||||
"pdfmake": "^0.2.8",
|
"pdfmake": "^0.2.10",
|
||||||
|
"process": "^0.11.10",
|
||||||
"request": "^2.88.2",
|
"request": "^2.88.2",
|
||||||
"request-promise": "^4.2.6",
|
"request-promise": "^4.2.6",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"sha256": "^0.2.0",
|
"sha256": "^0.2.0",
|
||||||
"socket.io-client": "^4.7.2",
|
"socket.io-client": "^4.7.5",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"tslib": "^2.6.2",
|
"tslib": "^2.6.2",
|
||||||
"ws": "^8.14.2",
|
"vm-browserify": "^1.1.2",
|
||||||
"zone.js": "^0.14.2"
|
"ws": "^8.17.0",
|
||||||
|
"zone.js": "^0.14.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@angular-devkit/build-angular": "^17.0.3",
|
"@angular-devkit/build-angular": "^18.0.2",
|
||||||
"@angular-eslint/builder": "^17.1.0",
|
"@angular-eslint/builder": "^18.0.1",
|
||||||
"@angular-eslint/eslint-plugin": "^17.1.0",
|
"@angular-eslint/eslint-plugin": "^18.0.1",
|
||||||
"@angular-eslint/eslint-plugin-template": "^17.1.0",
|
"@angular-eslint/eslint-plugin-template": "^18.0.1",
|
||||||
"@angular-eslint/schematics": "^17.1.0",
|
"@angular-eslint/schematics": "^18.0.1",
|
||||||
"@angular-eslint/template-parser": "^17.1.0",
|
"@angular-eslint/template-parser": "^18.0.1",
|
||||||
"@angular/animations": "^17.0.4",
|
"@angular/animations": "^18.0.1",
|
||||||
"@angular/cdk": "^17.0.1",
|
"@angular/cdk": "^17.0.1",
|
||||||
"@angular/cli": "^17.0.3",
|
"@angular/cli": "^18.0.2",
|
||||||
"@angular/common": "^17.0.4",
|
"@angular/common": "^18.0.1",
|
||||||
"@angular/compiler": "^17.0.4",
|
"@angular/compiler": "^18.0.1",
|
||||||
"@angular/compiler-cli": "^17.0.4",
|
"@angular/compiler-cli": "^18.0.1",
|
||||||
"@angular/core": "^17.0.4",
|
"@angular/core": "^18.0.1",
|
||||||
"@angular/flex-layout": "^15.0.0-beta.42",
|
"@angular/flex-layout": "^15.0.0-beta.42",
|
||||||
"@angular/forms": "^17.0.4",
|
"@angular/forms": "^18.0.1",
|
||||||
"@angular/material": "^17.0.1",
|
"@angular/material": "^17.0.1",
|
||||||
"@angular/platform-browser": "^17.0.4",
|
"@angular/platform-browser": "^18.0.1",
|
||||||
"@angular/platform-browser-dynamic": "^17.0.4",
|
"@angular/platform-browser-dynamic": "^18.0.1",
|
||||||
"@angular/router": "^17.0.4",
|
"@angular/router": "^18.0.1",
|
||||||
"@fortawesome/angular-fontawesome": "^0.14.0",
|
"@fortawesome/angular-fontawesome": "^0.15.0",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.4.2",
|
"@fortawesome/free-regular-svg-icons": "^6.5.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.4.2",
|
"@fortawesome/free-solid-svg-icons": "^6.5.2",
|
||||||
"@ngrx/store-devtools": "^17.0.0",
|
"@ngrx/store-devtools": "^17.2.0",
|
||||||
"@types/jasmine": "^5.1.4",
|
"@types/jasmine": "^5.1.4",
|
||||||
"@types/node": "^20.9.4",
|
"@types/node": "^20.14.1",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.10.0",
|
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
||||||
"@typescript-eslint/parser": "^6.10.0",
|
"@typescript-eslint/parser": "^7.12.0",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.4.5",
|
||||||
"eslint": "^8.53.0",
|
"eslint": "^9.4.0",
|
||||||
"eslint-plugin-deprecation": "^2.0.0",
|
"eslint-plugin-deprecation": "^3.0.0",
|
||||||
"jasmine-core": "^5.1.1",
|
"jasmine-core": "^5.1.2",
|
||||||
"jasmine-spec-reporter": "^7.0.0",
|
"jasmine-spec-reporter": "^7.0.0",
|
||||||
"karma": "^6.4.2",
|
"karma": "^6.4.3",
|
||||||
"karma-chrome-launcher": "^3.2.0",
|
"karma-chrome-launcher": "^3.2.0",
|
||||||
"karma-coverage": "^2.2.1",
|
"karma-coverage": "^2.2.1",
|
||||||
"karma-jasmine": "^5.1.0",
|
"karma-jasmine": "^5.1.0",
|
||||||
"karma-jasmine-html-reporter": "^2.1.0",
|
"karma-jasmine-html-reporter": "^2.1.0",
|
||||||
"material-icons": "^1.13.12",
|
"material-icons": "^1.13.12",
|
||||||
"nodemon": "^3.0.1",
|
"nodemon": "^3.1.3",
|
||||||
"protractor": "^7.0.0",
|
"protractor": "^7.0.0",
|
||||||
"roboto-fontface": "^0.10.0",
|
"roboto-fontface": "^0.10.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.2",
|
||||||
"typescript": "~5.2.2"
|
"typescript": "~5.4.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
5
rtl.js
5
rtl.js
@ -5,11 +5,16 @@ import { Config } from './backend/utils/config.js'; // Follow sequence to set se
|
|||||||
import { WSServer } from './backend/utils/webSocketServer.js';
|
import { WSServer } from './backend/utils/webSocketServer.js';
|
||||||
import App from './backend/utils/app.js';
|
import App from './backend/utils/app.js';
|
||||||
|
|
||||||
|
|
||||||
const logger = Logger;
|
const logger = Logger;
|
||||||
const common = Common;
|
const common = Common;
|
||||||
const wsServer = WSServer;
|
const wsServer = WSServer;
|
||||||
const app = new App();
|
const app = new App();
|
||||||
|
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
process.exit();
|
||||||
|
});
|
||||||
|
|
||||||
const onError = (error) => {
|
const onError = (error) => {
|
||||||
if (error.syscall !== 'listen') { throw error; }
|
if (error.syscall !== 'listen') { throw error; }
|
||||||
switch (error.code) {
|
switch (error.code) {
|
||||||
|
@ -11,7 +11,7 @@ export const listPeerChannels = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Peer Channels..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Peer Channels..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeerchannels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeerchannels';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body.channels });
|
||||||
return Promise.all(body.channels?.map((channel) => {
|
return Promise.all(body.channels?.map((channel) => {
|
||||||
@ -32,7 +32,7 @@ export const openChannel = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/fundchannel';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fundchannel';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -48,7 +48,7 @@ export const setChannelFee = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Setting Channel Fee..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Setting Channel Fee..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/setchannel';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/setchannel';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -65,7 +65,7 @@ export const closeChannel = (req, res, next) => {
|
|||||||
req.setTimeout(60000 * 10); // timeout 10 mins
|
req.setTimeout(60000 * 10); // timeout 10 mins
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/close';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/close';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -78,14 +78,15 @@ export const closeChannel = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const listForwards = (req, res, next) => {
|
export const listForwards = (req, res, next) => {
|
||||||
|
const { status } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listforwards';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listforwards';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + req.body.status, data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status ' + status, data: body });
|
||||||
body.forwards = !body.forwards ? [] : (req.body.status === 'failed' || req.body.status === 'local_failed') ? body.forwards.slice(Math.max(0, body.forwards.length - 1000), Math.max(1000, body.forwards.length)).reverse() : body.forwards.reverse();
|
body.forwards = !body.forwards ? [] : (status === 'failed' || status === 'local_failed') ? body.forwards.slice(Math.max(0, body.forwards.length - 1000), Math.max(1000, body.forwards.length)).reverse() : body.forwards.reverse();
|
||||||
res.status(200).json(body.forwards);
|
res.status(200).json(body.forwards);
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
const err = common.handleError(errRes, 'Channels', 'Forwarding History Error', req.session.selectedNode);
|
const err = common.handleError(errRes, 'Channels', 'Forwarding History Error', req.session.selectedNode);
|
||||||
@ -97,7 +98,7 @@ export const funderUpdatePolicy = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting or Updating Funder Policy..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting or Updating Funder Policy..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/funderupdate';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/funderupdate';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Funder Update Body', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
|
@ -16,8 +16,8 @@ export const getInfo = (req, res, next) => {
|
|||||||
common.setOptions(req);
|
common.setOptions(req);
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/getinfo';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getinfo';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Core Lightning server url ' + options.url });
|
||||||
if (!options.headers || !options.headers.rune) {
|
if (!options.headers || !options.headers.rune) {
|
||||||
const errMsg = 'Core lightning get info failed due to missing rune!';
|
const errMsg = 'Core lightning get info failed due to missing rune!';
|
||||||
@ -45,7 +45,7 @@ export const getInfo = (req, res, next) => {
|
|||||||
body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
|
body.uris.push(body.id + '@' + addr.address + ':' + addr.port);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
req.session.selectedNode.ln_version = body.version || '';
|
req.session.selectedNode.lnVersion = body.version || '';
|
||||||
req.session.selectedNode.api_version = body.api_version || '';
|
req.session.selectedNode.api_version = body.api_version || '';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Core Lightning\'s Websocket Server.' });
|
||||||
clWsClient.updateSelectedNode(req.session.selectedNode);
|
clWsClient.updateSelectedNode(req.session.selectedNode);
|
||||||
|
@ -9,7 +9,7 @@ export const deleteExpiredInvoice = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Deleting Expired Invoices..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Deleting Expired Invoices..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/delexpiredinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/delexpiredinvoice';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoices Deleted', data: body });
|
||||||
@ -24,7 +24,7 @@ export const listInvoices = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Getting Invoices..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Getting Invoices..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listinvoices';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listinvoices';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List URL', data: options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -40,7 +40,7 @@ export const addInvoice = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/invoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/invoice';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Created', data: body });
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import request from 'request-promise';
|
import request from 'request-promise';
|
||||||
import { Logger, LoggerService } from '../../utils/logger.js';
|
import { Logger, LoggerService } from '../../utils/logger.js';
|
||||||
import { Common, CommonService } from '../../utils/common.js';
|
import { Common, CommonService } from '../../utils/common.js';
|
||||||
import { CommonSelectedNode } from '../../models/config.model.js';
|
import { SelectedNode } from '../../models/config.model.js';
|
||||||
|
|
||||||
let options = null;
|
let options = null;
|
||||||
const logger: LoggerService = Logger;
|
const logger: LoggerService = Logger;
|
||||||
@ -11,7 +11,7 @@ export const getRoute = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Routes..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Routes..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/getroute';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/getroute';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Routes Received', data: body });
|
||||||
@ -29,7 +29,7 @@ export const listChannels = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listchannels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listchannels';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Channel Lookup Finished', data: body });
|
||||||
@ -41,13 +41,14 @@ export const listChannels = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const feeRates = (req, res, next) => {
|
export const feeRates = (req, res, next) => {
|
||||||
|
const { style } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Fee Rates..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Getting Network Fee Rates..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/feerates';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/feerates';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + req.body.style, data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received for ' + style, data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
const err = common.handleError(errRes, 'Network', 'Fee Rates Error', req.session.selectedNode);
|
const err = common.handleError(errRes, 'Network', 'Fee Rates Error', req.session.selectedNode);
|
||||||
@ -56,12 +57,12 @@ export const feeRates = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const listNodes = (req, res, next) => {
|
export const listNodes = (req, res, next) => {
|
||||||
|
const filter_liquidity_ads = !!req.body.liquidity_ads;
|
||||||
|
delete req.body.liquidity_ads;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'List Nodes..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listnodes';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listnodes';
|
||||||
const filter_liquidity_ads = !!req.body.liquidity_ads;
|
|
||||||
delete req.body.liquidity_ads;
|
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Network', msg: 'List Nodes URL' + options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -77,8 +78,8 @@ export const listNodes = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getAlias = (selNode: CommonSelectedNode, peer: any, id: string) => {
|
export const getAlias = (selNode: SelectedNode, peer: any, id: string) => {
|
||||||
options.url = selNode.ln_server_url + '/v1/listnodes';
|
options.url = selNode.settings.lnServerUrl + '/v1/listnodes';
|
||||||
if (!peer[id]) {
|
if (!peer[id]) {
|
||||||
logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' });
|
logger.log({ selectedNode: selNode, level: 'ERROR', fileName: 'Network', msg: 'Empty Peer ID' });
|
||||||
peer.alias = '';
|
peer.alias = '';
|
||||||
|
@ -21,10 +21,11 @@ export const listOfferBookmarks = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const deleteOfferBookmark = (req, res, next) => {
|
export const deleteOfferBookmark = (req, res, next) => {
|
||||||
|
const { offer_str } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Deleting Offer Bookmark..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Deleting Offer Bookmark..' });
|
||||||
databaseService.remove(req.session.selectedNode, CollectionsEnum.OFFERS, CollectionFieldsEnum.BOLT12, req.body.offer_str).then((deleteRes) => {
|
databaseService.remove(req.session.selectedNode, CollectionsEnum.OFFERS, CollectionFieldsEnum.BOLT12, offer_str).then((deleteRes) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmark Deleted', data: deleteRes });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Bookmark Deleted', data: deleteRes });
|
||||||
res.status(204).json(req.body.offer_str);
|
res.status(204).json(offer_str);
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
const err = common.handleError(errRes, 'Offers', 'Offer Bookmark Delete Error', req.session.selectedNode);
|
const err = common.handleError(errRes, 'Offers', 'Offer Bookmark Delete Error', req.session.selectedNode);
|
||||||
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
return res.status(err.statusCode).json({ message: err.message, error: err.error });
|
||||||
@ -35,7 +36,7 @@ export const listOffers = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offers..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offers..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listoffers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listoffers';
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offers List URL', data: options.url });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offers List Received', data: body });
|
||||||
@ -50,7 +51,7 @@ export const createOffer = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Creating Offer..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Creating Offer..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/offer';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/offer';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Created', data: body });
|
||||||
@ -65,7 +66,7 @@ export const fetchOfferInvoice = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Invoice..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Getting Offer Invoice..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/fetchinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/fetchinvoice';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Offers', msg: 'Offer Invoice Body', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -81,7 +82,7 @@ export const disableOffer = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Disabling Offer..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Disabling Offer..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/disableOffer';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disableOffer';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Offers', msg: 'Offer Disabled', data: body });
|
||||||
|
@ -9,7 +9,7 @@ export const getNewAddress = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Generating New Address..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/newaddr';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/newaddr';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'New Address Generated', data: body });
|
||||||
@ -24,7 +24,7 @@ export const onChainWithdraw = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Withdrawing from On Chain..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Withdrawing from On Chain..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/withdraw';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/withdraw';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -40,7 +40,7 @@ export const getUTXOs = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Listing Funds..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Listing Funds..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listfunds';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listfunds';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'OnChain', msg: 'Funds List Received', data: body });
|
||||||
// Local Remote Balance Calculation
|
// Local Remote Balance Calculation
|
||||||
|
@ -3,15 +3,15 @@ import { Logger, LoggerService } from '../../utils/logger.js';
|
|||||||
import { Common, CommonService } from '../../utils/common.js';
|
import { Common, CommonService } from '../../utils/common.js';
|
||||||
import { Database, DatabaseService } from '../../utils/database.js';
|
import { Database, DatabaseService } from '../../utils/database.js';
|
||||||
import { CollectionFieldsEnum, CollectionsEnum, Offer } from '../../models/database.model.js';
|
import { CollectionFieldsEnum, CollectionsEnum, Offer } from '../../models/database.model.js';
|
||||||
import { CommonSelectedNode } from '../../models/config.model.js';
|
import { SelectedNode } from '../../models/config.model.js';
|
||||||
|
|
||||||
let options = null;
|
let options = null;
|
||||||
const logger: LoggerService = Logger;
|
const logger: LoggerService = Logger;
|
||||||
const common: CommonService = Common;
|
const common: CommonService = Common;
|
||||||
const databaseService: DatabaseService = Database;
|
const databaseService: DatabaseService = Database;
|
||||||
|
|
||||||
export const getMemo = (selNode: CommonSelectedNode, payment: any) => {
|
export const getMemo = (selNode: SelectedNode, payment: any) => {
|
||||||
options.url = selNode.ln_server_url + '/v1/decode';
|
options.url = selNode.settings.lnServerUrl + '/v1/decode';
|
||||||
options.body = { string: payment.bolt11 };
|
options.body = { string: payment.bolt11 };
|
||||||
return request.post(options).then((res) => {
|
return request.post(options).then((res) => {
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: res });
|
||||||
@ -74,7 +74,7 @@ export const listPayments = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'List Payments..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'List Payments..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listsendpays';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listsendpays';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments });
|
||||||
body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : [];
|
body.payments = body.payments && body.payments.length && body.payments.length > 0 ? groupBy(body.payments) : [];
|
||||||
@ -89,12 +89,13 @@ export const listPayments = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const postPayment = (req, res, next) => {
|
export const postPayment = (req, res, next) => {
|
||||||
|
const { paymentType, saveToDB, bolt12, zeroAmtOffer, amount_msat, title, issuer, description } = req.body;
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
const options_body = JSON.parse(JSON.stringify(req.body));
|
const options_body = JSON.parse(JSON.stringify(req.body));
|
||||||
if (req.body.paymentType === 'KEYSEND') {
|
if (paymentType === 'KEYSEND') {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/keysend';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/keysend';
|
||||||
delete options_body.uiMessage;
|
delete options_body.uiMessage;
|
||||||
delete options_body.fromDialog;
|
delete options_body.fromDialog;
|
||||||
delete options_body.paymentType;
|
delete options_body.paymentType;
|
||||||
@ -112,12 +113,12 @@ export const postPayment = (req, res, next) => {
|
|||||||
delete options_body.saveToDB;
|
delete options_body.saveToDB;
|
||||||
options.body = options_body;
|
options.body = options_body;
|
||||||
} else {
|
} else {
|
||||||
if (req.body.paymentType === 'OFFER') {
|
if (paymentType === 'OFFER') {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Offer Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Offer Payment..' });
|
||||||
} else {
|
} else {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' });
|
||||||
}
|
}
|
||||||
if (req.body.paymentType === 'OFFER') {
|
if (paymentType === 'OFFER') {
|
||||||
// delete amount for zero amt offer also as fetchinvoice already has amount information
|
// delete amount for zero amt offer also as fetchinvoice already has amount information
|
||||||
delete options_body.amount_msat;
|
delete options_body.amount_msat;
|
||||||
}
|
}
|
||||||
@ -133,18 +134,18 @@ export const postPayment = (req, res, next) => {
|
|||||||
delete options_body.pubkey;
|
delete options_body.pubkey;
|
||||||
delete options_body.saveToDB;
|
delete options_body.saveToDB;
|
||||||
options.body = options_body;
|
options.body = options_body;
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/pay';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/pay';
|
||||||
}
|
}
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Sent', data: body });
|
||||||
if (req.body.paymentType === 'OFFER') {
|
if (paymentType === 'OFFER') {
|
||||||
if (req.body.saveToDB && req.body.bolt12) {
|
if (saveToDB && bolt12) {
|
||||||
const offerToUpdate: Offer = { bolt12: req.body.bolt12, amountMSat: (req.body.zeroAmtOffer ? 0 : req.body.amount_msat), title: req.body.title, lastUpdatedAt: new Date(Date.now()).getTime() };
|
const offerToUpdate: Offer = { bolt12: bolt12, amountMSat: (zeroAmtOffer ? 0 : amount_msat), title: title, lastUpdatedAt: new Date(Date.now()).getTime() };
|
||||||
if (req.body.issuer) { offerToUpdate['issuer'] = req.body.issuer; }
|
if (issuer) { offerToUpdate['issuer'] = issuer; }
|
||||||
if (req.body.description) { offerToUpdate['description'] = req.body.description; }
|
if (description) { offerToUpdate['description'] = description; }
|
||||||
// eslint-disable-next-line arrow-body-style
|
// eslint-disable-next-line arrow-body-style
|
||||||
return databaseService.validateDocument(CollectionsEnum.OFFERS, offerToUpdate).then((validated) => {
|
return databaseService.validateDocument(CollectionsEnum.OFFERS, offerToUpdate).then((validated) => {
|
||||||
return databaseService.update(req.session.selectedNode, CollectionsEnum.OFFERS, offerToUpdate, CollectionFieldsEnum.BOLT12, req.body.bolt12).then((updatedOffer) => {
|
return databaseService.update(req.session.selectedNode, CollectionsEnum.OFFERS, offerToUpdate, CollectionFieldsEnum.BOLT12, bolt12).then((updatedOffer) => {
|
||||||
logger.log({ level: 'DEBUG', fileName: 'Payments', msg: 'Offer Updated', data: updatedOffer });
|
logger.log({ level: 'DEBUG', fileName: 'Payments', msg: 'Offer Updated', data: updatedOffer });
|
||||||
return res.status(201).json({ paymentResponse: body, saveToDBResponse: updatedOffer });
|
return res.status(201).json({ paymentResponse: body, saveToDBResponse: updatedOffer });
|
||||||
}).catch((errDB) => {
|
}).catch((errDB) => {
|
||||||
@ -159,10 +160,10 @@ export const postPayment = (req, res, next) => {
|
|||||||
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (req.body.paymentType === 'INVOICE') {
|
if (paymentType === 'INVOICE') {
|
||||||
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
return res.status(201).json({ paymentResponse: body, saveToDBResponse: 'NA' });
|
||||||
}
|
}
|
||||||
if (req.body.paymentType === 'KEYSEND') {
|
if (paymentType === 'KEYSEND') {
|
||||||
return res.status(201).json(body);
|
return res.status(201).json(body);
|
||||||
}
|
}
|
||||||
}).catch((errRes) => {
|
}).catch((errRes) => {
|
||||||
|
@ -11,7 +11,7 @@ export const getPeers = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'List Peers..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'List Peers..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listpeers';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peers List Received', data: body });
|
||||||
const peers = !body.peers ? [] : body.peers;
|
const peers = !body.peers ? [] : body.peers;
|
||||||
@ -29,12 +29,12 @@ export const postPeer = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Connecting Peer..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/connect';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/connect';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((connectRes) => {
|
request.post(options).then((connectRes) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Peers', msg: 'Peer Connected', data: connectRes });
|
||||||
const listOptions = common.getOptions(req);
|
const listOptions = common.getOptions(req);
|
||||||
listOptions.url = req.session.selectedNode.ln_server_url + '/v1/listpeers';
|
listOptions.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listpeers';
|
||||||
request.post(listOptions).then((listPeersRes) => {
|
request.post(listOptions).then((listPeersRes) => {
|
||||||
const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : [];
|
const peers = listPeersRes && listPeersRes.peers ? common.newestOnTop(listPeersRes.peers, 'id', connectRes.id) : [];
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peers List after Connect Received', data: peers });
|
||||||
@ -53,7 +53,7 @@ export const deletePeer = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Disconnecting Peer..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/disconnect';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/disconnect';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected', data: body });
|
||||||
|
@ -10,7 +10,7 @@ export const decodePayment = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Decoding Payment..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/decode';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/decode';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded', data: body });
|
||||||
@ -25,7 +25,7 @@ export const signMessage = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Signing Message..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/signmessage';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/signmessage';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Signed', data: body });
|
||||||
@ -40,7 +40,7 @@ export const verifyMessage = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Verifying Message..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/checkmessage';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/checkmessage';
|
||||||
options.body = req.body;
|
options.body = req.body;
|
||||||
request.post(options, (error, response, body) => {
|
request.post(options, (error, response, body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Message', msg: 'Message Verified', data: body });
|
||||||
@ -55,7 +55,7 @@ export const listConfigs = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/v1/listconfigs';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/v1/listconfigs';
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Utility', msg: 'List Configs Received', data: body });
|
||||||
res.status(200).json(body);
|
res.status(200).json(body);
|
||||||
|
@ -2,14 +2,14 @@ import socketIOClient from 'socket.io-client';
|
|||||||
import { Logger, LoggerService } from '../../utils/logger.js';
|
import { Logger, LoggerService } from '../../utils/logger.js';
|
||||||
import { Common, CommonService } from '../../utils/common.js';
|
import { Common, CommonService } from '../../utils/common.js';
|
||||||
import { WSServer } from '../../utils/webSocketServer.js';
|
import { WSServer } from '../../utils/webSocketServer.js';
|
||||||
import { CommonSelectedNode } from '../../models/config.model.js';
|
import { SelectedNode } from '../../models/config.model.js';
|
||||||
|
|
||||||
export class CLWebSocketClient {
|
export class CLWebSocketClient {
|
||||||
|
|
||||||
public logger: LoggerService = Logger;
|
public logger: LoggerService = Logger;
|
||||||
public common: CommonService = Common;
|
public common: CommonService = Common;
|
||||||
public wsServer = WSServer;
|
public wsServer = WSServer;
|
||||||
public webSocketClients: Array<{ selectedNode: CommonSelectedNode, reConnect: boolean, webSocketClient: any }> = [];
|
public webSocketClients: Array<{ selectedNode: SelectedNode, reConnect: boolean, webSocketClient: any }> = [];
|
||||||
public reconnectTimeOut = null;
|
public reconnectTimeOut = null;
|
||||||
public waitTime = 0.5;
|
public waitTime = 0.5;
|
||||||
|
|
||||||
@ -34,17 +34,17 @@ export class CLWebSocketClient {
|
|||||||
}, this.waitTime * 1000);
|
}, this.waitTime * 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
public connect = (selectedNode: CommonSelectedNode) => {
|
public connect = (selectedNode: SelectedNode) => {
|
||||||
try {
|
try {
|
||||||
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
||||||
if (!clientExists) {
|
if (!clientExists) {
|
||||||
if (selectedNode.ln_server_url) {
|
if (selectedNode.settings.lnServerUrl) {
|
||||||
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
|
const newWebSocketClient = { selectedNode: selectedNode, reConnect: true, webSocketClient: null };
|
||||||
this.connectWithClient(newWebSocketClient);
|
this.connectWithClient(newWebSocketClient);
|
||||||
this.webSocketClients.push(newWebSocketClient);
|
this.webSocketClients.push(newWebSocketClient);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.ln_server_url) {
|
if ((!clientExists.webSocketClient || !clientExists.webSocketClient.connected) && selectedNode.settings.lnServerUrl) {
|
||||||
clientExists.reConnect = true;
|
clientExists.reConnect = true;
|
||||||
this.connectWithClient(clientExists);
|
this.connectWithClient(clientExists);
|
||||||
}
|
}
|
||||||
@ -57,11 +57,11 @@ export class CLWebSocketClient {
|
|||||||
public connectWithClient = (clWsClt) => {
|
public connectWithClient = (clWsClt) => {
|
||||||
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' });
|
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Connecting to the Core Lightning\'s Websocket Server..' });
|
||||||
try {
|
try {
|
||||||
if (!clWsClt.selectedNode.rune_value) {
|
if (!clWsClt.selectedNode.authentication.runeValue) {
|
||||||
clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path);
|
clWsClt.selectedNode.authentication.runeValue = this.common.getRuneValue(clWsClt.selectedNode.authentication.runePath);
|
||||||
}
|
}
|
||||||
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, {
|
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.settings.lnServerUrl, {
|
||||||
extraHeaders: { rune: clWsClt.selectedNode.rune_value },
|
extraHeaders: { rune: clWsClt.selectedNode.authentication.runeValue },
|
||||||
transports: ['websocket'],
|
transports: ['websocket'],
|
||||||
secure: true,
|
secure: true,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
@ -76,7 +76,7 @@ export class CLWebSocketClient {
|
|||||||
});
|
});
|
||||||
|
|
||||||
clWsClt.webSocketClient.on('disconnect', (reason) => {
|
clWsClt.webSocketClient.on('disconnect', (reason) => {
|
||||||
if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.ln_implementation === 'CLN') {
|
if (clWsClt && clWsClt.selectedNode && clWsClt.selectedNode.lnImplementation === 'CLN') {
|
||||||
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason });
|
this.logger.log({ selectedNode: clWsClt.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Web socket disconnected, will reconnect again...', data: reason });
|
||||||
clWsClt.webSocketClient.close();
|
clWsClt.webSocketClient.close();
|
||||||
if (clWsClt.reConnect) { this.reconnect(clWsClt); }
|
if (clWsClt.reConnect) { this.reconnect(clWsClt); }
|
||||||
@ -97,7 +97,7 @@ export class CLWebSocketClient {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
public disconnect = (selectedNode: CommonSelectedNode) => {
|
public disconnect = (selectedNode: SelectedNode) => {
|
||||||
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
const clientExists = this.webSocketClients.find((wsc) => wsc.selectedNode.index === selectedNode.index);
|
||||||
if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.connected) {
|
if (clientExists && clientExists.webSocketClient && clientExists.webSocketClient.connected) {
|
||||||
this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the Core Lightning\'s Websocket Server..' });
|
this.logger.log({ selectedNode: clientExists.selectedNode, level: 'INFO', fileName: 'CLWebSocket', msg: 'Disconnecting from the Core Lightning\'s Websocket Server..' });
|
||||||
@ -108,7 +108,7 @@ export class CLWebSocketClient {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public updateSelectedNode = (newSelectedNode: CommonSelectedNode) => {
|
public updateSelectedNode = (newSelectedNode: SelectedNode) => {
|
||||||
const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index);
|
const clientIdx = this.webSocketClients.findIndex((wsc) => +wsc.selectedNode.index === +newSelectedNode.index);
|
||||||
let newClient = this.webSocketClients[clientIdx];
|
let newClient = this.webSocketClients[clientIdx];
|
||||||
if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; }
|
if (!newClient) { newClient = { selectedNode: null, reConnect: true, webSocketClient: null }; }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import request from 'request-promise';
|
import request from 'request-promise';
|
||||||
import { Logger, LoggerService } from '../../utils/logger.js';
|
import { Logger, LoggerService } from '../../utils/logger.js';
|
||||||
import { Common, CommonService } from '../../utils/common.js';
|
import { Common, CommonService } from '../../utils/common.js';
|
||||||
import { CommonSelectedNode } from '../../models/config.model.js';
|
import { SelectedNode } from '../../models/config.model.js';
|
||||||
import { createInvoiceRequestCall, listPendingInvoicesRequestCall } from './invoices.js';
|
import { createInvoiceRequestCall, listPendingInvoicesRequestCall } from './invoices.js';
|
||||||
import { findRouteBetweenNodesRequestCall } from './network.js';
|
import { findRouteBetweenNodesRequestCall } from './network.js';
|
||||||
import { getSentInfoFromPaymentRequest, sendPaymentToRouteRequestCall } from './payments.js';
|
import { getSentInfoFromPaymentRequest, sendPaymentToRouteRequestCall } from './payments.js';
|
||||||
@ -10,7 +10,7 @@ let options = null;
|
|||||||
const logger: LoggerService = Logger;
|
const logger: LoggerService = Logger;
|
||||||
const common: CommonService = Common;
|
const common: CommonService = Common;
|
||||||
|
|
||||||
export const simplifyAllChannels = (selNode: CommonSelectedNode, channels) => {
|
export const simplifyAllChannels = (selNode: SelectedNode, channels) => {
|
||||||
let channelNodeIds = '';
|
let channelNodeIds = '';
|
||||||
const simplifiedChannels = [];
|
const simplifiedChannels = [];
|
||||||
channels.forEach((channel) => {
|
channels.forEach((channel) => {
|
||||||
@ -30,7 +30,7 @@ export const simplifyAllChannels = (selNode: CommonSelectedNode, channels) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
channelNodeIds = channelNodeIds.substring(1);
|
channelNodeIds = channelNodeIds.substring(1);
|
||||||
options.url = selNode.ln_server_url + '/nodes';
|
options.url = selNode.settings.lnServerUrl + '/nodes';
|
||||||
options.form = { nodeIds: channelNodeIds };
|
options.form = { nodeIds: channelNodeIds };
|
||||||
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds });
|
logger.log({ selectedNode: selNode, level: 'DEBUG', fileName: 'Channels', msg: 'Node Ids to find alias', data: channelNodeIds });
|
||||||
return request.post(options).then((nodes) => {
|
return request.post(options).then((nodes) => {
|
||||||
@ -49,7 +49,7 @@ export const getChannels = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'List Channels..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'List Channels..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/channels';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/channels';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
if (req.query && req.query.nodeId) {
|
if (req.query && req.query.nodeId) {
|
||||||
options.form = req.query;
|
options.form = req.query;
|
||||||
@ -57,7 +57,7 @@ export const getChannels = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Options', data: options });
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('Channels', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(data); });
|
common.getDummyData('Channels', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(data); });
|
||||||
} else {
|
} else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channels List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Channels List Received', data: body });
|
||||||
@ -82,7 +82,7 @@ export const getChannelStats = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel States..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channel States..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/channelstats';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/channelstats';
|
||||||
const today = new Date(Date.now());
|
const today = new Date(Date.now());
|
||||||
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
||||||
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
||||||
@ -103,7 +103,7 @@ export const openChannel = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Opening Channel..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/open';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/open';
|
||||||
options.form = req.body;
|
options.form = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -119,7 +119,7 @@ export const updateChannelRelayFee = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Relay Fee..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Relay Fee..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/updaterelayfee';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/updaterelayfee';
|
||||||
options.form = req.query;
|
options.form = req.query;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Relay Fee Params', data: options.form });
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -136,10 +136,10 @@ export const closeChannel = (req, res, next) => {
|
|||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
if (req.query.force !== 'true') {
|
if (req.query.force !== 'true') {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/close';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/close';
|
||||||
} else {
|
} else {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Force Closing Channel..' });
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/forceclose';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/forceclose';
|
||||||
}
|
}
|
||||||
options.form = { channelId: req.query.channelId };
|
options.form = { channelId: req.query.channelId };
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Close URL', data: options.url });
|
||||||
@ -154,7 +154,8 @@ export const closeChannel = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const circularRebalance = (req, res, next) => {
|
export const circularRebalance = (req, res, next) => {
|
||||||
const crInvDescription = 'Circular rebalancing invoice for ' + (req.body.amountMsat / 1000) + ' Sats';
|
const { amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format, sourceShortChannelId, targetShortChannelId } = req.body;
|
||||||
|
const crInvDescription = 'Circular rebalancing invoice for ' + (amountMsat / 1000) + ' Sats';
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.form = req.body;
|
options.form = req.body;
|
||||||
@ -162,22 +163,22 @@ export const circularRebalance = (req, res, next) => {
|
|||||||
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
||||||
// Check if unpaid Invoice exists already
|
// Check if unpaid Invoice exists already
|
||||||
listPendingInvoicesRequestCall(req.session.selectedNode).then((callRes: any[]) => {
|
listPendingInvoicesRequestCall(req.session.selectedNode).then((callRes: any[]) => {
|
||||||
const foundExistingInvoice = callRes.find((inv) => inv.description.includes(crInvDescription) && inv.amount === req.body.amountMsat && inv.expiry && inv.timestamp && ((inv.expiry + inv.timestamp) >= tillToday));
|
const foundExistingInvoice = callRes.find((inv) => inv.description.includes(crInvDescription) && inv.amount === amountMsat && inv.expiry && inv.timestamp && ((inv.expiry + inv.timestamp) >= tillToday));
|
||||||
// Create new invoice if doesn't exist already
|
// Create new invoice if doesn't exist already
|
||||||
const requestCalls = foundExistingInvoice && foundExistingInvoice.serialized ?
|
const requestCalls = foundExistingInvoice && foundExistingInvoice.serialized ?
|
||||||
[findRouteBetweenNodesRequestCall(req.session.selectedNode, req.body.amountMsat, req.body.sourceNodeId, req.body.targetNodeId, req.body.ignoreNodeIds, req.body.format)] :
|
[findRouteBetweenNodesRequestCall(req.session.selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format)] :
|
||||||
[findRouteBetweenNodesRequestCall(req.session.selectedNode, req.body.amountMsat, req.body.sourceNodeId, req.body.targetNodeId, req.body.ignoreNodeIds, req.body.format), createInvoiceRequestCall(req.session.selectedNode, crInvDescription, req.body.amountMsat)];
|
[findRouteBetweenNodesRequestCall(req.session.selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format), createInvoiceRequestCall(req.session.selectedNode, crInvDescription, amountMsat)];
|
||||||
Promise.all(requestCalls).then((values: any[]) => {
|
Promise.all(requestCalls).then((values: any[]) => {
|
||||||
// eslint-disable-next-line arrow-body-style
|
// eslint-disable-next-line arrow-body-style
|
||||||
const routes = values[0]?.routes?.filter((route) => {
|
const routes = values[0]?.routes?.filter((route) => {
|
||||||
return !((route.shortChannelIds[0] === req.body.sourceShortChannelId && route.shortChannelIds[1] === req.body.targetShortChannelId) ||
|
return !((route.shortChannelIds[0] === sourceShortChannelId && route.shortChannelIds[1] === targetShortChannelId) ||
|
||||||
(route.shortChannelIds[1] === req.body.sourceShortChannelId && route.shortChannelIds[0] === req.body.targetShortChannelId));
|
(route.shortChannelIds[1] === sourceShortChannelId && route.shortChannelIds[0] === targetShortChannelId));
|
||||||
});
|
});
|
||||||
const firstRoute = routes[0].shortChannelIds.join() || '';
|
const firstRoute = routes[0].shortChannelIds.join() || '';
|
||||||
const shortChannelIds = req.body.sourceShortChannelId + ',' + firstRoute + ',' + req.body.targetShortChannelId;
|
const shortChannelIds = sourceShortChannelId + ',' + firstRoute + ',' + targetShortChannelId;
|
||||||
const invoice = (foundExistingInvoice && foundExistingInvoice.serialized ? foundExistingInvoice.serialized : (values[1] ? values[1].serialized : '')) || '';
|
const invoice = (foundExistingInvoice && foundExistingInvoice.serialized ? foundExistingInvoice.serialized : (values[1] ? values[1].serialized : '')) || '';
|
||||||
const paymentHash = (foundExistingInvoice && foundExistingInvoice.paymentHash ? foundExistingInvoice.paymentHash : (values[1] ? values[1].paymentHash : '') || '');
|
const paymentHash = (foundExistingInvoice && foundExistingInvoice.paymentHash ? foundExistingInvoice.paymentHash : (values[1] ? values[1].paymentHash : '') || '');
|
||||||
return sendPaymentToRouteRequestCall(req.session.selectedNode, shortChannelIds, invoice, req.body.amountMsat).then((payToRouteCallRes) => {
|
return sendPaymentToRouteRequestCall(req.session.selectedNode, shortChannelIds, invoice, amountMsat).then((payToRouteCallRes) => {
|
||||||
// eslint-disable-next-line arrow-body-style
|
// eslint-disable-next-line arrow-body-style
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
return getSentInfoFromPaymentRequest(req.session.selectedNode, paymentHash).then((sentInfoCallRes) => {
|
return getSentInfoFromPaymentRequest(req.session.selectedNode, paymentHash).then((sentInfoCallRes) => {
|
||||||
|
@ -1,34 +1,35 @@
|
|||||||
import request from 'request-promise';
|
import request from 'request-promise';
|
||||||
import { Logger, LoggerService } from '../../utils/logger.js';
|
import { Logger, LoggerService } from '../../utils/logger.js';
|
||||||
import { Common, CommonService } from '../../utils/common.js';
|
import { Common, CommonService } from '../../utils/common.js';
|
||||||
import { CommonSelectedNode } from '../../models/config.model.js';
|
import { SelectedNode } from '../../models/config.model.js';
|
||||||
let options = null;
|
let options = null;
|
||||||
const logger: LoggerService = Logger;
|
const logger: LoggerService = Logger;
|
||||||
const common: CommonService = Common;
|
const common: CommonService = Common;
|
||||||
|
|
||||||
export const arrangeFees = (selNode: CommonSelectedNode, body, current_time) => {
|
export const arrangeFees = (selNode: SelectedNode, body, current_time) => {
|
||||||
const fees = { daily_fee: 0, daily_txs: 0, weekly_fee: 0, weekly_txs: 0, monthly_fee: 0, monthly_txs: 0 };
|
const fees = { daily_fee: 0, daily_txs: 0, weekly_fee: 0, weekly_txs: 0, monthly_fee: 0, monthly_txs: 0 };
|
||||||
const week_start_time = current_time - 604800000;
|
const week_start_time = current_time - 604800000;
|
||||||
const day_start_time = current_time - 86400000;
|
const day_start_time = current_time - 86400000;
|
||||||
let fee = 0;
|
let fee = 0;
|
||||||
body.relayed.forEach((relayedEle) => {
|
body.relayed.forEach((relayedEle) => {
|
||||||
fee = Math.round((relayedEle.amountIn - relayedEle.amountOut) / 1000);
|
fee = Math.round((relayedEle.amountIn - relayedEle.amountOut) / 1000);
|
||||||
if (relayedEle.timestamp) {
|
const relayedEleTimestamp = relayedEle.settledAt ? relayedEle.settledAt : relayedEle.timestamp;
|
||||||
if (relayedEle.timestamp.unix) {
|
if (relayedEleTimestamp) {
|
||||||
if ((relayedEle.timestamp.unix * 1000) >= day_start_time) {
|
if (relayedEleTimestamp.unix) {
|
||||||
|
if ((relayedEleTimestamp.unix * 1000) >= day_start_time) {
|
||||||
fees.daily_fee = fees.daily_fee + fee;
|
fees.daily_fee = fees.daily_fee + fee;
|
||||||
fees.daily_txs = fees.daily_txs + 1;
|
fees.daily_txs = fees.daily_txs + 1;
|
||||||
}
|
}
|
||||||
if ((relayedEle.timestamp.unix * 1000) >= week_start_time) {
|
if ((relayedEleTimestamp.unix * 1000) >= week_start_time) {
|
||||||
fees.weekly_fee = fees.weekly_fee + fee;
|
fees.weekly_fee = fees.weekly_fee + fee;
|
||||||
fees.weekly_txs = fees.weekly_txs + 1;
|
fees.weekly_txs = fees.weekly_txs + 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (relayedEle.timestamp >= day_start_time) {
|
if (relayedEleTimestamp >= day_start_time) {
|
||||||
fees.daily_fee = fees.daily_fee + fee;
|
fees.daily_fee = fees.daily_fee + fee;
|
||||||
fees.daily_txs = fees.daily_txs + 1;
|
fees.daily_txs = fees.daily_txs + 1;
|
||||||
}
|
}
|
||||||
if (relayedEle.timestamp >= week_start_time) {
|
if (relayedEleTimestamp >= week_start_time) {
|
||||||
fees.weekly_fee = fees.weekly_fee + fee;
|
fees.weekly_fee = fees.weekly_fee + fee;
|
||||||
fees.weekly_txs = fees.weekly_txs + 1;
|
fees.weekly_txs = fees.weekly_txs + 1;
|
||||||
}
|
}
|
||||||
@ -41,7 +42,7 @@ export const arrangeFees = (selNode: CommonSelectedNode, body, current_time) =>
|
|||||||
return fees;
|
return fees;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const arrangePayments = (selNode: CommonSelectedNode, body) => {
|
export const arrangePayments = (selNode: SelectedNode, body) => {
|
||||||
const payments = {
|
const payments = {
|
||||||
sent: body && body.sent ? body.sent : [],
|
sent: body && body.sent ? body.sent : [],
|
||||||
received: body && body.received ? body.received : [],
|
received: body && body.received ? body.received : [],
|
||||||
@ -68,7 +69,10 @@ export const arrangePayments = (selNode: CommonSelectedNode, body) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
payments.relayed.forEach((relayedEle) => {
|
payments.relayed.forEach((relayedEle) => {
|
||||||
if (relayedEle.timestamp.unix) { relayedEle.timestamp = relayedEle.timestamp.unix * 1000; }
|
// Changing the timestamp value to keep the response backward compatible.
|
||||||
|
// ECL < 0.7.0 sent timestamp in unix milliseconds, then in {"iso", "unix"} object.
|
||||||
|
// From v0.10.0, it sends settledAt in {"iso", "unix"} object too.
|
||||||
|
relayedEle.timestamp = relayedEle.settledAt && relayedEle.settledAt.unix ? relayedEle.settledAt.unix * 1000 : relayedEle.timestamp && relayedEle.timestamp.unix ? relayedEle.timestamp.unix * 1000 : relayedEle.timestamp;
|
||||||
if (relayedEle.amountIn) { relayedEle.amountIn = Math.round(relayedEle.amountIn / 1000); }
|
if (relayedEle.amountIn) { relayedEle.amountIn = Math.round(relayedEle.amountIn / 1000); }
|
||||||
if (relayedEle.amountOut) { relayedEle.amountOut = Math.round(relayedEle.amountOut / 1000); }
|
if (relayedEle.amountOut) { relayedEle.amountOut = Math.round(relayedEle.amountOut / 1000); }
|
||||||
});
|
});
|
||||||
@ -80,7 +84,7 @@ export const getFees = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Fees..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/audit';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
|
||||||
const today = new Date(Date.now());
|
const today = new Date(Date.now());
|
||||||
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
const tillToday = (Math.round(today.getTime() / 1000)).toString();
|
||||||
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
const fromLastMonth = (Math.round(new Date(today.getFullYear(), today.getMonth() - 1, today.getDate() + 1, 0, 0, 0).getTime() / 1000)).toString();
|
||||||
@ -90,7 +94,7 @@ export const getFees = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Fees', msg: 'Fee Audit Options', data: options.form });
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('Fees', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); });
|
common.getDummyData('Fees', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangeFees(req.session.selectedNode, data, Math.round((new Date().getTime())))); });
|
||||||
} else {
|
} else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Fee Received', data: body });
|
||||||
@ -106,11 +110,13 @@ export const getPayments = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Payments..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Getting Payments..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/audit';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
|
||||||
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
||||||
options.form = { from: 0, to: tillToday };
|
options.form = { from: 0, to: tillToday };
|
||||||
|
if (req.query.count) { options.form.count = req.query.count; }
|
||||||
|
if (req.query.skip) { options.form.skip = req.query.skip; }
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('Payments', req.session.selectedNode.ln_implementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
|
common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
|
||||||
} else {
|
} else {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Payments Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Fees', msg: 'Payments Received', data: body });
|
||||||
|
@ -16,12 +16,12 @@ export const getInfo = (req, res, next) => {
|
|||||||
common.setOptions(req);
|
common.setOptions(req);
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/getinfo';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/getinfo';
|
||||||
options.form = {};
|
options.form = {};
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.ln_node });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Selected Node ' + req.session.selectedNode.lnNode });
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url ' + options.url });
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
common.getDummyData('GetInfo', req.session.selectedNode.ln_implementation).then((data: any) => {
|
common.getDummyData('GetInfo', req.session.selectedNode.lnImplementation).then((data: any) => {
|
||||||
data.lnImplementation = 'Eclair';
|
data.lnImplementation = 'Eclair';
|
||||||
return res.status(200).json(data);
|
return res.status(200).json(data);
|
||||||
});
|
});
|
||||||
@ -34,7 +34,7 @@ export const getInfo = (req, res, next) => {
|
|||||||
return request.post(options).then((body) => {
|
return request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Connecting to the Eclair\'s Websocket Server.' });
|
||||||
body.lnImplementation = 'Eclair';
|
body.lnImplementation = 'Eclair';
|
||||||
req.session.selectedNode.ln_version = body.version.split('-')[0] || '';
|
req.session.selectedNode.lnVersion = body.version.split('-')[0] || '';
|
||||||
eclWsClient.updateSelectedNode(req.session.selectedNode);
|
eclWsClient.updateSelectedNode(req.session.selectedNode);
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'GetInfo', msg: 'Node Information Received', data: body });
|
||||||
return res.status(200).json(body);
|
return res.status(200).json(body);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import request from 'request-promise';
|
import request from 'request-promise';
|
||||||
import { Logger, LoggerService } from '../../utils/logger.js';
|
import { Logger, LoggerService } from '../../utils/logger.js';
|
||||||
import { Common, CommonService } from '../../utils/common.js';
|
import { Common, CommonService } from '../../utils/common.js';
|
||||||
import { CommonSelectedNode } from 'server/models/config.model.js';
|
import { SelectedNode } from 'server/models/config.model.js';
|
||||||
let options = null;
|
let options = null;
|
||||||
const logger: LoggerService = Logger;
|
const logger: LoggerService = Logger;
|
||||||
const common: CommonService = Common;
|
const common: CommonService = Common;
|
||||||
@ -37,7 +37,7 @@ export const getInvoice = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Invoice..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Invoice..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/getinvoice';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/getinvoice';
|
||||||
options.form = { paymentHash: req.params.paymentHash };
|
options.form = { paymentHash: req.params.paymentHash };
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoice', msg: 'Invoice Found', data: body });
|
||||||
@ -52,11 +52,14 @@ export const getInvoice = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const listPendingInvoicesRequestCall = (selectedNode: CommonSelectedNode) => {
|
export const listPendingInvoicesRequestCall = (selectedNode: SelectedNode, count?: number, skip?: number) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
|
||||||
options = selectedNode.options;
|
options = selectedNode.authentication.options;
|
||||||
options.url = selectedNode.ln_server_url + '/listpendinginvoices';
|
options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices';
|
||||||
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
|
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
|
||||||
|
// Limit the number of invoices till provided count
|
||||||
|
if (count) { options.form.count = count; }
|
||||||
|
if (skip) { options.form.skip = skip; }
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request.post(options).then((pendingInvoicesResponse) => {
|
request.post(options).then((pendingInvoicesResponse) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Pending Invoices List ', data: pendingInvoicesResponse });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Pending Invoices List ', data: pendingInvoicesResponse });
|
||||||
@ -72,28 +75,28 @@ export const listInvoices = (req, res, next) => {
|
|||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
|
||||||
options.form = { from: 0, to: tillToday };
|
|
||||||
const options1 = JSON.parse(JSON.stringify(options));
|
const options1 = JSON.parse(JSON.stringify(options));
|
||||||
options1.url = req.session.selectedNode.ln_server_url + '/listinvoices';
|
options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices';
|
||||||
options1.form = { from: 0, to: tillToday };
|
options1.form = { from: 0, to: tillToday };
|
||||||
|
if (req.query.count) { options1.form.count = req.query.count; }
|
||||||
|
if (req.query.skip) { options1.form.skip = req.query.skip; }
|
||||||
const options2 = JSON.parse(JSON.stringify(options));
|
const options2 = JSON.parse(JSON.stringify(options));
|
||||||
options2.url = req.session.selectedNode.ln_server_url + '/listpendinginvoices';
|
options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices';
|
||||||
options2.form = { from: 0, to: tillToday };
|
options2.form = { from: 0, to: tillToday };
|
||||||
if (common.read_dummy_data) {
|
if (common.read_dummy_data) {
|
||||||
return common.getDummyData('Invoices', req.session.selectedNode.ln_implementation).then((body) => {
|
return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then(([invoices, pendingInvoicesRes]: any[]) => {
|
||||||
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
|
pendingInvoices = pendingInvoicesRes;
|
||||||
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
|
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
|
||||||
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
|
|
||||||
then((values) => res.status(200).json(invoices));
|
then((values) => res.status(200).json(invoices));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Promise.all([request(options1), request(options2)]).
|
return Promise.all([request(options1), request(options2)]).
|
||||||
then((body) => {
|
then(([invoices, pendingInvoicesRes]) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: invoices });
|
||||||
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
|
// pendingInvoices will be used to get the status (paid/unpaid) of the invoice via getReceivedPaymentInfo
|
||||||
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
|
pendingInvoices = pendingInvoicesRes;
|
||||||
if (invoices && invoices.length > 0) {
|
if (invoices && invoices.length > 0) {
|
||||||
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.ln_server_url, invoice))).
|
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
|
||||||
then((values) => {
|
then((values) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Sorted Invoices List Received', data: invoices });
|
||||||
return res.status(200).json(invoices);
|
return res.status(200).json(invoices);
|
||||||
@ -114,10 +117,10 @@ export const listInvoices = (req, res, next) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createInvoiceRequestCall = (selectedNode: CommonSelectedNode, description: string, amount: number) => {
|
export const createInvoiceRequestCall = (selectedNode: SelectedNode, description: string, amount: number) => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
||||||
options = selectedNode.options;
|
options = selectedNode.authentication.options;
|
||||||
options.url = selectedNode.ln_server_url + '/createinvoice';
|
options.url = selectedNode.settings.lnServerUrl + '/createinvoice';
|
||||||
options.form = { description: description, amountMsat: amount };
|
options.form = { description: description, amountMsat: amount };
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request.post(options).then((invResponse) => {
|
request.post(options).then((invResponse) => {
|
||||||
@ -131,10 +134,11 @@ export const createInvoiceRequestCall = (selectedNode: CommonSelectedNode, descr
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const createInvoice = (req, res, next) => {
|
export const createInvoice = (req, res, next) => {
|
||||||
|
const { description, amountMsat } = req.body;
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Creating Invoice..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
createInvoiceRequestCall(req.session.selectedNode, req.body.description, req.body.amountMsat).then((invRes) => {
|
createInvoiceRequestCall(req.session.selectedNode, description, amountMsat).then((invRes) => {
|
||||||
res.status(201).json(invRes);
|
res.status(201).json(invRes);
|
||||||
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import request from 'request-promise';
|
import request from 'request-promise';
|
||||||
import { Logger, LoggerService } from '../../utils/logger.js';
|
import { Logger, LoggerService } from '../../utils/logger.js';
|
||||||
import { Common, CommonService } from '../../utils/common.js';
|
import { Common, CommonService } from '../../utils/common.js';
|
||||||
import { CommonSelectedNode } from 'server/models/config.model.js';
|
import { SelectedNode } from 'server/models/config.model.js';
|
||||||
let options = null;
|
let options = null;
|
||||||
const logger: LoggerService = Logger;
|
const logger: LoggerService = Logger;
|
||||||
const common: CommonService = Common;
|
const common: CommonService = Common;
|
||||||
@ -10,7 +10,7 @@ export const getNodes = (req, res, next) => {
|
|||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup..' });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup..' });
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
options.url = req.session.selectedNode.ln_server_url + '/nodes';
|
options.url = req.session.selectedNode.settings.lnServerUrl + '/nodes';
|
||||||
options.form = { nodeIds: req.params.id };
|
options.form = { nodeIds: req.params.id };
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body });
|
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Network', msg: 'Node Lookup Finished', data: body });
|
||||||
@ -21,10 +21,10 @@ export const getNodes = (req, res, next) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findRouteBetweenNodesRequestCall = (selectedNode: CommonSelectedNode, amountMsat: number, sourceNodeId: string, targetNodeId: string, ignoreNodeIds: string[] = [], format: string = 'shortChannelId') => {
|
export const findRouteBetweenNodesRequestCall = (selectedNode: SelectedNode, amountMsat: number, sourceNodeId: string, targetNodeId: string, ignoreNodeIds: string[] = [], format: string = 'shortChannelId') => {
|
||||||
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' });
|
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Network', msg: 'Find Route Between Nodes..' });
|
||||||
options = selectedNode.options;
|
options = selectedNode.authentication.options;
|
||||||
options.url = selectedNode.ln_server_url + '/findroutebetweennodes';
|
options.url = selectedNode.settings.lnServerUrl + '/findroutebetweennodes';
|
||||||
options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format };
|
options.form = { amountMsat: amountMsat, sourceNodeId: sourceNodeId, targetNodeId: targetNodeId, ignoreNodeIds: ignoreNodeIds, format: format };
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
request.post(options).then((body) => {
|
request.post(options).then((body) => {
|
||||||
@ -37,9 +37,10 @@ export const findRouteBetweenNodesRequestCall = (selectedNode: CommonSelectedNod
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const findRouteBetweenNodes = (req, res, next) => {
|
export const findRouteBetweenNodes = (req, res, next) => {
|
||||||
|
const { amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format } = req.body;
|
||||||
options = common.getOptions(req);
|
options = common.getOptions(req);
|
||||||
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
|
||||||
findRouteBetweenNodesRequestCall(req.session.selectedNode, req.body.amountMsat, req.body.sourceNodeId, req.body.targetNodeId, req.body.ignoreNodeIds, req.body.format).then((callRes) => {
|
findRouteBetweenNodesRequestCall(req.session.selectedNode, amountMsat, sourceNodeId, targetNodeId, ignoreNodeIds, format).then((callRes) => {
|
||||||
res.status(200).json(callRes);
|
res.status(200).json(callRes);
|
||||||
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
}).catch((err) => res.status(err.statusCode).json({ message: err.message, error: err.error }));
|
||||||
};
|
};
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user