Release 0.11.1 (#770)

Release 0.11.1
pull/773/head
ShahanaFarooqui 3 years ago committed by GitHub
parent c6e435a151
commit c1d7e22642
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,40 +1,187 @@
{
"root": true,
"ignorePatterns": [
"projects/**/*"
"projects/**/*",
"rtl.js",
"/routes/**/*.js",
"/controllers/**/*.js",
"/src/prebuild.js"
],
"overrides": [
{
"files": [
"*.ts"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": [
"tsconfig.json",
"e2e/tsconfig.json"
],
"ecmaVersion": 2020,
"sourceType": "module",
"project": "./tsconfig.json",
"createDefaultProgram": true
},
"plugins": ["deprecation"],
"extends": [
"plugin:@angular-eslint/all",
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/recommended--extra",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/component-selector": [
"error",
{
"prefix": "rtl",
"style": "kebab-case",
"type": "element"
}
],
"@angular-eslint/directive-selector": [
"error",
{
"style": "camelCase",
"type": "attribute"
}
]
"deprecation/deprecation": "error",
"@angular-eslint/use-injectable-provided-in": "off",
"@angular-eslint/prefer-on-push-component-change-detection": "off",
"@angular-eslint/use-component-view-encapsulation": "off",
"@angular-eslint/sort-ngmodule-metadata-arrays": "off",
"@angular-eslint/arrow-body-style": "off",
"@angular-eslint/component-selector": ["error", { "prefix": "rtl", "style": "kebab-case", "type": "element" }],
"@angular-eslint/directive-selector": ["error", { "style": "camelCase", "type": "attribute" }],
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/member-delimiter-style": ["error", { "multiline": { "delimiter": "semi", "requireLast": true}, "singleline": { "delimiter": "comma", "requireLast": false }}],
"quotes": ["error", "single"],
"comma-dangle": ["error", "never"],
"comma-spacing": ["error", { "before": false, "after": true }],
"computed-property-spacing": ["error", "never", { "enforceForClassMembers": true }],
"array-bracket-spacing": ["error", "never", { "objectsInArrays": false }],
"space-in-parens": ["error", "never"],
"eol-last": ["error", "always"],
"array-bracket-newline": ["error", "consistent"],
"curly": "error",
"no-unused-expressions": "error",
"strict": "error",
"max-len": ["error", { "code": 430 }],
"new-parens": "error",
"no-multiple-empty-lines": "error",
"no-trailing-spaces": "error",
"quote-props": ["error", "as-needed"],
"space-before-function-paren": ["error", { "anonymous": "never", "asyncArrow": "always", "named": "never" }],
"semi": ["error", "always"],
"dot-location": "error",
"no-await-in-loop": "error",
"no-console": "error",
"no-loss-of-precision": "error",
"no-promise-executor-return": "error",
"no-template-curly-in-string": "error",
"no-unreachable-loop": "error",
"no-unsafe-optional-chaining": "error",
"no-useless-backreference": "error",
"require-atomic-updates": "error",
"array-callback-return": "error",
"block-scoped-var": "error",
"default-case": "error",
"default-case-last": "error",
"eqeqeq": "error",
"grouped-accessor-pairs": "error",
"guard-for-in": "error",
"no-alert": "error",
"no-caller": "error",
"no-constructor-return": "error",
"no-div-regex": "error",
"no-eq-null": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
"no-floating-decimal": "error",
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-iterator": "error",
"no-labels": "error",
"no-lone-blocks": "error",
"no-loop-func": "error",
"no-multi-str": "error",
"no-new": "error",
"no-new-func": "error",
"no-multi-spaces": "error",
"no-new-wrappers": "error",
"no-nonoctal-decimal-escape": "error",
"no-octal-escape": "error",
"no-proto": "error",
"no-restricted-properties": "error",
"no-return-assign": "error",
"no-return-await": "error",
"no-script-url": "error",
"no-self-compare": "error",
"no-sequences": "error",
"no-throw-literal": "error",
"no-unmodified-loop-condition": "error",
"no-unused-labels": "error",
"no-useless-call": "error",
"no-useless-concat": "error",
"no-useless-return": "error",
"no-void": "error",
"no-warning-comments": "error",
"prefer-named-capture-group": "error",
"prefer-promise-reject-errors": "error",
"prefer-regex-literals": "error",
"vars-on-top": "error",
"wrap-iife": "error",
"yoda": "error",
"no-label-var": "error",
"no-restricted-globals": "error",
"no-undef-init": "error",
"no-undefined": "error",
"block-spacing": "error",
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
"comma-style": "error",
"func-call-spacing": "error",
"func-name-matching": "error",
"func-names": "error",
"id-match": "error",
"implicit-arrow-linebreak": "error",
"indent": ["error", 2, { "SwitchCase": 1, "MemberExpression": 1 }],
"keyword-spacing": ["error", { "before": true, "after": true, "overrides": { "this": { "before": false }}}],
"lines-around-comment": "error",
"max-depth": "error",
"max-nested-callbacks": "error",
"max-statements-per-line": ["error", { "max": 2 }],
"no-array-constructor": "error",
"no-bitwise": "error",
"no-continue": "error",
"no-mixed-operators": "error",
"no-multi-assign": "error",
"no-new-object": "error",
"no-restricted-syntax": "error",
"no-tabs": "error",
"no-unneeded-ternary": "error",
"no-whitespace-before-property": "error",
"nonblock-statement-body-position": "error",
"object-curly-newline": "error",
"object-curly-spacing": ["error", "always"],
"one-var-declaration-per-line": "error",
"operator-linebreak": ["error", "after"],
"padded-blocks": ["error", { "classes": "always", "blocks": "never", "switches": "never" }],
"padding-line-between-statements": "error",
"prefer-exponentiation-operator": "error",
"semi-spacing": "error",
"semi-style": "error",
"space-before-blocks": "error",
"space-infix-ops": "error",
"space-unary-ops": "error",
"spaced-comment": "error",
"switch-colon-spacing": "error",
"template-tag-spacing": "error",
"unicode-bom": "error",
"wrap-regex": "error",
"arrow-body-style": "error",
"arrow-parens": "error",
"arrow-spacing": "error",
"generator-star-spacing": "error",
"no-confusing-arrow": "error",
"no-duplicate-imports": "error",
"no-restricted-exports": "error",
"no-restricted-imports": "error",
"no-useless-computed-key": "error",
"no-useless-rename": "error",
"no-var": "error",
"prefer-arrow-callback": "error",
"prefer-const": "error",
"prefer-numeric-literals": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"rest-spread-spacing": "error",
"symbol-description": "error",
"template-curly-spacing": "error",
"yield-star-spacing": "error"
}
},
{
@ -42,9 +189,21 @@
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/all",
"plugin:@angular-eslint/template/recommended"
],
"rules": {}
"rules": {
"@angular-eslint/template/accessibility-elements-content": "off",
"@angular-eslint/template/click-events-have-key-events": "off",
"@angular-eslint/template/conditional-complexity": "off",
"@angular-eslint/template/cyclomatic-complexity": "off",
"@angular-eslint/template/i18n": "off",
"@angular-eslint/template/no-autofocus": "off",
"@angular-eslint/template/no-call-expression": "off",
"@angular-eslint/template/no-positive-tabindex": "off",
"@angular-eslint/template/use-track-by-function": "off"
}
}
]
}
// https://eslint.org/docs/rules/

@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-node",
"request": "launch",
"name": "Launch Program",
"skipFiles": [
"<node_internals>/**"
],
"env": {
"NODE_ENV": "development"
},
"program": "${workspaceFolder}\\rtl.js"
}
]
}

@ -116,18 +116,6 @@
"src/**/*.html"
]
}
},
"e2e": {
"builder": "@angular-devkit/build-angular:protractor",
"options": {
"protractorConfig": "e2e/protractor.conf.js",
"devServerTarget": "RTLApp:serve"
},
"configurations": {
"production": {
"devServerTarget": "RTLApp:serve:production"
}
}
}
}
}

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

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -2,17 +2,17 @@
<meta charset="utf-8">
<title>RTL</title>
<base href="/rtl/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" sizes="180x180" href="assets/images/favicon-light/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon-light/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon-light/favicon-16x16.png">
<link rel="manifest" href="assets/images/favicon-light/site.webmanifest">
<link rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<style>@font-face{font-family:Roboto;src:url(Roboto-Thin.dbd56bd3357dc3617fe5.woff2) format("woff2"),url(Roboto-Thin.e7f7c82374bd0ebef14b.woff) format("woff");font-weight:100;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.a8cef84f735ef887abdc.woff2) format("woff2"),url(Roboto-ThinItalic.5dd9349c940073834e9a.woff) format("woff");font-weight:100;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Light.c27d89ac77468ae18f28.woff2) format("woff2"),url(Roboto-Light.d923dfafc0c5183b59aa.woff) format("woff");font-weight:300;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.506274c7228cf81cae4d.woff2) format("woff2"),url(Roboto-LightItalic.d4b8c137518d9d92bb28.woff) format("woff");font-weight:300;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Regular.64cfb66c866ea50cad47.woff2) format("woff2"),url(Roboto-Regular.e02e9d6ff5547f7e9962.woff) format("woff");font-weight:400;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.4dd2af1e8df532f41db8.woff2) format("woff2"),url(Roboto-RegularItalic.5ea38fff9eebef99c5df.woff) format("woff");font-weight:400;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Medium.1d3bced88509b0838984.woff2) format("woff2"),url(Roboto-Medium.092c6130df8fd2199888.woff) format("woff");font-weight:500;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.d620b8f53f75966fe42e.woff2) format("woff2"),url(Roboto-MediumItalic.18ff1628c628080166c1.woff) format("woff");font-weight:500;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Bold.92fbd4e93cf0a5dbebaa.woff2) format("woff2"),url(Roboto-Bold.73288d91c325e82a5b92.woff) format("woff");font-weight:700;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.5f600d98a73d800ae575.woff2) format("woff2"),url(Roboto-BoldItalic.6d89acbd21d7e3fbecb2.woff) format("woff");font-weight:700;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Black.41ed1105a6ebb8ffe34e.woff2) format("woff2"),url(Roboto-Black.937491dfcbe64ca9a9f1.woff) format("woff");font-weight:900;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.50ca4c51ebc27e7e7d2f.woff2) format("woff2"),url(Roboto-BlackItalic.2e1ee657996854c6f427.woff) format("woff");font-weight:900;font-style:italic;}html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:62.5%;}body{box-sizing:border-box;margin:0;}body{height:100%;overflow:hidden;}*{margin:0;padding:0;}</style><link rel="stylesheet" href="styles.97554e699a42acff6579.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.97554e699a42acff6579.css"></noscript></head>
<meta i18n-content="" name="viewport" content="width=device-width, initial-scale=1">
<link i18n-sizes="" i18n-rel="" rel="apple-touch-icon" sizes="180x180" href="assets/images/favicon-light/apple-touch-icon.png">
<link i18n-sizes="" i18n-rel="" rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon-light/favicon-32x32.png">
<link i18n-sizes="" i18n-rel="" rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon-light/favicon-16x16.png">
<link i18n-rel="" rel="manifest" href="assets/images/favicon-light/site.webmanifest">
<link i18n-rel="" rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5">
<meta i18n-content="" name="msapplication-TileColor" content="#da532c">
<meta i18n-content="" name="theme-color" content="#ffffff">
<style>@font-face{font-family:Roboto;src:url(Roboto-Thin.dbd56bd3357dc3617fe5.woff2) format("woff2"),url(Roboto-Thin.e7f7c82374bd0ebef14b.woff) format("woff");font-weight:100;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.a8cef84f735ef887abdc.woff2) format("woff2"),url(Roboto-ThinItalic.5dd9349c940073834e9a.woff) format("woff");font-weight:100;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Light.c27d89ac77468ae18f28.woff2) format("woff2"),url(Roboto-Light.d923dfafc0c5183b59aa.woff) format("woff");font-weight:300;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.506274c7228cf81cae4d.woff2) format("woff2"),url(Roboto-LightItalic.d4b8c137518d9d92bb28.woff) format("woff");font-weight:300;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Regular.64cfb66c866ea50cad47.woff2) format("woff2"),url(Roboto-Regular.e02e9d6ff5547f7e9962.woff) format("woff");font-weight:400;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.4dd2af1e8df532f41db8.woff2) format("woff2"),url(Roboto-RegularItalic.5ea38fff9eebef99c5df.woff) format("woff");font-weight:400;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Medium.1d3bced88509b0838984.woff2) format("woff2"),url(Roboto-Medium.092c6130df8fd2199888.woff) format("woff");font-weight:500;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.d620b8f53f75966fe42e.woff2) format("woff2"),url(Roboto-MediumItalic.18ff1628c628080166c1.woff) format("woff");font-weight:500;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Bold.92fbd4e93cf0a5dbebaa.woff2) format("woff2"),url(Roboto-Bold.73288d91c325e82a5b92.woff) format("woff");font-weight:700;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.5f600d98a73d800ae575.woff2) format("woff2"),url(Roboto-BoldItalic.6d89acbd21d7e3fbecb2.woff) format("woff");font-weight:700;font-style:italic;}@font-face{font-family:Roboto;src:url(Roboto-Black.41ed1105a6ebb8ffe34e.woff2) format("woff2"),url(Roboto-Black.937491dfcbe64ca9a9f1.woff) format("woff");font-weight:900;font-style:normal;}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.50ca4c51ebc27e7e7d2f.woff2) format("woff2"),url(Roboto-BlackItalic.2e1ee657996854c6f427.woff) format("woff");font-weight:900;font-style:italic;}html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:62.5%;}body{box-sizing:border-box;margin:0;}body{height:100%;overflow:hidden;}*{margin:0;padding:0;}</style><link rel="stylesheet" href="styles.50804d64c130486c55c1.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.50804d64c130486c55c1.css"></noscript></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.28bc9723e141277838d0.js" defer></script><script src="polyfills.99f4d82f067fba7525c4.js" defer></script><script src="main.0fde3abb5a45cd8835db.js" defer></script>
<script src="runtime.f5bf3b7e70912bf34aaa.js" defer></script><script src="polyfills.a979cbbe16939013cdcf.js" defer></script><script src="main.522ca56ef954d078d551.js" defer></script>
</body></html>

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
(()=>{"use strict";var e,r,t,a={},o={};function n(e){var r=o[e];if(void 0!==r)return r.exports;var t=o[e]={id:e,loaded:!1,exports:{}};return a[e].call(t.exports,t,t.exports,n),t.loaded=!0,t.exports}n.m=a,e=[],n.O=(r,t,a,o)=>{if(!t){var l=1/0;for(s=0;s<e.length;s++){for(var[t,a,o]=e[s],d=!0,i=0;i<t.length;i++)(!1&o||l>=o)&&Object.keys(n.O).every(e=>n.O[e](t[i]))?t.splice(i--,1):(d=!1,o<l&&(l=o));d&&(e.splice(s--,1),r=a())}return r}o=o||0;for(var s=e.length;s>0&&e[s-1][2]>o;s--)e[s]=e[s-1];e[s]=[t,a,o]},n.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return n.d(r,{a:r}),r},n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce((r,t)=>(n.f[t](e,r),r),[])),n.u=e=>e+"."+{432:"635dd65c825f8e4ca25b",646:"4d1e1dc02d21b483a9c9",891:"65e70a7da1bfef9d82e4",958:"9a3ae49eb9fc6ea729f7"}[e]+".js",n.miniCssF=e=>"styles.97554e699a42acff6579.css",n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="rtl:",n.l=(e,a,o,l)=>{if(r[e])r[e].push(a);else{var d,i;if(void 0!==o)for(var s=document.getElementsByTagName("script"),u=0;u<s.length;u++){var c=s[u];if(c.getAttribute("src")==e||c.getAttribute("data-webpack")==t+o){d=c;break}}d||(i=!0,(d=document.createElement("script")).charset="utf-8",d.timeout=120,n.nc&&d.setAttribute("nonce",n.nc),d.setAttribute("data-webpack",t+o),d.src=e),r[e]=[a];var f=(t,a)=>{d.onerror=d.onload=null,clearTimeout(p);var o=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),o&&o.forEach(e=>e(a)),t)return t(a)},p=setTimeout(f.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=f.bind(null,d.onerror),d.onload=f.bind(null,d.onload),i&&document.head.appendChild(d)}},n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),n.p="",(()=>{var e={666:0};n.f.j=(r,t)=>{var a=n.o(e,r)?e[r]:void 0;if(0!==a)if(a)t.push(a[2]);else if(666!=r){var o=new Promise((t,o)=>a=e[r]=[t,o]);t.push(a[2]=o);var l=n.p+n.u(r),d=new Error;n.l(l,t=>{if(n.o(e,r)&&(0!==(a=e[r])&&(e[r]=void 0),a)){var o=t&&("load"===t.type?"missing":t.type),l=t&&t.target&&t.target.src;d.message="Loading chunk "+r+" failed.\n("+o+": "+l+")",d.name="ChunkLoadError",d.type=o,d.request=l,a[1](d)}},"chunk-"+r,r)}else e[r]=0},n.O.j=r=>0===e[r];var r=(r,t)=>{var a,o,[l,d,i]=t,s=0;for(a in d)n.o(d,a)&&(n.m[a]=d[a]);if(i)var u=i(n);for(r&&r(t);s<l.length;s++)n.o(e,o=l[s])&&e[o]&&e[o][0](),e[l[s]]=0;return n.O(u)},t=self.webpackChunkrtl=self.webpackChunkrtl||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})()})();

