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, "root": true,
"ignorePatterns": [ "ignorePatterns": [
"projects/**/*" "projects/**/*",
"rtl.js",
"/routes/**/*.js",
"/controllers/**/*.js",
"/src/prebuild.js"
], ],
"overrides": [ "overrides": [
{ {
"files": [ "files": [
"*.ts" "*.ts"
], ],
"parser": "@typescript-eslint/parser",
"parserOptions": { "parserOptions": {
"project": [ "ecmaVersion": 2020,
"tsconfig.json", "sourceType": "module",
"e2e/tsconfig.json" "project": "./tsconfig.json",
],
"createDefaultProgram": true "createDefaultProgram": true
}, },
"plugins": ["deprecation"],
"extends": [ "extends": [
"plugin:@angular-eslint/all",
"plugin:@angular-eslint/recommended", "plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/recommended--extra",
"plugin:@angular-eslint/template/process-inline-templates" "plugin:@angular-eslint/template/process-inline-templates"
], ],
"rules": { "rules": {
"@angular-eslint/component-selector": [ "deprecation/deprecation": "error",
"error", "@angular-eslint/use-injectable-provided-in": "off",
{ "@angular-eslint/prefer-on-push-component-change-detection": "off",
"prefix": "rtl", "@angular-eslint/use-component-view-encapsulation": "off",
"style": "kebab-case", "@angular-eslint/sort-ngmodule-metadata-arrays": "off",
"type": "element" "@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" }],
"@angular-eslint/directive-selector": [ "@typescript-eslint/type-annotation-spacing": "error",
"error", "@typescript-eslint/member-delimiter-style": ["error", { "multiline": { "delimiter": "semi", "requireLast": true}, "singleline": { "delimiter": "comma", "requireLast": false }}],
{ "quotes": ["error", "single"],
"style": "camelCase", "comma-dangle": ["error", "never"],
"type": "attribute" "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" "*.html"
], ],
"extends": [ "extends": [
"plugin:@angular-eslint/template/all",
"plugin:@angular-eslint/template/recommended" "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" "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"> <meta charset="utf-8">
<title>RTL</title> <title>RTL</title>
<base href="/rtl/"> <base href="/rtl/">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta i18n-content="" 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 i18n-sizes="" i18n-rel="" 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 i18n-sizes="" i18n-rel="" 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 i18n-sizes="" i18n-rel="" 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 i18n-rel="" rel="manifest" href="assets/images/favicon-light/site.webmanifest">
<link rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5"> <link i18n-rel="" rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c"> <meta i18n-content="" name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff"> <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.97554e699a42acff6579.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.97554e699a42acff6579.css"></noscript></head> <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> <body>
<rtl-app></rtl-app> <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> </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'; options.url = common.getSelLNServerUrl() + '/v1/getBalance';
request(options).then((body) => { request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Balance', msg: 'Balance Received', data: body}); logger.log({level: 'DEBUG', fileName: 'Balance', msg: 'Balance Received', data: body});
if(!body.totalBalance) { if (!body.totalBalance) { body.totalBalance = 0; }
body.totalBalance = 0; if (!body.confBalance) { body.confBalance = 0; }
body.btc_totalBalance = 0; if (!body.unconfBalance) { body.unconfBalance = 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);
}
logger.log({level: 'INFO', fileName: 'Balance', msg: 'Balance Received'}); logger.log({level: 'INFO', fileName: 'Balance', msg: 'Balance Received'});
res.status(200).json(body); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Balance', 'Get Balance Error');
if (err.options && err.options.headers && err.options.headers.macaroon) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };

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

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

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

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

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

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

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

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

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

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

@ -81,18 +81,8 @@ exports.getFees = (req, res, next) => {
res.status(200).json(arrangeFees(body, Math.round((new Date().getTime())))); res.status(200).json(arrangeFees(body, Math.round((new Date().getTime()))));
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Fees', 'Get Fees Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
} }
}; };
@ -111,18 +101,8 @@ exports.getPayments = (req, res, next) => {
res.status(200).json(arrangePayments(body)); res.status(200).json(arrangePayments(body));
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Fees', 'Get Payments Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
} }
}; };

@ -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}); logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Calling Info from Eclair server url', data: options.url});
if (common.read_dummy_data) { if (common.read_dummy_data) {
common.getDummyData('GetInfo').then(function(data) { common.getDummyData('GetInfo').then(function(data) {
data.currency_unit = 'BTC';
data.smaller_currency_unit = 'Sats';
data.lnImplementation = 'Eclair'; data.lnImplementation = 'Eclair';
res.status(200).json(data); res.status(200).json(data);
}); });
} else { } else {
if (!options.headers || !options.headers.authorization) { 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.'}}); const errMsg = 'Eclair Get info failed due to missing or wrong password!';
res.status(502).json({ const err = common.handleError({ statusCode: 502, message: 'Missing or Wrong Password', error: errMsg }, 'GetInfo', errMsg);
message: "Fetching Info Failed!", return res.status(err.statusCode).json({message: err.message, error: err.error});
error: "Missing Or Wrong Password"
});
} else { } else {
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'GetInfo', msg: 'Get Info Response', data: 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'; body.lnImplementation = 'Eclair';
logger.log({level: 'INFO', fileName: 'GetInfo', msg: 'Eclair Node Information Received'}); logger.log({level: 'INFO', fileName: 'GetInfo', msg: 'Eclair Node Information Received'});
res.status(200).json(body); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'GetInfo', 'Get Info Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
} }
} }

@ -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) => { exports.listInvoices = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Getting List Invoices..'}); logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Getting List Invoices..'});
options = common.getOptions(); options = common.getOptions();
@ -65,18 +84,8 @@ exports.listInvoices = (req, res, next) => {
res.status(200).json(invoices); res.status(200).json(invoices);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Invoices', 'List Invoices Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
} else { } else {
logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Empty List Invoice Received'}); logger.log({level: 'INFO', fileName: 'Invoices', msg: 'Empty List Invoice Received'});
@ -84,18 +93,8 @@ exports.listInvoices = (req, res, next) => {
} }
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Invoices', 'List Invoices Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
} }
}; };
@ -112,17 +111,7 @@ exports.createInvoice = (req, res, next) => {
res.status(201).json(body); res.status(201).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Invoices', 'Create Invoice Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
}; };

@ -14,17 +14,7 @@ exports.getNodes = (req, res, next) => {
res.status(200).json(body); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Network', 'Node Lookup Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
}; };

@ -4,18 +4,8 @@ var logger = require('../shared/logger');
var options = {}; var options = {};
arrangeBalances = (body) => { arrangeBalances = (body) => {
if(!body.confirmed) { if (!body.confirmed) { body.confirmed = 0; }
body.confirmed = 0; if (!body.unconfirmed) { body.unconfirmed = 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);
}
body.total = +body.confirmed + +body.unconfirmed; body.total = +body.confirmed + +body.unconfirmed;
body.btc_total = +body.btc_confirmed + +body.btc_unconfirmed; body.btc_total = +body.btc_confirmed + +body.btc_unconfirmed;
return body; return body;
@ -32,18 +22,8 @@ exports.getNewAddress = (req, res, next) => {
res.status(200).json(body); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'OnChain', 'Get New Address Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
}; };
@ -61,18 +41,8 @@ exports.getBalance = (req, res, next) => {
res.status(200).json(arrangeBalances(body)); res.status(200).json(arrangeBalances(body));
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'OnChain', 'Get Balance Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
} }
}; };
@ -95,18 +65,8 @@ exports.getTransactions = (req, res, next) => {
res.status(200).json(body); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'OnChain', 'Get Transactions Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
}; };
@ -126,17 +86,7 @@ exports.sendFunds = (req, res, next) => {
res.status(201).json(body); res.status(201).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'OnChain', 'Send Funds Error');
if (err.options && err.options.headers && err.options.headers.authorization) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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"
});
}); });
}; };

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

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