@ -0,0 +1 @@
(()=>{"use strict";var e,r,t,o={},a={};function n(e){var r=a[e];if(void 0!==r)return r.exports;var t=a[e]={id:e,loaded:!1,exports:{}};return o[e].call(t.exports,t,t.exports,n),t.loaded=!0,t.exports}n.m=o,e=[],n.O=(r,t,o,a)=>{if(!t){var l=1/0;for(s=0;s<e.length;s++){for(var[t,o,a]=e[s],i=!0,d=0;d<t.length;d++)(!1&a||l>=a)&&Object.keys(n.O).every(e=>n.O[e](t[d]))?t.splice(d--,1):(i=!1,a<l&&(l=a));i&&(e.splice(s--,1),r=o())}return r}a=a||0;for(var s=e.length;s>0&&e[s-1][2]>a;s--)e[s]=e[s-1];e[s]=[t,o,a]},n.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return n.d(r,{a:r}),r},n.d=(e,r)=>{for(var t in r)n.o(r,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},n.f={},n.e=e=>Promise.all(Object.keys(n.f).reduce((r,t)=>(n.f[t](e,r),r),[])),n.u=e=>e+"."+{145:"bd793f88eee8abcb2b20",432:"cc664c98c4074918e24a",891:"4fbbfe370fa877de7f39",958:"88b5fa8d3b93e7a0e7b3"}[e]+".js",n.miniCssF=e=>"styles.50804d64c130486c55c1.css",n.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="rtl:",n.l=(e,o,a,l)=>{if(r[e])r[e].push(o);else{var i,d;if(void 0!==a)for(var s=document.getElementsByTagName("script"),u=0;u<s.length;u++){var c=s[u];if(c.getAttribute("src")==e||c.getAttribute("data-webpack")==t+a){i=c;break}}i||(d=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,n.nc&&i.setAttribute("nonce",n.nc),i.setAttribute("data-webpack",t+a),i.src=e),r[e]=[o];var f=(t,o)=>{i.onerror=i.onload=null,clearTimeout(b);var a=r[e];if(delete r[e],i.parentNode&&i.parentNode.removeChild(i),a&&a.forEach(e=>e(o)),t)return t(o)},b=setTimeout(f.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=f.bind(null,i.onerror),i.onload=f.bind(null,i.onload),d&&document.head.appendChild(i)}},n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),n.p="",(()=>{var e={666:0};n.f.j=(r,t)=>{var o=n.o(e,r)?e[r]:void 0;if(0!==o)if(o)t.push(o[2]);else if(666!=r){var a=new Promise((t,a)=>o=e[r]=[t,a]);t.push(o[2]=a);var l=n.p+n.u(r),i=new Error;n.l(l,t=>{if(n.o(e,r)&&(0!==(o=e[r])&&(e[r]=void 0),o)){var a=t&&("load"===t.type?"missing":t.type),l=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+a+": "+l+")",i.name="ChunkLoadError",i.type=a,i.request=l,o[1](i)}},"chunk-"+r,r)}else e[r]=0},n.O.j=r=>0===e[r];var r=(r,t)=>{var o,a,[l,i,d]=t,s=0;for(o in i)n.o(i,o)&&(n.m[o]=i[o]);if(d)var u=d(n);for(r&&r(t);s<l.length;s++)n.o(e,a=l[s])&&e[a]&&e[a][0](),e[l[s]]=0;return n.O(u)},t=self.webpackChunkrtl=self.webpackChunkrtl||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})()})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -9,39 +9,14 @@ exports.getBalance = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/getBalance';
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Balance', msg: 'Balance Received', data: body});
if(!body.totalBalance) {
body.totalBalance = 0;
body.btc_totalBalance = 0;
} else {
body.btc_totalBalance = common.convertToBTC(body.totalBalance);
}
if(!body.confBalance) {
body.confBalance = 0;
body.btc_confBalance = 0;
} else {
body.btc_confBalance = common.convertToBTC(body.confBalance);
}
if(!body.unconfBalance) {
body.unconfBalance = 0;
body.btc_unconfBalance = 0;
} else {
body.btc_unconfBalance = common.convertToBTC(body.unconfBalance);
}
if (!body.totalBalance) { body.totalBalance = 0; }
if (!body.confBalance) { body.confBalance = 0; }
if (!body.unconfBalance) { body.unconfBalance = 0; }
logger.log({level: 'INFO', fileName: 'Balance', msg: 'Balance Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Balance', msg: 'Balance Fetch Error', error: err});
return res.status(500).json({
message: "Fetching balance failed!",
error: err.error
});
const err = common.handleError(errRes, 'Balance', 'Get Balance Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -20,18 +20,8 @@ exports.listChannels = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'List Channels Error', error: err});
return res.status(500).json({
message: 'Fetching List Channels Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'List Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -43,30 +33,12 @@ exports.openChannel = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Options', data: options.body});
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Open Channel Error', error: body.error});
res.status(500).json({
message: 'Open Channel Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Opened'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Opened'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Open Channel Error', error: err});
return res.status(500).json({
message: 'Open Channel Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Open Channel Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -78,30 +50,12 @@ exports.setChannelFee = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.body});
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Update Channel Policy Error', error: body.error});
res.status(500).json({
message: 'Update Channel Policy Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Fee Set'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Fee Set'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Update Channel Policy Error', error: err});
return res.status(500).json({
message: 'Update Channel Policy Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Update Channel Policy Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -114,30 +68,12 @@ exports.closeChannel = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel', data: options.url});
request.delete(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Close Channel Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Close Channel Error', error: body.error});
res.status(500).json({
message: 'Close Channel Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Closed'});
res.status(204).json(body);
}
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Closed'});
res.status(204).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Close Channel Error', error: err});
return res.status(500).json({
message: 'Close Channel Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Close Channel Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -147,70 +83,30 @@ exports.getLocalRemoteBalance = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/channel/localremotebal';
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Local Remote Balance', data: body});
if(!body.localBalance) {
body.localBalance = 0;
body.btc_localBalance = 0;
} else {
body.btc_localBalance = common.convertToBTC(body.localBalance);
}
if(!body.remoteBalance) {
body.remoteBalance = 0;
body.btc_remoteBalance = 0;
} else {
body.btc_remoteBalance = common.convertToBTC(body.remoteBalance);
}
if (!body.localBalance) { body.localBalance = 0; }
if (!body.remoteBalance) { body.remoteBalance = 0; }
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Local & Remote Balances Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Local Remote Balance Error', error: err});
return res.status(500).json({
message: 'Fetching Local Remote Balance Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Local Remote Balance Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.listForwards = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Getting Channel List Forwards..'});
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/channel/listForwards/';
options.url = common.getSelLNServerUrl() + '/v1/channel/listForwards?status=' + req.query.status;
request.get(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Forwarding History Error', error: body.error});
res.status(500).json({
message: "Forwarding History Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
if (body && body.length > 0) {
body = common.sortDescByKey(body, 'received_time');
}
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received', data: body});
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel List Forwards Received'});
res.status(200).json({ last_offset_index: 0, forwarding_events: body });
}
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Response For Status ' + req.query.status, data: body});
if (body && body.length > 0) { body = common.sortDescByKey(body, 'received_time'); }
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Forwarding History Received For Status' + req.query.status, data: body});
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel List Forwards Received For Status ' + req.query.status});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Forwarding History Error', error: err});
return res.status(500).json({
message: "Forwarding History Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Forwarding History Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -9,35 +9,12 @@ exports.getFees = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/getFees';
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Fee Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Get Fee Error', error: body.error});
res.status(500).json({
message: "Fetching fee failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
if(!body.feeCollected) {
body.feeCollected = 0;
body.btc_feeCollected = 0;
} else {
body.btc_feeCollected = common.convertToBTC(body.feeCollected);
}
logger.log({level: 'INFO', fileName: 'Fees', msg: 'Fees Received'});
res.status(200).json(body);
}
if (!body.feeCollected) { body.feeCollected = 0; }
logger.log({level: 'INFO', fileName: 'Fees', msg: 'Fees Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Get Fees Error', error: err});
return res.status(500).json({
message: "Fetching fee failed!",
error: err.error
});
const err = common.handleError(errRes, 'Fees', 'Get Fees Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -11,25 +11,19 @@ exports.getInfo = (req, res, next) => {
logger.log({level: 'DEBUG', fileName:'GetInfo', msg: 'Selected Node', data: common.selectedNode.ln_node});
logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Calling Info from C-Lightning server url', data: options.url});
if (!options.headers || !options.headers.macaroon) {
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'C-Lightning Get info failed due to bad or missing macaroon!', error: {error: 'Bad macaroon.'}});
res.status(502).json({
message: "Fetching Info Failed!",
error: "Bad Macaroon"
});
const errMsg = 'C-Lightning get info failed due to bad or missing macaroon!';
const err = common.handleError({ statusCode: 502, message: 'Bad Macaroon', error: errMsg }, 'GetInfo', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Node Information', data: body});
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'Get Info Error', error: body.error});
res.status(500).json({
message: "Fetching Info failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
if (!body || search_idx > -1 || body.error) {
if (body && !body.error) { body.error = 'Error From Server!'; }
const err = common.handleError(body, 'GetInfo', 'Get Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
body.currency_unit = 'BTC';
body.smaller_currency_unit = 'Sats';
body.lnImplementation = 'C-Lightning';
let chainObj = { chain: '', network: '' };
if (body.network === 'testnet') {
@ -57,18 +51,8 @@ exports.getInfo = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'Get Info Error', error: err});
return res.status(500).json({
message: "Fetching Info failed!",
error: err.error
});
const err = common.handleError(errRes, 'GetInfo', 'Get Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};

@ -10,29 +10,12 @@ exports.deleteExpiredInvoice = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/invoice/delExpiredInvoice' + queryStr;
request.delete(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices Deleted', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Invoice Delete Error', error: body.error});
res.status(500).json({
message: "Deleting Invoice Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
}
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Expired Invoices Deleted'});
res.status(204).json({status: 'Invoice Deleted Successfully'});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Invoice Delete Error', error: err});
return res.status(500).json({
message: "Deleting Invoice Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Invoice', 'Delete Invoice Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -43,34 +26,16 @@ exports.listInvoices = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/invoice/listInvoices' + labelQuery;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'List Invoice Error', error: body.error});
res.status(500).json({
message: "Fetching Invoice Info failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
if ( body.invoices && body.invoices.length > 0) {
body.invoices = common.sortDescByKey(body.invoices, 'expires_at');
}
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body});
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Invoices Received'});
res.status(200).json(body);
if ( body.invoices && body.invoices.length > 0) {
body.invoices = common.sortDescByKey(body.invoices, 'expires_at');
}
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body});
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Invoices Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'List Invoice Error', error: err});
return res.status(500).json({
message: "Fetching Invoice Info failed!",
error: err.error
});
const err = common.handleError(errRes, 'Invoice', 'List Invoices Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -81,29 +46,11 @@ exports.addInvoice = (req, res, next) => {
options.body = req.body;
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Add Invoice Responce', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Add Invoice Error', error: body.error});
res.status(500).json({
message: "Add Invoice Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Invoice Created'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Invoice Created'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Add Invoice Error', error: err});
return res.status(500).json({
message: "Add Invoice Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Invoice', 'Add Invoice Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -8,32 +8,14 @@ exports.signMessage = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/utility/signMessage';
options.form = { message: req.body.message };
request.post(options, (error, response, body) => {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Messages', msg: 'Message Signed', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Message Sign Error', error: body.error});
res.status(500).json({
message: "Sign message failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Signed'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Signed'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Sign Message Error', error: err});
return res.status(500).json({
message: 'Sign Message Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Message', 'Sign Message Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -43,29 +25,11 @@ exports.verifyMessage = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/utility/checkMessage/' + req.body.message + '/' + req.body.signature;
request.get(options, (error, response, body) => {
logger.log({level: 'DEBUG', fileName: 'Messages', msg: 'Message Verified', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Verify Message Error', error: body.error});
res.status(500).json({
message: "Verify message failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Verified'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Verified'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Message Verification Error', error: err});
return res.status(500).json({
message: 'Verify Message Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Message', 'Verify Message Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -9,29 +9,12 @@ exports.getRoute = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/network/getRoute/' + req.params.destPubkey + '/' + req.params.amount;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Network', msg: 'Query Routes Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Network', msg: 'Query Routes Error', error: body.error});
res.status(500).json({
message: "Fetching Query Routes Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
}
logger.log({level: 'INFO', fileName: 'Network', msg: 'Network Routes Received'});
res.status(200).json({routes: body});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Network', msg: 'Query Routes Error', error: err});
return res.status(500).json({
message: "Fetching Query Routes Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Network', 'Query Routes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -45,18 +28,8 @@ exports.listNode = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Network', msg: 'Node Lookup Error', error: err});
return res.status(500).json({
message: "Node Lookup Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Network', 'Node Lookup Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -70,18 +43,8 @@ exports.listChannel = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Network', msg: 'Channel Lookup Error', error: err});
return res.status(500).json({
message: "Channel Lookup Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Network', 'Channel Lookup Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -90,21 +53,11 @@ exports.feeRates = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/network/feeRates/' + req.params.feeRateStyle;
request(options).then(function (body) {
logger.log({level: 'INFO', fileName: 'Network', msg: 'Network Fee Rates Received'});
logger.log({level: 'DEBUG', fileName: 'Network', msg: 'Network Fee Rates Received for ' + req.params.feeRateStyle, data: body});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Network', msg: 'Fee Rates Error', error: err});
return res.status(500).json({
message: "Fee Rates Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Network', 'Fee Rates Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -12,18 +12,8 @@ exports.getNewAddress = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'OnChain', msg: 'OnChain New Address Error', error: err});
return res.status(500).json({
message: "Fetching new address failed!",
error: err.error
});
const err = common.handleError(errRes, 'OnChain', 'New Address Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -35,30 +25,12 @@ exports.onChainWithdraw = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Options', data: options.body});
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'OnChain', msg: 'OnChain Withdraw Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'OnChain', msg: 'OnChain Withdraw Error', error: body.error});
res.status(500).json({
message: 'OnChain Withdraw Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'OnChain', msg: 'Withdraw Finished'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'OnChain', msg: 'Withdraw Finished'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'OnChain', msg: 'OnChain Withdraw Error', error: err});
return res.status(500).json({
message: 'OnChain Withdraw Failed!',
error: err
});
const err = common.handleError(errRes, 'OnChain', 'Withdraw Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -68,20 +40,10 @@ exports.getUTXOs = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/listFunds';
request(options).then((body) => {
if (body.outputs) { body.outputs = common.sortDescByStrKey(body.outputs, 'status'); }
logger.log({level: 'INFO', fileName: 'OnChain', msg: 'List Funds Received'});
logger.log({level: 'DEBUG', fileName: 'OnChain', msg: 'List Funds Received', data: body});
res.status(200).json(body);
}).catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'OnChain', msg: 'OnChain List Funds Error', error: err});
return res.status(500).json({
message: "Fetching list funds failed!",
error: err.error
});
const err = common.handleError(errRes, 'OnChain', 'List Funds Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -6,7 +6,7 @@ var options = {};
function paymentReducer(accumulator, currentPayment) {
let currPayHash = currentPayment.payment_hash;
if (!currentPayment.partid) { currentPayment.partid = 0; }
if(!accumulator[currPayHash]) {
if (!accumulator[currPayHash]) {
accumulator[currPayHash] = [currentPayment];
} else {
accumulator[currPayHash].push(currentPayment);
@ -51,33 +51,15 @@ exports.listPayments = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/pay/listPayments';
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body.payments});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Payments List Error', error: body.error});
res.status(500).json({
message: "Payments List Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
if ( body && body.payments && body.payments.length > 0) {
body.payments = common.sortDescByKey(body.payments, 'created_at');
}
logger.log({level: 'INFO', fileName: 'Payments', msg: 'List Payments Received'});
res.status(200).json(groupBy(body.payments));
if ( body && body.payments && body.payments.length > 0) {
body.payments = common.sortDescByKey(body.payments, 'created_at');
}
logger.log({level: 'INFO', fileName: 'Payments', msg: 'List Payments Received'});
res.status(200).json(groupBy(body.payments));
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Payments List Error', error: err});
return res.status(500).json({
message: "Payments List Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Payments', 'List Payments Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -87,30 +69,12 @@ exports.decodePayment = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/pay/decodePay/' + req.params.invoice;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Payment Decode Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Payment Decode Error', error: body.error});
res.status(500).json({
message: "Payment Request Decode Failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded'});
res.status(200).json(body);
}
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Payment Decoded'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Payment Decode Error', error: err});
return res.status(500).json({
message: "Payment Request Decode Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Payments', 'Decode Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -126,29 +90,11 @@ exports.postPayment = (req, res, next) => {
options.body = req.body;
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Send Payment Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Send Payment Error', error: body.error});
res.status(500).json({
message: "Send Payment Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Payment Sent'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Payment Sent'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Send Payments Error', error: err});
return res.status(500).json({
message: "Send Payment Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Payments', 'Send Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -15,18 +15,8 @@ exports.getPeers = (req, res, next) => {
res.status(200).json(peers);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Peers List Error', error: err});
return res.status(500).json({
message: "Peers Fetch Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Peers', 'List Peers Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -35,38 +25,23 @@ exports.postPeer = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/peer/connect';
options.body = req.body;
request.post(options, (error, response, body) => {
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Connect Peer Error', error: body.error});
res.status(500).json({
message: "Adding peer failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Added', data: body});
options.url = common.getSelLNServerUrl() + '/v1/peer/listPeers';
request(options).then(function (body) {
let peers = ( body) ? common.sortDescByStrKey(body, 'alias') : [];
peers = common.newestOnTop(peers, 'id', req.body.id);
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer with Newest On Top', data: peers});
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Added Successfully'});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Connected'});
res.status(201).json(peers);
}).catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Connect Peer Error', error: err});
return res.status(500).json({
message: "Peer Add Failed!",
error: err.error
});
});
}
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Added', data: body});
options.url = common.getSelLNServerUrl() + '/v1/peer/listPeers';
request(options).then(function (body) {
let peers = ( body) ? common.sortDescByStrKey(body, 'alias') : [];
peers = common.newestOnTop(peers, 'id', req.body.id);
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer with Newest On Top', data: peers});
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Added Successfully'});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Connected'});
res.status(201).json(peers);
}).catch(errRes => {
const err = common.handleError(errRes, 'Peers', 'Connect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}).catch(errRes => {
const err = common.handleError(errRes, 'Peers', 'Connect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -76,30 +51,12 @@ exports.deletePeer = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/peer/disconnect/' + req.params.peerId + '?force=' + req.query.force;
request.delete(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Detach Peer Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Detach Peer Error', error: body.error});
res.status(500).json({
message: "Detach peer failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Detached', data: req.params.peerId});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected'});
res.status(204).json({});
}
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Detached', data: req.params.peerId});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected'});
res.status(204).json({});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Detach Peer Error', error: err});
return res.status(500).json({
message: "Detach Peer Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Peers', 'Detach Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -95,7 +95,7 @@ exports.getChannels = (req, res, next) => {
} else {
request.post(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'All Channels', data: body});
if(body && body.length) {
if (body && body.length) {
return simplifyAllChannels(body).then(function(simplifiedChannels) {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Simplified Channels with Alias', data: simplifiedChannels});
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channels List Received'});
@ -107,18 +107,8 @@ exports.getChannels = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Get Channels Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: 'Fetching Channels Failed!',
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Channels', 'List Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};
@ -134,18 +124,8 @@ exports.getChannelStats = (req, res, next) => {
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'ChannelStats', msg: 'Get Channel Stats Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Channel Stats Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Channels', 'Get Channel Stats Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -157,30 +137,12 @@ exports.openChannel = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Params', data: options.form});
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Open Channel Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Open Channel Error', error: body.error});
res.status(500).json({
message: 'Open Channel Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Opened'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Opened'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Open Channel Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Open Channel Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Channels', 'Open Channel Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -196,18 +158,8 @@ exports.updateChannelRelayFee = (req, res, next) => {
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Update Relay Fee Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Update Relay Fee Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Channels', 'Update Relay Fee Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -228,18 +180,8 @@ exports.closeChannel = (req, res, next) => {
res.status(204).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Close Channel Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Close Channel Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Channels', 'Close Channel Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}

@ -81,18 +81,8 @@ exports.getFees = (req, res, next) => {
res.status(200).json(arrangeFees(body, Math.round((new Date().getTime()))));
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Get Fees Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Fetching Fees failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Fees', 'Get Fees Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};
@ -111,18 +101,8 @@ exports.getPayments = (req, res, next) => {
res.status(200).json(arrangePayments(body));
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Get Payments Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Fetching Payments failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Fees', 'Get Payments Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};

@ -13,42 +13,24 @@ exports.getInfo = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url', data: options.url});
if (common.read_dummy_data) {
common.getDummyData('GetInfo').then(function(data) {
data.currency_unit = 'BTC';
data.smaller_currency_unit = 'Sats';
data.lnImplementation = 'Eclair';
res.status(200).json(data);
});
} else {
if (!options.headers || !options.headers.authorization) {
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'Eclair Get info failed due to missing or wrong password!', error: {error: 'Missing or wrong password.'}});
res.status(502).json({
message: "Fetching Info Failed!",
error: "Missing Or Wrong Password"
});
const errMsg = 'Eclair Get info failed due to missing or wrong password!';
const err = common.handleError({ statusCode: 502, message: 'Missing or Wrong Password', error: errMsg }, 'GetInfo', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Get Info Response', data: body});
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
body.currency_unit = 'BTC';
body.smaller_currency_unit = 'Sats';
body.lnImplementation = 'Eclair';
logger.log({level: 'INFO', fileName: 'GetInfo', msg: 'Eclair Node Information Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'Get Info Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Fetching Info failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'GetInfo', 'Get Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
}

@ -30,6 +30,25 @@ getReceivedPaymentInfo = (invoice) => {
}
}
exports.getInvoice = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Getting Invoice..'});
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/getinvoice';
options.form = { paymentHash: req.params.paymentHash };
request.post(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoice Found', data: body});
let current_time = (Math.round(new Date(Date.now()).getTime()/1000)).toString();
body.amount = body.amount ? body.amount/1000 : 0;
body.expiresAt = body.expiresAt ? body.expiresAt : (body.timestamp + body.expiry);
body.status = body.status ? body.status : (+body.expiresAt < current_time ? "expired" : "unknown");
res.status(200).json(body);
})
.catch(errRes => {
const err = common.handleError(errRes, 'Invoices', 'Get Invoice Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.listInvoices = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Getting List Invoices..'});
options = common.getOptions();
@ -65,18 +84,8 @@ exports.listInvoices = (req, res, next) => {
res.status(200).json(invoices);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'List Invoices Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Fetching Invoices failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Invoices', 'List Invoices Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Empty List Invoice Received'});
@ -84,18 +93,8 @@ exports.listInvoices = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'List Invoices Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Fetching Invoices failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Invoices', 'List Invoices Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};
@ -112,17 +111,7 @@ exports.createInvoice = (req, res, next) => {
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Create Invoice Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Create Invoice Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Invoices', 'Create Invoice Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -14,17 +14,7 @@ exports.getNodes = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Network', msg: 'Node Lookup Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: 'Node Lookup Failed!',
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Network', 'Node Lookup Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -4,18 +4,8 @@ var logger = require('../shared/logger');
var options = {};
arrangeBalances = (body) => {
if(!body.confirmed) {
body.confirmed = 0;
body.btc_confirmed = 0;
} else {
body.btc_confirmed = common.convertToBTC(body.confirmed);
}
if(!body.unconfirmed) {
body.unconfirmed = 0;
body.btc_unconfirmed = 0;
} else {
body.btc_unconfirmed = common.convertToBTC(body.unconfirmed);
}
if (!body.confirmed) { body.confirmed = 0; }
if (!body.unconfirmed) { body.unconfirmed = 0; }
body.total = +body.confirmed + +body.unconfirmed;
body.btc_total = +body.btc_confirmed + +body.btc_unconfirmed;
return body;
@ -32,18 +22,8 @@ exports.getNewAddress = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Onchain', msg: 'Get New Address Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Getting New Address failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'OnChain', 'Get New Address Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -61,18 +41,8 @@ exports.getBalance = (req, res, next) => {
res.status(200).json(arrangeBalances(body));
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Onchain', msg: 'Fetch Balance Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Fetching balance failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'OnChain', 'Get Balance Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};
@ -95,18 +65,8 @@ exports.getTransactions = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Onchain', msg: 'Get Transactions Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Getting transactions failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'OnChain', 'Get Transactions Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -126,17 +86,7 @@ exports.sendFunds = (req, res, next) => {
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Onchain', msg: 'Send Funds Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Send funds failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'OnChain', 'Send Funds Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -26,18 +26,8 @@ exports.decodePayment = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Payment Decode Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Payment Decode Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Payments', 'Decode Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -53,18 +43,8 @@ exports.postPayment = (req, res, next) => {
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Send Payment Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Send Payment Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Payments', 'Send Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -97,18 +77,8 @@ exports.queryPaymentRoute = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Query Payment Route Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Query Payment Route Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Payments', 'Query Route Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -119,24 +89,13 @@ exports.getSentPaymentsInformation = (req, res, next) => {
let paymentsArr = req.body.payments.split(',');
return Promise.all(paymentsArr.map(payment => {return getSentInfoFromPaymentRequest(payment)}))
.then(function(values) {
console.warn(values);
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Payment Sent Informations', data: values});
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Sent Payment Information Received'});
res.status(200).json(values);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'Payment Sent Information Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Payment Sent Information Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Payments', 'Sent Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Empty Sent Payment Information Received'});

@ -45,18 +45,8 @@ exports.getPeers = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Get Peers Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: 'Fetching Peers Failed!',
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Peers', 'List Peers Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};
@ -70,22 +60,18 @@ exports.connectPeer = (req, res, next) => {
options.form = req.query;
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Connect Peer Params', data: options.form});
}
request.post(options, (error, response, body) => {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Add Peer Response', data: body});
if (body === 'already connected') {
return res.status(500).json({
message: "Connect Peer Failed!",
error: "Already connected"
});
if (typeof body === 'string' && body.includes('already connected')) {
const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body);
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else if (typeof body === 'string' && body.includes('connection failed')) {
return res.status(500).json({
message: "Connect Peer Failed!",
error: body.charAt(0).toUpperCase() + body.slice(1)
});
const err = common.handleError({ statusCode: 500, message: 'Connect Peer Error', error: body }, 'Peers', body);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = common.getSelLNServerUrl() + '/peers';
options.form = {};
request.post(options).then(function (body) {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peers Received', data: body});
if (body && body.length) {
let peersNodeIds = '';
@ -108,32 +94,12 @@ exports.connectPeer = (req, res, next) => {
res.status(201).json([]);
}
}).catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Connect Peer Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Connect Peer Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Peers', 'Connect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}).catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Connect Peer Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Connect Peer Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Peers', 'Connect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -146,24 +112,14 @@ exports.deletePeer = (req, res, next) => {
options.form = { nodeId: req.params.nodeId };
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Disconnect Peer Params', data: options.form});
}
request.post(options, (error, response, body) => {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Disconnect Peer Response', data: body});
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Disconnected: ' + req.params.nodeId});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected'});
res.status(204).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Disconnect Peer Error', error: err});
return res.status(err.statusCode ? err.statusCode : 500).json({
message: "Disconnect Peer Failed!",
error: err.error && err.error.error ? err.error.error : err.error ? err.error : "Unknown Server Error"
});
const err = common.handleError(errRes, 'Peers', 'Disconnect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -6,7 +6,7 @@ var options = {};
exports.getBalance = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Balance', msg: 'Getting Balance..'});
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/balance/' + req.params.source;
options.url = common.getSelLNServerUrl() + '/v1/balance/' + (req.params.source).toLowerCase();
options.qs = req.query;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Balance', msg: '[Request params, Request Query, Balance Received]', data: [req.params, req.query, body]});
@ -15,32 +15,17 @@ exports.getBalance = (req, res, next) => {
if (!body.total_balance) { body.total_balance = 0; }
if (!body.confirmed_balance) { body.confirmed_balance = 0; }
if (!body.unconfirmed_balance) { body.unconfirmed_balance = 0; }
body.btc_total_balance = common.convertToBTC(body.total_balance);
body.btc_confirmed_balance = common.convertToBTC(body.confirmed_balance);
body.btc_unconfirmed_balance = common.convertToBTC(body.unconfirmed_balance);
}
if (req.params.source === 'channels') {
if (!body.balance) { body.balance = 0; }
if (!body.pending_open_balance) { body.pending_open_balance = 0; }
body.btc_balance = common.convertToBTC(body.balance);
body.btc_pending_open_balance = common.convertToBTC(body.pending_open_balance);
}
logger.log({level: 'INFO', fileName: 'Balance', msg: 'Balance Received'});
res.status(200).json(body);
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Balance', msg: 'Fetch Balance Error', error: err});
return res.status(500).json({
message: "Fetching balance failed!",
error: err.error
});
const err = common.handleError(errRes, 'Balance', 'Get Balance Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -27,7 +27,7 @@ exports.getAllChannels = (req, res, next) => {
let total = 0;
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'All Channels Received', data: body});
if(body.channels) {
if (body.channels) {
return Promise.all(
body.channels.map(channel => {
local = (channel.local_balance) ? +channel.local_balance : 0;
@ -44,18 +44,8 @@ exports.getAllChannels = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Get All Channel Alias Error', error: err});
res.status(500).json({
message: 'Fetching Channels Alias Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Get All Channel Aliases Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
body.channels = [];
@ -64,18 +54,8 @@ exports.getAllChannels = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Get All Channels Error', error: err});
return res.status(500).json({
message: 'Fetching All Channels Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'List Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -87,21 +67,18 @@ exports.getPendingChannels = (req, res, next) => {
request(options).then(function (body) {
if (!body.total_limbo_balance) {
body.total_limbo_balance = 0;
body.btc_total_limbo_balance = 0;
} else {
body.btc_total_limbo_balance = common.convertToBTC(body.total_limbo_balance);
}
const promises = [];
if(body.pending_open_channels && body.pending_open_channels.length > 0) {
if (body.pending_open_channels && body.pending_open_channels.length > 0) {
body.pending_open_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
}
if(body.pending_closing_channels && body.pending_closing_channels.length > 0) {
if (body.pending_closing_channels && body.pending_closing_channels.length > 0) {
body.pending_closing_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
}
if(body.pending_force_closing_channels && body.pending_force_closing_channels.length > 0) {
if (body.pending_force_closing_channels && body.pending_force_closing_channels.length > 0) {
body.pending_force_closing_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
}
if(body.waiting_close_channels && body.waiting_close_channels.length > 0) {
if (body.waiting_close_channels && body.waiting_close_channels.length > 0) {
body.waiting_close_channels.map(channel => { return promises.push(getAliasForChannel(channel.channel))});
}
return Promise.all(promises).then(function(values) {
@ -110,33 +87,13 @@ exports.getPendingChannels = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Get Pending Channel Alias Error', error: err});
res.status(500).json({
message: 'Fetching Pending Channels Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Get Pending Channel Aliases Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Get Pending Channel Error', error: err});
return res.status(500).json({
message: 'Fetching Pending Channels Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'List Pending Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -160,18 +117,8 @@ exports.getClosedChannels = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Get All Channel Alias Error', error: err});
res.status(500).json({
message: 'Fetching Channels Alias Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Get Closed Channel Aliases Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
body.channels = [];
@ -179,18 +126,8 @@ exports.getClosedChannels = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Get Closed Channel Error', error: err});
return res.status(500).json({
message: 'Fetching Closed Channels Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'List Closed Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -212,30 +149,12 @@ exports.postChannel = (req, res, next) => {
options.form = JSON.stringify(options.form);
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Channel Open Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Open New Channel Error', error: body.error});
res.status(500).json({
message: 'Open Channel Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channels Opened'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channels Opened'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Open New Channel Error', error: err});
return res.status(500).json({
message: 'Open Channel Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Open Channel Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -244,7 +163,7 @@ exports.postTransactions = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/channels/transactions';
options.form = { payment_request: req.body.paymentReq };
if(req.body.paymentAmount) {
if (req.body.paymentAmount) {
options.form.amt = req.body.paymentAmount;
}
if (req.body.feeLimit) { options.form.fee_limit = req.body.feeLimit; }
@ -255,82 +174,42 @@ exports.postTransactions = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Send Payment Options', data: options.form});
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Send Payment Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Send Payment Error', error: body.error});
res.status(500).json({
message: 'Send Payment Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else if (body.payment_error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Send Payment Error: ' + JSON.stringify(body.payment_error)});
res.status(500).json({
message: 'Send Payment Failed!',
error: (!body) ? 'Error From Server!' : body.payment_error
});
if (body.payment_error) {
const err = common.handleError(body.payment_error, 'Channels', 'Send Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Payment Sent'});
res.status(201).json(body);
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Send Payment Error', error: err});
return res.status(500).json({
message: 'Send Payment Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Send Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.closeChannel = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..'});
req.setTimeout(60000 * 10); // timeout 10 mins
options = common.getOptions();
let channelpoint = req.params.channelPoint.replace(':', '/');
options.url = common.getSelLNServerUrl() + '/v1/channels/' + channelpoint + '?force=' + req.query.force;
if(req.query.target_conf) { options.url = options.url + '&target_conf=' + req.query.target_conf; }
if(req.query.sat_per_byte) { options.url = options.url + '&sat_per_byte=' + req.query.sat_per_byte; }
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel Options URL', data: options.url});
request.delete(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Close Channel Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Close Channel Error', error: body.error});
res.status(500).json({
message: 'Close Channel Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Closed'});
res.status(204).json({message: 'Channel Closed!'});
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Close Channel Error', error: err});
return res.status(500).json({
message: 'Close Channel Failed!',
error: err.error
});
});
try {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Closing Channel..'});
options = common.getOptions();
let channelpoint = req.params.channelPoint.replace(':', '/');
options.url = common.getSelLNServerUrl() + '/v1/channels/' + channelpoint + '?force=' + req.query.force;
if (req.query.target_conf) { options.url = options.url + '&target_conf=' + req.query.target_conf; }
if (req.query.sat_per_byte) { options.url = options.url + '&sat_per_byte=' + req.query.sat_per_byte; }
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Closing Channel Options URL', data: options.url});
request.delete(options);
res.status(202).json({message: 'Close channel request has been submitted.'});
} catch (error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Close Channel Error', error: error.message});
return res.status(500).json({message: 'Close Channel Error', error: error.message});
}
}
exports.postChanPolicy = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Updating Channel Policy..'});
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/chanpolicy';
if(req.body.chanPoint === 'all') {
if (req.body.chanPoint === 'all') {
options.form = JSON.stringify({
global: true,
base_fee_msat: req.body.baseFeeMsat,
@ -351,29 +230,11 @@ exports.postChanPolicy = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.form});
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Update Channel Policy Error', error: body.error});
res.status(500).json({
message: 'Update Channel Failed!',
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Policy Updated'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Channels', msg: 'Channel Policy Updated'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Channels', msg: 'Update Channel Policy Error', error: err});
return res.status(500).json({
message: 'Update Channel Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Channels', 'Update Channel Policy Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -9,8 +9,10 @@ function getFilesList(callback) {
let all_restore_exists = false;
let response = {all_restore_exists: false, files: []};
fs.readdir(common.selectedNode.channel_backup_path + common.path_separator + 'restore', function (err, files) {
if (err && err.code !== 'ENOENT' && err.errno !== -4058) { response = { message: 'Channels Restore List Failed!', error: err } }
if( files && files.length > 0) {
if (err && err.code !== 'ENOENT' && err.errno !== -4058) {
response = { message: 'Channels Restore List Failed!', error: err, statusCode: 500 };
}
if (files && files.length > 0) {
files.forEach(file => {
if (!file.includes('.restored')) {
if (file.toLowerCase() === 'channel-all.bak' || file.toLowerCase() === 'backup-channel-all.bak') {
@ -49,15 +51,8 @@ exports.getBackup = (req, res, next) => {
createStream.end();
}
catch (errRes) {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'ChannelsBackup', msg: 'Channels Backup Error', error: err});
return res.status(500).json({ message: 'Channels Backup Failed!', error: err });
const err = common.handleError(errRes, 'ChannelsBackup', 'Backup Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
}
}
@ -65,15 +60,8 @@ exports.getBackup = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'ChannelsBackup', msg: 'Channel Backup', data: body});
fs.writeFile(channel_backup_file, JSON.stringify(body), function(errRes) {
if (errRes) {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'ChannelsBackup', msg: 'Channels Backup Error', error: err});
return res.status(500).json({ message: 'Channels Backup Failed!', error: err.error });
const err = common.handleError(errRes, 'ChannelsBackup', 'Backup Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
logger.log({level: 'INFO', fileName: 'ChannelBackup', msg: 'Channel Backup Finished'});
res.status(200).json({ message: message });
@ -81,18 +69,8 @@ exports.getBackup = (req, res, next) => {
});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'ChannelsBackup', msg: 'Channel Backup Error', error: err});
return res.status(500).json({
message: 'Channels Backup Failed!',
error: err.error
});
const err = common.handleError(errRes, 'ChannelsBackup', 'Backup Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -114,13 +92,15 @@ exports.postBackupVerify = (req, res, next) => {
delete verify_backup.single_chan_backups;
options.form = JSON.stringify(verify_backup);
} else {
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Backup Verify Error. Channel backup to verify does not Exist!', error: {error: 'Channel backup to verify does not Exist.'}});
res.status(404).json({ message: 'Channels backup to verify does not Exist!' });
const errMsg = 'Channel backup to verify does not Exist.';
const err = common.handleError({ statusCode: 404, message: 'Verify Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
} else {
verify_backup = '';
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Backup Verify Error. Channel backup to verify does not Exist!', error: {error: 'Channel backup to verify does not Exist.'}});
res.status(404).json({ message: 'Channels backup to verify does not Exist!' });
const errMsg = 'Channel backup to verify does not Exist.';
const err = common.handleError({ statusCode: 404, message: 'Verify Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
} else {
message = 'Channel Verify Successful.';
@ -131,8 +111,9 @@ exports.postBackupVerify = (req, res, next) => {
options.form = JSON.stringify({ single_chan_backups: { chan_backups: [JSON.parse(verify_backup)] } });
} else {
verify_backup = '';
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Backup Verify Error. Channel backup to verify does not Exist!', error: {error: 'Channel backup to verify does not Exist.'}});
res.status(404).json({ message: 'Channel backup to verify does not Exist!' });
const errMsg = 'Channel backup to verify does not Exist.';
const err = common.handleError({ statusCode: 404, message: 'Verify Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
}
if (verify_backup !== '') {
@ -142,18 +123,8 @@ exports.postBackupVerify = (req, res, next) => {
res.status(201).json({ message: message });
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Backup Verify Error', error: err});
return res.status(404).json({
message: 'Channel backup to Verify failed!',
error: err.error
});
const err = common.handleError(errRes, 'ChannelsBackup', 'Verify Channels Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};
@ -176,8 +147,9 @@ exports.postRestore = (req, res, next) => {
restore_backup = JSON.parse(restore_backup);
options.form = JSON.stringify({multi_chan_backup: restore_backup.multi_chan_backup.multi_chan_backup});
} else {
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Restore Error.Channels backup to restore does not Exist!', error: {error: 'Channel backup to restore does not Exist.'}});
res.status(404).json({ message: 'Channels backup to restore does not Exist!' });
const errMsg = 'Channel backup to restore does not Exist.';
const err = common.handleError({ statusCode: 404, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
} else if (downloaded_exists) {
restore_backup = fs.readFileSync(channel_restore_file + 'backup-channel-all.bak', 'utf-8');
@ -185,13 +157,15 @@ exports.postRestore = (req, res, next) => {
restore_backup = JSON.parse(restore_backup);
options.form = JSON.stringify({multi_chan_backup: restore_backup.multi_chan_backup.multi_chan_backup});
} else {
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Restore Error. Channels backup to restore does not Exist!', error: {error: 'Channel backup to restore does not Exist.'}});
res.status(404).json({ message: 'Channels backup to restore does not Exist!' });
const errMsg = 'Channel backup to restore does not Exist.';
const err = common.handleError({ statusCode: 404, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
} else {
restore_backup = '';
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Restore Error. Channels backup to restore does not Exist!', error: {error: 'Channel backup to restore does not Exist.'}});
res.status(404).json({ message: 'Channels backup to restore does not Exist!' });
const errMsg = 'Channel backup to restore does not Exist.';
const err = common.handleError({ statusCode: 404, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
} else {
message = 'Channel Restore Successful.';
@ -202,18 +176,21 @@ exports.postRestore = (req, res, next) => {
options.form = JSON.stringify({ chan_backups: { chan_backups: [JSON.parse(restore_backup)] } });
} else {
restore_backup = '';
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Restore Error. Channels backup to restore does not Exist!', error: {error: 'Channel backup to restore does not Exist.'}});
res.status(404).json({ message: 'Channel backup to restore does not Exist!' });
const errMsg = 'Channel backup to restore does not Exist.';
const err = common.handleError({ statusCode: 404, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
}
if (restore_backup !== '') {
request.post(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'ChannelBackup', msg: 'Channel Backup Restore', data: body});
if(req.params.channelPoint === 'ALL') { channel_restore_file = channel_restore_file + 'channel-all.bak'; }
fs.rename(channel_restore_file, channel_restore_file + '.restored', () => {
getFilesList(getFilesListRes => {
if (getFilesListRes.error) {
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Restore Error', error: getFilesListRes.error});
return res.status(500).json({ message: 'Channel restore failed!', list: getFilesListRes });
const errMsg = getFilesListRes.error;
const err = common.handleError({ statusCode: 500, message: 'Restore Channel Error', error: errMsg }, 'ChannelBackup', errMsg);
return res.status(err.statusCode).json({message: err.error, list: getFilesListRes});
} else {
logger.log({level: 'INFO', fileName: 'ChannelBackup', msg: 'Channel Restored'});
return res.status(201).json({ message: message, list: getFilesListRes });
@ -222,18 +199,8 @@ exports.postRestore = (req, res, next) => {
});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'ChannelBackup', msg: 'Channel Restore Error', error: err});
return res.status(404).json({
message: 'Channel restore failed!',
error: err.error.error
});
const err = common.handleError(errRes, 'ChannelsBackup', 'Restore Channel Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};
@ -241,7 +208,7 @@ exports.postRestore = (req, res, next) => {
exports.getRestoreList = (req, res, next) => {
getFilesList(getFilesListRes => {
if (getFilesListRes.error) {
return res.status(500).json(getFilesListRes);
return res.status(getFilesListRes.statusCode).json(getFilesListRes);
} else {
return res.status(200).json(getFilesListRes);
}

@ -10,57 +10,36 @@ exports.getFees = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/fees';
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Fee Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Get Fee Error', error: body.error});
res.status(500).json({
message: "Fetching fee failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
let today = new Date(Date.now());
let start_date = new Date(today.getFullYear(), today.getMonth(), 1, 0, 0, 0);
let current_time = (Math.round(today.getTime()/1000)).toString();
let month_start_time = (Math.round(start_date.getTime()/1000)).toString();
let week_start_time = current_time - 604800;
let day_start_time = current_time - 86400;
return swtch.getAllForwardingEvents(month_start_time, current_time, 0, (history) => {
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Forwarding History Received', data: history});
daily_sum = history.forwarding_events.reduce((acc, curr) => (curr.timestamp >= day_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc, [0, 0]);
weekly_sum = history.forwarding_events.reduce((acc, curr) => (curr.timestamp >= week_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc, [0, 0]);
monthly_sum = history.forwarding_events.reduce((acc, curr) => [(acc[0] + 1), (acc[1] + +curr.fee_msat)], [0, 0]);
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Daily Sum (Transactions, Fee)', data: daily_sum});
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Weekly Sum (Transactions, Fee)', data: weekly_sum});
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Monthly Sum (Transactions, Fee)', data: monthly_sum});
body.daily_tx_count = daily_sum[0];
body.weekly_tx_count = weekly_sum[0];
body.monthly_tx_count = monthly_sum[0];
body.day_fee_sum = (daily_sum[1] / 1000).toFixed(2);
body.week_fee_sum = (weekly_sum[1] / 1000).toFixed(2);
body.month_fee_sum = (monthly_sum[1] / 1000).toFixed(2);
body.btc_day_fee_sum = common.convertToBTC(body.day_fee_sum);
body.btc_week_fee_sum = common.convertToBTC(body.week_fee_sum);
body.btc_month_fee_sum = common.convertToBTC(body.month_fee_sum);
body.forwarding_events_history = history;
if (history.error) {
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Fetch Forwarding Events Error', error: history.error});
}
logger.log({level: 'INFO', fileName: 'Fees', msg: 'Fees Received'});
res.status(200).json(body);
})
}
let today = new Date(Date.now());
let start_date = new Date(today.getFullYear(), today.getMonth(), 1, 0, 0, 0);
let current_time = (Math.round(today.getTime()/1000)).toString();
let month_start_time = (Math.round(start_date.getTime()/1000)).toString();
let week_start_time = current_time - 604800;
let day_start_time = current_time - 86400;
return swtch.getAllForwardingEvents(month_start_time, current_time, 0, (history) => {
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Forwarding History Received', data: history});
daily_sum = history.forwarding_events.reduce((acc, curr) => (curr.timestamp >= day_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc, [0, 0]);
weekly_sum = history.forwarding_events.reduce((acc, curr) => (curr.timestamp >= week_start_time) ? [(acc[0] + 1), (acc[1] + +curr.fee_msat)] : acc, [0, 0]);
monthly_sum = history.forwarding_events.reduce((acc, curr) => [(acc[0] + 1), (acc[1] + +curr.fee_msat)], [0, 0]);
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Daily Sum (Transactions, Fee)', data: daily_sum});
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Weekly Sum (Transactions, Fee)', data: weekly_sum});
logger.log({level: 'DEBUG', fileName: 'Fees', msg: 'Monthly Sum (Transactions, Fee)', data: monthly_sum});
body.daily_tx_count = daily_sum[0];
body.weekly_tx_count = weekly_sum[0];
body.monthly_tx_count = monthly_sum[0];
body.day_fee_sum = (daily_sum[1] / 1000).toFixed(2);
body.week_fee_sum = (weekly_sum[1] / 1000).toFixed(2);
body.month_fee_sum = (monthly_sum[1] / 1000).toFixed(2);
body.forwarding_events_history = history;
if (history.error) {
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Fetch Forwarding Events Error', error: history.error});
}
logger.log({level: 'INFO', fileName: 'Fees', msg: 'Fees Received'});
res.status(200).json(body);
})
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Fees', msg: 'Fetch Forwarding Events Error', error: err});
return res.status(500).json({
message: "Fetching fee failed!",
error: err.error
});
const err = common.handleError(errRes, 'Fees', 'Get Forwarding Events Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -12,41 +12,27 @@ exports.getInfo = (req, res, next) => {
logger.log({level: 'DEBUG', fileName:'GetInfo', msg: 'Selected Node', data: common.selectedNode.ln_node});
logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Calling Info from LND server url', data: options.url});
if (!options.headers || !options.headers['Grpc-Metadata-macaroon']) {
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'LND Get info failed due to bad or missing macaroon!', error: {error: 'Bad or missing macaroon.'}});
res.status(502).json({
message: "Fetching Info Failed!",
error: "Bad Macaroon"
});
const errMsg = 'LND Get info failed due to bad or missing macaroon!';
const err = common.handleError({ statusCode: 502, message: 'Bad or Missing Macaroon', error: errMsg }, 'GetInfo', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
common.nodes.map(node => { if (node.lnImplementation === 'LND') { connect.getAllNodeAllChannelBackup(node); }});
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Node Information', data: body});
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'Get Info Error', error: body.error});
res.status(500).json({
message: "Fetching Info Failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
if (!body || search_idx > -1 || body.error) {
if (body && !body.error) { body.error = 'Error From Server!'; }
const err = common.handleError(body, 'GetInfo', 'Get Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
logger.log({level: 'INFO', fileName: 'GetInfo', msg: 'LND Node Information Received'});
res.status(200).json(body);
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'GetInfo', msg: 'Get Info Error', error: err});
return res.status(500).json({
message: "Fetching Info Failed!",
error: err.error
});
const err = common.handleError(errRes, 'GetInfo', 'Get Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
};

@ -17,33 +17,13 @@ exports.getDescribeGraph = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/graph';
request.get(options).then((body) => {
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Describe Graph Received', data: body_str});
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Describe Graph Error', error: body.error});
res.status(500).json({
message: "Fetching Describe Graph Failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received'});
res.status(200).json(body);
}
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Describe Graph Received', data: body});
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Network Graph Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Describe Graph Error', error: err});
return res.status(500).json({
message: "Fetching Describe Graph Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Graph', 'Describe Graph Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -52,38 +32,13 @@ exports.getGraphInfo = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/graph/info';
request.get(options).then((body) => {
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Network Info Received', data: body_str});
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Network Info Error', error: body.error});
res.status(500).json({
message: "Fetching network Info failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
body.btc_total_network_capacity = (!body.total_network_capacity) ? 0 : common.convertToBTC(body.total_network_capacity);
body.btc_avg_channel_size = (!body.avg_channel_size) ? 0 : common.convertToBTC(body.avg_channel_size);
body.btc_min_channel_size = (!body.min_channel_size) ? 0 : common.convertToBTC(body.min_channel_size);
body.btc_max_channel_size = (!body.max_channel_size) ? 0 : common.convertToBTC(body.max_channel_size);
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Network Information After Rounding and Conversion', data: body_str});
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received'});
res.status(200).json(body);
}
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Network Information After Rounding and Conversion', data: body});
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Graph Information Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Network Info Error', error: err});
return res.status(500).json({
message: "Fetching network Info failed!",
error: err.error
});
const err = common.handleError(errRes, 'Graph', 'Graph Information Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -93,29 +48,12 @@ exports.getGraphNode = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/graph/node/' + req.params.pubKey;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Node Info Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Node Info Error', error: body.error});
res.status(500).json({
message: "Fetching node Info failed!",
error: (!body) ? 'Error From Server!' : body.error
});
}
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Graph Node Information Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Node Info Error', error: err});
return res.status(500).json({
message: "Fetching node Info failed!",
error: err.error
});
const err = common.handleError(errRes, 'Graph', 'Get Node Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -125,50 +63,26 @@ exports.getGraphEdge = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/graph/edge/' + req.params.chanid;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Edge Info Error', error: body.error});
res.status(500).json({
message: "Fetching Edge Info Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
}
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Graph Edge Information Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Edge Info Error', error: err});
return res.status(500).json({
message: "Fetching Edge Info Failed!",
error: err.error
});
});
const err = common.handleError(errRes, 'Graph', 'Get Edge Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.getQueryRoutes = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Getting Graph Routes..'});
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/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;
}
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes URL', data: options.url});
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Query Routes Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Query Routes Error', error: body.error});
res.status(500).json({
message: "Fetching Query Routes Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
}
if(body.routes && body.routes.length && body.routes.length > 0 && body.routes[0].hops && body.routes[0].hops.length && body.routes[0].hops.length > 0) {
if (body.routes && body.routes.length && body.routes.length > 0 && body.routes[0].hops && body.routes[0].hops.length && body.routes[0].hops.length > 0) {
return Promise.all(body.routes[0].hops.map(hop => getAliasFromPubkey(hop.pub_key)))
.then(function(values) {
body.routes[0].hops.map((hop, i) => {
@ -181,18 +95,8 @@ exports.getQueryRoutes = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Query Routes Error', error: err});
return res.status(500).json({
message: "Fetching Query Routes Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Graph', 'Get Query Routes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
logger.log({level: 'INFO', fileName: 'Graph', msg: 'Graph Routes Received'});
@ -200,18 +104,8 @@ exports.getQueryRoutes = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Query Routes Error', error: err});
return res.status(500).json({
message: "Fetching Query Routes Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Graph', 'Get Query Routes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -221,21 +115,14 @@ exports.getRemoteFeePolicy = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/graph/edge/' + req.params.chanid;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Graph', msg: 'Edge Info Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Edge Info Error', error: body.error});
res.status(500).json({
message: "Fetching Edge Info Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
}
remoteNodeFee = {};
if(body.node1_pub === req.params.localPubkey){
if (body.node1_pub === req.params.localPubkey){
remoteNodeFee = {
time_lock_delta: body.node2_policy.time_lock_delta,
fee_base_msat: body.node2_policy.fee_base_msat,
fee_rate_milli_msat: body.node2_policy.fee_rate_milli_msat
};
} else if(body.node2_pub === req.params.localPubkey) {
} else if (body.node2_pub === req.params.localPubkey) {
remoteNodeFee = {
time_lock_delta: body.node1_policy.time_lock_delta,
fee_base_msat: body.node1_policy.fee_base_msat,
@ -246,18 +133,8 @@ exports.getRemoteFeePolicy = (req, res, next) => {
res.status(200).json(remoteNodeFee);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Fetch Edge Info Error', error: err});
return res.status(500).json({
message: "Fetching Edge Info Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Graph', 'Remote Fee Policy Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -271,18 +148,8 @@ exports.getAliasesForPubkeys = (req, res, next) => {
res.status(200).json(values);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Graph', msg: 'Get Aliases for Pubkeys Error', error: err});
return res.status(500).json({
message: "Getting Aliases for Pubkeys Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Graph', 'Get Aliases for Pubkeys Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
res.status(200).json([]);

@ -9,29 +9,15 @@ exports.getInvoice = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/invoice/' + req.params.rHashStr;
request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoice Info Received', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Invoice Info Error', error: body.error});
res.status(500).json({
message: "Fetching Invoice Info Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
}
logger.log({level: 'INFO', fileName: 'Invoice', msg: 'Invoice Information Received'});
body.r_preimage = body.r_preimage ? Buffer.from(body.r_preimage, 'base64').toString('hex') : '';
body.r_hash = body.r_hash ? Buffer.from(body.r_hash, 'base64').toString('hex') : '';
body.description_hash = body.description_hash ? Buffer.from(body.description_hash, 'base64').toString('hex') : null;
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Fetch Invoice Info Error', error: err});
return res.status(500).json({
message: "Fetching Invoice Info Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Invoices', 'Get Invoice Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -41,44 +27,22 @@ exports.listInvoices = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/invoices?num_max_invoices=' + req.query.num_max_invoices + '&index_offset=' + req.query.index_offset +
'&reversed=' + req.query.reversed;
request(options).then((body) => {
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body_str});
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'List Invoices Error', error: body.error});
res.status(500).json({
message: "Fetching Invoice Info failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body});
if (body.invoices && body.invoices.length > 0) {
body.invoices.forEach(invoice => {
invoice.r_preimage = invoice.r_preimage ? Buffer.from(invoice.r_preimage, 'base64').toString('hex') : '';
invoice.r_hash = invoice.r_hash ? Buffer.from(invoice.r_hash, 'base64').toString('hex') : '';
invoice.description_hash = invoice.description_hash ? Buffer.from(invoice.description_hash, 'base64').toString('hex') : null;
});
} else {
if (body.invoices && body.invoices.length > 0) {
body.invoices.forEach(invoice => {
invoice.r_preimage = invoice.r_preimage ? Buffer.from(invoice.r_preimage, 'base64').toString('hex') : '';
invoice.r_hash = invoice.r_hash ? Buffer.from(invoice.r_hash, 'base64').toString('hex') : '';
invoice.description_hash = invoice.description_hash ? Buffer.from(invoice.description_hash, 'base64').toString('hex') : null;
invoice.btc_value = (!invoice.value) ? 0 : common.convertToBTC(invoice.value);
invoice.btc_amt_paid_sat = (!invoice.amt_paid_sat) ? 0 : common.convertToBTC(invoice.amt_paid_sat);
});
body.invoices = common.sortDescByKey(body.invoices, 'creation_date');
}
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body});
logger.log({level: 'INFO', fileName: 'Invoice', msg: 'Invoices List Received'});
res.status(200).json(body);
body.invoices = common.sortDescByKey(body.invoices, 'creation_date');
}
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body});
logger.log({level: 'INFO', fileName: 'Invoice', msg: 'Invoices List Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'List Invoice Error', error: err});
return res.status(500).json({
message: "Fetching Invoices failed!",
error: err.error
});
const err = common.handleError(errRes, 'Invoices', 'List Invoices Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -99,29 +63,11 @@ exports.addInvoice = (req, res, next) => {
options.form = JSON.stringify(options.form);
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Invoice', msg: 'Add Invoice Responce', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Add Invoice Error', error: body.error});
res.status(500).json({
message: "Add Invoice Failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Invoice', msg: 'Invoice Added'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Invoice', msg: 'Add Invoice Error', error: err});
return res.status(500).json({
message: "Add Invoice Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Invoices', 'Add Invoice Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -10,32 +10,14 @@ exports.signMessage = (req, res, next) => {
options.form = JSON.stringify({
msg: Buffer.from(req.body.message).toString('base64')
});
request.post(options, (error, response, body) => {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Messages', msg: 'Message Signed', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Sign Message Error', error: body.error});
res.status(500).json({
message: "Sign message failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Signed'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Signed'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Sign Message Error', error: err});
return res.status(500).json({
message: 'Sign Message Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Messages', 'Sign Message Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -47,31 +29,13 @@ exports.verifyMessage = (req, res, next) => {
msg: Buffer.from(req.body.message).toString('base64'),
signature: req.body.signature
});
request.post(options, (error, response, body) => {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Messages', msg: 'Message Verified', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Verify Message Error', error: body.error});
res.status(500).json({
message: "Verify message failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Verified'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Message', msg: 'Message Verified'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Messages', msg: 'Message Verification Error', error: err});
return res.status(500).json({
message: 'Verify Message Failed!',
error: err.error
});
const err = common.handleError(errRes, 'Messages', 'Verify Message Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -8,32 +8,12 @@ exports.getNewAddress = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/newaddress?type=' + req.query.type;
request(options).then((body) => {
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
logger.log({level: 'DEBUG', fileName: 'NewAddress', msg: 'New Address Received', data: body_str});
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'NewAddress', msg: 'New Address Error', error: body.error});
res.status(500).json({
message: "Fetching new address failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'NewAddress', msg: 'New Address Received'});
res.status(200).json(body);
}
logger.log({level: 'DEBUG', fileName: 'NewAddress', msg: 'New Address Received', data: body});
logger.log({level: 'INFO', fileName: 'NewAddress', msg: 'New Address Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'NewAddress', msg: 'New Address Error', error: err});
return res.status(500).json({
message: "Fetching new address failed!",
error: err.error
});
const err = common.handleError(errRes, 'NewAddress', 'New Address Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -17,34 +17,13 @@ exports.decodePayment = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/payreq/' + req.params.payRequest;
request(options).then((body) => {
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
logger.log({level: 'DEBUG', fileName: 'PayReq', msg: 'Payment Decode Received', data: body_str});
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'PayReq', msg: 'Payment Decode Error 1', error: body.error});
res.status(500).json({
message: "Payment Request Decode Failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
body.btc_num_satoshis = (!body.num_satoshis) ? 0 : common.convertToBTC(body.num_satoshis);
logger.log({level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded'});
res.status(200).json(body);
}
logger.log({level: 'DEBUG', fileName: 'PayReq', msg: 'Payment Decode Received', data: body});
logger.log({level: 'INFO', fileName: 'PayRequest', msg: 'Payment Decoded'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'PayReq', msg: 'Payment Decode Error 2', error: err.error});
return res.status(500).json({
message: "Payment Request Decode Failed!",
error: err.error
});
const err = common.handleError(errRes, 'PayRequest', 'Decode Payment Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -60,18 +39,8 @@ exports.decodePayments = (req, res, next) => {
res.status(200).json(values);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'PayReq', msg: 'Decode Payments Error', error: err});
return res.status(500).json({
message: "Decode Payments Failed!",
error: err.error
});
const err = common.handleError(errRes, 'PayRequest', 'Decode Payments Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
logger.log({level: 'INFO', fileName: 'PayRequest', msg: 'Empty Payment List Decoded'});

@ -8,37 +8,17 @@ exports.getPayments = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/payments?max_payments=' + req.query.max_payments + '&index_offset=' + req.query.index_offset + '&reversed=' + req.query.reversed;
request(options).then((body) => {
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body_str});
if(!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'List Payments Error', error: body.error});
res.status(500).json({
message: "Payments List Failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
if (body.payments && body.payments.length > 0) {
body.payments = common.sortDescByKey(body.payments, 'creation_date');
}
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Payments After Sort', data: body});
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Payments List Received'});
res.status(200).json(body);
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Payment List Received', data: body});
if (body.payments && body.payments.length > 0) {
body.payments = common.sortDescByKey(body.payments, 'creation_date');
}
logger.log({level: 'DEBUG', fileName: 'Payments', msg: 'Payments After Sort', data: body});
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Payments List Received'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'List Payments Error', error: err});
return res.status(500).json({
message: "Payments List Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Payments', 'List Payments Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -54,17 +34,7 @@ exports.getAllLightningTransactions = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Payments', msg: 'Payments & Invoices Received'});
res.status(200).json({paymentsAll: values[0], invoicesAll: values[1]});
}).catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Payments', msg: 'All Lightning Transactions Error', error: err});
return res.status(500).json({
message: "All Lightning Transactions Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Payments', 'All Lightning Transactions Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -33,18 +33,8 @@ exports.getPeers = (req, res, next) => {
res.status(200).json(body.peers);
})
}).catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'List Peers Error', error: err});
return res.status(500).json({
message: "Peers List Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Peers', 'List Peers Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -53,48 +43,35 @@ exports.postPeer = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/peers';
options.form = JSON.stringify({
addr: { host: req.body.host, pubkey: req.body.pubkey },
// addr: { host: req.body.host, pubkey: req.body.pubkey },
perm: req.body.perm
});
request.post(options, (error, response, body) => {
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Added', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Add Peer Error', error: body.error});
res.status(500).json({
message: "Adding peer failed!",
error: (!body) ? 'Error From Server!' : body.error
options.url = common.getSelLNServerUrl() + '/v1/peers';
request(options).then((body) => {
let peers = (!body.peers) ? [] : body.peers;
return Promise.all(peers.map(peer => getAliasForPeers(peer))).then(function(values) {
if (body.peers) {
body.peers = common.sortDescByStrKey(body.peers, 'alias');
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer with Alias', data: body});
body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey);
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer with Newest On Top', data: body});
}
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Added Successfully'});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Connected'});
res.status(201).json(body.peers);
}).catch(errRes => {
const err = common.handleError(errRes, 'Peers', 'Connect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
} else {
options.url = common.getSelLNServerUrl() + '/v1/peers';
request(options).then(function (body) {
let peers = (!body.peers) ? [] : body.peers;
return Promise.all(peers.map(peer => getAliasForPeers(peer))).then(function(values) {
if (body.peers) {
body.peers = common.sortDescByStrKey(body.peers, 'alias');
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer with Alias', data: body});
body.peers = common.newestOnTop(body.peers, 'pub_key', req.body.pubkey);
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer with Newest On Top', data: body});
}
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Added Successfully'});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Connected'});
res.status(201).json(body.peers);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Peer', msg: 'Add Peer Error', error: err});
return res.status(500).json({
message: "Peer Add Failed!",
error: err.error
});
});
})
}
}).catch(errRes => {
const err = common.handleError(errRes, 'Peers', 'Connect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}).catch(errRes => {
const err = common.handleError(errRes, 'Peers', 'Connect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -104,30 +81,12 @@ exports.deletePeer = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/peers/' + req.params.peerPubKey;
request.delete(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Detach Peer Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Detach Peer Error', error: body.error});
res.status(500).json({
message: "Detach peer failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Detached', data: req.params.peerPubKey});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected'});
res.status(204).json({});
}
logger.log({level: 'DEBUG', fileName: 'Peers', msg: 'Peer Detached', data: req.params.peerPubKey});
logger.log({level: 'INFO', fileName: 'Peers', msg: 'Peer Disconnected'});
res.status(204).json({});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Peers', msg: 'Detach Peer Error', error: err});
return res.status(500).json({
message: "Detach Peer Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Peers', 'Disconnect Peer Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -9,7 +9,7 @@ var responseData = { forwarding_events: [], last_offset_index: 0 };
exports.forwardingHistory = (req, res, next) => {
return this.getAllForwardingEvents(req.body.start_time, req.body.end_time, 0, (eventsResponse) => {
if (eventsResponse.error) {
res.status(500).json(eventsResponse);
res.status(error.statusCode).json(eventsResponse);
} else {
res.status(201).json(eventsResponse);
}
@ -45,17 +45,7 @@ exports.getAllForwardingEvents = (start, end, offset, callback) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Switch', msg: 'Get All Forwarding Events Error', error: err});
return callback({
message: "Forwarding Events Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Switch', 'Get All Forwarding Events Error');
return callback({message: err.message, error: err.error, statusCode: err.statusCode});
});
}

@ -8,36 +8,16 @@ exports.getTransactions = (req, res, next) => {
options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/transactions';
request(options).then((body) => {
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
logger.log({level: 'DEBUG', fileName: 'Transactions', msg: 'Transaction Received', data: body_str});
if (!body || search_idx > -1 || body.error) {
logger.log({level: 'ERROR', fileName: 'Transactions', msg: 'List Transactions Error', error: body.error});
res.status(500).json({
message: "Fetching Transactions Failed!",
error: (!body || search_idx > -1) ? 'Error From Server!' : body.error
});
} else {
if (body.transactions && body.transactions.length > 0) {
body.transactions = common.sortDescByKey(body.transactions, 'time_stamp');
}
logger.log({level: 'INFO', fileName: 'Transactions', msg: 'Transactions Received'});
res.status(200).json(body.transactions);
logger.log({level: 'DEBUG', fileName: 'Transactions', msg: 'Transaction Received', data: body});
if (body.transactions && body.transactions.length > 0) {
body.transactions = common.sortDescByKey(body.transactions, 'time_stamp');
}
logger.log({level: 'INFO', fileName: 'Transactions', msg: 'Transactions Received'});
res.status(200).json(body.transactions);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Transactions', msg: 'List Transactions Error', error: err});
return res.status(500).json({
message: "Fetching Transactions Failed!",
error: err.error
});
const err = common.handleError(errRes, 'Transactions', 'List Transactions Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
@ -57,29 +37,11 @@ exports.postTransactions = (req, res, next) => {
options.form = JSON.stringify(options.form);
request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Transactions', msg: 'Transaction Post Response', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Transactions', msg: 'Post Transaction Error', error: body.error});
res.status(500).json({
message: "Transactions post failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Transactions', msg: 'Transaction Sent'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Transactions', msg: 'Transaction Sent'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Transactions', msg: 'Transaction Post Error', error: err});
return res.status(500).json({
message: "Transactions post failed!",
error: err.error
});
const err = common.handleError(errRes, 'Transactions', 'Send Transaction Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -13,30 +13,12 @@ exports.genSeed = (req, res, next) => {
options.url = common.getSelLNServerUrl() + '/v1/genseed';
}
request(options).then((body) => {
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Gen Seed Error', error: body.error});
res.status(500).json({
message: "Genseed failed!",
error: (!body) ? 'Error From Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated'});
res.status(200).json(body);
}
logger.log({level: 'INFO', fileName: 'Wallet', msg: 'Seed Generated'});
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Gen Seed Error', error: err});
return res.status(500).json({
message: "Genseed failed!",
error: err.error
});
const err = common.handleError(errRes, 'Wallet', 'Gen Seed Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -71,27 +53,21 @@ exports.operateWallet = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Wallet', msg: 'Wallet Response', data: body});
const body_str = (!body) ? '' : JSON.stringify(body);
const search_idx = (!body) ? -1 : body_str.search('Not Found');
if(!body) {
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Wallet Error', error: {error: (error ? error : err_message)}});
res.status(500).json({
message: err_message,
error: (error) ? error : err_message
});
} else if(search_idx > -1) {
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Wallet Error', error: {error: err_message}});
res.status(500).json({
message: err_message,
error: err_message
});
} else if(body.error) {
if((body.code === 1 && body.error === 'context canceled') || (body.code === 14 && body.error === 'transport is closing')) {
if (!body) {
const errMsg = error ? error : err_message;
const err = common.handleError({ statusCode: 500, message: 'Wallet Error', error: errMsg }, 'Wallet', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
} else if (search_idx > -1) {
const errMsg = err_message;
const err = common.handleError({ statusCode: 500, message: 'Wallet Error', error: errMsg }, 'Wallet', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
} else if (body.error) {
if ((body.code === 1 && body.error === 'context canceled') || (body.code === 14 && body.error === 'transport is closing')) {
res.status(201).json('Successful');
} else {
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Wallet Error', error: body.error});
res.status(500).json({
message: err_message,
error: body.error
});
const errMsg = (body.error && typeof body.error === 'object') ? JSON.stringify(body.error) : (body.error && typeof body.error === 'string') ? body.error : err_message;
const err = common.handleError({ statusCode: 500, message: 'Wallet Error', error: errMsg }, 'Wallet', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
}
} else {
logger.log({level: 'INFO', fileName: 'Wallet', msg: 'Wallet Unlocked/Initialized'});
@ -99,21 +75,11 @@ exports.operateWallet = (req, res, next) => {
}
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Wallet Error', error: err});
if((err.error.code === 1 && err.error.error === 'context canceled') || (err.error.code === 14 && err.error.error === 'transport is closing')) {
if ((err.error.code === 1 && err.error.error === 'context canceled') || (err.error.code === 14 && err.error.error === 'transport is closing')) {
res.status(201).json('Successful');
} else {
res.status(500).json({
message: err_message,
error: err.error.message ? err.error.message : err.message ? err.message : err_message
});
const err = common.handleError(errRes, 'Wallet', err_message);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
});
};
@ -133,18 +99,8 @@ exports.getUTXOs = (req, res, next) => {
res.status(200).json(body.utxos ? body.utxos : []);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'UTXOs Error', error: err});
return res.status(500).json({
message: "UTXO list failed!",
error: err.error
});
const err = common.handleError(errRes, 'Wallet', 'List UTXOs Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -169,18 +125,8 @@ exports.bumpFee = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Bump Fee Error', error: err});
return res.status(500).json({
message: "Bump fee failed!",
error: err.error
});
const err = common.handleError(errRes, 'Wallet', 'Bump Fee Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -200,18 +146,8 @@ exports.labelTransaction = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Label Transaction Error', error: err});
return res.status(500).json({
message: "Transaction label failed!",
error: err.error
});
const err = common.handleError(errRes, 'Wallet', 'Label Transaction Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -233,18 +169,8 @@ exports.leaseUTXO = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Lease UTXO Error', error: err});
return res.status(500).json({
message: "Lease UTXO failed!",
error: err.error
});
const err = common.handleError(errRes, 'Wallet', 'Lease UTXO Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}
@ -265,17 +191,7 @@ exports.releaseUTXO = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Wallet', msg: 'Release UTXO Error', error: err});
return res.status(500).json({
message: "Release UTXO failed!",
error: err.error
});
const err = common.handleError(errRes, 'Wallet', 'Release UTXO Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
}

@ -16,21 +16,58 @@ exports.updateSelectedNode = (req, res, next) => {
res.status(200).json({status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!'});
};
exports.getRTLConfigInitial = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Getting Initial RTL Configuration..'});
var confFile = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
fs.readFile(confFile, 'utf8', function(errRes, data) {
if (errRes) {
if (errRes.code === 'ENOENT') {
logger.log({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);
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 ? false : true;
var nodesArr = [];
if (common.nodes && common.nodes.length > 0) {
common.nodes.forEach((node, i) => {
const settings = {};
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.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: {}})
});
}
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Initial RTL Configuration Received'});
res.status(200).json({ defaultNodeIndex: nodeConfData.defaultNodeIndex, selectedNodeIndex: common.selectedNode.index, sso: sso, enable2FA: enable2FA, nodes: nodesArr });
}
});
};
exports.getRTLConfig = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Getting RTL Configuration..'});
var confFile = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
logger.log({level: 'DEBUG', fileName: 'RTLConf', msg: 'Getting Node Config'});
fs.readFile(confFile, 'utf8', function(err, data) {
if (err) {
if (err.code === 'ENOENT') {
fs.readFile(confFile, 'utf8', function(errRes, data) {
if (errRes) {
if (errRes.code === 'ENOENT') {
logger.log({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 {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Getting Node Config Failed!', error: err});
res.status(500).json({
message: "Reading Node Config Failed!",
error: err
});
const errMsg = 'Get Node Config Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
}
} else {
const nodeConfData = JSON.parse(data);
@ -49,7 +86,7 @@ exports.getRTLConfig = (req, res, next) => {
settings.themeColor = (node.theme_color) ? node.theme_color : 'PURPLE';
settings.fiatConversion = (node.fiat_conversion) ? !!node.fiat_conversion : false;
settings.bitcoindConfigPath = node.bitcoind_config_path;
settings.enableLogging = node.enable_logging ? !!node.enable_logging : false;
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;
@ -74,12 +111,12 @@ exports.updateUISettings = (req, res, next) => {
var RTLConfFile = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
var config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.nodes.find(node => {
if(node.index == common.selectedNode.index) {
if (node.index == common.selectedNode.index) {
node.Settings.userPersona = req.body.updatedSettings.userPersona;
node.Settings.themeMode = req.body.updatedSettings.themeMode;
node.Settings.themeColor = req.body.updatedSettings.themeColor;
node.Settings.fiatConversion = req.body.updatedSettings.fiatConversion;
if(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;
@ -89,7 +126,7 @@ exports.updateUISettings = (req, res, next) => {
selectedNode.theme_mode = req.body.updatedSettings.themeMode;
selectedNode.theme_color = req.body.updatedSettings.themeColor;
selectedNode.fiat_conversion = req.body.updatedSettings.fiatConversion;
if(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;
@ -103,12 +140,10 @@ exports.updateUISettings = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'UI Settings Updated'});
res.status(201).json({message: 'Node Settings Updated Successfully'});
}
catch (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Updating Node Settings Failed!', error: {error: 'Updating node settings failed.'}});
res.status(500).json({
message: "Updating Node Settings Failed!",
error: 'Updating Node Settings Failed!'
});
catch (errRes) {
const errMsg = 'Update Node Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
}
};
@ -125,12 +160,10 @@ exports.update2FASettings = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: '2FA Updated'});
res.status(201).json({message: message});
}
catch (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Updating 2FA Settings Failed!', error: {error: 'Updating 2FA settings failed.'}});
res.status(500).json({
message: "Updating 2FA Settings Failed!",
error: 'Updating 2FA Settings Failed!'
});
catch (errRes) {
const errMsg = 'Update 2FA Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
}
};
@ -145,12 +178,10 @@ exports.updateDefaultNode = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Default Node Updated'});
res.status(201).json({message: 'Default Node Updated Successfully'});
}
catch (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Updating Default Node Failed!', error: {error: 'Updating dafault node failed.'}});
res.status(500).json({
message: "Updating Default Node Failed!",
error: 'Updating Default Node Failed!'
});
catch (errRes) {
const errMsg = 'Update Default Node Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
}
};
@ -174,13 +205,11 @@ exports.getConfig = (req, res, next) => {
break;
}
logger.log({level: 'DEBUG', fileName: 'RTLConf', msg: '[Node Type, File Path]', data: [req.params.nodeType, confFile]});
fs.readFile(confFile, 'utf8', function(err, data) {
if (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Reading Conf Failed!', error: err});
res.status(500).json({
message: "Reading Config File Failed!",
error: err
});
fs.readFile(confFile, 'utf8', function(errRes, data) {
if (errRes) {
const errMsg = 'Reading Config Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
} else {
let jsonConfig = {};
if (fileFormat === 'JSON') {
@ -205,16 +234,12 @@ exports.getFile = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Getting File..'});
let file = req.query.path ? req.query.path : (common.selectedNode.channel_backup_path + common.path_separator + 'channel-' + req.query.channel.replace(':', '-') + '.bak');
logger.log({level: 'DEBUG', fileName: 'RTLConf', msg: '[Channel Point, File Path]', data: [req.query.channel, file]});
fs.readFile(file, 'utf8', function(err, data) {
if (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Reading File Failed!', error: err});
if (err.code && err.code === 'ENOENT') {
err.code = 'Backup File Not Found!';
}
res.status(500).json({
message: "Reading File Failed!",
error: err
});
fs.readFile(file, 'utf8', function(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);
return res.status(err.statusCode).json({message: err.error, error: err.error});
} else {
logger.log({level: 'DEBUG', fileName: 'RTLConf', msg: 'File Data', data: data});
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'File Data Received'});
@ -227,22 +252,13 @@ exports.getCurrencyRates = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Getting Currency Rates..'});
options.url = 'https://blockchain.info/ticker';
request(options).then((body) => {
if(!body || body.error) {
res.status(500).json({
message: "Fetching Rates Failed!",
error: (!body) ? 'Error From External Server!' : body.error
});
} else {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received'});
res.status(200).json(JSON.parse(body));
}
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Currency Rates Received'});
res.status(200).json(JSON.parse(body));
})
.catch(function (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Fetching Rates Failed!', error: err});
return res.status(500).json({
message: "Fetching Rates Failed!",
error: err.error
});
.catch(errRes => {
const errMsg = 'Get Rates Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
});
};
@ -258,12 +274,10 @@ exports.updateSSO = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'SSO Setting Updated'});
res.status(201).json({message: 'SSO Updated Successfully'});
}
catch (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Updating SSO Failed!', error: {error: 'Updating SSO failed.'}});
res.status(500).json({
message: "Updating SSO Failed!",
error: 'Updating SSO Failed!'
});
catch (errRes) {
const errMsg = 'Update SSO Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
}
};
@ -273,7 +287,7 @@ exports.updateServiceSettings = (req, res, next) => {
var config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
const selectedNode = common.findNode(common.selectedNode.index);
config.nodes.find(node => {
if(node.index == common.selectedNode.index) {
if (node.index == common.selectedNode.index) {
switch (req.body.service) {
case 'LOOP':
if (req.body.settings.enable) {
@ -315,12 +329,10 @@ exports.updateServiceSettings = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'RTLConf', msg: 'Service Settings Updated'});
res.status(201).json({message: 'Service Settings Updated Successfully'});
}
catch (err) {
logger.log({level: 'ERROR', fileName: 'RTLConf', msg: 'Updating Service Settings Failed!', error: {error: 'Updating service settings failed.'}});
res.status(500).json({
message: "Updating Service Settings Failed!",
error: 'Updating Service Settings Failed!'
});
catch (errRes) {
const errMsg = 'Update Service Settings Error';
const err = common.handleError({ statusCode: 500, message: errMsg, error: errRes }, 'RTLConf', errMsg);
return res.status(err.statusCode).json({message: err.error, error: err.error});
}
};

@ -25,11 +25,11 @@ getFailedInfo = (reqIP, currentTime) => {
return failed;
}
handleError = (failed, currentTime, errMsg) => {
handleMultipleFailedAttemptsError = (failed, currentTime, errMsg) => {
if (failed.count >= ALLOWED_LOGIN_ATTEMPTS && (currentTime <= (failed.lastTried + LOCKING_PERIOD))) {
return {
message: "Multiple Failed Login Attempts!",
error: "Application locked for " + (LOCKING_PERIOD/ONE_MINUTE) + " minutes due to multiple failed login attempts! Try again after " + common.convertTimestampToTime((failed.lastTried + LOCKING_PERIOD)/1000) + "!"
error: "Application locked for " + (LOCKING_PERIOD/ONE_MINUTE) + " minutes due to multiple failed attempts!\nTry again after " + common.convertTimestampToTime((failed.lastTried + LOCKING_PERIOD)/1000) + "!"
};
} else {
return {
@ -48,24 +48,19 @@ exports.verifyToken = (twoFAToken) => {
exports.authenticateUser = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..'});
if(+common.rtl_sso) {
if(req.body.authenticateWith === 'JWT' && jwt.verify(req.body.authenticationValue, common.secret_key)) {
if (+common.rtl_sso) {
if (req.body.authenticateWith === 'JWT' && jwt.verify(req.body.authenticationValue, common.secret_key)) {
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated'});
res.status(200).json({ token: token });
} else if (req.body.authenticateWith === 'PASSWORD' && common.cookie.trim().length >= 32 && crypto.timingSafeEqual(Buffer.from(crypto.createHash('sha256').update(common.cookie).digest('hex'), 'utf-8'), Buffer.from(req.body.authenticationValue, 'utf-8'))) {
connect.refreshCookie(common.rtl_cookie_path);
const token = jwt.sign(
{ user: 'SSO_USER', configPath: common.nodes[0].config_path, macaroonPath: common.nodes[0].macaroon_path },
common.secret_key
);
const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key);
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated.'});
res.status(200).json({ token: token });
} else {
logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'SSO Authentication Failed! Access key too short or does not match.', error: {error: 'Access key too short or does not match.'}});
res.status(406).json({
message: "SSO Authentication Failed!",
error: "SSO failed. Access key too short or does not match."
});
const errMsg = 'SSO Authentication Failed! Access key too short or does not match.';
const err = common.handleError({ statusCode: 406, message: 'SSO Authentication Error', error: errMsg }, 'Authenticate', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
} else {
const currentTime = new Date().getTime();
@ -78,51 +73,39 @@ exports.authenticateUser = (req, res, next) => {
logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: {error: 'Invalid token.'}});
failed.count = failed.count + 1;
failed.lastTried = currentTime;
return res.status(401).json(handleError(failed, currentTime, 'Invalid 2FA Token!'));
return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid 2FA Token!'));
}
}
delete failedLoginAttempts[reqIP];
let rpcUser = 'NODE_USER';
const token = jwt.sign(
{ user: rpcUser, configPath: common.nodes[0].config_path, macaroonPath: common.nodes[0].macaroon_path },
common.secret_key
);
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated'});
res.status(200).json({ token: token });
} else {
logger.log({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.lastTried = common.rtl_pass !== password ? currentTime : failed.lastTried;
return res.status(401).json(handleError(failed, currentTime, 'Invalid Password!'));
return res.status(401).json(handleMultipleFailedAttemptsError(failed, currentTime, 'Invalid Password!'));
}
}
};
exports.resetPassword = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..'});
if(+common.rtl_sso) {
logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'Password Reset Failed!', error: {error: 'Password reset failed.'}});
res.status(401).json({
message: "Password Reset Failed!",
error: "Password cannot be reset for SSO authentication!"
});
if (+common.rtl_sso) {
const errMsg = 'Password cannot be reset for SSO authentication';
const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
} else {
const currPassword = req.body.currPassword;
if (common.rtl_pass === currPassword) {
common.rtl_pass = connect.replacePasswordWithHash(req.body.newPassword);
var rpcUser = 'NODE_USER';
const token = jwt.sign(
{ user: rpcUser, configPath: common.nodes[0].config_path, macaroonPath: common.nodes[0].macaroon_path },
common.secret_key
);
const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful'});
res.status(200).json({ token: token });
} else {
logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'Password Reset Failed!', error: {error: 'Password reset failed.'}});
res.status(401).json({
message: "Password Reset Failed!",
error: "Old password is not correct!"
});
const errMsg = 'Incorrect Old Password';
const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
}
};

@ -6,7 +6,11 @@ var options = {};
exports.getInfo = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Getting Boltz Information..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Boltz Get Info Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Get Info Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/info';
request(options).then(function (body) {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Boltz Information Received'});
@ -14,25 +18,19 @@ exports.getInfo = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Boltz Get Info Error', error: err});
return res.status(500).json({
message: "Boltz Get Info Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'Get Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.getServiceInfo = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Getting Service Information..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Boltz Get Service Info Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Get Service Information Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/serviceinfo';
request(options).then(function (body) {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Service Information Received'});
@ -40,25 +38,19 @@ exports.getServiceInfo = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Boltz Get Service Info Error', error: err});
return res.status(500).json({
message: "Boltz Get Service Info Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'Get Service Information Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.listSwaps = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Getting List Swaps..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Boltz List Swaps Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'List Swaps Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/listswaps';
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Boltz List Swaps Info', data: body});
@ -68,25 +60,19 @@ exports.listSwaps = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Boltz List Swaps Error', error: err});
return res.status(500).json({
message: "Boltz List Swaps Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'List Swaps Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.getSwapInfo = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Getting Swap..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Boltz Swap Info Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Get Swap Information Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/swap/' + req.params.swapId;
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Boltz Swap Info', data: body});
@ -94,162 +80,96 @@ exports.getSwapInfo = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Boltz Swap Info Error', error: err});
return res.status(500).json({
message: "Boltz Swap Info Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'Swap Info Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.createSwap = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Creating Swap..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Create Swap Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Create Swap Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/createswap';
options.body = { amount: req.body.amount };
if (req.body.address !== '') { options.body.address = req.body.address; }
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Create Swap Body', data: options.body});
request.post(options).then(createSwapRes => {
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Create Swap Response', data: createSwapRes});
if(!createSwapRes || createSwapRes.error) {
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Create Swap Error', error: createSwapRes.error});
res.status(500).json({
message: 'Create Swap Failed!',
error: (!createSwapRes) ? 'Error From Server!' : createSwapRes.error.message
});
} else {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Swap Created'});
res.status(201).json(createSwapRes);
}
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Swap Created'});
res.status(201).json(createSwapRes);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Create Swap Error', error: err});
return res.status(500).json({
message: "Create Swap Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'Create Swap Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.createReverseSwap = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Creating Reverse Swap..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Create Reverse Swap Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Create Reverse Swap Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/createreverseswap';
options.body = { amount: req.body.amount };
if (req.body.address !== '') { options.body.address = req.body.address; }
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Create Reverse Swap Body', data: options.body});
request.post(options).then(createReverseSwapRes => {
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Create Reverse Swap Response', data: createReverseSwapRes});
if(!createReverseSwapRes || createReverseSwapRes.error) {
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Create Reverse Swap Error', error: createReverseSwapRes.error});
res.status(500).json({
message: 'Create Reverse Swap Failed!',
error: (!createReverseSwapRes) ? 'Error From Server!' : createReverseSwapRes.error.message
});
} else {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Reverse Swap Created'});
res.status(201).json(createReverseSwapRes);
}
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Reverse Swap Created'});
res.status(201).json(createReverseSwapRes);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Create Reverse Swap Error', error: err});
return res.status(500).json({
message: "Create Reverse Swap Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'Create Reverse Swap Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.createChannel = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Creating Boltz Channel..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Create Channel Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Create Channel Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/createchannel';
options.body = { amount: req.body.amount };
if (req.body.address !== '') { options.body.address = req.body.address; }
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Create Channel Body', data: options.body});
request.post(options).then(createChannelRes => {
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Create Channel Response', data: createChannelRes});
if(!createChannelRes || createChannelRes.error) {
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Create Channel Error', error: createChannelRes.error});
res.status(500).json({
message: 'Create Channel Failed!',
error: (!createChannelRes) ? 'Error From Server!' : createChannelRes.error.message
});
} else {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Boltz Channel Created'});
res.status(201).json(createChannelRes);
}
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Boltz Channel Created'});
res.status(201).json(createChannelRes);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Create Channel Error', error: err});
return res.status(500).json({
message: "Create Channel Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'Create Channel Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.deposit = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Boltz Deposit Start..'});
options = common.getBoltzServerOptions();
if(options.url === '') { return res.status(500).json({message: "Deposit Failed!",error: { message: 'Boltz Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Boltz Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Deposit Error', error: errMsg }, 'Boltz', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/deposit';
request.post(options).then(depositRes => {
logger.log({level: 'DEBUG', fileName: 'Boltz', msg: 'Deposit Response', data: depositRes});
if(!depositRes || depositRes.error) {
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Deposit Error', error: depositRes.error});
res.status(500).json({
message: 'Deposit Failed!',
error: (!depositRes) ? 'Error From Server!' : depositRes.error.message
});
} else {
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Boltz Deposit Finished'});
res.status(201).json(depositRes);
}
logger.log({level: 'INFO', fileName: 'Boltz', msg: 'Boltz Deposit Finished'});
res.status(201).json(depositRes);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Boltz', msg: 'Deposit Error', error: err});
return res.status(500).json({
message: "Deposit Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Boltz', 'Deposit Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -2,57 +2,46 @@ var fs = require('fs');
var common = require('../../routes/common');
exports.log = (msgJSON, selNode = common.selectedNode) => {
let msgStr = '\r\n[' + new Date().toISOString() + '] ' + msgJSON.level + ': ' + msgJSON.fileName + ' => ' + msgJSON.msg;
let msgStr = '\r\n[' + new Date().toISOString() + '] ' + msgJSON.level + ': ' + msgJSON.fileName + ' => ' + msgJSON.msg;
switch (msgJSON.level) {
case 'ERROR':
msgStr = msgStr + ': ' + (msgJSON.error && typeof msgJSON.error === 'object' ? JSON.stringify(msgJSON.error) : (msgJSON.error && typeof msgJSON.error === 'string') ? msgJSON.error : '');
console.error(msgStr);
if(selNode && selNode.enable_logging) {
fs.appendFile(selNode.log_file, msgStr, function(err) {
if (err) {
return ({ error: 'Updating Log Failed!' });
} else {
return ({ message: 'Log Updated Successfully' });
}
});
if (selNode) {
msgStr = msgStr + ': ' + (typeof msgJSON.error === 'object' ? JSON.stringify(msgJSON.error) : (typeof msgJSON.error === 'string') ? msgJSON.error : '');
console.error(msgStr);
fs.appendFile(selNode.log_file, msgStr, () => {});
}
break;
case 'WARN':
if (selNode && (selNode.log_level == "INFO" || selNode.log_level == "WARN" || selNode.log_level == "DEBUG")) {
msgStr = msgStr + ': ' + (typeof msgJSON.data === 'object' ? JSON.stringify(msgJSON.data) : (typeof msgJSON.data === 'string') ? msgJSON.data : '');
console.warn(msgStr)
fs.appendFile(selNode.log_file, msgStr, () => {});
}
break;
case 'INFO':
if(selNode && selNode.enable_logging && msgJSON.data) {
msgStr = msgStr + ': ' + (msgJSON.data && typeof msgJSON.data === 'object' ? JSON.stringify(msgJSON.data) : (msgJSON.data && typeof msgJSON.data === 'string') ? msgJSON.data : '');
if (msgJSON.fileName !== 'Config Setup Variable') { console.log(msgStr); }
fs.appendFile(selNode.log_file, msgStr, function(err) {
if (err) {
return ({ error: 'Updating Log Failed!' });
} else {
return ({ message: 'Log Updated Successfully' });
}
});
} else {
console.log(msgStr + '.');
if (selNode && (selNode.log_level == "INFO" || selNode.log_level == "DEBUG")) {
msgStr = msgStr + '. ' + (typeof msgJSON.data === 'object' ? JSON.stringify(msgJSON.data) : (typeof msgJSON.data === 'string') ? msgJSON.data : '');
console.log(msgStr);
fs.appendFile(selNode.log_file, msgStr, () => {});
}
break;
case 'DEBUG':
if(selNode && selNode.enable_logging) {
if (msgJSON.data && typeof msgJSON.data !== 'string' && msgJSON.data.length && msgJSON.data.length > 0) {
if (selNode && selNode.log_level == "DEBUG") {
if (typeof msgJSON.data !== 'string' && msgJSON.data && msgJSON.data.length && msgJSON.data.length > 0) {
msgStr = msgJSON.data.reduce((accumulator, dataEle) => {
return accumulator + (typeof dataEle === 'object' ? JSON.stringify(dataEle) : (typeof dataEle === 'string') ? dataEle : '') + ', ';
}, msgStr + ': [');
msgStr = msgStr.slice(0, -2) + ']';
} else {
msgStr = msgStr + ': ' + (msgJSON.data && typeof msgJSON.data === 'object' ? JSON.stringify(msgJSON.data) : (msgJSON.data && typeof msgJSON.data === 'string') ? msgJSON.data : '');
}
if (msgJSON.fileName !== 'Config Setup Variable') { console.log(msgStr); }
fs.appendFile(selNode.log_file, msgStr, function(err) {
if (err) {
return ({ error: 'Updating Log Failed!' });
} else {
return ({ message: 'Log Updated Successfully' });
if (msgJSON.data && msgJSON.data !== '') {
msgStr = msgStr + ': ' + (typeof msgJSON.data === 'object' ? JSON.stringify(msgJSON.data) : typeof msgJSON.data == 'string' ? msgJSON.data : '');
}
});
}
}
fs.appendFile(selNode.log_file, msgStr, () => {});
}
break;
default:

@ -6,7 +6,11 @@ var options = {};
exports.loopOut = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Looping Out..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop Out Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop Out Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/out';
options.body = {
amt: req.body.amount,
@ -24,37 +28,23 @@ exports.loopOut = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Body', data: options.body});
request.post(options).then(loopOutRes => {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out', data: loopOutRes});
if(!loopOutRes || loopOutRes.error) {
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop Out Error', error: loopOutRes.error});
res.status(500).json({
message: 'Loop Out Failed!',
error: (!loopOutRes) ? 'Error From Server!' : loopOutRes.error.message
});
} else {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Loop Out Finished'});
res.status(201).json(loopOutRes);
}
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Loop Out Finished'});
res.status(201).json(loopOutRes);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop Out Error', error: err});
return res.status(500).json({
message: "Loop Out Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop Out Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.loopOutTerms = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Terms..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop Out Terms Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop Out Terms Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/out/terms';
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Terms', data: body});
@ -62,25 +52,19 @@ exports.loopOutTerms = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop Out Terms Error', error: err});
return res.status(500).json({
message: "Loop Out Terms Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop Out Terms Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.loopOutQuote = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Quotes..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop Out Quote Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop Out Quotes Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/out/quote/' + req.params.amount + '?conf_target=' + (req.query.targetConf ? req.query.targetConf : '2') + '&swap_publication_deadline=' + req.query.swapPublicationDeadline;
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Quote URL', data: options.url});
request(options).then(function (quoteRes) {
@ -91,25 +75,19 @@ exports.loopOutQuote = (req, res, next) => {
res.status(200).json(quoteRes);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop Out Quote Error', error: err});
return res.status(500).json({
message: "Loop Out Quote Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop Out Quotes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.loopOutTermsAndQuotes = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Terms & Quotes..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop Out Terms And Quotes Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop Out Terms & Quotes Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/out/terms';
request(options).then(function(terms) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Terms', data: terms});
@ -129,40 +107,24 @@ exports.loopOutTermsAndQuotes = (req, res, next) => {
res.status(200).json(values);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop Out Quotes Error', error: err});
return res.status(500).json({
message: "Loop Out Quotes Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop Out Terms & Quotes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop Out Terms Error', error: err});
return res.status(500).json({
message: "Loop Out Terms Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop Out Terms & Quotes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.loopIn = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Looping In..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop In Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop In Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/in';
options.body = {
amt: req.body.amount,
@ -173,37 +135,23 @@ exports.loopIn = (req, res, next) => {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Body', data: options.body});
request.post(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In', data: body});
if(!body || body.error) {
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop In Error', error: body.error});
res.status(500).json({
message: 'Loop In Failed!',
error: (body.error && body.error.message) ? body.error.message : 'Error From Server!'
});
} else {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Loop In Finished'});
res.status(201).json(body);
}
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Loop In Finished'});
res.status(201).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop In Error', error: err});
return res.status(500).json({
message: "Loop In Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop In Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.loopInTerms = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Terms..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop In Terms Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop In Terms Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/in/terms';
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Terms', data: body});
@ -211,25 +159,19 @@ exports.loopInTerms = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop In Terms Error', error: err});
return res.status(500).json({
message: "Loop In Terms Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop In Terms Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.loopInQuote = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Quotes..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop In Quote Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop In Quotes Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/in/quote/' + req.params.amount + '?conf_target=' + (req.query.targetConf ? req.query.targetConf : '2') + '&swap_publication_deadline=' + req.query.swapPublicationDeadline;
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Quote Options', data: options.url});
request(options).then(function (body) {
@ -240,25 +182,19 @@ exports.loopInQuote = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop In Quote Error', error: err});
return res.status(500).json({
message: "Loop In Quote Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop In Quote Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.loopInTermsAndQuotes = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Terms & Quotes..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop In Terms And Quotes Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Loop In Terms & Quotes Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/in/terms';
request(options).then(function(terms) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Terms', data: terms});
@ -278,40 +214,24 @@ exports.loopInTermsAndQuotes = (req, res, next) => {
res.status(200).json(values);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop In Quotes Error', error: err});
return res.status(500).json({
message: "Loop In Quotes Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop In Terms & Quotes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop In Terms Error', error: err});
return res.status(500).json({
message: "Loop In Terms Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Loop In Terms & Quotes Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.swaps = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting List Swaps..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop Out Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'List Swaps Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/swaps';
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Swaps', data: body});
@ -323,25 +243,19 @@ exports.swaps = (req, res, next) => {
res.status(200).json(body.swaps);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'List Swaps Error', error: err});
return res.status(500).json({
message: "Loop Swaps Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'List Swaps Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};
exports.swap = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Swap Information..'});
options = common.getSwapServerOptions();
if(options.url === '') { return res.status(500).json({message: "Loop Out Failed!",error: { message: 'Loop Server URL is missing in the configuration.'}}); }
if (options.url === '') {
const errMsg = 'Loop Server URL is missing in the configuration.';
const err = common.handleError({ statusCode: 500, message: 'Get Swap Error', error: errMsg }, 'Loop', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
options.url = options.url + '/v1/loop/swap/' + req.params.id;
request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Swap', data: body});
@ -349,17 +263,7 @@ exports.swap = (req, res, next) => {
res.status(200).json(body);
})
.catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes));
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Swap Info Error', error: err});
return res.status(500).json({
message: "Loop Swap Failed!",
error: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : err
});
const err = common.handleError(errRes, 'Loop', 'Get Swap Error');
return res.status(err.statusCode).json({message: err.message, error: err.error});
});
};

@ -31,7 +31,7 @@ parameters have `default` values for initial setup and can be updated after RTL
"themeColor": "<Theme colors, Allowed values PURPLE, TEAL, INDIGO, PINK, YELLOW. Default PURPLE, Required>",
"channelBackupPath": "<Path to save channel backup file. Only for LND implementation, Default <RTL root>\backup\node-1, Optional>",
"bitcoindConfigPath": "<Path of bitcoind.conf path if available locally>",
"enableLogging": <Parameter to turn RTL logging off/on. Allowed values - true, false, default false, Required>,
"logLevel": <logging levels, will log in accordance with the logLevel value provided, Allowed values ERROR, WARN, INFO, DEBUG>,
"fiatConversion": <parameter to turn fiat conversion off/on. Allowed values - true, false, default false, Required>,
"currencyUnit": "<Optional: Fiat current Unit for currency conversion, default 'USD' If fiatConversion is true, Required if fiatConversion is true>",
"lnServerUrl": "<Service url for LND/CLightning 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://localhost:8080', Required",

@ -78,7 +78,7 @@ Ensure that the follow values are correct per your config:
"themeMode": "DAY",
"themeColor": "PURPLE",
"bitcoindConfigPath": "",
"enableLogging": true,
"logLevel": "INFO",
"fiatConversion": false,
"lnServerUrl": "https://<cl-rest api server ip address>:3001"
}

@ -38,16 +38,38 @@ Design suggestions are always welcome and helpful. Design suggestion can range f
#### <a name="code"></a>Code
Contributions via code is the most sought after contribution and something we enthusiastically encourage. Follow the below guideline to be able to contribute code to RTL.
##### Pull Code
* Pull the code from the release (current eg Release-0.11.1) or [master](https://github.com/Ride-The-Lightning/RTL/tree/master) branch into your local workspace via github commandline/GUI.
##### Install Dependencies
##### Node Server
* Assuming that nodejs (v12 & above) and npm are already installed on your local machine. Go into your RTL root folder and run `npm install`.
* Sometimes after installation, user receives a message from npm to fix dependency vulnerability by running `npm audit fix`. Please do not follow this step as it can break some of the working RTL code on your machine. We audit and fix these vulnerabilities as soon as possible at our end.
##### Node Server for Development
* To run RTL node server in development mode, go to workspace/RTL and excute `npm run server` in the command window. This will run the script named `server` defined in package.json. This script sets the node environment as development and starts the server from rtl.js. Nodemon restarts the node application when file changes in the directory are detected.
* This `server` script has been written for windows machine. Please update the script to set the `NODE_ENV=development` according to your machine's OS.
* To check all available scripts for the project, explore the `scripts` section of package.json.
![](../screenshots/node-server-dev.jpg)
##### Angular Server for Development
##### Package Angular Updates
##### Create a New Branch
* The last step starts the node server but it cannot detect and update the code written in Angular. We run the angular development server separately while working on the frontend of the project and package the final build once the development is finished.
* To run the angular development server, go to workspace/RTL and run `npm run start`. It will start the angular server at default '4200' port and serve the application on localhost:4200.
![](../screenshots/angular-server-dev.jpg)
![](../screenshots/localhost-ui-dev.jpg)
##### Package Angular Build
* If the change/update were only made for the backend, you can directly move to the next step.
* In case the code was updated for the frontend (in the src folder), the Angular application code needs to be compiled into the output directory named `angular` at workspace/RTL. It can be done by running `npm run build` command in the RTL root.
* Please make sure to remove all linting and other errors thrown by the build command before moving to the next step.
![](../screenshots/angular-build.jpg)
##### Create a Pull Request
* Create a new branch on the github to push your updated code.
* Commit your updates into the newly created branch.
* Create a new pull request once you are satisfied with your updates to be merged into the `release`/`master` branch with details of your updates and submit it for the review.
##### Caution about adding new libraries
* We are very conservative in adding new dependencies. Do your best to not add any new libraries on RTL. This is the best strategy to keep the software safe from adding new vulnerabilites.
* Confirm before starting by creating an issue about the adding the library
* We are conservative in adding new dependencies to the repository. Do your best to not add any new libraries on RTL. We believe this is the best strategy to keep the software safe from vulnerabilites.
* Confirm before starting by creating an issue about adding the library
* The library should be popular, well maintained and pre-existing vulnerability free.
##### Commit Updates
##### Create Pull Request

@ -73,7 +73,7 @@ Ensure that the follow values are correct per your config:
"themeMode": "DAY",
"themeColor": "PURPLE",
"bitcoindConfigPath": "",
"enableLogging": true,
"logLevel": "INFO",
"fiatConversion": false,
"lnServerUrl": "http://<eclair api server ip address>:port"
}

@ -104,7 +104,7 @@ Example RTL-Config.json:
"themeColor": "PURPLE",
"channelBackupPath": "C:\\RTL\\backup\\node-1",
"bitcoindConfigPath": "<Optional: path of bitcoind.conf path if available locally>",
"enableLogging": true,
"logLevel": "INFO",
"fiatConversion": false,
"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://localhost:8081>",

@ -37,7 +37,7 @@ If your running RTL and LND on different devices on your local LAN, certain conf
"themeColor": "PURPLE",
"channelBackupPath": "<RTL Root path + \backup\node-1>",
"bitcoindConfigPath": "<Optional: path of bitcoind.conf path if available locally>",
"enableLogging": false,
"logLevel": "INFO",
"fiatConversion": false,
"lnServerUrl": "<https://<ip-address-of-device-running-lnd>:8080; e.g. https://192.168.0.1:8080>",
"swapServerUrl": "<https://<localhost>:8081>",

@ -23,7 +23,7 @@
"themeMode": "DAY",
"themeColor": "PURPLE",
"channelBackupPath": "C:\\Users\\xyz\\backup\\node-1",
"enableLogging": false,
"logLevel": "ERROR",
"lnServerUrl": "https://localhost:8080",
"swapServerUrl": "https://localhost:8081",
"boltzServerUrl": "https://localhost:9003",

@ -1,37 +0,0 @@
// @ts-check
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter');
/**
* @type { import("protractor").Config }
*/
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./src/**/*.e2e-spec.ts'
],
capabilities: {
browserName: 'chrome'
},
directConnect: true,
SELENIUM_PROMISE_MANAGER: false,
baseUrl: 'http://localhost:4200/',
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
onPrepare() {
require('ts-node').register({
project: require('path').join(__dirname, './tsconfig.json')
});
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: StacktraceOption.PRETTY
}
}));
}
};

@ -1,23 +0,0 @@
import { AppPage } from './app.po';
import { browser, logging } from 'protractor';
describe('workspace-project App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should display welcome message', async () => {
await page.navigateTo();
expect(await page.getTitleText()).toEqual('RTL app is running!');
});
afterEach(async () => {
// Assert that there are no errors emitted from the browser
const logs = await browser.manage().logs().get(logging.Type.BROWSER);
expect(logs).not.toContain(jasmine.objectContaining({
level: logging.Level.SEVERE,
} as logging.Entry));
});
});

@ -1,11 +0,0 @@
import { browser, by, element } from 'protractor';
export class AppPage {
async navigateTo(): Promise<unknown> {
return browser.get(browser.baseUrl);
}
async getTitleText(): Promise<string> {
return element(by.css('app-root .content span')).getText();
}
}

@ -1,13 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"module": "commonjs",
"target": "es2018",
"types": [
"jasmine",
"node"
]
}
}

189
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "rtl",
"version": "0.11.0-beta",
"version": "0.11.1-beta",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -1657,9 +1657,9 @@
"dev": true
},
"@eslint/eslintrc": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz",
"integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==",
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
"integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
@ -1674,9 +1674,9 @@
},
"dependencies": {
"globals": {
"version": "13.9.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz",
"integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==",
"version": "13.10.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
"integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@ -1733,6 +1733,23 @@
"@fortawesome/fontawesome-common-types": "^0.2.35"
}
},
"@humanwhocodes/config-array": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
"integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
"dev": true,
"requires": {
"@humanwhocodes/object-schema": "^1.2.0",
"debug": "^4.1.1",
"minimatch": "^3.0.4"
}
},
"@humanwhocodes/object-schema": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz",
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
"dev": true
},
"@istanbuljs/schema": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@ -2374,9 +2391,9 @@
"dev": true
},
"acorn-jsx": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
"integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
},
"adjust-sourcemap-loader": {
@ -4450,15 +4467,15 @@
}
},
"css-select": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz",
"integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==",
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
"integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
"dev": true,
"requires": {
"boolbase": "^1.0.0",
"css-what": "^4.0.0",
"domhandler": "^4.0.0",
"domutils": "^2.4.3",
"css-what": "^5.0.0",
"domhandler": "^4.2.0",
"domutils": "^2.6.0",
"nth-check": "^2.0.0"
}
},
@ -4473,9 +4490,9 @@
}
},
"css-what": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz",
"integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==",
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
"integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==",
"dev": true
},
"cssdb": {
@ -5344,13 +5361,14 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz",
"integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==",
"version": "7.32.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
"integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
"dev": true,
"requires": {
"@babel/code-frame": "7.12.11",
"@eslint/eslintrc": "^0.4.2",
"@eslint/eslintrc": "^0.4.3",
"@humanwhocodes/config-array": "^0.5.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@ -5409,9 +5427,9 @@
}
},
"chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@ -5451,9 +5469,9 @@
"dev": true
},
"globals": {
"version": "13.9.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz",
"integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==",
"version": "13.10.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
"integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
@ -5518,6 +5536,75 @@
}
}
},
"eslint-plugin-deprecation": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-deprecation/-/eslint-plugin-deprecation-1.2.1.tgz",
"integrity": "sha512-8KFAWPO3AvF0szxIh1ivRtHotd1fzxVOuNR3NI8dfCsQKgcxu9fAgEY+eTKvCRLAwwI8kaDDfImMt+498+EgRw==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "^2.19.2 || ^3.0.0",
"tslib": "^1.10.0",
"tsutils": "^3.0.0"
},
"dependencies": {
"@typescript-eslint/experimental-utils": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz",
"integrity": "sha512-DewqIgscDzmAfd5nOGe4zm6Bl7PKtMG2Ad0KG8CUZAHlXfAKTF9Ol5PXhiMh39yRL2ChRH1cuuUGOcVyyrhQIw==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/types": "3.10.1",
"@typescript-eslint/typescript-estree": "3.10.1",
"eslint-scope": "^5.0.0",
"eslint-utils": "^2.0.0"
}
},
"@typescript-eslint/types": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.10.1.tgz",
"integrity": "sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz",
"integrity": "sha512-QbcXOuq6WYvnB3XPsZpIwztBoquEYLXh2MtwVU+kO8jgYCiv4G5xrSP/1wg4tkvrEE+esZVquIPX/dxPlePk1w==",
"dev": true,
"requires": {
"@typescript-eslint/types": "3.10.1",
"@typescript-eslint/visitor-keys": "3.10.1",
"debug": "^4.1.1",
"glob": "^7.1.6",
"is-glob": "^4.0.1",
"lodash": "^4.17.15",
"semver": "^7.3.2",
"tsutils": "^3.17.1"
}
},
"@typescript-eslint/visitor-keys": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz",
"integrity": "sha512-9JgC82AaQeglebjZMgYR5wgmfUdUc+EitGUUMW8u2nDckaeimzW+VsoLV6FoimPv2id3VQzfjwBxEMVz08ameQ==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
},
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
},
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
}
}
},
"eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@ -6027,9 +6114,9 @@
}
},
"flatted": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz",
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==",
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
"integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
"dev": true
},
"flatten": {
@ -7637,9 +7724,9 @@
}
},
"jszip": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz",
"integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==",
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz",
"integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==",
"dev": true,
"requires": {
"lie": "~3.3.0",
@ -13066,15 +13153,15 @@
}
},
"svgo": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.0.tgz",
"integrity": "sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==",
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.1.tgz",
"integrity": "sha512-riDDIQgXpEnn0BEl9Gvhh1LNLIyiusSpt64IR8upJu7MwxnzetmF/Y57pXQD2NMX2lVyMRzXt5f2M5rO4wG7Dw==",
"dev": true,
"requires": {
"@trysound/sax": "0.1.1",
"chalk": "^4.1.0",
"commander": "^7.1.0",
"css-select": "^3.1.2",
"css-select": "^4.1.3",
"css-tree": "^1.1.2",
"csso": "^4.2.0",
"stable": "^0.1.8"
@ -13090,9 +13177,9 @@
}
},
"chalk": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
@ -13152,9 +13239,9 @@
},
"dependencies": {
"ajv": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz",
"integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==",
"version": "8.6.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
"integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
@ -13178,9 +13265,9 @@
"dev": true
},
"tar": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
"version": "6.1.8",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.8.tgz",
"integrity": "sha512-sb9b0cp855NbkMJcskdSYA7b11Q8JsX4qe4pyUAfHp+Y6jBjJeek2ZVlwEfWayshEIwlIzXx0Fain3QG9JPm2A==",
"dev": true,
"requires": {
"chownr": "^2.0.0",
@ -13765,9 +13852,9 @@
}
},
"url-parse": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==",
"version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"dev": true,
"requires": {
"querystringify": "^2.1.1",

@ -1,18 +1,15 @@
{
"name": "rtl",
"version": "0.11.0-beta",
"version": "0.11.1-beta",
"license": "MIT",
"scripts": {
"ng": "ng",
"start": "ng serve --open",
"prebuild": "node ./src/prebuild",
"build": "ng analytics off && ng lint && ng build --configuration production",
"devbuild": "ng build --configuration production",
"serve": "ng serve",
"build": "ng analytics off && ng lint && ng test && ng build --configuration production",
"server": "set NODE_ENV=development&&nodemon ./rtl.js",
"test": "ng test",
"test": "ng test --watch=true --code-coverage",
"lint": "ng lint",
"e2e": "ng e2e",
"postinstall": "ngcc"
},
"private": true,
@ -72,7 +69,8 @@
"@typescript-eslint/parser": "4.23.0",
"crypto-browserify": "^3.12.0",
"dotenv": "^8.2.0",
"eslint": "^7.26.0",
"eslint": "^7.32.0",
"eslint-plugin-deprecation": "^1.2.1",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
"karma": "~6.3.2",

@ -157,10 +157,6 @@ common.replaceNode = (selNodeIndex, newNode) => {
common.selectedNode = common.findNode(selNodeIndex);
}
common.convertToBTC = (num) => {
return (num / 100000000).toFixed(6);
};
common.convertTimestampToTime = (num) => {
let myDate = new Date(+num * 1000);
let days = myDate.getDate().toString();
@ -213,6 +209,58 @@ common.newestOnTop = (array, key, value) => {
return array;
}
common.handleError = (errRes, fileName, errMsg) => {
let err = JSON.parse(JSON.stringify(errRes));
switch (common.selectedNode.ln_implementation) {
case 'LND':
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) {
delete err.options.headers['Grpc-Metadata-macaroon'];
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers['Grpc-Metadata-macaroon']) {
delete err.response.request.headers['Grpc-Metadata-macaroon'];
}
break;
case 'CLT':
if (err.options && err.options.headers && err.options.headers.macaroon) {
delete err.options.headers.macaroon;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.macaroon) {
delete err.response.request.headers.macaroon;
}
break;
case 'ECL':
if (err.options && err.options.headers && err.options.headers.authorization) {
delete err.options.headers.authorization;
}
if (err.response && err.response.request && err.response.request.headers && err.response.request.headers.authorization) {
delete err.response.request.headers.authorization;
}
break;
default:
if (err.options && err.options.headers) { delete err.options.headers; }
break;
}
const msgStr = '\r\n[' + new Date().toISOString() + '] ERROR: ' + fileName + ' => ' + errMsg + ': ' + (typeof err === 'object' ? JSON.stringify(err) : (typeof err === 'string') ? err : 'Unknown Error');
console.error(msgStr);
if (common.selectedNode) { fs.appendFile(common.selectedNode.log_file, msgStr, () => {}) }
const newErrorObj = {
statusCode: err.statusCode ? err.statusCode : err.status ? err.status : (err.error && err.error.code && err.error.code === 'ECONNREFUSED') ? 503 : 500,
message: (err.error && err.error.message) ? err.error.message : err.message ? err.message : errMsg,
error: (
(err.error && err.error.error && err.error.error.error && typeof err.error.error.error === 'string') ? err.error.error.error :
(err.error && err.error.error && typeof err.error.error === 'string') ? err.error.error :
(err.error && err.error.error && err.error.error.message && typeof err.error.error.message === 'string') ? err.error.error.message :
(err.error && err.error.message && typeof err.error.message === 'string') ? err.error.message :
(err.message && typeof err.message === 'string') ? err.message :
(err.error) ? err.error : (typeof err === 'string') ? err : 'Unknown Error'
)
};
return newErrorObj;
}
common.getRequestIP = (req) => {
return (typeof req.headers['x-forwarded-for'] === 'string' && req.headers['x-forwarded-for'].split(',').shift())
|| req.ip
@ -249,41 +297,36 @@ common.getMonthDays = (selMonth, selYear) => {
filterData = (data_key) => {
let search_string = '';
switch (data_key) {
case 'GetInfo':
search_string = 'INFO: GetInfo => Get Info Response: ';
break;
case 'Fees':
search_string = 'INFO: Fees => Fee Response: ';
break;
case 'Payments':
search_string = 'INFO: Fees => Payments Response: ';
break;
case 'Invoices':
search_string = 'INFO: Invoice => Invoices List Received: ';
break;
case 'OnChainBalance':
search_string = 'INFO: Onchain => Balance Received: ';
break;
case 'Peers':
search_string = 'INFO: Peers => Peers with Alias: ';
break;
case 'Channels':
search_string = 'INFO: Channels => Simplified Channels with Alias: ';
break;
default:
search_string = 'INFO: GetInfo => Get Info Response: ';
break;
if (common.selectedNode.ln_implementation === 'ECL') {
switch (data_key) {
case 'GetInfo': search_string = 'INFO: GetInfo => Get Info Response: '; break;
case 'Fees': search_string = 'INFO: Fees => Fee Response: '; break;
case 'Payments': search_string = 'INFO: Fees => Payments Response: '; break;
case 'Invoices': search_string = 'INFO: Invoice => Invoices List Received: '; break;
case 'OnChainBalance': search_string = 'INFO: Onchain => Balance Received: '; break;
case 'Peers': search_string = 'INFO: Peers => Peers with Alias: '; break;
case 'Channels': search_string = 'INFO: Channels => Simplified Channels with Alias: '; break;
default: search_string = 'Random Line'; break;
}
} else if (common.selectedNode.ln_implementation === 'CLT') {
switch (data_key) {
case 'GetInfo': search_string = 'DEBUG: GetInfo => Node Information. '; break;
case 'Fees': search_string = 'DEBUG: Fees => Fee Received. '; break;
case 'Payments': search_string = 'DEBUG: Payments => Payment List Received: '; break;
case 'Invoices': search_string = 'DEBUG: Invoice => Invoices List Received. '; break;
case 'ChannelBalance': search_string = 'DEBUG: Channels => Local Remote Balance. '; break;
case 'Peers': search_string = 'DEBUG: Peers => Peers with Alias: '; break;
case 'Channels': search_string = 'DEBUG: Channels => List Channels: '; break;
case 'Balance': search_string = 'DEBUG: Balance => Balance Received. '; break;
case 'ForwardingHistory': search_string = 'DEBUG: Channels => Forwarding History Received: '; break;
case 'UTXOs': search_string = 'DEBUG: OnChain => List Funds Received. '; break;
case 'FeeRateperkb': search_string = 'DEBUG: Network => Network Fee Rates Received for perkb. '; break;
case 'FeeRateperkw': search_string = 'DEBUG: Network => Network Fee Rates Received for perkw. '; break;
default: search_string = 'Random Line'; break;
}
}
let foundDataLine = dummy_data_array_from_file.find(dataItem => dataItem.includes(search_string));
let dataStr = foundDataLine ? foundDataLine.replace(search_string, '') : {};
let dataStr = foundDataLine ? foundDataLine.substring((foundDataLine.indexOf(search_string)) + search_string.length) : '{}';
return JSON.parse(dataStr);
}

@ -39,7 +39,7 @@ connect.setDefaultConfig = () => {
configPath = '';
channelBackupPath = '';
break;
}
}
return {
multiPass: "password",
port: "3000",
@ -53,7 +53,7 @@ connect.setDefaultConfig = () => {
{
index: 1,
lnNode: "Node 1",
lnImplementation: "LND",
lnImplementation: "LND",
Authentication: {
macaroonPath: macaroonPath,
configPath: configPath,
@ -63,7 +63,7 @@ connect.setDefaultConfig = () => {
themeMode: "DAY",
themeColor: "PURPLE",
channelBackupPath: channelBackupPath,
enableLogging: false,
logLevel: "ERROR",
lnServerUrl: "https://localhost:8080",
fiatConversion: false
}
@ -86,7 +86,7 @@ connect.normalizePort = val => {
connect.replacePasswordWithHash = (multiPassHashed) => {
common.rtl_conf_file_path = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : path.join(__dirname, '..');
try {
RTLConfFile = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
RTLConfFile = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
var config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.multiPassHashed = multiPassHashed;
delete config.multiPass;
@ -98,8 +98,29 @@ connect.replacePasswordWithHash = (multiPassHashed) => {
}
}
connect.updateLogByLevel = () => {
updateLogFlag = false;
common.rtl_conf_file_path = process.env.RTL_CONFIG_PATH ? process.env.RTL_CONFIG_PATH : path.join(__dirname, '..');
try {
RTLConfFile = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
var config = JSON.parse(fs.readFileSync(RTLConfFile, 'utf-8'));
config.nodes.forEach((node) => {
if (node.Settings.hasOwnProperty('enableLogging')) {
updateLogFlag = true;
node.Settings.logLevel = node.Settings.enableLogging? 'INFO' : 'ERROR';
delete node.Settings.enableLogging;
}
})
if (updateLogFlag) {
fs.writeFileSync(RTLConfFile, JSON.stringify(config, null, 2), 'utf-8');
}
} catch (err) {
errMsg = errMsg + '\nLog level update failed!';
}
}
connect.validateNodeConfig = (config) => {
if((process.env.RTL_SSO == 0) || (typeof process.env.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
if ((process.env.RTL_SSO == 0) || (typeof process.env.RTL_SSO === 'undefined' && +config.SSO.rtlSSO === 0)) {
if (config.multiPassHashed !== '' && config.multiPassHashed) {
common.rtl_pass = config.multiPassHashed;
} else if (config.multiPass !== '' && config.multiPass) {
@ -119,7 +140,7 @@ connect.validateNodeConfig = (config) => {
common.nodes[idx].ln_implementation = (process.env.LN_IMPLEMENTATION) ? process.env.LN_IMPLEMENTATION : node.lnImplementation ? node.lnImplementation : 'LND';
if (common.nodes[idx].ln_implementation !== 'ECL' && process.env.MACAROON_PATH && process.env.MACAROON_PATH.trim() !== '') {
common.nodes[idx].macaroon_path = process.env.MACAROON_PATH;
} else if(common.nodes[idx].ln_implementation !== 'ECL' && node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') {
} else if (common.nodes[idx].ln_implementation !== 'ECL' && node.Authentication && node.Authentication.macaroonPath && node.Authentication.macaroonPath.trim() !== '') {
common.nodes[idx].macaroon_path = node.Authentication.macaroonPath;
} else if (common.nodes[idx].ln_implementation !== 'ECL') {
errMsg = 'Please set macaroon path for node index ' + node.index + ' in RTL-Config.json!';
@ -158,7 +179,7 @@ connect.validateNodeConfig = (config) => {
}
} else {
errMsg = errMsg + '\nInvalid config path: ' + common.nodes[idx].config_path;
}
}
} catch (err) {
errMsg = errMsg + '\nUnable to read config file: \n' + err;
}
@ -167,13 +188,13 @@ connect.validateNodeConfig = (config) => {
errMsg = 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() !== '') {
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;
} 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() !== '') {
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;
} else if(node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') {
} else if (node.Settings.lnServerUrl && node.Settings.lnServerUrl.trim() !== '') {
common.nodes[idx].ln_server_url = 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() !== '') {
common.nodes[idx].ln_server_url = node.Settings.lndServerUrl.endsWith('/v1') ? node.Settings.lndServerUrl.slice(0, -3) : node.Settings.lndServerUrl;
} else {
errMsg = errMsg + '\nPlease set LN Server URL for node index ' + node.index + ' in RTL-Config.json!';
@ -181,24 +202,25 @@ connect.validateNodeConfig = (config) => {
common.nodes[idx].user_persona = node.Settings.userPersona ? node.Settings.userPersona : 'MERCHANT';
common.nodes[idx].theme_mode = node.Settings.themeMode ? node.Settings.themeMode : 'DAY';
common.nodes[idx].theme_color = node.Settings.themeColor ? node.Settings.themeColor : 'PURPLE';
common.nodes[idx].log_level = node.Settings.logLevel ? node.Settings.logLevel : 'ERROR'
common.nodes[idx].fiat_conversion = node.Settings.fiatConversion ? !!node.Settings.fiatConversion : false;
if(common.nodes[idx].fiat_conversion) {
if (common.nodes[idx].fiat_conversion) {
common.nodes[idx].currency_unit = 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() !== '') {
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;
common.nodes[idx].swap_macaroon_path = process.env.SWAP_MACAROON_PATH;
} else if(node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') {
} else if (node.Settings.swapServerUrl && node.Settings.swapServerUrl.trim() !== '') {
common.nodes[idx].swap_server_url = node.Settings.swapServerUrl.endsWith('/v1') ? node.Settings.swapServerUrl.slice(0, -3) : node.Settings.swapServerUrl;
common.nodes[idx].swap_macaroon_path = node.Authentication.swapMacaroonPath ? node.Authentication.swapMacaroonPath : '';
} else {
common.nodes[idx].swap_server_url = '';
common.nodes[idx].swap_macaroon_path = '';
}
if(process.env.BOLTZ_SERVER_URL && process.env.BOLTZ_SERVER_URL.trim() !== '') {
if (process.env.BOLTZ_SERVER_URL && process.env.BOLTZ_SERVER_URL.trim() !== '') {
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;
common.nodes[idx].boltz_macaroon_path = process.env.BOLTZ_MACAROON_PATH;
} else if(node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') {
} else if (node.Settings.boltzServerUrl && node.Settings.boltzServerUrl.trim() !== '') {
common.nodes[idx].boltz_server_url = node.Settings.boltzServerUrl.endsWith('/v1') ? node.Settings.boltzServerUrl.slice(0, -3) : node.Settings.boltzServerUrl;
common.nodes[idx].boltz_macaroon_path = node.Authentication.boltzMacaroonPath ? node.Authentication.boltzMacaroonPath : '';
} else {
@ -206,7 +228,6 @@ connect.validateNodeConfig = (config) => {
common.nodes[idx].boltz_macaroon_path = '';
}
common.nodes[idx].bitcoind_config_path = process.env.BITCOIND_CONFIG_PATH ? process.env.BITCOIND_CONFIG_PATH : (node.Settings.bitcoindConfigPath) ? node.Settings.bitcoindConfigPath : '';
common.nodes[idx].enable_logging = (node.Settings.enableLogging) ? !!node.Settings.enableLogging : false;
common.nodes[idx].channel_backup_path = process.env.CHANNEL_BACKUP_PATH ? process.env.CHANNEL_BACKUP_PATH : (node.Settings.channelBackupPath) ? node.Settings.channelBackupPath : common.rtl_conf_file_path + common.path_separator + 'backup' + common.path_separator + 'node-' + node.index;
try {
connect.createDirectory(common.nodes[idx].channel_backup_path);
@ -218,42 +239,38 @@ connect.validateNodeConfig = (config) => {
} catch (err) {
console.error('Something went wrong while creating backup file: \n' + err);
}
}
}
} catch (err) {
console.error('Something went wrong while creating the backup directory: \n' + err);
}
if (common.nodes[idx].enable_logging) {
common.nodes[idx].log_file = common.rtl_conf_file_path + '/logs/RTL-Node-' + node.index + '.log';
const log_file = common.nodes[idx].log_file;
if (fs.existsSync(log_file)) {
fs.writeFile(log_file, '', () => { });
} else {
try {
var dirname = path.dirname(log_file);
connect.createDirectory(dirname);
var createStream = fs.createWriteStream(log_file);
createStream.end();
}
catch (err) {
console.error('Something went wrong while creating log file ' + log_file + ': \n' + err);
}
common.nodes[idx].log_file = common.rtl_conf_file_path + '/logs/RTL-Node-' + node.index + '.log';
const log_file = common.nodes[idx].log_file;
if (fs.existsSync(log_file)) {
fs.writeFile(log_file, '', () => { });
} else {
try {
var dirname = path.dirname(log_file);
connect.createDirectory(dirname);
var createStream = fs.createWriteStream(log_file);
createStream.end();
}
catch (err) {
console.error('Something went wrong while creating log file ' + log_file + ': \n' + err);
}
}
});
}
connect.setSSOParams(config);
if (errMsg && errMsg.trim() !== '') { throw new Error(errMsg); }
if (errMsg && errMsg.trim() !== '') { throw new Error(errMsg); }
}
connect.setSSOParams = (config) => {
if (process.env.RTL_SSO) {
common.rtl_sso = process.env.RTL_SSO;
} else if (config.SSO && config.SSO.rtlSSO) {
common.rtl_sso = config.SSO.rtlSSO;
}
if (process.env.RTL_SSO) {
common.rtl_sso = process.env.RTL_SSO;
} else if (config.SSO && config.SSO.rtlSSO) {
common.rtl_sso = config.SSO.rtlSSO;
}
if (process.env.RTL_COOKIE_PATH) {
common.rtl_cookie_path = process.env.RTL_COOKIE_PATH;
} else if (config.SSO && config.SSO.rtlCookiePath) {
@ -314,7 +331,7 @@ connect.readCookie = (cookieFile) => {
fs.writeFileSync(cookieFile, crypto.randomBytes(64).toString('hex'));
common.cookie = fs.readFileSync(cookieFile, 'utf-8');
}
catch(err) {
catch (err) {
console.error('Something went wrong while reading the cookie: \n' + err);
throw new Error(err);
}
@ -326,62 +343,59 @@ connect.refreshCookie = (cookieFile) => {
fs.writeFileSync(cookieFile, crypto.randomBytes(64).toString('hex'));
common.cookie = fs.readFileSync(cookieFile, 'utf-8');
}
catch(err) {
catch (err) {
console.error('Something went wrong while refreshing cookie: \n' + err);
throw new Error(err);
}
}
connect.logEnvVariables = () => {
if (common.nodes && common.nodes.length > 0) {
common.nodes.forEach((node, idx) => {
if (!node.enable_logging) { return; }
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'PORT: ' + common.port, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'HOST: ' + common.host, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + common.selectedNode.index});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'SSO: ' + common.rtl_sso, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + common.logout_redirect_link + '\r\n', node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'INDEX: ' + node.index, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + node.ln_node, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + node.ln_implementation, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + node.fiat_conversion, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + node.currency_unit, node});
logger.log({level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + node.ln_server_url, node});
});
if (common.selectedNode && common.selectedNode.index) {
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'PORT: ' + common.port});
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'HOST: ' + common.host });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'SSO: ' + common.rtl_sso });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'DEFAULT NODE INDEX: ' + common.selectedNode.index });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'INDEX: ' + common.selectedNode.index });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LN NODE: ' + common.selectedNode.ln_node });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LN IMPLEMENTATION: ' + common.selectedNode.ln_implementation });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'FIAT CONVERSION: ' + common.selectedNode.fiat_conversion });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'CURRENCY UNIT: ' + common.selectedNode.currency_unit });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LN SERVER URL: ' + common.selectedNode.ln_server_url });
logger.log({ level: 'DEBUG', fileName: 'Config Setup Variable', msg: 'LOGOUT REDIRECT LINK: ' + common.logout_redirect_link + '\r\n' });
}
}
connect.getAllNodeAllChannelBackup = (node) => {
let channel_backup_file = node.channel_backup_path + common.path_separator + 'channel-all.bak';
let options = {
let options = {
url: node.ln_server_url + '/channels/backup',
rejectUnauthorized: false,
json: true,
headers: {'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex')}
headers: { 'Grpc-Metadata-macaroon': fs.readFileSync(node.macaroon_path + '/admin.macaroon').toString('hex') }
};
request(options).then(function(body) {
fs.writeFile(channel_backup_file, JSON.stringify(body), function(err) {
request(options).then(function (body) {
fs.writeFile(channel_backup_file, JSON.stringify(body), function (err) {
if (err) {
if (node.ln_node) {
logger.log({level: 'ERROR', fileName: 'Connect', msg: 'Channel Backup Failed for Node ' + node.ln_node, error: err});
logger.log({ level: 'ERROR', fileName: 'Connect', msg: 'Channel Backup Failed for Node ' + node.ln_node, error: err });
} else {
logger.log({level: 'ERROR', fileName: 'Connect', msg: 'Channel Backup Error', error: err});
logger.log({ level: 'ERROR', fileName: 'Connect', msg: 'Channel Backup Error', error: err });
}
} else {
if (node.ln_node) {
logger.log({level: 'DEBUG', fileName: 'Connect', msg: 'Channel Backup Successful for Node', data: node.ln_node});
logger.log({ level: 'DEBUG', fileName: 'Connect', msg: 'Channel Backup Successful for Node', data: node.ln_node });
} else {
logger.log({level: 'DEBUG', fileName: 'Connect', msg: 'Channel Backup Successful'});
logger.log({ level: 'DEBUG', fileName: 'Connect', msg: 'Channel Backup Successful' });
}
}
});
}, (err) => {
logger.log({level: 'ERROR', fileName: 'Connect', msg: 'Channel Backup Response Error', error: err});
logger.log({ level: 'ERROR', fileName: 'Connect', msg: 'Channel Backup Response Error', error: err });
})
};
connect.setSelectedNode = (config) => {
if(config.defaultNodeIndex) {
if (config.defaultNodeIndex) {
common.selectedNode = common.findNode(config.defaultNodeIndex);
} else {
common.selectedNode = common.findNode(common.nodes[0].index);
@ -405,19 +419,19 @@ connect.modifyJsonMultiNodeConfig = (confFileFullPath) => {
if (config.host) {
newConfig.host = config.host;
}
if(config.nodes && config.nodes.length > 0) {
if (config.nodes && config.nodes.length > 0) {
let newNode = {};
config.nodes.forEach((node, idx) => {
newNode = {
index: node.index ? node.index : (idx + 1),
lnNode: node.lnNode ? node.lnNode : "Node " + (idx + 1),
lnImplementation: node.lnImplementation ? node.lnImplementation : "LND",
lnImplementation: node.lnImplementation ? node.lnImplementation : "LND",
Authentication: {
macaroonPath: node.Authentication.macaroonPath ? node.Authentication.macaroonPath : ''
},
Settings: {
userPersona: node.Settings.userPersona ? node.Settings.userPersona : "MERCHANT",
enableLogging: node.Settings.enableLogging ? !!node.Settings.enableLogging : false,
logLevel: node.Settings.logLevel,
fiatConversion: node.Settings.fiatConversion ? node.Settings.fiatConversion : false
}
};
@ -476,14 +490,14 @@ connect.modifyIniSingleNodeConfig = (confFileFullPath) => {
{
index: 1,
lnNode: "Node 1",
lnImplementation: config.Settings.lnImplementation ? config.Settings.lnImplementation : "LND",
lnImplementation: config.Settings.lnImplementation ? config.Settings.lnImplementation : "LND",
Authentication: {
macaroonPath: config.Authentication.macaroonPath ? config.Authentication.macaroonPath : (config.Authentication.macroonPath ? config.Authentication.macroonPath : ''),
configPath: config.Authentication.configPath ? config.Authentication.configPath : (config.Authentication.lndConfigPath ? config.Authentication.lndConfigPath : ''),
},
Settings: {
userPersona: config.Settings.userPersona ? config.Settings.userPersona : "MERCHANT",
enableLogging: config.Settings.enableLogging ? !!config.Settings.enableLogging : (config.Authentication.enableLogging ? !!config.Authentication.enableLogging : false),
logLevel: config.Settings.logLevel ? config.Settings.logLevel : 'ERROR',
fiatConversion: config.Settings.fiatConversion ? config.Settings.fiatConversion : false
}
}
@ -504,7 +518,7 @@ connect.modifyIniSingleNodeConfig = (confFileFullPath) => {
if (config.Settings.bitcoindConfigPath) {
newConfig.nodes[0].Settings.bitcoindConfigPath = config.Settings.bitcoindConfigPath;
} else if(config.Authentication.bitcoindConfigPath) {
} else if (config.Authentication.bitcoindConfigPath) {
newConfig.nodes[0].Settings.bitcoindConfigPath = config.Authentication.bitcoindConfigPath;
}
@ -543,7 +557,7 @@ connect.upgradeConfig = (confFileFullPath) => {
console.log('End...config creation.');
}
}
} catch(err) {
} catch (err) {
console.error('Something went wrong while upgrading the RTL config file: \n' + err);
throw new Error(err);
}
@ -552,15 +566,16 @@ connect.upgradeConfig = (confFileFullPath) => {
connect.setServerConfiguration = () => {
try {
common.rtl_conf_file_path = (process.env.RTL_CONFIG_PATH) ? process.env.RTL_CONFIG_PATH : path.join(__dirname, '/..');
confFileFullPath = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
if(!fs.existsSync(confFileFullPath)) {
confFileFullPath = common.rtl_conf_file_path + common.path_separator + 'RTL-Config.json';
if (!fs.existsSync(confFileFullPath)) {
connect.upgradeConfig(confFileFullPath);
}
var config = JSON.parse(fs.readFileSync(confFileFullPath, 'utf-8'));
connect.updateLogByLevel();
connect.validateNodeConfig(config);
connect.setSelectedNode(config);
connect.logEnvVariables();
} catch(err) {
} catch (err) {
console.error('Something went wrong while configuring the node server: \n' + err);
throw new Error(err);
}

@ -4,6 +4,7 @@ const router = express.Router();
const authCheck = require("../shared/authCheck");
router.get("/", authCheck, invoicesController.listInvoices);
router.get("/:paymentHash", authCheck, invoicesController.getInvoice);
router.post("/", authCheck, invoicesController.createInvoice);
module.exports = router;

@ -3,7 +3,8 @@ const express = require("express");
const router = express.Router();
const authCheck = require("./authCheck");
router.get("/rtlconf", RTLConfController.getRTLConfig);
router.get("/rtlconfinit", RTLConfController.getRTLConfigInitial);
router.get("/rtlconf", authCheck, RTLConfController.getRTLConfig);
router.post("/", authCheck, RTLConfController.updateUISettings);
router.post("/update2FA", authCheck, RTLConfController.update2FASettings);
router.get("/config/:nodeType", authCheck, RTLConfController.getConfig);

@ -7,9 +7,8 @@ module.exports = (req, res, next) => {
jwt.verify(token, common.secret_key);
next();
} catch (error) {
res.status(401).json({
message: "Authentication Failed!",
error: "Authentication Failed! Please Login First!"
});
const errMsg = 'Authentication Failed! Please Login First!';
const err = common.handleError({ statusCode: 401, message: 'Authentication Error', error: errMsg }, 'AuthCheck', errMsg);
return res.status(err.statusCode).json({message: err.message, error: err.error});
}
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

@ -26,6 +26,7 @@ import * as fromRTLReducer from './store/rtl.reducers';
animations: [routeAnimation]
})
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('sideNavigation', { static: false }) sideNavigation: any;
@ViewChild('sideNavContent', { static: false }) sideNavContent: any;
public selNode: ConfigSettingsNode;
@ -42,90 +43,99 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
public flgLoggedIn = false;
unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions,
private userIdle: UserIdleService, private router: Router, private sessionService: SessionService, private breakpointObserver: BreakpointObserver, private renderer: Renderer2) {}
constructor(
private logger: LoggerService, private commonService: CommonService, private store: Store<fromRTLReducer.RTLState>, private actions: Actions,
private userIdle: UserIdleService, private router: Router, private sessionService: SessionService, private breakpointObserver: BreakpointObserver, private renderer: Renderer2
) { }
ngOnInit() {
this.router.events.subscribe((evt) => {
if (!(evt instanceof NavigationEnd)) { return; }
document.getElementsByTagName('mat-sidenav-content')[0].scrollTo(0, 0);
});
this.breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.TabletPortrait, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge])
.pipe(takeUntil(this.unSubs[0]))
.subscribe((matches) => {
if(matches.breakpoints[Breakpoints.XSmall]) {
this.commonService.setScreenSize(ScreenSizeEnum.XS);
this.smallScreen = true;
} else if(matches.breakpoints[Breakpoints.TabletPortrait]) {
this.commonService.setScreenSize(ScreenSizeEnum.SM);
this.smallScreen = true;
} else if(matches.breakpoints[Breakpoints.Small] || matches.breakpoints[Breakpoints.Medium]) {
this.commonService.setScreenSize(ScreenSizeEnum.MD);
this.smallScreen = false;
} else if(matches.breakpoints[Breakpoints.Large]) {
this.commonService.setScreenSize(ScreenSizeEnum.LG);
this.smallScreen = false;
} else {
this.commonService.setScreenSize(ScreenSizeEnum.XL);
this.smallScreen = false;
if (!(evt instanceof NavigationEnd)) {
return;
}
document.getElementsByTagName('mat-sidenav-content')[0].scrollTo(0, 0);
});
this.breakpointObserver.observe([Breakpoints.XSmall, Breakpoints.TabletPortrait, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge]).
pipe(takeUntil(this.unSubs[0])).
subscribe((matches) => {
if (matches.breakpoints[Breakpoints.XSmall]) {
this.commonService.setScreenSize(ScreenSizeEnum.XS);
this.smallScreen = true;
} else if (matches.breakpoints[Breakpoints.TabletPortrait]) {
this.commonService.setScreenSize(ScreenSizeEnum.SM);
this.smallScreen = true;
} else if (matches.breakpoints[Breakpoints.Small] || matches.breakpoints[Breakpoints.Medium]) {
this.commonService.setScreenSize(ScreenSizeEnum.MD);
this.smallScreen = false;
} else if (matches.breakpoints[Breakpoints.Large]) {
this.commonService.setScreenSize(ScreenSizeEnum.LG);
this.smallScreen = false;
} else {
this.commonService.setScreenSize(ScreenSizeEnum.XL);
this.smallScreen = false;
}
});
this.store.dispatch(new RTLActions.FetchRTLConfig());
this.accessKey = this.readAccessKey();
this.store.select('root')
.pipe(takeUntil(this.unSubs[1]))
.subscribe(rtlStore => {
this.selNode = rtlStore.selNode;
this.settings = this.selNode.settings;
this.appConfig = rtlStore.appConfig;
this.information = rtlStore.nodeData;
this.flgLoading[0] = ( this.information.identity_pubkey) ? false : true;
this.logger.info(this.settings);
if (!this.sessionService.getItem('token')) {
this.flgLoggedIn = false;
this.flgLoading[0] = false;
} else {
this.flgLoggedIn = true;
this.userIdle.startWatching();
}
});
this.store.select('root').
pipe(takeUntil(this.unSubs[1])).
subscribe((rtlStore) => {
this.selNode = rtlStore.selNode;
this.settings = this.selNode.settings;
this.appConfig = rtlStore.appConfig;
this.information = rtlStore.nodeData;
this.flgLoading[0] = !(this.information.identity_pubkey);
this.logger.info(this.settings);
if (!this.sessionService.getItem('token')) {
this.flgLoggedIn = false;
this.flgLoading[0] = false;
} else {
this.flgLoggedIn = true;
this.userIdle.startWatching();
}
});
if (this.sessionService.getItem('defaultPassword') === 'true') {
this.flgSideNavOpened = false;
}
this.actions$.pipe(takeUntil(this.unSubs[2]),
filter((action) => action.type === RTLActions.SET_RTL_CONFIG || action.type === RTLActions.LOGOUT))
.subscribe((action: (RTLActions.SetRTLConfig | RTLActions.Logout)) => {
if (action.type === RTLActions.SET_RTL_CONFIG) {
if (!this.sessionService.getItem('token')) {
if (+action.payload.sso.rtlSSO) {
if(!this.accessKey || this.accessKey.trim().length < 32) {
this.router.navigate(['./error'], { state: {errorCode: '406', errorMessage: 'Access key too short. It should be at least 32 characters long.'} });
}
this.actions.pipe(
takeUntil(this.unSubs[2]),
filter((action) => action.type === RTLActions.SET_RTL_CONFIG || action.type === RTLActions.LOGOUT)).
subscribe((action: (RTLActions.SetRTLConfig | RTLActions.Logout)) => {
if (action.type === RTLActions.SET_RTL_CONFIG) {
if (!this.sessionService.getItem('token')) {
if (+action.payload.sso.rtlSSO) {
if (!this.accessKey || this.accessKey.trim().length < 32) {
this.router.navigate(['./error'], { state: { errorCode: '406', errorMessage: 'Access key too short. It should be at least 32 characters long.' } });
} else {
this.store.dispatch(new RTLActions.Login({ password: sha256(this.accessKey), defaultPassword: false }));
}
} else {
this.store.dispatch(new RTLActions.Login({password: sha256(this.accessKey), defaultPassword: false}));
this.router.navigate(['./login']);
}
} else {
this.router.navigate(['./login']);
}
}
}
if (action.type === RTLActions.LOGOUT) {
this.flgLoggedIn = false;
this.userIdle.stopWatching();
this.userIdle.stopTimer();
}
if (action.type === RTLActions.LOGOUT) {
this.flgLoggedIn = false;
this.userIdle.stopWatching();
this.userIdle.stopTimer();
}
});
this.userIdle.onTimerStart().pipe(takeUntil(this.unSubs[3])).subscribe((count) => {
this.logger.info('Counting Down: ' + (11 - count));
});
this.userIdle.onTimerStart().pipe(takeUntil(this.unSubs[3])).subscribe(count => {this.logger.info('Counting Down: ' + (11 - count))});
this.userIdle.onTimeout().pipe(takeUntil(this.unSubs[4])).subscribe(() => {
this.logger.info('Time Out!');
if (this.sessionService.getItem('token')) {
this.flgLoggedIn = false;
this.logger.warn('Time limit exceeded for session inactivity.');
this.store.dispatch(new RTLActions.CloseAllDialogs());
this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.WARNING,
alertTitle: 'Logging out',
titleMessage: 'Time limit exceeded for session inactivity.'
}}));
this.store.dispatch(new RTLActions.OpenAlert({
data: {
type: AlertTypeEnum.WARNING,
alertTitle: 'Logging out',
titleMessage: 'Time limit exceeded for session inactivity.'
}
}));
this.store.dispatch(new RTLActions.Logout());
}
});
@ -146,7 +156,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
} else {
setTimeout(() => {
if (this.flgLoggedIn) {
this.renderer.setStyle(this.sideNavContent.elementRef.nativeElement, 'marginLeft', '22rem'); //$regular-sidenav-width
this.renderer.setStyle(this.sideNavContent.elementRef.nativeElement, 'marginLeft', '22rem'); // $regular-sidenav-width
}
this.commonService.setContainerSize(this.sideNavContent.elementRef.nativeElement.clientWidth, this.sideNavContent.elementRef.nativeElement.clientHeight);
}, 100);
@ -166,14 +176,17 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
copiedText(payload: string) {
this.flgCopied = true;
setTimeout(() => {this.flgCopied = false; }, 5000);
setTimeout(() => {
this.flgCopied = false;
}, 5000);
this.logger.info('Copied Text: ' + payload);
}
ngOnDestroy() {
this.unSubs.forEach(unsub => {
this.unSubs.forEach((unsub) => {
unsub.next();
unsub.complete();
});
}
}

@ -1,4 +1,4 @@
import { BrowserModule, HammerModule } from '@angular/platform-browser';
import { HammerModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
@ -30,13 +30,12 @@ import { LayoutModule } from '@angular/cdk/layout';
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
SharedModule,
routing,
LayoutModule,
HammerModule,
UserIdleModule.forRoot({idle: 3590, timeout: 10, ping: 12000}), // One hour
UserIdleModule.forRoot({ idle: 3590, timeout: 10, ping: 12000 }), // One hour
StoreModule.forRoot(RTLReducer, {
runtimeChecks: {
strictStateImmutability: false,

@ -22,37 +22,37 @@ import { AuthGuard } from './shared/services/auth.guard';
export const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'login' },
{ path: 'lnd', loadChildren: () => import('./lnd/lnd.module').then(childModule => childModule.LNDModule), canActivate: [AuthGuard] },
{ path: 'cl', loadChildren: () => import('./clightning/cl.module').then(childModule => childModule.CLModule), canActivate: [AuthGuard] },
{ path: 'ecl', loadChildren: () => import('./eclair/ecl.module').then(childModule => childModule.ECLModule), canActivate: [AuthGuard] },
{ path: 'lnd', loadChildren: () => import('./lnd/lnd.module').then((childModule) => childModule.LNDModule), canActivate: [AuthGuard] },
{ path: 'cl', loadChildren: () => import('./clightning/cl.module').then((childModule) => childModule.CLModule), canActivate: [AuthGuard] },
{ path: 'ecl', loadChildren: () => import('./eclair/ecl.module').then((childModule) => childModule.ECLModule), canActivate: [AuthGuard] },
{ path: 'settings', component: SettingsComponent, canActivate: [AuthGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'app' },
{ path: 'app', component: AppSettingsComponent, canActivate: [AuthGuard] },
{ path: 'auth', component: AuthSettingsComponent, canActivate: [AuthGuard] },
{ path: 'bconfig', component: BitcoinConfigComponent, canActivate: [AuthGuard] }
]},
] },
{ path: 'config', component: NodeConfigComponent, canActivate: [AuthGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'node' },
{ path: 'node', component: NodeSettingsComponent, canActivate: [AuthGuard] },
{ path: 'services', component: ServicesSettingsComponent, canActivate: [AuthGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'loop' },
{ path: 'loop', component: LoopServiceSettingsComponent, canActivate: [AuthGuard] },
{ path: 'boltz', component: BoltzServiceSettingsComponent, canActivate: [AuthGuard] },
]},
{ path: 'boltz', component: BoltzServiceSettingsComponent, canActivate: [AuthGuard] }
] },
{ path: 'lnconfig', component: LNPConfigComponent, canActivate: [AuthGuard] }
]},
] },
{ path: 'services', component: ServicesComponent, canActivate: [AuthGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'loop' },
{ path: 'loop', pathMatch: 'full', redirectTo: 'loop/loopout' },
{ path: 'loop/:selTab', component: LoopComponent },
{ path: 'boltz', pathMatch: 'full', redirectTo: 'boltz/swapout' },
{ path: 'boltz/:selTab', component: BoltzRootComponent },
]},
{ path: 'boltz/:selTab', component: BoltzRootComponent }
] },
{ path: 'help', component: HelpComponent },
{ path: 'login', component: LoginComponent },
{ path: 'error', component: ErrorComponent },
{ path: '**', component: NotFoundComponent }
{ path: '**', component: NotFoundComponent }
];
// export const routing: ModuleWithProviders<RouterModule> = RouterModule.forRoot(routes, { enableTracing: true });
// Export const routing: ModuleWithProviders<RouterModule> = RouterModule.forRoot(routes, { enableTracing: true });
export const routing: ModuleWithProviders<RouterModule> = RouterModule.forRoot(routes);

@ -9,6 +9,7 @@ import { routeAnimation } from '../shared/animation/route-animation';
animations: [routeAnimation]
})
export class CLRootComponent {
loading = false;
constructor(private router: Router) {
@ -28,6 +29,7 @@ export class CLRootComponent {
break;
}
}
});
});
}
}

@ -20,11 +20,13 @@ import { CLLookupsComponent } from './lookups/lookups.component';
import { CLRoutingComponent } from './routing/routing.component';
import { CLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component';
import { CLFailedTransactionsComponent } from './routing/failed-transactions/failed-transactions.component';
import { CLRoutingPeersComponent } from './routing/routing-peers/routing-peers.component';
import { CLChannelLookupComponent } from './lookups/channel-lookup/channel-lookup.component';
import { CLNodeLookupComponent } from './lookups/node-lookup/node-lookup.component';
import { CLQueryRoutesComponent } from './transactions/query-routes/query-routes.component';
import { CLChannelOpenTableComponent } from './peers-channels/channels/channels-tables/channel-open-table/channel-open-table.component';
import { CLChannelPendingTableComponent } from './peers-channels/channels/channels-tables/channel-pending-table/channel-pending-table.component';
import { CLBumpFeeComponent } from './peers-channels/channels/bump-fee-modal/bump-fee.component';
import { CLNodeInfoComponent } from './home/node-info/node-info.component';
import { CLBalancesInfoComponent } from './home/balances-info/balances-info.component';
import { CLFeeInfoComponent } from './home/fee-info/fee-info.component';
@ -33,6 +35,7 @@ import { CLChannelCapacityInfoComponent } from './home/channel-capacity-info/cha
import { CLChannelLiquidityInfoComponent } from './home/channel-liquidity-info/channel-liquidity-info.component';
import { CLNetworkInfoComponent } from './network-info/network-info.component';
import { CLFeeRatesComponent } from './network-info/fee-rates/fee-rates.component';
import { CLOnChainFeeEstimatesComponent } from './network-info/on-chain-fee-estimates/on-chain-fee-estimates.component';
import { CLSignVerifyMessageComponent } from './sign-verify-message/sign-verify-message.component';
import { CLSignComponent } from './sign-verify-message/sign/sign.component';
import { CLVerifyComponent } from './sign-verify-message/verify/verify.component';
@ -68,6 +71,7 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
CLRoutingComponent,
CLForwardingHistoryComponent,
CLFailedTransactionsComponent,
CLRoutingPeersComponent,
CLChannelLookupComponent,
CLNodeLookupComponent,
CLQueryRoutesComponent,
@ -78,6 +82,7 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
CLChannelsTablesComponent,
CLChannelOpenTableComponent,
CLChannelPendingTableComponent,
CLBumpFeeComponent,
CLNodeInfoComponent,
CLBalancesInfoComponent,
CLFeeInfoComponent,
@ -86,6 +91,7 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
CLChannelLiquidityInfoComponent,
CLNetworkInfoComponent,
CLFeeRatesComponent,
CLOnChainFeeEstimatesComponent,
CLSignVerifyMessageComponent,
CLSignComponent,
CLVerifyComponent,

@ -23,6 +23,8 @@ import { CLSignComponent } from './sign-verify-message/sign/sign.component';
import { CLVerifyComponent } from './sign-verify-message/verify/verify.component';
import { CLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component';
import { CLFailedTransactionsComponent } from './routing/failed-transactions/failed-transactions.component';
import { CLRoutingPeersComponent } from './routing/routing-peers/routing-peers.component';
import { CLReportsComponent } from './reports/reports.component';
import { CLFeeReportComponent } from './reports/fee/fee-report.component';
import { CLTransactionsReportComponent } from './reports/transactions/transactions-report.component';
@ -37,8 +39,8 @@ export const ClRoutes: Routes = [
{ path: 'onchain', component: CLOnChainComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'receive/utxos' },
{ path: 'receive/:selTab', component: CLOnChainReceiveComponent, canActivate: [CLUnlockedGuard] },
{ path: 'send/:selTab', component: CLOnChainSendComponent, data : {sweepAll : false}, canActivate: [CLUnlockedGuard] },
{ path: 'sweep/:selTab', component: CLOnChainSendComponent, data : {sweepAll : true}, canActivate: [CLUnlockedGuard] }
{ path: 'send/:selTab', component: CLOnChainSendComponent, data: { sweepAll: false }, canActivate: [CLUnlockedGuard] },
{ path: 'sweep/:selTab', component: CLOnChainSendComponent, data: { sweepAll: true }, canActivate: [CLUnlockedGuard] }
] },
{ path: 'connections', component: CLConnectionsComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'channels' },
@ -47,7 +49,7 @@ export const ClRoutes: Routes = [
{ path: 'open', component: CLChannelOpenTableComponent, canActivate: [CLUnlockedGuard] },
{ path: 'pending', component: CLChannelPendingTableComponent, canActivate: [CLUnlockedGuard] }
] },
{ path: 'peers', component: CLPeersComponent, data : {sweepAll : false}, canActivate: [CLUnlockedGuard] }
{ path: 'peers', component: CLPeersComponent, data: { sweepAll: false }, canActivate: [CLUnlockedGuard] }
] },
{ path: 'transactions', component: CLTransactionsComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'payments' },
@ -63,7 +65,8 @@ export const ClRoutes: Routes = [
{ path: 'routing', component: CLRoutingComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'forwardinghistory' },
{ path: 'forwardinghistory', component: CLForwardingHistoryComponent, canActivate: [CLUnlockedGuard] },
{ path: 'failedtransactions', component: CLFailedTransactionsComponent, canActivate: [CLUnlockedGuard] }
{ path: 'failedtransactions', component: CLFailedTransactionsComponent, canActivate: [CLUnlockedGuard] },
{ path: 'routingpeers', component: CLRoutingPeersComponent, canActivate: [CLUnlockedGuard] }
] },
{ path: 'reports', component: CLReportsComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'routingfees' },
@ -76,8 +79,7 @@ export const ClRoutes: Routes = [
{ path: 'network', redirectTo: 'rates' },
{ path: 'wallet', redirectTo: 'home' },
{ path: 'backup', redirectTo: 'home' }
]
}
] }
];
export const CLRouting: ModuleWithProviders<RouterModule> = RouterModule.forChild(ClRoutes);

@ -1,4 +1,4 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch" *ngIf="errorMessage?.trim() === ''; else errorBlock">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Lightning</h4>
<div class="overflow-wrap dashboard-info-value">{{balances.lightning | number}} Sats</div>
@ -14,3 +14,8 @@
<div class="overflow-wrap dashboard-info-value">{{balances.total | number}} Sats</div>
</div>
</div>
<ng-template #errorBlock>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between" class="p-2">
<p>{{errorMessage}}</p>
</div>
</ng-template>

@ -1,4 +1,5 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { SharedModule } from '../../../shared/shared.module';
import { CLBalancesInfoComponent } from './balances-info.component';
@ -6,11 +7,12 @@ describe('CLBalancesInfoComponent', () => {
let component: CLBalancesInfoComponent;
let fixture: ComponentFixture<CLBalancesInfoComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ CLBalancesInfoComponent ]
})
.compileComponents();
declarations: [CLBalancesInfoComponent],
imports: [SharedModule]
}).
compileComponents();
}));
beforeEach(() => {
@ -22,4 +24,8 @@ describe('CLBalancesInfoComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
afterEach(() => {
TestBed.resetTestingModule();
});
});

@ -6,7 +6,9 @@ import { Component, Input } from '@angular/core';
styleUrls: ['./balances-info.component.scss']
})
export class CLBalancesInfoComponent {
@Input() balances = { onchain: 0, lightning: 0, total: 0 };
@Input() errorMessage: string;
constructor() {}

@ -1,15 +1,15 @@
<div fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100">
<div fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100" *ngIf="errorMessage?.trim() === ''; else errorBlock">
<div fxLayout="column" fxFlex="9" fxLayoutAlign="end start">
<span class="dashboard-capacity-header this-channel-capacity">Total Capacity</span>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint fxFlex="40" fxLayoutAlign="start center" class="font-size-90"><strong class="font-weight-900 mr-5px">Local:</strong>{{channelBalances.localBalance || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint fxFlex="40" fxLayoutAlign="start center" class="font-size-90"><strong class="font-weight-900 mr-5px">Local:</strong>{{channelBalances?.localBalance || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint fxFlex="20" fxLayoutAlign="center center" class="font-size-90">
<fa-icon [icon]="faBalanceScale" class="mr-3px" matTooltip="Balance Score"></fa-icon>
({{channelBalances?.balancedness || 0 | number}})
</mat-hint>
<mat-hint fxFlex="40" fxLayoutAlign="end center" class="font-size-90"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channelBalances.remoteBalance || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint fxFlex="40" fxLayoutAlign="end center" class="font-size-90"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channelBalances?.remoteBalance || 0 | number:'1.0-0'}} Sats</mat-hint>
</div>
<mat-progress-bar class="dashboard-progress-bar this-channel-bar" mode="determinate" color="accent" value="{{channelBalances.localBalance && channelBalances.localBalance > 0 ? ((+channelBalances.localBalance/((+channelBalances.localBalance)+(+channelBalances.remoteBalance)))*100) : 0}}"></mat-progress-bar>
<mat-progress-bar class="dashboard-progress-bar this-channel-bar" mode="determinate" color="accent" value="{{channelBalances?.localBalance && channelBalances?.localBalance > 0 ? ((+channelBalances?.localBalance/((+channelBalances?.localBalance)+(+channelBalances?.remoteBalance)))*100) : 0}}"></mat-progress-bar>
</div>
<div fxLayout="column" fxFlex="3" fxLayoutAlign="end stretch"><mat-divider class="dashboard-divider"></mat-divider></div>
<div class="channels-capacity-scroll" [perfectScrollbar]>
@ -35,3 +35,8 @@
<button mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
</div>
</ng-template>
<ng-template #errorBlock>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between" class="p-2">
<p>{{errorMessage}}</p>
</div>
</ng-template>

@ -1,4 +1,6 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { SharedModule } from '../../../shared/shared.module';
import { CLChannelCapacityInfoComponent } from './channel-capacity-info.component';
@ -6,11 +8,12 @@ describe('CLChannelCapacityInfoComponent', () => {
let component: CLChannelCapacityInfoComponent;
let fixture: ComponentFixture<CLChannelCapacityInfoComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ CLChannelCapacityInfoComponent ]
})
.compileComponents();
declarations: [CLChannelCapacityInfoComponent],
imports: [SharedModule, RouterTestingModule]
}).
compileComponents();
}));
beforeEach(() => {
@ -22,4 +25,8 @@ describe('CLChannelCapacityInfoComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
afterEach(() => {
TestBed.resetTestingModule();
});
});

@ -10,11 +10,13 @@ import { Channel } from '../../../shared/models/clModels';
styleUrls: ['./channel-capacity-info.component.scss']
})
export class CLChannelCapacityInfoComponent {
public faBalanceScale = faBalanceScale;
public faDumbbell = faDumbbell;
@Input() channelBalances: {localBalance: number, remoteBalance: number, balancedness: number};
@Input() allChannels: Channel[];
@Input() sortBy: string = 'Balance Score';
@Input() sortBy = 'Balance Score';
@Input() errorMessage: string;
constructor(private router: Router) {}

@ -1,4 +1,4 @@
<div fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100" [ngClass]="{'mb-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM, 'mb-2': screenSize === screenSizeEnum.MD, 'mb-1': screenSize === screenSizeEnum.LG || screenSize === screenSizeEnum.XL}">
<div *ngIf="errorMessage?.trim() === ''; else errorBlock" fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100" [ngClass]="{'mb-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM, 'mb-2': screenSize === screenSizeEnum.MD, 'mb-1': screenSize === screenSizeEnum.LG || screenSize === screenSizeEnum.XL}">
<div fxLayout="column" fxFlex="9" fxLayoutAlign="end start">
<span class="dashboard-capacity-header this-channel-capacity">Total Capacity</span>
<mat-hint class="font-size-90">{{totalLiquidity | number:'1.0-0'}} Sats</mat-hint>
@ -25,3 +25,8 @@
<button *ngIf="direction === 'Out'" mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
</div>
</ng-template>
<ng-template #errorBlock>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between" class="p-2">
<p>{{errorMessage}}</p>
</div>
</ng-template>

@ -1,16 +1,27 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { SharedModule } from '../../../shared/shared.module';
import { CommonService } from '../../../shared/services/common.service';
import { mockDataService } from '../../../shared/test-helpers/mock-services';
import { CLChannelLiquidityInfoComponent } from './channel-liquidity-info.component';
import { DataService } from '../../../shared/services/data.service';
describe('CLChannelLiquidityInfoComponent', () => {
let component: CLChannelLiquidityInfoComponent;
let fixture: ComponentFixture<CLChannelLiquidityInfoComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ CLChannelLiquidityInfoComponent ]
})
.compileComponents();
declarations: [CLChannelLiquidityInfoComponent],
imports: [SharedModule, RouterTestingModule],
providers: [
CommonService,
{ provide: DataService, useClass: mockDataService }
]
}).
compileComponents();
}));
beforeEach(() => {

@ -11,9 +11,11 @@ import { CommonService } from '../../../shared/services/common.service';
styleUrls: ['./channel-liquidity-info.component.scss']
})
export class CLChannelLiquidityInfoComponent implements OnInit {
@Input() direction: string;
@Input() totalLiquidity: number;
@Input() allChannels: Channel[];
@Input() errorMessage: string;
public screenSize = '';
public screenSizeEnum = ScreenSizeEnum;

@ -1,28 +1,35 @@
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Active</h4>
<div class="overflow-wrap dashboard-info-value"><span class="dot tiny-dot green"></span>{{(channelsStatus.active.channels || 0) | number}}</div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start stretch" *ngIf="errorMessage?.trim() === ''; else errorBlock">
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Active</h4>
<div class="overflow-wrap dashboard-info-value"><span class="dot tiny-dot green"></span>{{(channelsStatus?.active?.channels || 0) | number}}</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Pending</h4>
<div class="overflow-wrap dashboard-info-value"><span class="dot tiny-dot yellow"></span>{{(channelsStatus?.pending?.channels || 0) | number}}</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Inactive</h4>
<div class="overflow-wrap dashboard-info-value"><span class="dot tiny-dot grey"></span>{{(channelsStatus?.inactive?.channels || 0) | number}}</div>
</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Pending</h4>
<div class="overflow-wrap dashboard-info-value"><span class="dot tiny-dot yellow"></span>{{(channelsStatus.pending.channels || 0) | number}}</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Inactive</h4>
<div class="overflow-wrap dashboard-info-value"><span class="dot tiny-dot grey"></span>{{(channelsStatus.inactive.channels || 0) | number}}</div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus?.active?.capacity || 0) | number}} Sats</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus?.pending?.capacity || 0) | number}} Sats</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus?.inactive?.capacity || 0) | number}} Sats</div>
</div>
</div>
</div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus.active.capacity || 0) | number}} Sats</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus.pending.capacity || 0) | number}} Sats</div>
<ng-template #errorBlock>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between" class="p-2">
<p>{{errorMessage}}</p>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus.inactive.capacity || 0) | number}} Sats</div>
</div>
</div>
</ng-template>

@ -1,4 +1,5 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { SharedModule } from '../../../shared/shared.module';
import { CLChannelStatusInfoComponent } from './channel-status-info.component';
@ -6,11 +7,12 @@ describe('CLChannelStatusInfoComponent', () => {
let component: CLChannelStatusInfoComponent;
let fixture: ComponentFixture<CLChannelStatusInfoComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ CLChannelStatusInfoComponent ]
})
.compileComponents();
declarations: [CLChannelStatusInfoComponent],
imports: [SharedModule]
}).
compileComponents();
}));
beforeEach(() => {
@ -22,4 +24,8 @@ describe('CLChannelStatusInfoComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
afterEach(() => {
TestBed.resetTestingModule();
});
});

@ -7,7 +7,9 @@ import { ChannelsStatus } from '../../../shared/models/clModels';
styleUrls: ['./channel-status-info.component.scss']
})
export class CLChannelStatusInfoComponent {
@Input() channelsStatus: ChannelsStatus = {};
@Input() errorMessage: string;
constructor() {}

@ -1,12 +1,19 @@
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Total</h4>
<div class="overflow-wrap dashboard-info-value">{{fees?.feeCollected/1000 | number}} Sats</div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start stretch" *ngIf="errorMessage?.trim() === ''; else errorBlock">
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Total</h4>
<div class="overflow-wrap dashboard-info-value">{{fees?.feeCollected/1000 | number}} Sats</div>
</div>
</div>
</div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Transactions</h4>
<div class="overflow-wrap dashboard-info-value">{{fees?.totalTxCount | number}}</div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Transactions</h4>
<div class="overflow-wrap dashboard-info-value">{{fees?.totalTxCount | number}}</div>
</div>
</div>
</div>
<ng-template #errorBlock>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between" class="p-2">
<p>{{errorMessage}}</p>
</div>
</ng-template>

@ -1,4 +1,5 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { SharedModule } from '../../../shared/shared.module';
import { CLFeeInfoComponent } from './fee-info.component';
@ -6,11 +7,12 @@ describe('CLFeeInfoComponent', () => {
let component: CLFeeInfoComponent;
let fixture: ComponentFixture<CLFeeInfoComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ CLFeeInfoComponent ]
})
.compileComponents();
declarations: [CLFeeInfoComponent],
imports: [SharedModule]
}).
compileComponents();
}));
beforeEach(() => {
@ -22,4 +24,8 @@ describe('CLFeeInfoComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});
afterEach(() => {
TestBed.resetTestingModule();
});
});

@ -7,7 +7,9 @@ import { Fees } from '../../../shared/models/clModels';
styleUrls: ['./fee-info.component.scss']
})
export class CLFeeInfoComponent {
@Input() fees: Fees;
totalFees = [{'name': 'Total', 'value': 0}];
@Input() errorMessage: string;
totalFees = [{ name: 'Total', value: 0 }];
}

@ -1,7 +1,7 @@
<div fxLayout="column" *ngIf="selNode.userPersona === userPersonaEnum.OPERATOR; else merchantDashboard">
<div fxLayout="row" fxLayoutAlign="start start" class="page-title-container mb-0">
<fa-icon [icon]="!flgLoading[0] ? faSmile : faFrown" class="page-title-img mr-1"></fa-icon>
<span class="page-title">{{!flgLoading[0] ? 'Welcome ' + information.alias + '! Your node is up and running.' : 'Error! Please check the server connection.'}}</span>
<fa-icon [icon]="apisCallStatus?.FetchInfo.status === apiCallStatusEnum.ERROR ? faFrown : faSmile" class="page-title-img mr-1"></fa-icon>
<span class="page-title">{{apisCallStatus?.FetchInfo.status === apiCallStatusEnum.COMPLETED ? 'Welcome ' + information.alias + '! Your node is up and running.' : apisCallStatus?.FetchInfo.status === apiCallStatusEnum.INITIATED ? 'Wait! Getting your node information...' : 'Error! Please check the server connection.'}}</span>
</div>
<mat-grid-list cols="10" [rowHeight]="operatorCardHeight">
<mat-grid-tile *ngFor="let card of operatorCards" [colspan]="card.cols" [rowspan]="card.rows">
@ -24,13 +24,26 @@
</div>
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content" fxLayout="column" fxFlex="{{card.id === 'capacity' ? 90 : 70}}">
<mat-card-content fxLayout="column" fxFlex="{{card.id === 'capacity' ? 90 : 70}}"
[ngClass]="{'dashboard-card-content': true,
'error-border': (card.id === 'node' && apisCallStatus?.FetchInfo.status === apiCallStatusEnum.ERROR) ||
(card.id === 'balance' && (apisCallStatus?.FetchBalance.status === apiCallStatusEnum.ERROR || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.ERROR)) ||
(card.id === 'capacity' && (apisCallStatus?.FetchChannels.status === apiCallStatusEnum.ERROR || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.ERROR)) ||
(card.id === 'fee' && (apisCallStatus?.FetchFees.status === apiCallStatusEnum.ERROR || apisCallStatus?.FetchChannels.status === apiCallStatusEnum.ERROR || apisCallStatus?.GetForwardingHistory.status === apiCallStatusEnum.ERROR)) ||
(card.id === 'status' && (apisCallStatus?.FetchInfo.status === apiCallStatusEnum.ERROR || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.ERROR))}">
<mat-progress-bar mode="indeterminate"
*ngIf="(card.id === 'node' && apisCallStatus?.FetchInfo.status === apiCallStatusEnum.INITIATED) ||
(card.id === 'balance' && (apisCallStatus?.FetchBalance.status === apiCallStatusEnum.INITIATED || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.INITIATED)) ||
(card.id === 'capacity' && (apisCallStatus?.FetchChannels.status === apiCallStatusEnum.INITIATED || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.INITIATED)) ||
(card.id === 'fee' && (apisCallStatus?.FetchFees.status === apiCallStatusEnum.INITIATED || apisCallStatus?.FetchChannels.status === apiCallStatusEnum.INITIATED || apisCallStatus?.GetForwardingHistory.status === apiCallStatusEnum.INITIATED)) ||
(card.id === 'status' && (apisCallStatus?.FetchInfo.status === apiCallStatusEnum.INITIATED || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.INITIATED))"
></mat-progress-bar>
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="100">
<rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [showColorFieldSeparately]="false" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-node-info>
<rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error'}"></rtl-cl-balances-info>
<rtl-cl-channel-capacity-info fxFlex="100" *ngSwitchCase="'capacity'" [sortBy]="sortField" [channelBalances]="channelBalances" [allChannels]="allChannelsCapacity" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-capacity-info>
<rtl-cl-fee-info fxFlex="100" *ngSwitchCase="'fee'" [fees]="fees" [ngClass]="{'error-border': flgLoading[1]==='error'}"></rtl-cl-fee-info>
<rtl-cl-channel-status-info fxFlex="100" *ngSwitchCase="'status'" [channelsStatus]="channelsStatus" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-channel-status-info>
<rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [showColorFieldSeparately]="false"></rtl-cl-node-info>
<rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [errorMessage]="errorMessages[2] + ' ' + errorMessages[3]"></rtl-cl-balances-info>
<rtl-cl-channel-capacity-info fxFlex="100" *ngSwitchCase="'capacity'" [sortBy]="sortField" [channelBalances]="channelBalances" [allChannels]="allChannelsCapacity" [errorMessage]="errorMessages[4] + ' ' + errorMessages[3]"></rtl-cl-channel-capacity-info>
<rtl-cl-fee-info fxFlex="100" *ngSwitchCase="'fee'" [fees]="fees" [errorMessage]="errorMessages[1] + ' ' + errorMessages[4] + ' ' + errorMessages[5]"></rtl-cl-fee-info>
<rtl-cl-channel-status-info fxFlex="100" *ngSwitchCase="'status'" [channelsStatus]="channelsStatus" [errorMessage]="errorMessages[0] + ' ' + errorMessages[3]"></rtl-cl-channel-status-info>
<h3 *ngSwitchDefault>Error! Unable to find information!</h3>
</div>
</mat-card-content>
@ -62,12 +75,21 @@
</div>
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content" fxLayout="column" fxLayoutAlign="start stretch" fxFlex="{{card.id === 'transactions' ? 100 : card.id === 'balance' ? 70: 90}}">
<mat-card-content fxLayout="column" fxLayoutAlign="start stretch" fxFlex="{{card.id === 'transactions' ? 100 : card.id === 'balance' ? 70: 90}}"
[ngClass]="{'dashboard-card-content': true,
'error-border': (card.id === 'node' && apisCallStatus?.FetchInfo.status === apiCallStatusEnum.ERROR) ||
(card.id === 'balance' && (apisCallStatus?.FetchBalance.status === apiCallStatusEnum.ERROR || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.ERROR)) ||
((card.id === 'inboundLiq' || card.id === 'outboundLiq') && apisCallStatus?.FetchChannels.status === apiCallStatusEnum.ERROR)}">
<mat-progress-bar mode="indeterminate"
*ngIf="(card.id === 'node' && apisCallStatus?.FetchInfo.status === apiCallStatusEnum.INITIATED) ||
(card.id === 'balance' && (apisCallStatus?.FetchBalance.status === apiCallStatusEnum.INITIATED || apisCallStatus?.FetchLocalRemoteBalance.status === apiCallStatusEnum.INITIATED)) ||
((card.id === 'inboundLiq' || card.id === 'outboundLiq') && apisCallStatus?.FetchChannels.status === apiCallStatusEnum.INITIATED)"
></mat-progress-bar>
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="100">
<rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-node-info>
<rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error'}"></rtl-cl-balances-info>
<rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'inboundLiq'" [direction]="'In'" [totalLiquidity]="totalInboundLiquidity" [allChannels]="allInboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-liquidity-info>
<rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'outboundLiq'" [direction]="'Out'" [totalLiquidity]="totalOutboundLiquidity" [allChannels]="allOutboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-liquidity-info>
<rtl-cl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information"></rtl-cl-node-info>
<rtl-cl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [errorMessage]="errorMessages[2] + ' ' + errorMessages[3]"></rtl-cl-balances-info>
<rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'inboundLiq'" [direction]="'In'" [totalLiquidity]="totalInboundLiquidity" [allChannels]="allInboundChannels" [errorMessage]="errorMessages[4]"></rtl-cl-channel-liquidity-info>
<rtl-cl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'outboundLiq'" [direction]="'Out'" [totalLiquidity]="totalOutboundLiquidity" [allChannels]="allOutboundChannels" [errorMessage]="errorMessages[4]"></rtl-cl-channel-liquidity-info>
<span fxLayout="column" fxFlex="100" fxLayoutAlign="space-between start" *ngSwitchCase="'transactions'">
<mat-tab-group fxLayout="column" class="w-100 dashboard-tabs-group">
<mat-tab label="Receive"><rtl-cl-lightning-invoices class="h-100" [calledFrom]="'home'"></rtl-cl-lightning-invoices></mat-tab>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save