@ -6,7 +6,7 @@ var options = {};
exports.getBalance = (req, res, next) => { exports.getBalance = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Balance', msg: 'Getting Balance..'}); logger.log({level: 'INFO', fileName: 'Balance', msg: 'Getting Balance..'});
options = common.getOptions(); 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; options.qs = req.query;
request(options).then((body) => { request(options).then((body) => {
logger.log({level: 'DEBUG', fileName: 'Balance', msg: '[Request params, Request Query, Balance Received]', data: [req.params, req.query, 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.total_balance) { body.total_balance = 0; }
if (!body.confirmed_balance) { body.confirmed_balance = 0; } if (!body.confirmed_balance) { body.confirmed_balance = 0; }
if (!body.unconfirmed_balance) { body.unconfirmed_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 (req.params.source === 'channels') {
if (!body.balance) { body.balance = 0; } if (!body.balance) { body.balance = 0; }
if (!body.pending_open_balance) { body.pending_open_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'}); logger.log({level: 'INFO', fileName: 'Balance', msg: 'Balance Received'});
res.status(200).json(body); res.status(200).json(body);
} }
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Balance', 'Get Balance Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -25,11 +25,11 @@ getFailedInfo = (reqIP, currentTime) => {
return failed; return failed;
} }
handleError = (failed, currentTime, errMsg) => { handleMultipleFailedAttemptsError = (failed, currentTime, errMsg) => {
if (failed.count >= ALLOWED_LOGIN_ATTEMPTS && (currentTime <= (failed.lastTried + LOCKING_PERIOD))) { if (failed.count >= ALLOWED_LOGIN_ATTEMPTS && (currentTime <= (failed.lastTried + LOCKING_PERIOD))) {
return { return {
message: "Multiple Failed Login Attempts!", 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 { } else {
return { return {
@ -48,24 +48,19 @@ exports.verifyToken = (twoFAToken) => {
exports.authenticateUser = (req, res, next) => { exports.authenticateUser = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..'}); logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Authenticating User..'});
if(+common.rtl_sso) { if (+common.rtl_sso) {
if(req.body.authenticateWith === 'JWT' && jwt.verify(req.body.authenticationValue, common.secret_key)) { if (req.body.authenticateWith === 'JWT' && jwt.verify(req.body.authenticationValue, common.secret_key)) {
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated'}); logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated'});
res.status(200).json({ token: token }); 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'))) { } 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); connect.refreshCookie(common.rtl_cookie_path);
const token = jwt.sign( const token = jwt.sign({ user: 'SSO_USER' }, common.secret_key);
{ user: 'SSO_USER', configPath: common.nodes[0].config_path, macaroonPath: common.nodes[0].macaroon_path },
common.secret_key
);
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated.'}); logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated.'});
res.status(200).json({ token: token }); res.status(200).json({ token: token });
} else { } 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.'}}); const errMsg = 'SSO Authentication Failed! Access key too short or does not match.';
res.status(406).json({ const err = common.handleError({ statusCode: 406, message: 'SSO Authentication Error', error: errMsg }, 'Authenticate', errMsg);
message: "SSO Authentication Failed!", return res.status(err.statusCode).json({message: err.message, error: err.error});
error: "SSO failed. Access key too short or does not match."
});
} }
} else { } else {
const currentTime = new Date().getTime(); 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.'}}); logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Token! Failed IP ' + reqIP, error: {error: 'Invalid token.'}});
failed.count = failed.count + 1; failed.count = failed.count + 1;
failed.lastTried = currentTime; failed.lastTried = currentTime;
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]; delete failedLoginAttempts[reqIP];
let rpcUser = 'NODE_USER'; const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
const token = jwt.sign(
{ user: rpcUser, configPath: common.nodes[0].config_path, macaroonPath: common.nodes[0].macaroon_path },
common.secret_key
);
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated'}); logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'User Authenticated'});
res.status(200).json({ token: token }); res.status(200).json({ token: token });
} else { } else {
logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'Invalid Password! Failed IP ' + reqIP, error: {error: 'Invalid password.'}}); 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.count = common.rtl_pass !== password ? (failed.count + 1) : failed.count;
failed.lastTried = common.rtl_pass !== password ? currentTime : failed.lastTried; 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) => { exports.resetPassword = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..'}); logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Resetting Password..'});
if(+common.rtl_sso) { if (+common.rtl_sso) {
logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'Password Reset Failed!', error: {error: 'Password reset failed.'}}); const errMsg = 'Password cannot be reset for SSO authentication';
res.status(401).json({ const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg);
message: "Password Reset Failed!", return res.status(err.statusCode).json({message: err.message, error: err.error});
error: "Password cannot be reset for SSO authentication!"
});
} else { } else {
const currPassword = req.body.currPassword; const currPassword = req.body.currPassword;
if (common.rtl_pass === currPassword) { if (common.rtl_pass === currPassword) {
common.rtl_pass = connect.replacePasswordWithHash(req.body.newPassword); common.rtl_pass = connect.replacePasswordWithHash(req.body.newPassword);
var rpcUser = 'NODE_USER'; const token = jwt.sign({ user: 'NODE_USER' }, common.secret_key);
const token = jwt.sign(
{ user: rpcUser, configPath: common.nodes[0].config_path, macaroonPath: common.nodes[0].macaroon_path },
common.secret_key
);
logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful'}); logger.log({level: 'INFO', fileName: 'Authenticate', msg: 'Password Reset Successful'});
res.status(200).json({ token: token }); res.status(200).json({ token: token });
} else { } else {
logger.log({level: 'ERROR', fileName: 'Authenticate', msg: 'Password Reset Failed!', error: {error: 'Password reset failed.'}}); const errMsg = 'Incorrect Old Password';
res.status(401).json({ const err = common.handleError({ statusCode: 401, message: 'Password Reset Error', error: errMsg }, 'Authenticate', errMsg);
message: "Password Reset Failed!", return res.status(err.statusCode).json({message: err.message, error: err.error});
error: "Old password is not correct!"
});
} }
} }
}; };

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

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

@ -6,7 +6,11 @@ var options = {};
exports.loopOut = (req, res, next) => { exports.loopOut = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Looping Out..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Looping Out..'});
options = common.getSwapServerOptions(); 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.url = options.url + '/v1/loop/out';
options.body = { options.body = {
amt: req.body.amount, 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}); logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Body', data: options.body});
request.post(options).then(loopOutRes => { request.post(options).then(loopOutRes => {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out', data: loopOutRes}); logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out', data: loopOutRes});
if(!loopOutRes || loopOutRes.error) { logger.log({level: 'INFO', fileName: 'Loop', msg: 'Loop Out Finished'});
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop Out Error', error: loopOutRes.error}); res.status(201).json(loopOutRes);
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);
}
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop Out Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.loopOutTerms = (req, res, next) => { exports.loopOutTerms = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Terms..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Terms..'});
options = common.getSwapServerOptions(); 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'; options.url = options.url + '/v1/loop/out/terms';
request(options).then(function (body) { request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Terms', data: 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); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop Out Terms Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.loopOutQuote = (req, res, next) => { exports.loopOutQuote = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Quotes..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Quotes..'});
options = common.getSwapServerOptions(); 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; 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}); logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Quote URL', data: options.url});
request(options).then(function (quoteRes) { request(options).then(function (quoteRes) {
@ -91,25 +75,19 @@ exports.loopOutQuote = (req, res, next) => {
res.status(200).json(quoteRes); res.status(200).json(quoteRes);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop Out Quotes Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.loopOutTermsAndQuotes = (req, res, next) => { exports.loopOutTermsAndQuotes = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Terms & Quotes..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop Out Terms & Quotes..'});
options = common.getSwapServerOptions(); 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'; options.url = options.url + '/v1/loop/out/terms';
request(options).then(function(terms) { request(options).then(function(terms) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Out Terms', data: 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); res.status(200).json(values);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop Out Terms & Quotes Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop Out Terms & Quotes Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.loopIn = (req, res, next) => { exports.loopIn = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Looping In..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Looping In..'});
options = common.getSwapServerOptions(); 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.url = options.url + '/v1/loop/in';
options.body = { options.body = {
amt: req.body.amount, 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}); logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Body', data: options.body});
request.post(options).then(function (body) { request.post(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In', data: body}); logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In', data: body});
if(!body || body.error) { logger.log({level: 'INFO', fileName: 'Loop', msg: 'Loop In Finished'});
logger.log({level: 'ERROR', fileName: 'Loop', msg: 'Loop In Error', error: body.error}); res.status(201).json(body);
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);
}
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop In Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.loopInTerms = (req, res, next) => { exports.loopInTerms = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Terms..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Terms..'});
options = common.getSwapServerOptions(); 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'; options.url = options.url + '/v1/loop/in/terms';
request(options).then(function (body) { request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Terms', data: 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); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop In Terms Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.loopInQuote = (req, res, next) => { exports.loopInQuote = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Quotes..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Quotes..'});
options = common.getSwapServerOptions(); 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; 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}); logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Quote Options', data: options.url});
request(options).then(function (body) { request(options).then(function (body) {
@ -240,25 +182,19 @@ exports.loopInQuote = (req, res, next) => {
res.status(200).json(body); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop In Quote Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.loopInTermsAndQuotes = (req, res, next) => { exports.loopInTermsAndQuotes = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Terms & Quotes..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Loop In Terms & Quotes..'});
options = common.getSwapServerOptions(); 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'; options.url = options.url + '/v1/loop/in/terms';
request(options).then(function(terms) { request(options).then(function(terms) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop In Terms', data: 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); res.status(200).json(values);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop In Terms & Quotes Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Loop In Terms & Quotes Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.swaps = (req, res, next) => { exports.swaps = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting List Swaps..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting List Swaps..'});
options = common.getSwapServerOptions(); 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'; options.url = options.url + '/v1/loop/swaps';
request(options).then(function (body) { request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Swaps', data: 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); res.status(200).json(body.swaps);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'List Swaps Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };
exports.swap = (req, res, next) => { exports.swap = (req, res, next) => {
logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Swap Information..'}); logger.log({level: 'INFO', fileName: 'Loop', msg: 'Getting Swap Information..'});
options = common.getSwapServerOptions(); 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; options.url = options.url + '/v1/loop/swap/' + req.params.id;
request(options).then(function (body) { request(options).then(function (body) {
logger.log({level: 'DEBUG', fileName: 'Loop', msg: 'Loop Swap', data: 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); res.status(200).json(body);
}) })
.catch(errRes => { .catch(errRes => {
let err = JSON.parse(JSON.stringify(errRes)); const err = common.handleError(errRes, 'Loop', 'Get Swap Error');
if (err.options && err.options.headers && err.options.headers['Grpc-Metadata-macaroon']) { return res.status(err.statusCode).json({message: err.message, error: err.error});
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
});
}); });
}; };

@ -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>", "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>", "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>", "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>, "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>", "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", "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", "themeMode": "DAY",
"themeColor": "PURPLE", "themeColor": "PURPLE",
"bitcoindConfigPath": "", "bitcoindConfigPath": "",
"enableLogging": true, "logLevel": "INFO",
"fiatConversion": false, "fiatConversion": false,
"lnServerUrl": "https://<cl-rest api server ip address>:3001" "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 #### <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. 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 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 ##### 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 ##### Angular Server for Development
##### Package Angular Updates * 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.
##### Create a New Branch * 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 ##### 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. * 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 the adding the library * Confirm before starting by creating an issue about adding the library
* The library should be popular, well maintained and pre-existing vulnerability free. * 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", "themeMode": "DAY",
"themeColor": "PURPLE", "themeColor": "PURPLE",
"bitcoindConfigPath": "", "bitcoindConfigPath": "",
"enableLogging": true, "logLevel": "INFO",
"fiatConversion": false, "fiatConversion": false,
"lnServerUrl": "http://<eclair api server ip address>:port" "lnServerUrl": "http://<eclair api server ip address>:port"
} }

@ -104,7 +104,7 @@ Example RTL-Config.json:
"themeColor": "PURPLE", "themeColor": "PURPLE",
"channelBackupPath": "C:\\RTL\\backup\\node-1", "channelBackupPath": "C:\\RTL\\backup\\node-1",
"bitcoindConfigPath": "<Optional: path of bitcoind.conf path if available locally>", "bitcoindConfigPath": "<Optional: path of bitcoind.conf path if available locally>",
"enableLogging": true, "logLevel": "INFO",
"fiatConversion": false, "fiatConversion": false,
"lnServerUrl": "<url for LND REST APIs for node #1 e.g. https://192.168.0.1:8080>", "lnServerUrl": "<url for LND REST APIs for node #1 e.g. https://192.168.0.1:8080>",
"swapServerUrl": "<url for swap server REST APIs for the node. e.g. https://localhost:8081>", "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", "themeColor": "PURPLE",
"channelBackupPath": "<RTL Root path + \backup\node-1>", "channelBackupPath": "<RTL Root path + \backup\node-1>",
"bitcoindConfigPath": "<Optional: path of bitcoind.conf path if available locally>", "bitcoindConfigPath": "<Optional: path of bitcoind.conf path if available locally>",
"enableLogging": false, "logLevel": "INFO",
"fiatConversion": false, "fiatConversion": false,
"lnServerUrl": "<https://<ip-address-of-device-running-lnd>:8080; e.g. https://192.168.0.1:8080>", "lnServerUrl": "<https://<ip-address-of-device-running-lnd>:8080; e.g. https://192.168.0.1:8080>",
"swapServerUrl": "<https://<localhost>:8081>", "swapServerUrl": "<https://<localhost>:8081>",

@ -23,7 +23,7 @@
"themeMode": "DAY", "themeMode": "DAY",
"themeColor": "PURPLE", "themeColor": "PURPLE",
"channelBackupPath": "C:\\Users\\xyz\\backup\\node-1", "channelBackupPath": "C:\\Users\\xyz\\backup\\node-1",
"enableLogging": false, "logLevel": "ERROR",
"lnServerUrl": "https://localhost:8080", "lnServerUrl": "https://localhost:8080",
"swapServerUrl": "https://localhost:8081", "swapServerUrl": "https://localhost:8081",
"boltzServerUrl": "https://localhost:9003", "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", "name": "rtl",
"version": "0.11.0-beta", "version": "0.11.1-beta",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -1657,9 +1657,9 @@
"dev": true "dev": true
}, },
"@eslint/eslintrc": { "@eslint/eslintrc": {
"version": "0.4.2", "version": "0.4.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
"integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
"dev": true, "dev": true,
"requires": { "requires": {
"ajv": "^6.12.4", "ajv": "^6.12.4",
@ -1674,9 +1674,9 @@
}, },
"dependencies": { "dependencies": {
"globals": { "globals": {
"version": "13.9.0", "version": "13.10.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
"integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
"dev": true, "dev": true,
"requires": { "requires": {
"type-fest": "^0.20.2" "type-fest": "^0.20.2"
@ -1733,6 +1733,23 @@
"@fortawesome/fontawesome-common-types": "^0.2.35" "@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": { "@istanbuljs/schema": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
@ -2374,9 +2391,9 @@
"dev": true "dev": true
}, },
"acorn-jsx": { "acorn-jsx": {
"version": "5.3.1", "version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true "dev": true
}, },
"adjust-sourcemap-loader": { "adjust-sourcemap-loader": {
@ -4450,15 +4467,15 @@
} }
}, },
"css-select": { "css-select": {
"version": "3.1.2", "version": "4.1.3",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-3.1.2.tgz", "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.1.3.tgz",
"integrity": "sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==", "integrity": "sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==",
"dev": true, "dev": true,
"requires": { "requires": {
"boolbase": "^1.0.0", "boolbase": "^1.0.0",
"css-what": "^4.0.0", "css-what": "^5.0.0",
"domhandler": "^4.0.0", "domhandler": "^4.2.0",
"domutils": "^2.4.3", "domutils": "^2.6.0",
"nth-check": "^2.0.0" "nth-check": "^2.0.0"
} }
}, },
@ -4473,9 +4490,9 @@
} }
}, },
"css-what": { "css-what": {
"version": "4.0.0", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-4.0.0.tgz", "resolved": "https://registry.npmjs.org/css-what/-/css-what-5.0.1.tgz",
"integrity": "sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==", "integrity": "sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg==",
"dev": true "dev": true
}, },
"cssdb": { "cssdb": {
@ -5344,13 +5361,14 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
}, },
"eslint": { "eslint": {
"version": "7.28.0", "version": "7.32.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
"integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@babel/code-frame": "7.12.11", "@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", "ajv": "^6.10.0",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"cross-spawn": "^7.0.2", "cross-spawn": "^7.0.2",
@ -5409,9 +5427,9 @@
} }
}, },
"chalk": { "chalk": {
"version": "4.1.1", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-styles": "^4.1.0", "ansi-styles": "^4.1.0",
@ -5451,9 +5469,9 @@
"dev": true "dev": true
}, },
"globals": { "globals": {
"version": "13.9.0", "version": "13.10.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz",
"integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==",
"dev": true, "dev": true,
"requires": { "requires": {
"type-fest": "^0.20.2" "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": { "eslint-scope": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@ -6027,9 +6114,9 @@
} }
}, },
"flatted": { "flatted": {
"version": "3.1.1", "version": "3.2.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz",
"integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==",
"dev": true "dev": true
}, },
"flatten": { "flatten": {
@ -7637,9 +7724,9 @@
} }
}, },
"jszip": { "jszip": {
"version": "3.6.0", "version": "3.7.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.6.0.tgz", "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz",
"integrity": "sha512-jgnQoG9LKnWO3mnVNBnfhkh0QknICd1FGSrXcgrl67zioyJ4wgx25o9ZqwNtrROSflGBCGYnJfjrIyRIby1OoQ==", "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==",
"dev": true, "dev": true,
"requires": { "requires": {
"lie": "~3.3.0", "lie": "~3.3.0",
@ -13066,15 +13153,15 @@
} }
}, },
"svgo": { "svgo": {
"version": "2.3.0", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.0.tgz", "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.3.1.tgz",
"integrity": "sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q==", "integrity": "sha512-riDDIQgXpEnn0BEl9Gvhh1LNLIyiusSpt64IR8upJu7MwxnzetmF/Y57pXQD2NMX2lVyMRzXt5f2M5rO4wG7Dw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@trysound/sax": "0.1.1", "@trysound/sax": "0.1.1",
"chalk": "^4.1.0", "chalk": "^4.1.0",
"commander": "^7.1.0", "commander": "^7.1.0",
"css-select": "^3.1.2", "css-select": "^4.1.3",
"css-tree": "^1.1.2", "css-tree": "^1.1.2",
"csso": "^4.2.0", "csso": "^4.2.0",
"stable": "^0.1.8" "stable": "^0.1.8"
@ -13090,9 +13177,9 @@
} }
}, },
"chalk": { "chalk": {
"version": "4.1.1", "version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-styles": "^4.1.0", "ansi-styles": "^4.1.0",
@ -13152,9 +13239,9 @@
}, },
"dependencies": { "dependencies": {
"ajv": { "ajv": {
"version": "8.6.0", "version": "8.6.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz",
"integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==",
"dev": true, "dev": true,
"requires": { "requires": {
"fast-deep-equal": "^3.1.1", "fast-deep-equal": "^3.1.1",
@ -13178,9 +13265,9 @@
"dev": true "dev": true
}, },
"tar": { "tar": {
"version": "6.1.0", "version": "6.1.8",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.8.tgz",
"integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "integrity": "sha512-sb9b0cp855NbkMJcskdSYA7b11Q8JsX4qe4pyUAfHp+Y6jBjJeek2ZVlwEfWayshEIwlIzXx0Fain3QG9JPm2A==",
"dev": true, "dev": true,
"requires": { "requires": {
"chownr": "^2.0.0", "chownr": "^2.0.0",
@ -13765,9 +13852,9 @@
} }
}, },
"url-parse": { "url-parse": {
"version": "1.5.1", "version": "1.5.3",
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz",
"integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"querystringify": "^2.1.1", "querystringify": "^2.1.1",

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

@ -157,10 +157,6 @@ common.replaceNode = (selNodeIndex, newNode) => {
common.selectedNode = common.findNode(selNodeIndex); common.selectedNode = common.findNode(selNodeIndex);
} }
common.convertToBTC = (num) => {
return (num / 100000000).toFixed(6);
};
common.convertTimestampToTime = (num) => { common.convertTimestampToTime = (num) => {
let myDate = new Date(+num * 1000); let myDate = new Date(+num * 1000);
let days = myDate.getDate().toString(); let days = myDate.getDate().toString();
@ -213,6 +209,58 @@ common.newestOnTop = (array, key, value) => {
return array; 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) => { common.getRequestIP = (req) => {
return (typeof req.headers['x-forwarded-for'] === 'string' && req.headers['x-forwarded-for'].split(',').shift()) return (typeof req.headers['x-forwarded-for'] === 'string' && req.headers['x-forwarded-for'].split(',').shift())
|| req.ip || req.ip
@ -249,41 +297,36 @@ common.getMonthDays = (selMonth, selYear) => {
filterData = (data_key) => { filterData = (data_key) => {
let search_string = ''; let search_string = '';
switch (data_key) { if (common.selectedNode.ln_implementation === 'ECL') {
case 'GetInfo': switch (data_key) {
search_string = 'INFO: GetInfo => Get Info Response: '; case 'GetInfo': search_string = 'INFO: GetInfo => Get Info Response: '; break;
break; case 'Fees': search_string = 'INFO: Fees => Fee Response: '; break;
case 'Payments': search_string = 'INFO: Fees => Payments Response: '; break;
case 'Fees': case 'Invoices': search_string = 'INFO: Invoice => Invoices List Received: '; break;
search_string = 'INFO: Fees => Fee Response: '; case 'OnChainBalance': search_string = 'INFO: Onchain => Balance Received: '; break;
break; case 'Peers': search_string = 'INFO: Peers => Peers with Alias: '; break;
case 'Channels': search_string = 'INFO: Channels => Simplified Channels with Alias: '; break;
case 'Payments': default: search_string = 'Random Line'; break;
search_string = 'INFO: Fees => Payments Response: '; }
break; } else if (common.selectedNode.ln_implementation === 'CLT') {
switch (data_key) {
case 'Invoices': case 'GetInfo': search_string = 'DEBUG: GetInfo => Node Information. '; break;
search_string = 'INFO: Invoice => Invoices List Received: '; case 'Fees': search_string = 'DEBUG: Fees => Fee Received. '; break;
break; case 'Payments': search_string = 'DEBUG: Payments => Payment List Received: '; break;
case 'Invoices': search_string = 'DEBUG: Invoice => Invoices List Received. '; break;
case 'OnChainBalance': case 'ChannelBalance': search_string = 'DEBUG: Channels => Local Remote Balance. '; break;
search_string = 'INFO: Onchain => Balance Received: '; case 'Peers': search_string = 'DEBUG: Peers => Peers with Alias: '; break;
break; case 'Channels': search_string = 'DEBUG: Channels => List Channels: '; break;
case 'Balance': search_string = 'DEBUG: Balance => Balance Received. '; break;
case 'Peers': case 'ForwardingHistory': search_string = 'DEBUG: Channels => Forwarding History Received: '; break;
search_string = 'INFO: Peers => Peers with Alias: '; case 'UTXOs': search_string = 'DEBUG: OnChain => List Funds Received. '; break;
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;
case 'Channels': default: search_string = 'Random Line'; break;
search_string = 'INFO: Channels => Simplified Channels with Alias: '; }
break;
default:
search_string = 'INFO: GetInfo => Get Info Response: ';
break;
} }
let foundDataLine = dummy_data_array_from_file.find(dataItem => dataItem.includes(search_string)); 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); return JSON.parse(dataStr);
} }

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

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

@ -3,7 +3,8 @@ const express = require("express");
const router = express.Router(); const router = express.Router();
const authCheck = require("./authCheck"); 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("/", authCheck, RTLConfController.updateUISettings);
router.post("/update2FA", authCheck, RTLConfController.update2FASettings); router.post("/update2FA", authCheck, RTLConfController.update2FASettings);
router.get("/config/:nodeType", authCheck, RTLConfController.getConfig); router.get("/config/:nodeType", authCheck, RTLConfController.getConfig);

@ -7,9 +7,8 @@ module.exports = (req, res, next) => {
jwt.verify(token, common.secret_key); jwt.verify(token, common.secret_key);
next(); next();
} catch (error) { } catch (error) {
res.status(401).json({ const errMsg = 'Authentication Failed! Please Login First!';
message: "Authentication Failed!", const err = common.handleError({ statusCode: 401, message: 'Authentication Error', error: errMsg }, 'AuthCheck', errMsg);
error: "Authentication Failed! Please Login First!" 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] animations: [routeAnimation]
}) })
export class AppComponent implements OnInit, AfterViewInit, OnDestroy { export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('sideNavigation', { static: false }) sideNavigation: any; @ViewChild('sideNavigation', { static: false }) sideNavigation: any;
@ViewChild('sideNavContent', { static: false }) sideNavContent: any; @ViewChild('sideNavContent', { static: false }) sideNavContent: any;
public selNode: ConfigSettingsNode; public selNode: ConfigSettingsNode;
@ -42,90 +43,99 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
public flgLoggedIn = false; public flgLoggedIn = false;
unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()]; 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, constructor(
private userIdle: UserIdleService, private router: Router, private sessionService: SessionService, private breakpointObserver: BreakpointObserver, private renderer: Renderer2) {} 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() { ngOnInit() {
this.router.events.subscribe((evt) => { this.router.events.subscribe((evt) => {
if (!(evt instanceof NavigationEnd)) { return; } if (!(evt instanceof NavigationEnd)) {
document.getElementsByTagName('mat-sidenav-content')[0].scrollTo(0, 0); return;
});
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;
} }
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.store.dispatch(new RTLActions.FetchRTLConfig());
this.accessKey = this.readAccessKey(); this.accessKey = this.readAccessKey();
this.store.select('root') this.store.select('root').
.pipe(takeUntil(this.unSubs[1])) pipe(takeUntil(this.unSubs[1])).
.subscribe(rtlStore => { subscribe((rtlStore) => {
this.selNode = rtlStore.selNode; this.selNode = rtlStore.selNode;
this.settings = this.selNode.settings; this.settings = this.selNode.settings;
this.appConfig = rtlStore.appConfig; this.appConfig = rtlStore.appConfig;
this.information = rtlStore.nodeData; this.information = rtlStore.nodeData;
this.flgLoading[0] = ( this.information.identity_pubkey) ? false : true; this.flgLoading[0] = !(this.information.identity_pubkey);
this.logger.info(this.settings); this.logger.info(this.settings);
if (!this.sessionService.getItem('token')) { if (!this.sessionService.getItem('token')) {
this.flgLoggedIn = false; this.flgLoggedIn = false;
this.flgLoading[0] = false; this.flgLoading[0] = false;
} else { } else {
this.flgLoggedIn = true; this.flgLoggedIn = true;
this.userIdle.startWatching(); this.userIdle.startWatching();
} }
}); });
if (this.sessionService.getItem('defaultPassword') === 'true') { if (this.sessionService.getItem('defaultPassword') === 'true') {
this.flgSideNavOpened = false; this.flgSideNavOpened = false;
} }
this.actions$.pipe(takeUntil(this.unSubs[2]), this.actions.pipe(
filter((action) => action.type === RTLActions.SET_RTL_CONFIG || action.type === RTLActions.LOGOUT)) takeUntil(this.unSubs[2]),
.subscribe((action: (RTLActions.SetRTLConfig | RTLActions.Logout)) => { filter((action) => action.type === RTLActions.SET_RTL_CONFIG || action.type === RTLActions.LOGOUT)).
if (action.type === RTLActions.SET_RTL_CONFIG) { subscribe((action: (RTLActions.SetRTLConfig | RTLActions.Logout)) => {
if (!this.sessionService.getItem('token')) { if (action.type === RTLActions.SET_RTL_CONFIG) {
if (+action.payload.sso.rtlSSO) { if (!this.sessionService.getItem('token')) {
if(!this.accessKey || this.accessKey.trim().length < 32) { if (+action.payload.sso.rtlSSO) {
this.router.navigate(['./error'], { state: {errorCode: '406', errorMessage: 'Access key too short. It should be at least 32 characters long.'} }); 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 { } 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) {
if (action.type === RTLActions.LOGOUT) { this.flgLoggedIn = false;
this.flgLoggedIn = false; this.userIdle.stopWatching();
this.userIdle.stopWatching(); this.userIdle.stopTimer();
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.userIdle.onTimeout().pipe(takeUntil(this.unSubs[4])).subscribe(() => {
this.logger.info('Time Out!'); this.logger.info('Time Out!');
if (this.sessionService.getItem('token')) { if (this.sessionService.getItem('token')) {
this.flgLoggedIn = false; this.flgLoggedIn = false;
this.logger.warn('Time limit exceeded for session inactivity.'); this.logger.warn('Time limit exceeded for session inactivity.');
this.store.dispatch(new RTLActions.CloseAllDialogs()); this.store.dispatch(new RTLActions.CloseAllDialogs());
this.store.dispatch(new RTLActions.OpenAlert({ data: { this.store.dispatch(new RTLActions.OpenAlert({
type: AlertTypeEnum.WARNING, data: {
alertTitle: 'Logging out', type: AlertTypeEnum.WARNING,
titleMessage: 'Time limit exceeded for session inactivity.' alertTitle: 'Logging out',
}})); titleMessage: 'Time limit exceeded for session inactivity.'
}
}));
this.store.dispatch(new RTLActions.Logout()); this.store.dispatch(new RTLActions.Logout());
} }
}); });
@ -146,7 +156,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
} else { } else {
setTimeout(() => { setTimeout(() => {
if (this.flgLoggedIn) { 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); this.commonService.setContainerSize(this.sideNavContent.elementRef.nativeElement.clientWidth, this.sideNavContent.elementRef.nativeElement.clientHeight);
}, 100); }, 100);
@ -166,14 +176,17 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
copiedText(payload: string) { copiedText(payload: string) {
this.flgCopied = true; this.flgCopied = true;
setTimeout(() => {this.flgCopied = false; }, 5000); setTimeout(() => {
this.flgCopied = false;
}, 5000);
this.logger.info('Copied Text: ' + payload); this.logger.info('Copied Text: ' + payload);
} }
ngOnDestroy() { ngOnDestroy() {
this.unSubs.forEach(unsub => { this.unSubs.forEach((unsub) => {
unsub.next(); unsub.next();
unsub.complete(); 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 { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { HTTP_INTERCEPTORS } from '@angular/common/http'; import { HTTP_INTERCEPTORS } from '@angular/common/http';
@ -30,13 +30,12 @@ import { LayoutModule } from '@angular/cdk/layout';
@NgModule({ @NgModule({
imports: [ imports: [
BrowserModule,
BrowserAnimationsModule, BrowserAnimationsModule,
SharedModule, SharedModule,
routing, routing,
LayoutModule, LayoutModule,
HammerModule, HammerModule,
UserIdleModule.forRoot({idle: 3590, timeout: 10, ping: 12000}), // One hour UserIdleModule.forRoot({ idle: 3590, timeout: 10, ping: 12000 }), // One hour
StoreModule.forRoot(RTLReducer, { StoreModule.forRoot(RTLReducer, {
runtimeChecks: { runtimeChecks: {
strictStateImmutability: false, strictStateImmutability: false,

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

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

@ -20,11 +20,13 @@ import { CLLookupsComponent } from './lookups/lookups.component';
import { CLRoutingComponent } from './routing/routing.component'; import { CLRoutingComponent } from './routing/routing.component';
import { CLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component'; import { CLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component';
import { CLFailedTransactionsComponent } from './routing/failed-transactions/failed-transactions.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 { CLChannelLookupComponent } from './lookups/channel-lookup/channel-lookup.component';
import { CLNodeLookupComponent } from './lookups/node-lookup/node-lookup.component'; import { CLNodeLookupComponent } from './lookups/node-lookup/node-lookup.component';
import { CLQueryRoutesComponent } from './transactions/query-routes/query-routes.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 { 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 { 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 { CLNodeInfoComponent } from './home/node-info/node-info.component';
import { CLBalancesInfoComponent } from './home/balances-info/balances-info.component'; import { CLBalancesInfoComponent } from './home/balances-info/balances-info.component';
import { CLFeeInfoComponent } from './home/fee-info/fee-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 { CLChannelLiquidityInfoComponent } from './home/channel-liquidity-info/channel-liquidity-info.component';
import { CLNetworkInfoComponent } from './network-info/network-info.component'; import { CLNetworkInfoComponent } from './network-info/network-info.component';
import { CLFeeRatesComponent } from './network-info/fee-rates/fee-rates.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 { CLSignVerifyMessageComponent } from './sign-verify-message/sign-verify-message.component';
import { CLSignComponent } from './sign-verify-message/sign/sign.component'; import { CLSignComponent } from './sign-verify-message/sign/sign.component';
import { CLVerifyComponent } from './sign-verify-message/verify/verify.component'; import { CLVerifyComponent } from './sign-verify-message/verify/verify.component';
@ -68,6 +71,7 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
CLRoutingComponent, CLRoutingComponent,
CLForwardingHistoryComponent, CLForwardingHistoryComponent,
CLFailedTransactionsComponent, CLFailedTransactionsComponent,
CLRoutingPeersComponent,
CLChannelLookupComponent, CLChannelLookupComponent,
CLNodeLookupComponent, CLNodeLookupComponent,
CLQueryRoutesComponent, CLQueryRoutesComponent,
@ -78,6 +82,7 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
CLChannelsTablesComponent, CLChannelsTablesComponent,
CLChannelOpenTableComponent, CLChannelOpenTableComponent,
CLChannelPendingTableComponent, CLChannelPendingTableComponent,
CLBumpFeeComponent,
CLNodeInfoComponent, CLNodeInfoComponent,
CLBalancesInfoComponent, CLBalancesInfoComponent,
CLFeeInfoComponent, CLFeeInfoComponent,
@ -86,6 +91,7 @@ import { CLUnlockedGuard } from '../shared/services/auth.guard';
CLChannelLiquidityInfoComponent, CLChannelLiquidityInfoComponent,
CLNetworkInfoComponent, CLNetworkInfoComponent,
CLFeeRatesComponent, CLFeeRatesComponent,
CLOnChainFeeEstimatesComponent,
CLSignVerifyMessageComponent, CLSignVerifyMessageComponent,
CLSignComponent, CLSignComponent,
CLVerifyComponent, CLVerifyComponent,

@ -23,6 +23,8 @@ import { CLSignComponent } from './sign-verify-message/sign/sign.component';
import { CLVerifyComponent } from './sign-verify-message/verify/verify.component'; import { CLVerifyComponent } from './sign-verify-message/verify/verify.component';
import { CLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component'; import { CLForwardingHistoryComponent } from './routing/forwarding-history/forwarding-history.component';
import { CLFailedTransactionsComponent } from './routing/failed-transactions/failed-transactions.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 { CLReportsComponent } from './reports/reports.component';
import { CLFeeReportComponent } from './reports/fee/fee-report.component'; import { CLFeeReportComponent } from './reports/fee/fee-report.component';
import { CLTransactionsReportComponent } from './reports/transactions/transactions-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: 'onchain', component: CLOnChainComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'receive/utxos' }, { path: '', pathMatch: 'full', redirectTo: 'receive/utxos' },
{ path: 'receive/:selTab', component: CLOnChainReceiveComponent, canActivate: [CLUnlockedGuard] }, { path: 'receive/:selTab', component: CLOnChainReceiveComponent, canActivate: [CLUnlockedGuard] },
{ path: 'send/:selTab', component: CLOnChainSendComponent, data : {sweepAll : false}, canActivate: [CLUnlockedGuard] }, { path: 'send/:selTab', component: CLOnChainSendComponent, data: { sweepAll: false }, canActivate: [CLUnlockedGuard] },
{ path: 'sweep/:selTab', component: CLOnChainSendComponent, data : {sweepAll : true}, canActivate: [CLUnlockedGuard] } { path: 'sweep/:selTab', component: CLOnChainSendComponent, data: { sweepAll: true }, canActivate: [CLUnlockedGuard] }
] }, ] },
{ path: 'connections', component: CLConnectionsComponent, canActivate: [CLUnlockedGuard], children: [ { path: 'connections', component: CLConnectionsComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'channels' }, { path: '', pathMatch: 'full', redirectTo: 'channels' },
@ -47,7 +49,7 @@ export const ClRoutes: Routes = [
{ path: 'open', component: CLChannelOpenTableComponent, canActivate: [CLUnlockedGuard] }, { path: 'open', component: CLChannelOpenTableComponent, canActivate: [CLUnlockedGuard] },
{ path: 'pending', component: CLChannelPendingTableComponent, 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: 'transactions', component: CLTransactionsComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'payments' }, { path: '', pathMatch: 'full', redirectTo: 'payments' },
@ -63,7 +65,8 @@ export const ClRoutes: Routes = [
{ path: 'routing', component: CLRoutingComponent, canActivate: [CLUnlockedGuard], children: [ { path: 'routing', component: CLRoutingComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'forwardinghistory' }, { path: '', pathMatch: 'full', redirectTo: 'forwardinghistory' },
{ path: 'forwardinghistory', component: CLForwardingHistoryComponent, canActivate: [CLUnlockedGuard] }, { 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: 'reports', component: CLReportsComponent, canActivate: [CLUnlockedGuard], children: [
{ path: '', pathMatch: 'full', redirectTo: 'routingfees' }, { path: '', pathMatch: 'full', redirectTo: 'routingfees' },
@ -76,8 +79,7 @@ export const ClRoutes: Routes = [
{ path: 'network', redirectTo: 'rates' }, { path: 'network', redirectTo: 'rates' },
{ path: 'wallet', redirectTo: 'home' }, { path: 'wallet', redirectTo: 'home' },
{ path: 'backup', redirectTo: 'home' } { path: 'backup', redirectTo: 'home' }
] ] }
}
]; ];
export const CLRouting: ModuleWithProviders<RouterModule> = RouterModule.forChild(ClRoutes); 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> <div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Lightning</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Lightning</h4>
<div class="overflow-wrap dashboard-info-value">{{balances.lightning | number}} Sats</div> <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 class="overflow-wrap dashboard-info-value">{{balances.total | number}} Sats</div>
</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 { CLBalancesInfoComponent } from './balances-info.component'; import { CLBalancesInfoComponent } from './balances-info.component';
@ -6,11 +7,12 @@ describe('CLBalancesInfoComponent', () => {
let component: CLBalancesInfoComponent; let component: CLBalancesInfoComponent;
let fixture: ComponentFixture<CLBalancesInfoComponent>; let fixture: ComponentFixture<CLBalancesInfoComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ CLBalancesInfoComponent ] declarations: [CLBalancesInfoComponent],
}) imports: [SharedModule]
.compileComponents(); }).
compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -22,4 +24,8 @@ describe('CLBalancesInfoComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
afterEach(() => {
TestBed.resetTestingModule();
});
}); });

@ -6,7 +6,9 @@ import { Component, Input } from '@angular/core';
styleUrls: ['./balances-info.component.scss'] styleUrls: ['./balances-info.component.scss']
}) })
export class CLBalancesInfoComponent { export class CLBalancesInfoComponent {
@Input() balances = { onchain: 0, lightning: 0, total: 0 }; @Input() balances = { onchain: 0, lightning: 0, total: 0 };
@Input() errorMessage: string;
constructor() {} 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"> <div fxLayout="column" fxFlex="9" fxLayoutAlign="end start">
<span class="dashboard-capacity-header this-channel-capacity">Total Capacity</span> <span class="dashboard-capacity-header this-channel-capacity">Total Capacity</span>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100"> <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"> <mat-hint fxFlex="20" fxLayoutAlign="center center" class="font-size-90">
<fa-icon [icon]="faBalanceScale" class="mr-3px" matTooltip="Balance Score"></fa-icon> <fa-icon [icon]="faBalanceScale" class="mr-3px" matTooltip="Balance Score"></fa-icon>
({{channelBalances?.balancedness || 0 | number}}) ({{channelBalances?.balancedness || 0 | number}})
</mat-hint> </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> </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>
<div fxLayout="column" fxFlex="3" fxLayoutAlign="end stretch"><mat-divider class="dashboard-divider"></mat-divider></div> <div fxLayout="column" fxFlex="3" fxLayoutAlign="end stretch"><mat-divider class="dashboard-divider"></mat-divider></div>
<div class="channels-capacity-scroll" [perfectScrollbar]> <div class="channels-capacity-scroll" [perfectScrollbar]>
@ -35,3 +35,8 @@
<button mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button> <button mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
</div> </div>
</ng-template> </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'; import { CLChannelCapacityInfoComponent } from './channel-capacity-info.component';
@ -6,11 +8,12 @@ describe('CLChannelCapacityInfoComponent', () => {
let component: CLChannelCapacityInfoComponent; let component: CLChannelCapacityInfoComponent;
let fixture: ComponentFixture<CLChannelCapacityInfoComponent>; let fixture: ComponentFixture<CLChannelCapacityInfoComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ CLChannelCapacityInfoComponent ] declarations: [CLChannelCapacityInfoComponent],
}) imports: [SharedModule, RouterTestingModule]
.compileComponents(); }).
compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -22,4 +25,8 @@ describe('CLChannelCapacityInfoComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
afterEach(() => {
TestBed.resetTestingModule();
});
}); });

@ -10,11 +10,13 @@ import { Channel } from '../../../shared/models/clModels';
styleUrls: ['./channel-capacity-info.component.scss'] styleUrls: ['./channel-capacity-info.component.scss']
}) })
export class CLChannelCapacityInfoComponent { export class CLChannelCapacityInfoComponent {
public faBalanceScale = faBalanceScale; public faBalanceScale = faBalanceScale;
public faDumbbell = faDumbbell; public faDumbbell = faDumbbell;
@Input() channelBalances: {localBalance: number, remoteBalance: number, balancedness: number}; @Input() channelBalances: {localBalance: number, remoteBalance: number, balancedness: number};
@Input() allChannels: Channel[]; @Input() allChannels: Channel[];
@Input() sortBy: string = 'Balance Score'; @Input() sortBy = 'Balance Score';
@Input() errorMessage: string;
constructor(private router: Router) {} 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"> <div fxLayout="column" fxFlex="9" fxLayoutAlign="end start">
<span class="dashboard-capacity-header this-channel-capacity">Total Capacity</span> <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> <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> <button *ngIf="direction === 'Out'" mat-stroked-button color="primary" (click)="goToChannels()" tabindex="1">Open Channel</button>
</div> </div>
</ng-template> </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 { CLChannelLiquidityInfoComponent } from './channel-liquidity-info.component';
import { DataService } from '../../../shared/services/data.service';
describe('CLChannelLiquidityInfoComponent', () => { describe('CLChannelLiquidityInfoComponent', () => {
let component: CLChannelLiquidityInfoComponent; let component: CLChannelLiquidityInfoComponent;
let fixture: ComponentFixture<CLChannelLiquidityInfoComponent>; let fixture: ComponentFixture<CLChannelLiquidityInfoComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ CLChannelLiquidityInfoComponent ] declarations: [CLChannelLiquidityInfoComponent],
}) imports: [SharedModule, RouterTestingModule],
.compileComponents(); providers: [
CommonService,
{ provide: DataService, useClass: mockDataService }
]
}).
compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {

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

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

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

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

@ -1,12 +1,19 @@
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch"> <div fxLayout="row" fxFlex="100" fxLayoutAlign="start stretch" *ngIf="errorMessage?.trim() === ''; else errorBlock">
<div> <div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<h4 fxLayoutAlign="start" class="dashboard-info-title">Total</h4> <div>
<div class="overflow-wrap dashboard-info-value">{{fees?.feeCollected/1000 | number}} Sats</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> <div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch"> <div>
<div> <h4 fxLayoutAlign="start" class="dashboard-info-title">Transactions</h4>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Transactions</h4> <div class="overflow-wrap dashboard-info-value">{{fees?.totalTxCount | number}}</div>
<div class="overflow-wrap dashboard-info-value">{{fees?.totalTxCount | number}}</div> </div>
</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'; import { CLFeeInfoComponent } from './fee-info.component';
@ -6,11 +7,12 @@ describe('CLFeeInfoComponent', () => {
let component: CLFeeInfoComponent; let component: CLFeeInfoComponent;
let fixture: ComponentFixture<CLFeeInfoComponent>; let fixture: ComponentFixture<CLFeeInfoComponent>;
beforeEach(async(() => { beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
declarations: [ CLFeeInfoComponent ] declarations: [CLFeeInfoComponent],
}) imports: [SharedModule]
.compileComponents(); }).
compileComponents();
})); }));
beforeEach(() => { beforeEach(() => {
@ -22,4 +24,8 @@ describe('CLFeeInfoComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
afterEach(() => {
TestBed.resetTestingModule();
});
}); });

@ -7,7 +7,9 @@ import { Fees } from '../../../shared/models/clModels';
styleUrls: ['./fee-info.component.scss'] styleUrls: ['./fee-info.component.scss']
}) })
export class CLFeeInfoComponent { export class CLFeeInfoComponent {
@Input() fees: Fees; @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="column" *ngIf="selNode.userPersona === userPersonaEnum.OPERATOR; else merchantDashboard">
<div fxLayout="row" fxLayoutAlign="start start" class="page-title-container mb-0"> <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> <fa-icon [icon]="apisCallStatus?.FetchInfo.status === apiCallStatusEnum.ERROR ? faFrown : faSmile" 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> <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> </div>
<mat-grid-list cols="10" [rowHeight]="operatorCardHeight"> <mat-grid-list cols="10" [rowHeight]="operatorCardHeight">
<mat-grid-tile *ngFor="let card of operatorCards" [colspan]="card.cols" [rowspan]="card.rows"> <mat-grid-tile *ngFor="let card of operatorCards" [colspan]="card.cols" [rowspan]="card.rows">
@ -24,13 +24,26 @@
</div> </div>
</mat-card-title> </mat-card-title>
</mat-card-header> </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"> <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-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [showColorFieldSeparately]="false"></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-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" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-capacity-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" [ngClass]="{'error-border': flgLoading[1]==='error'}"></rtl-cl-fee-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" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-cl-channel-status-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> <h3 *ngSwitchDefault>Error! Unable to find information!</h3>
</div> </div>
</mat-card-content> </mat-card-content>
@ -62,12 +75,21 @@
</div> </div>
</mat-card-title> </mat-card-title>
</mat-card-header> </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"> <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-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information"></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-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" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-cl-channel-liquidity-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" [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" [errorMessage]="errorMessages[4]"></rtl-cl-channel-liquidity-info>
<span fxLayout="column" fxFlex="100" fxLayoutAlign="space-between start" *ngSwitchCase="'transactions'"> <span fxLayout="column" fxFlex="100" fxLayoutAlign="space-between start" *ngSwitchCase="'transactions'">
<mat-tab-group fxLayout="column" class="w-100 dashboard-tabs-group"> <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> <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