cln channels & transactions msat migration

pull/1244/head
Shahana Farooqui 1 year ago
parent 7a18d934f2
commit 8bce41276b

@ -4,21 +4,51 @@ import { Common } from '../../utils/common.js';
let options = null;
const logger = Logger;
const common = Common;
export const listPeerChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Peer Channels..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listPeerChannels';
request(options).then((body) => {
body?.map((channel) => {
if (!channel.alias || channel.alias === '') {
channel.alias = channel.peer_id.substring(0, 20);
}
const local = channel.to_us_msat || 0;
const remote = (channel.total_msat - channel.to_us_msat) || 0;
const total = channel.total_msat || 0;
channel.balancedness = (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3);
return channel;
});
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Channels', 'List Peer Channels Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const listChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channels..' });
options = common.getOptions(req);
if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels';
if (common.isVersionCompatible(req.session.selectedNode.api_version, '0.10.2')) {
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listPeerChannels';
}
else {
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels';
}
request(options).then((body) => {
body?.map((channel) => {
if (!channel.alias || channel.alias === '') {
channel.alias = channel.id.substring(0, 20);
}
const local = (channel.msatoshi_to_us) ? channel.msatoshi_to_us : 0;
const remote = (channel.msatoshi_to_them) ? channel.msatoshi_to_them : 0;
const total = channel.msatoshi_total ? channel.msatoshi_total : 0;
const local = (channel.msatoshi_to_us) ? channel.msatoshi_to_us : (channel.to_us_msat || 0);
const remote = (channel.msatoshi_to_them) ? channel.msatoshi_to_them : ((channel.total_msat - channel.to_us_msat) || 0);
const total = channel.msatoshi_total ? channel.msatoshi_total : (channel.total_msat || 0);
channel.balancedness = (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3);
return channel;
});

@ -1,9 +1,10 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { listChannels, openChannel, setChannelFee, closeChannel, getLocalRemoteBalance, listForwards, funderUpdatePolicy, listForwardsPaginated } from '../../controllers/cln/channels.js';
import { listChannels, listPeerChannels, openChannel, setChannelFee, closeChannel, getLocalRemoteBalance, listForwards, funderUpdatePolicy, listForwardsPaginated } from '../../controllers/cln/channels.js';
const router = Router();
router.get('/listChannels', isAuthenticated, listChannels);
router.get('/listPeerChannels', isAuthenticated, listPeerChannels);
router.post('/', isAuthenticated, openChannel);
router.post('/setChannelFee', isAuthenticated, setChannelFee);
router.delete('/:channelId', isAuthenticated, closeChannel);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -10,9 +10,9 @@
<link i18n-rel="" rel="mask-icon" href="assets/images/favicon-light/safari-pinned-tab.svg" color="#5bbad5">
<meta i18n-content="" name="msapplication-TileColor" content="#da532c">
<meta i18n-content="" name="theme-color" content="#ffffff">
<style>html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:100%}@media only screen and (max-width: 56.25em){html{font-size:90%}}@media only screen and (max-width: 37.5em){html{font-size:80%}}body{box-sizing:border-box;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}@font-face{font-family:Roboto;src:url(Roboto-Thin.f7a95c9c5999532c.woff2) format("woff2"),url(Roboto-Thin.c13c157cb81e8ebb.woff) format("woff");font-weight:100;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.b0e084abf689f393.woff2) format("woff2"),url(Roboto-ThinItalic.1111028df6cea564.woff) format("woff");font-weight:100;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Light.0e01b6cd13b3857f.woff2) format("woff2"),url(Roboto-Light.603ca9a537b88428.woff) format("woff");font-weight:300;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.232ef4b20215f720.woff2) format("woff2"),url(Roboto-LightItalic.1b5e142f787151c8.woff) format("woff");font-weight:300;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Regular.475ba9e4e2d63456.woff2) format("woff2"),url(Roboto-Regular.bcefbfee882bc1cb.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.e3a9ebdaac06bbc4.woff2) format("woff2"),url(Roboto-RegularItalic.0668fae6af0cf8c2.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Medium.457532032ceb0168.woff2) format("woff2"),url(Roboto-Medium.6e1ae5f0b324a0aa.woff) format("woff");font-weight:500;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.872f7060602d55d2.woff2) format("woff2"),url(Roboto-MediumItalic.e06fb533801cbb08.woff) format("woff");font-weight:500;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Bold.447291a88c067396.woff2) format("woff2"),url(Roboto-Bold.fc482e6133cf5e26.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.1b15168ef6fa4e16.woff2) format("woff2"),url(Roboto-BoldItalic.e26ba339b06f09f7.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Black.2eaa390d458c877d.woff2) format("woff2"),url(Roboto-Black.b25f67ad8583da68.woff) format("woff");font-weight:900;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.7dc03ee444552bc5.woff2) format("woff2"),url(Roboto-BlackItalic.c8dc642467cb3099.woff) format("woff");font-weight:900;font-style:italic}</style><link rel="stylesheet" href="styles.d31e61a01689a167.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.d31e61a01689a167.css"></noscript></head>
<style>html{width:100%;height:99%;line-height:1.5;overflow-x:hidden;font-family:Roboto,sans-serif!important;font-size:100%}@media only screen and (max-width: 56.25em){html{font-size:90%}}@media only screen and (max-width: 37.5em){html{font-size:80%}}body{box-sizing:border-box;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}@font-face{font-family:Roboto;src:url(Roboto-Thin.f7a95c9c5999532c.woff2) format("woff2"),url(Roboto-Thin.c13c157cb81e8ebb.woff) format("woff");font-weight:100;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-ThinItalic.b0e084abf689f393.woff2) format("woff2"),url(Roboto-ThinItalic.1111028df6cea564.woff) format("woff");font-weight:100;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Light.0e01b6cd13b3857f.woff2) format("woff2"),url(Roboto-Light.603ca9a537b88428.woff) format("woff");font-weight:300;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-LightItalic.232ef4b20215f720.woff2) format("woff2"),url(Roboto-LightItalic.1b5e142f787151c8.woff) format("woff");font-weight:300;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Regular.475ba9e4e2d63456.woff2) format("woff2"),url(Roboto-Regular.bcefbfee882bc1cb.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-RegularItalic.e3a9ebdaac06bbc4.woff2) format("woff2"),url(Roboto-RegularItalic.0668fae6af0cf8c2.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Medium.457532032ceb0168.woff2) format("woff2"),url(Roboto-Medium.6e1ae5f0b324a0aa.woff) format("woff");font-weight:500;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-MediumItalic.872f7060602d55d2.woff2) format("woff2"),url(Roboto-MediumItalic.e06fb533801cbb08.woff) format("woff");font-weight:500;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Bold.447291a88c067396.woff2) format("woff2"),url(Roboto-Bold.fc482e6133cf5e26.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BoldItalic.1b15168ef6fa4e16.woff2) format("woff2"),url(Roboto-BoldItalic.e26ba339b06f09f7.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Roboto;src:url(Roboto-Black.2eaa390d458c877d.woff2) format("woff2"),url(Roboto-Black.b25f67ad8583da68.woff) format("woff");font-weight:900;font-style:normal}@font-face{font-family:Roboto;src:url(Roboto-BlackItalic.7dc03ee444552bc5.woff2) format("woff2"),url(Roboto-BlackItalic.c8dc642467cb3099.woff) format("woff");font-weight:900;font-style:italic}</style><link rel="stylesheet" href="styles.b6cbe1ef9615b5dc.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.b6cbe1ef9615b5dc.css"></noscript></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.85c27805ea5ed7f0.js" type="module"></script><script src="polyfills.9720483e1820202a.js" type="module"></script><script src="main.209e81cddd0d5ce6.js" type="module"></script>
<script src="runtime.d6968d8be543024f.js" type="module"></script><script src="polyfills.9720483e1820202a.js" type="module"></script><script src="main.9e529b3607440023.js" type="module"></script>
</body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +0,0 @@
(()=>{"use strict";var e,v={},m={};function r(e){var f=m[e];if(void 0!==f)return f.exports;var t=m[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(f,t,i,o)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,i,o]=e[n],c=!0,d=0;d<t.length;d++)(!1&o||a>=o)&&Object.keys(r.O).every(b=>r.O[b](t[d]))?t.splice(d--,1):(c=!1,o<a&&(a=o));if(c){e.splice(n--,1);var u=i();void 0!==u&&(f=u)}}return f}o=o||0;for(var n=e.length;n>0&&e[n-1][2]>o;n--)e[n]=e[n-1];e[n]=[t,i,o]},r.d=(e,f)=>{for(var t in f)r.o(f,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:f[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((f,t)=>(r.f[t](e,f),f),[])),r.u=e=>e+"."+{167:"836d81485f16d9bc",267:"8f996ec2b4b156e0",315:"9c8bec49097dc4f1",636:"c6beed2b2207416a"}[e]+".js",r.miniCssF=e=>{},r.o=(e,f)=>Object.prototype.hasOwnProperty.call(e,f),(()=>{var e={},f="RTLApp:";r.l=(t,i,o,n)=>{if(e[t])e[t].push(i);else{var a,c;if(void 0!==o)for(var d=document.getElementsByTagName("script"),u=0;u<d.length;u++){var l=d[u];if(l.getAttribute("src")==t||l.getAttribute("data-webpack")==f+o){a=l;break}}a||(c=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",f+o),a.src=r.tu(t)),e[t]=[i];var s=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),c&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:f=>f},typeof trustedTypes<"u"&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(i,o)=>{var n=r.o(e,i)?e[i]:void 0;if(0!==n)if(n)o.push(n[2]);else if(666!=i){var a=new Promise((l,s)=>n=e[i]=[l,s]);o.push(n[2]=a);var c=r.p+r.u(i),d=new Error;r.l(c,l=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var s=l&&("load"===l.type?"missing":l.type),p=l&&l.target&&l.target.src;d.message="Loading chunk "+i+" failed.\n("+s+": "+p+")",d.name="ChunkLoadError",d.type=s,d.request=p,n[1](d)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var f=(i,o)=>{var d,u,[n,a,c]=o,l=0;if(n.some(p=>0!==e[p])){for(d in a)r.o(a,d)&&(r.m[d]=a[d]);if(c)var s=c(r)}for(i&&i(o);l<n.length;l++)r.o(e,u=n[l])&&e[u]&&e[u][0](),e[u]=0;return r.O(s)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(f.bind(null,0)),t.push=f.bind(null,t.push.bind(t))})()})();

@ -0,0 +1 @@
(()=>{"use strict";var e,v={},m={};function r(e){var o=m[e];if(void 0!==o)return o.exports;var t=m[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(o,t,i,f)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,i,f]=e[n],c=!0,d=0;d<t.length;d++)(!1&f||a>=f)&&Object.keys(r.O).every(b=>r.O[b](t[d]))?t.splice(d--,1):(c=!1,f<a&&(a=f));if(c){e.splice(n--,1);var u=i();void 0!==u&&(o=u)}}return o}f=f||0;for(var n=e.length;n>0&&e[n-1][2]>f;n--)e[n]=e[n-1];e[n]=[t,i,f]},r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((o,t)=>(r.f[t](e,o),o),[])),r.u=e=>e+"."+{167:"836d81485f16d9bc",267:"8f996ec2b4b156e0",315:"f4d6612db1adb63f",636:"c6beed2b2207416a"}[e]+".js",r.miniCssF=e=>{},r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),(()=>{var e={},o="RTLApp:";r.l=(t,i,f,n)=>{if(e[t])e[t].push(i);else{var a,c;if(void 0!==f)for(var d=document.getElementsByTagName("script"),u=0;u<d.length;u++){var l=d[u];if(l.getAttribute("src")==t||l.getAttribute("data-webpack")==o+f){a=l;break}}a||(c=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",o+f),a.src=r.tu(t)),e[t]=[i];var s=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),c&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:o=>o},typeof trustedTypes<"u"&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(i,f)=>{var n=r.o(e,i)?e[i]:void 0;if(0!==n)if(n)f.push(n[2]);else if(666!=i){var a=new Promise((l,s)=>n=e[i]=[l,s]);f.push(n[2]=a);var c=r.p+r.u(i),d=new Error;r.l(c,l=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var s=l&&("load"===l.type?"missing":l.type),p=l&&l.target&&l.target.src;d.message="Loading chunk "+i+" failed.\n("+s+": "+p+")",d.name="ChunkLoadError",d.type=s,d.request=p,n[1](d)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var o=(i,f)=>{var d,u,[n,a,c]=f,l=0;if(n.some(p=>0!==e[p])){for(d in a)r.o(a,d)&&(r.m[d]=a[d]);if(c)var s=c(r)}for(i&&i(f);l<n.length;l++)r.o(e,u=n[l])&&e[u]&&e[u][0](),e[u]=0;return r.O(s)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))})()})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -5,17 +5,43 @@ let options = null;
const logger: LoggerService = Logger;
const common: CommonService = Common;
export const listPeerChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Peer Channels..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listPeerChannels';
request(options).then((body) => {
body?.map((channel) => {
if (!channel.alias || channel.alias === '') { channel.alias = channel.peer_id.substring(0, 20); }
const local = channel.to_us_msat || 0;
const remote = (channel.total_msat - channel.to_us_msat) || 0;
const total = channel.total_msat || 0;
channel.balancedness = (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3);
return channel;
});
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Peer Channels List Received', data: body });
res.status(200).json(body);
}).catch((errRes) => {
const err = common.handleError(errRes, 'Channels', 'List Peer Channels Error', req.session.selectedNode);
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const listChannels = (req, res, next) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Getting Channels..' });
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels';
if (common.isVersionCompatible(req.session.selectedNode.api_version, '0.10.2')) {
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listPeerChannels';
} else {
options.url = req.session.selectedNode.ln_server_url + '/v1/channel/listChannels';
}
request(options).then((body) => {
body?.map((channel) => {
if (!channel.alias || channel.alias === '') { channel.alias = channel.id.substring(0, 20); }
const local = (channel.msatoshi_to_us) ? channel.msatoshi_to_us : 0;
const remote = (channel.msatoshi_to_them) ? channel.msatoshi_to_them : 0;
const total = channel.msatoshi_total ? channel.msatoshi_total : 0;
const local = (channel.msatoshi_to_us) ? channel.msatoshi_to_us : (channel.to_us_msat || 0);
const remote = (channel.msatoshi_to_them) ? channel.msatoshi_to_them : ((channel.total_msat - channel.to_us_msat) || 0);
const total = channel.msatoshi_total ? channel.msatoshi_total : (channel.total_msat || 0);
channel.balancedness = (total === 0) ? 1 : (1 - Math.abs((local - remote) / total)).toFixed(3);
return channel;
});

@ -1,11 +1,12 @@
import exprs from 'express';
const { Router } = exprs;
import { isAuthenticated } from '../../utils/authCheck.js';
import { listChannels, openChannel, setChannelFee, closeChannel, getLocalRemoteBalance, listForwards, funderUpdatePolicy, listForwardsPaginated } from '../../controllers/cln/channels.js';
import { listChannels, listPeerChannels, openChannel, setChannelFee, closeChannel, getLocalRemoteBalance, listForwards, funderUpdatePolicy, listForwardsPaginated } from '../../controllers/cln/channels.js';
const router = Router();
router.get('/listChannels', isAuthenticated, listChannels);
router.get('/listPeerChannels', isAuthenticated, listPeerChannels);
router.post('/', isAuthenticated, openChannel);
router.post('/setChannelFee', isAuthenticated, setChannelFee);
router.delete('/:channelId', isAuthenticated, closeChannel);

@ -32,6 +32,11 @@
<span class="foreground-secondary-text">{{lookupResult[0]?.base_fee_millisatoshi | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Fee/Millionth</h4>
<span class="foreground-secondary-text">{{lookupResult[0]?.fee_per_millionth | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Channel Flags</h4>
<span class="foreground-secondary-text">{{lookupResult[0]?.channel_flags | number}}</span>
@ -42,11 +47,6 @@
<span class="foreground-secondary-text">{{lookupResult[0]?.delay | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Fee/Millionth</h4>
<span class="foreground-secondary-text">{{lookupResult[0]?.fee_per_millionth | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Max Htlc (mSat)</h4>
<span class="foreground-secondary-text">{{lookupResult[0]?.htlc_maximum_msat | number}}</span>
@ -108,6 +108,11 @@
<span class="foreground-secondary-text">{{lookupResult[1]?.base_fee_millisatoshi | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Fee/Millionth</h4>
<span class="foreground-secondary-text">{{lookupResult[1]?.fee_per_millionth | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Channel Flags</h4>
<span class="foreground-secondary-text">{{lookupResult[1]?.channel_flags | number}}</span>
@ -118,11 +123,6 @@
<span class="foreground-secondary-text">{{lookupResult[1]?.delay | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Fee/Millionth</h4>
<span class="foreground-secondary-text">{{lookupResult[1]?.fee_per_millionth | number}}</span>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="column">
<h4 class="font-bold-500">Max Htlc (mSat)</h4>
<span class="foreground-secondary-text">{{lookupResult[1]?.htlc_maximum_msat | number}}</span>

@ -40,8 +40,10 @@ export class CLNNodeLookupComponent implements OnInit, OnDestroy {
if (this.lookupResult.features && this.lookupResult.features.trim() !== '') {
const featureHex = parseInt(this.lookupResult.features, 16);
NODE_FEATURES_CLN.forEach((feature) => {
if (!!(featureHex & ((1 << feature.range.min) | (1 << feature.range.max)))) {
this.featureDescriptions.push(feature.description + '\n');
if (featureHex & (1 << feature.range.min)) {
this.featureDescriptions.push('Mandatory: ' + feature.description + '\n');
} else if (featureHex & (1 << feature.range.max)) {
this.featureDescriptions.push('Optional: ' + feature.description + '\n');
}
});
}

@ -1,17 +1,17 @@
<div *ngIf="errorMessage?.trim() === ''; else errorBlock" class="mt-1" fxLayout="column" fxFlex="100"fxLayoutAlign="space-between stretch">
<div>
<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:'1.0-0'}} Sats</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{balances.lightning/balances.total*100}}"></mat-progress-bar>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">On-chain</h4>
<div class="overflow-wrap dashboard-info-value">{{balances.onchain | number}} Sats</div>
<div class="overflow-wrap dashboard-info-value">{{balances.onchain | number:'1.0-0'}} Sats</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{balances.onchain/balances.total*100}}"></mat-progress-bar>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Total</h4>
<div class="overflow-wrap dashboard-info-value">{{balances.total | number}} Sats</div>
<div class="overflow-wrap dashboard-info-value">{{balances.total | number:'1.0-0'}} Sats</div>
</div>
</div>
<ng-template #errorBlock>

@ -15,18 +15,18 @@
<div class="channels-capacity-scroll" [perfectScrollbar]>
<div *ngIf="activeChannels && activeChannels.length > 0; else noChannelBlock" fxLayout="column"fxFlex="100">
<div *ngFor="let channel of activeChannels" class="mt-2">
<a class="dashboard-capacity-header" [routerLink]="['../connections/channels/open']" [state]="{filter: channel.id}" matTooltip="{{channel.alias || channel.id}}" matTooltipDisabled="{{(channel.alias || channel.id).length < 26}}">
{{(channel.alias || channel.id) | slice:0:24}}{{(channel.alias || channel.id).length > 25 ? '...' : ''}}
<a class="dashboard-capacity-header" [routerLink]="['../connections/channels/open']" [state]="{filter: channel.peer_id}" matTooltip="{{channel.alias || channel.peer_id}}" matTooltipDisabled="{{(channel.alias || channel.peer_id).length < 26}}">
{{(channel.alias || channel.peer_id) | slice:0:24}}{{(channel.alias || channel.peer_id).length > 25 ? '...' : ''}}
</a>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint fxFlex="40" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Local:</strong>{{channel.msatoshi_to_us/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint fxFlex="40" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Local:</strong>{{channel.to_us_msat/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint fxFlex="20" fxLayoutAlign="center center" class="font-size-90 color-primary">
<fa-icon class="color-primary mr-3px" matTooltip="Balance Score" [icon]="faBalanceScale"></fa-icon>
({{channel.balancedness || 0 | number}})
</mat-hint>
<mat-hint fxFlex="40" fxLayoutAlign="end center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channel.msatoshi_to_them/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint fxFlex="40" fxLayoutAlign="end center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channel.to_them_msat/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channel.msatoshi_to_us && channel.msatoshi_to_us > 0 ? ((+channel.msatoshi_to_us/((+channel.msatoshi_to_us)+(+channel.msatoshi_to_them)))*100) : 0}}"></mat-progress-bar>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channel.to_us_msat && channel.to_us_msat > 0 ? ((channel.to_us_msat/((channel.to_us_msat)+(channel.to_them_msat)))*100) : 0}}"></mat-progress-bar>
</div>
</div>
</div>

@ -8,15 +8,15 @@
<div fxLayout="column" fxFlex.gt-sm="88" fxFlex="84" fxLayoutAlign="start start" [perfectScrollbar]>
<div *ngIf="activeChannels && activeChannels.length > 0; else noChannelBlock" fxLayout="column" fxFlex="100"class="w-100">
<div *ngFor="let channel of activeChannels" class="mt-2">
<a class="dashboard-capacity-header" [routerLink]="['../connections/channels/open']" [state]="{filter: channel.id}" matTooltip="{{channel.alias || channel.id}}" matTooltipDisabled="{{(channel.alias || channel.id).length < 26}}">
{{(channel.alias || channel.id) | slice:0:24}}{{(channel.alias || channel.id).length > 25 ? '...' : ''}}
<a class="dashboard-capacity-header" [routerLink]="['../connections/channels/open']" [state]="{filter: channel.peer_id}" matTooltip="{{channel.alias || channel.peer_id}}" matTooltipDisabled="{{(channel.alias || channel.peer_id).length < 26}}">
{{(channel.alias || channel.peer_id) | slice:0:24}}{{(channel.alias || channel.peer_id).length > 25 ? '...' : ''}}
</a>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint *ngIf="direction === 'In'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.msatoshi_to_them/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint *ngIf="direction === 'Out'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.msatoshi_to_us/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint *ngIf="direction === 'In'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.to_them_msat/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
<mat-hint *ngIf="direction === 'Out'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.to_us_msat/1000 || 0 | number:'1.0-0'}} Sats</mat-hint>
</div>
<mat-progress-bar *ngIf="direction === 'In'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.msatoshi_to_them/1000 || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>
<mat-progress-bar *ngIf="direction === 'Out'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.msatoshi_to_us/1000 || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>
<mat-progress-bar *ngIf="direction === 'In'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((channel.to_them_msat/1000 || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>
<mat-progress-bar *ngIf="direction === 'Out'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((channel.to_us_msat/1000 || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>
</div>
</div>
</div>

@ -16,15 +16,15 @@
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus?.active?.capacity || 0) | number}} Sats</div>
<div class="overflow-wrap dashboard-info-value">{{(channelsStatus?.active?.capacity || 0) | number:'1.0-0'}} 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 class="overflow-wrap dashboard-info-value">{{(channelsStatus?.pending?.capacity || 0) | number:'1.0-0'}} 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 class="overflow-wrap dashboard-info-value">{{(channelsStatus?.inactive?.capacity || 0) | number:'1.0-0'}} Sats</div>
</div>
</div>
</div>

@ -155,11 +155,11 @@ export class CLNHomeComponent implements OnInit, OnDestroy {
this.totalOutboundLiquidity = 0;
this.activeChannels = channelsSeletor.activeChannels;
this.activeChannelsCapacity = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels, 'balancedness'))) || [];
this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels?.filter((channel) => (channel.msatoshi_to_them ? channel.msatoshi_to_them > 0 : false)), 'msatoshi_to_them'))) || [];
this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels?.filter((channel) => (channel.msatoshi_to_us ? channel.msatoshi_to_us > 0 : false)), 'msatoshi_to_us'))) || [];
this.allInboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels?.filter((channel) => (channel.to_them_msat ? channel.to_them_msat > 0 : false)), 'to_them_msat'))) || [];
this.allOutboundChannels = JSON.parse(JSON.stringify(this.commonService.sortDescByKey(this.activeChannels?.filter((channel) => (channel.to_us_msat ? channel.to_us_msat > 0 : false)), 'to_us_msat'))) || [];
this.activeChannels.forEach((channel) => {
this.totalInboundLiquidity = this.totalInboundLiquidity + Math.ceil((channel.msatoshi_to_them || 0) / 1000);
this.totalOutboundLiquidity = this.totalOutboundLiquidity + Math.floor((channel.msatoshi_to_us || 0) / 1000);
this.totalInboundLiquidity = this.totalInboundLiquidity + Math.ceil((channel.to_them_msat || 0) / 1000);
this.totalOutboundLiquidity = this.totalOutboundLiquidity + Math.floor((channel.to_us_msat || 0) / 1000);
});
this.channelsStatus.active.channels = channelsSeletor.activeChannels.length || 0;
this.channelsStatus.pending.channels = channelsSeletor.pendingChannels.length || 0;
@ -205,8 +205,8 @@ export class CLNHomeComponent implements OnInit, OnDestroy {
if (this.sortField === 'Balance Score') {
this.sortField = 'Capacity';
this.activeChannelsCapacity = this.activeChannels.sort((a, b) => {
const x = (a.msatoshi_to_us ? +a.msatoshi_to_us : 0) + (a.msatoshi_to_them ? +a.msatoshi_to_them : 0);
const y = (b.msatoshi_to_them ? +b.msatoshi_to_them : 0) + (b.msatoshi_to_them ? +b.msatoshi_to_them : 0);
const x = (a.to_us_msat ? +a.to_us_msat : 0) + (a.to_them_msat ? +a.to_them_msat : 0);
const y = (b.to_them_msat ? +b.to_them_msat : 0) + (b.to_them_msat ? +b.to_them_msat : 0);
return ((x > y) ? -1 : ((x < y) ? 1 : 0));
});
} else {

@ -230,8 +230,10 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
if (lqNode.features && lqNode.features.trim() !== '') {
const featureHex = parseInt(lqNode.features, 16);
NODE_FEATURES_CLN.forEach((feature) => {
if (!!(featureHex & ((1 << feature.range.min) | (1 << feature.range.max)))) {
featureDescriptions.push(feature.description);
if (featureHex & (1 << feature.range.min)) {
featureDescriptions.push('Mandatory: ' + feature.description);
} else if (featureHex & (1 << feature.range.max)) {
featureDescriptions.push('Optional: ' + feature.description);
}
});
}

@ -64,7 +64,7 @@
<mat-label>Coin Selection</mat-label>
<mat-select tabindex="8" multiple [(value)]="selUTXOs" (selectionChange)="onUTXOSelectionChange($event)">
<mat-select-trigger>{{totalSelectedUTXOAmount | number}} Sats ({{selUTXOs.length > 1 ? selUTXOs.length + ' UTXOs' : '1 UTXO'}})</mat-select-trigger>
<mat-option *ngFor="let utxo of utxos" [value]="utxo">{{utxo.value | number}} Sats</mat-option>
<mat-option *ngFor="let utxo of utxos" [value]="utxo">{{utxo.amount_msat/1000 | number:'1.0-0'}} Sats</mat-option>
</mat-select>
</mat-form-field>
<div fxFlex="60" fxLayout="row" fxLayoutAlign="start center">

@ -285,7 +285,7 @@ export class CLNOnChainSendModalComponent implements OnInit, OnDestroy {
onUTXOSelectionChange(event: any) {
if (this.selUTXOs.length && this.selUTXOs.length > 0) {
this.totalSelectedUTXOAmount = this.selUTXOs?.reduce((total, curr) => (total + (curr.value || 0)), 0);
this.totalSelectedUTXOAmount = this.selUTXOs?.reduce((total, curr) => (total + ((curr.amount_msat || 0) / 1000)), 0);
if (this.flgUseAllBalance) {
this.onUTXOAllBalanceChange();
}

@ -31,7 +31,7 @@ export class CLNUTXOTablesComponent implements OnInit, OnDestroy {
subscribe((utxosSeletor: { utxos: UTXO[], apiCallStatus: ApiCallStatusPayload }) => {
if (utxosSeletor.utxos && utxosSeletor.utxos.length > 0) {
this.numUtxos = utxosSeletor.utxos.length || 0;
this.numDustUtxos = utxosSeletor.utxos?.filter((utxo) => +(utxo.value || 0) < this.DUST_AMOUNT).length || 0;
this.numDustUtxos = utxosSeletor.utxos?.filter((utxo) => (+(utxo.amount_msat || 0) / 1000) < this.DUST_AMOUNT).length || 0;
}
this.logger.info(utxosSeletor);
});

@ -21,7 +21,7 @@
<ng-container matColumnDef="is_dust">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before" matTooltip="Dust/Nondust"></th>
<td *matCellDef="let utxo" mat-cell>
<span *ngIf="numDustUTXOs > 0 && !isDustUTXO && utxo.value < dustAmount; else emptySpace" matTooltip="Risk of dust attack" matTooltipPosition="right">
<span *ngIf="numDustUTXOs > 0 && !isDustUTXO && (utxo?.amount_msat / 1000) < dustAmount; else emptySpace" matTooltip="Risk of dust attack" matTooltipPosition="right">
<mat-icon fxLayoutAlign="start center" color="warn" class="small-icon">warning</mat-icon>
</span>
</td>
@ -65,8 +65,8 @@
<ng-container matColumnDef="value">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Value (Sats)</th>
<td *matCellDef="let utxo" mat-cell>
<span *ngIf="utxo.value > 0 || utxo.value === 0" fxLayoutAlign="end center">{{utxo.value | number}}</span>
<span *ngIf="utxo.value < 0" fxLayoutAlign="end center" class="red">({{utxo.value * -1 | number}})</span>
<span *ngIf="utxo.amount_msat > 0 || utxo.amount_msat === 0" fxLayoutAlign="end center">{{utxo.amount_msat / 1000 | number:'1.0-0'}}</span>
<span *ngIf="utxo.amount_msat < 0" fxLayoutAlign="end center" class="red">({{utxo.amount_msat / 1000 * -1 | number:'1.0-0'}})</span>
</td>
</ng-container>
<ng-container matColumnDef="blockheight">

@ -87,7 +87,7 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;
}
if (utxosSelector.utxos && utxosSelector.utxos.length > 0) {
this.dustUtxos = utxosSelector.utxos?.filter((utxo) => +(utxo.value || 0) < this.dustAmount);
this.dustUtxos = utxosSelector.utxos?.filter((utxo) => +(utxo.amount_msat || 0) / 1000 < this.dustAmount);
this.utxos = utxosSelector.utxos;
if (this.isDustUTXO) {
if (this.dustUtxos && this.dustUtxos.length > 0 && this.sort && this.paginator && this.displayedColumns.length > 0) {
@ -122,7 +122,7 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
const reorderedUTXO = [
[{ key: 'txid', value: selUtxo.txid, title: 'Transaction ID', width: 100 }],
[{ key: 'output', value: selUtxo.output, title: 'Output', width: 50, type: DataTypeEnum.NUMBER },
{ key: 'value', value: selUtxo.value, title: 'Value (Sats)', width: 50, type: DataTypeEnum.NUMBER }],
{ key: 'amount_msat', value: (selUtxo.amount_msat || 0) / 1000, title: 'Value (Sats)', width: 50, type: DataTypeEnum.NUMBER }],
[{ key: 'status', value: this.commonService.titleCase(selUtxo.status || ''), title: 'Status', width: 50, type: DataTypeEnum.STRING },
{ key: 'blockheight', value: selUtxo.blockheight, title: 'Blockheight', width: 50, type: DataTypeEnum.NUMBER }],
[{ key: 'address', value: selUtxo.address, title: 'Address', width: 100 }]
@ -156,13 +156,17 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
break;
case 'is_dust':
rowToFilter = (rowData?.value || 0) < this.dustAmount ? 'dust' : 'nondust';
rowToFilter = (rowData?.amount_msat || 0) / 1000 < this.dustAmount ? 'dust' : 'nondust';
break;
case 'status':
rowToFilter = rowData?.status?.toLowerCase() || '';
break;
case 'value':
rowToFilter = (rowData?.value || ((rowData?.amount_msat || 0) / 1000)).toString();
break;
default:
rowToFilter = typeof rowData[this.selFilterBy] === 'undefined' ? '' : typeof rowData[this.selFilterBy] === 'string' ? rowData[this.selFilterBy].toLowerCase() : typeof rowData[this.selFilterBy] === 'boolean' ? (rowData[this.selFilterBy] ? 'yes' : 'no') : rowData[this.selFilterBy].toString();
break;
@ -176,7 +180,8 @@ export class CLNOnChainUtxosComponent implements OnInit, AfterViewInit, OnDestro
this.listUTXOs.sort = this.sort;
this.listUTXOs.sortingDataAccessor = (data: UTXO, sortHeaderId: string) => {
switch (sortHeaderId) {
case 'is_dust': return +(data.value || 0) < this.dustAmount;
case 'is_dust': return (+(data.amount_msat || 0) / 1000) < this.dustAmount;
case 'value': return data.value || (+(data.amount_msat || 0) / 1000);
default: return (data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null;
}
};

@ -32,49 +32,63 @@
<div fxLayout="row">
<div fxFlex="100">
<h4 fxLayoutAlign="start" class="font-bold-500">Peer Public Key</h4>
<span class="foreground-secondary-text">{{channel.id}}</span>
<span class="foreground-secondary-text">{{channel.peer_id}}</span>
</div>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">mSatoshi to Us</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.msatoshi_to_us | number}}</span>
</div>
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">Spendable (mSats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.spendable_msatoshi | number}}</span>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">State</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel?.state | camelcaseWithReplace:'_'}}</span>
</div>
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">Total (mSats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.msatoshi_total | number}}</span>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Connected</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.peer_connected ? 'Yes' : 'No'}}</span>
</div>
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">State</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.state}}</span>
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">Private</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.private ? 'Yes' : 'No'}}</span>
</div>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">Our Reserve (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.our_channel_reserve_satoshis | number}}</span>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Remote Balance (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.to_them_msat / 1000 | number:'1.0-0'}}</span>
</div>
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">Their Reserve (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.their_channel_reserve_satoshis | number}}</span>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Local Balance (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.to_us_msat / 1000 | number:'1.0-0'}}</span>
</div>
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">Connected</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.peer_connected ? 'Yes' : 'No'}}</span>
</div>
<div fxFlex="25">
<h4 fxLayoutAlign="start" class="font-bold-500">Private</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.private ? 'Yes' : 'No'}}</span>
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">Total (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.total_msat / 1000 | number:'1.0-0'}}</span>
</div>
</div>
<mat-divider class="my-1"></mat-divider>
<div *ngIf="showAdvanced">
<div fxLayout="row">
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">Receivable (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.receivable_msat / 1000 | number:'1.0-0'}}</span>
</div>
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">Spendable (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.spendable_msat / 1000 | number:'1.0-0'}}</span>
</div>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">Their Reserve (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.their_reserve_msat / 1000 | number:'1.0-2'}}</span>
</div>
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">Our Reserve (Sats)</h4>
<span class="overflow-wrap foreground-secondary-text">{{channel.our_reserve_msat / 1000 | number:'1.0-2'}}</span>
</div>
</div>
<mat-divider class="my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="100">
<h4 fxLayoutAlign="start" class="font-bold-500">Funding Transaction ID</h4>

@ -71,32 +71,32 @@
<ng-container matColumnDef="our_channel_reserve_satoshis">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Local Reserve (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.our_channel_reserve_satoshis | number:'1.0-0'}} </span></td>
{{channel?.our_reserve_msat | number:'1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="their_channel_reserve_satoshis">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Remote Reserve (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.their_channel_reserve_satoshis | number:'1.0-0'}} </span></td>
{{channel?.their_reserve_msat | number:'1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_total">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Total (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.msatoshi_total/1000 | number:channel?.msatoshi_to_us < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.total_msat/1000 | number:channel?.to_us_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="spendable_msatoshi">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Spendable (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.spendable_msatoshi/1000 | number:channel?.msatoshi_to_us < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.spendable_msat/1000 | number:channel?.to_us_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_to_us">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Local Balance (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.msatoshi_to_us/1000 | number:channel?.msatoshi_to_us < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.to_us_msat/1000 | number:channel?.to_us_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_to_them">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Remote Balance (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.msatoshi_to_them/1000 | number:channel?.msatoshi_to_them < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.to_them_msat/1000 | number:channel?.to_them_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="balancedness">
<th *matHeaderCellDef mat-header-cell mat-sort-header>Balance Score</th>
@ -104,7 +104,7 @@
<div fxLayout="row">
<mat-hint fxFlex="100" fxLayoutAlign="center center" class="font-size-80">{{channel.balancedness || 0 | number}}</mat-hint>
</div>
<mat-progress-bar mode="determinate" value="{{channel.msatoshi_to_us && channel.msatoshi_to_us > 0 ? ((+channel.msatoshi_to_us/((+channel.msatoshi_to_us)+(+channel.msatoshi_to_them)))*100) : 0}}"></mat-progress-bar>
<mat-progress-bar mode="determinate" value="{{channel.to_us_msat && channel.to_us_msat > 0 ? ((channel.to_us_msat/((channel.to_us_msat)+(channel.to_them_msat)))*100) : 0}}"></mat-progress-bar>
</td>
</ng-container>
<ng-container matColumnDef="actions">

@ -158,7 +158,6 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
return;
}
if (channelToUpdate === 'all') {
const confirmationMsg = [];
this.store.dispatch(openConfirmation({
payload: {
data: {
@ -166,7 +165,7 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
alertTitle: 'Update Fee Policy',
noBtnText: 'Cancel',
yesBtnText: 'Update All',
message: confirmationMsg,
message: [],
titleMessage: 'Update fee policy for all channels',
flgShowInput: true,
getInputs: [
@ -288,9 +287,10 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
rowToFilter = ((rowData.peer_connected) ? 'connected' : 'disconnected') + (rowData.channel_id ? rowData.channel_id.toLowerCase() : '') +
(rowData.short_channel_id ? rowData.short_channel_id.toLowerCase() : '') + (rowData.id ? rowData.id.toLowerCase() : '') + (rowData.alias ? rowData.alias.toLowerCase() : '') +
(rowData.private ? 'private' : 'public') + (rowData.state ? rowData.state.toLowerCase() : '') +
(rowData.funding_txid ? rowData.funding_txid.toLowerCase() : '') + (rowData.msatoshi_to_us ? rowData.msatoshi_to_us : '') +
(rowData.msatoshi_total ? rowData.msatoshi_total : '') + (rowData.their_channel_reserve_satoshis ? rowData.their_channel_reserve_satoshis : '') +
(rowData.our_channel_reserve_satoshis ? rowData.our_channel_reserve_satoshis : '') + (rowData.spendable_msatoshi ? rowData.spendable_msatoshi : '');
(rowData.funding_txid ? rowData.funding_txid.toLowerCase() : '') + (rowData.to_them_msat ? rowData.to_them_msat : '') +
(rowData.to_us_msat ? rowData.to_us_msat : '') + (rowData.total_msat ? rowData.total_msat : '') +
(rowData.their_reserve_msat ? rowData.their_reserve_msat : '') + (rowData.our_reserve_msat ? rowData.our_reserve_msat : '') +
(rowData.spendable_msat ? rowData.spendable_msat : '');
break;
case 'private':
@ -302,10 +302,19 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
break;
case 'msatoshi_total':
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['total_msat'] || 0)) / 1000)?.toString() || '';
break;
case 'spendable_msatoshi':
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['spendable_msat'] || 0)) / 1000)?.toString() || '';
break;
case 'msatoshi_to_us':
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['to_us_msat'] || 0)) / 1000)?.toString() || '';
break;
case 'msatoshi_to_them':
rowToFilter = ((+(rowData[this.selFilterBy] || 0)) / 1000)?.toString() || '';
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['to_them_msat'] || 0)) / 1000)?.toString() || '';
break;
default:
@ -319,7 +328,24 @@ export class CLNChannelOpenTableComponent implements OnInit, AfterViewInit, OnDe
loadChannelsTable(mychannels) {
this.channels = new MatTableDataSource<Channel>([...mychannels]);
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => {
switch (sortHeaderId) {
case 'msatoshi_total':
return data['msatoshi_total'] || data['total_msat'];
case 'spendable_msatoshi':
return data['spendable_msatoshi'] || data['spendable_msat'];
case 'msatoshi_to_us':
return data['msatoshi_to_us'] || data['to_us_msat'];
case 'msatoshi_to_them':
return data['msatoshi_to_them'] || data['to_them_msat'];
default:
return (data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null;
}
};
this.channels.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();

@ -67,32 +67,32 @@
<ng-container matColumnDef="our_channel_reserve_satoshis">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Local Reserve (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.our_channel_reserve_satoshis | number:'1.0-0'}} </span></td>
{{channel?.our_reserve_msat | number:'1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="their_channel_reserve_satoshis">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Remote Reserve (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.their_channel_reserve_satoshis | number:'1.0-0'}} </span></td>
{{channel?.their_reserve_msat | number:'1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_total">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Total (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.msatoshi_total/1000 | number:channel?.msatoshi_to_us < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.total_msat/1000 | number:channel?.to_us_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="spendable_msatoshi">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Spendable (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.spendable_msatoshi/1000 | number:channel?.msatoshi_to_us < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.spendable_msat/1000 | number:channel?.to_us_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_to_us">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Local Balance (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.msatoshi_to_us/1000 | number:channel?.msatoshi_to_us < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.to_us_msat/1000 | number:channel?.to_us_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_to_them">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Remote Balance (Sats)</th>
<td *matCellDef="let channel" mat-cell><span fxLayoutAlign="end center">
{{channel?.msatoshi_to_them/1000 | number:channel?.msatoshi_to_them < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
{{channel?.to_them_msat/1000 | number:channel?.to_them_msat < 1000 ? '1.0-4' : '1.0-0'}} </span></td>
</ng-container>
<ng-container matColumnDef="actions">
<th *matHeaderCellDef mat-header-cell>

@ -183,9 +183,9 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
rowToFilter = ((rowData.peer_connected) ? 'connected' : 'disconnected') + (rowData.channel_id ? rowData.channel_id.toLowerCase() : '') +
(rowData.short_channel_id ? rowData.short_channel_id.toLowerCase() : '') + (rowData.id ? rowData.id.toLowerCase() : '') + (rowData.alias ? rowData.alias.toLowerCase() : '') +
(rowData.private ? 'private' : 'public') + ((rowData.state && this.CLNChannelPendingState[rowData.state]) ? this.CLNChannelPendingState[rowData.state].toLowerCase() : '') +
(rowData.funding_txid ? rowData.funding_txid.toLowerCase() : '') + (rowData.msatoshi_to_us ? rowData.msatoshi_to_us : '') +
(rowData.msatoshi_total ? rowData.msatoshi_total : '') + (rowData.their_channel_reserve_satoshis ? rowData.their_channel_reserve_satoshis : '') +
(rowData.our_channel_reserve_satoshis ? rowData.our_channel_reserve_satoshis : '') + (rowData.spendable_msatoshi ? rowData.spendable_msatoshi : '');
(rowData.funding_txid ? rowData.funding_txid.toLowerCase() : '') + (rowData.to_us_msat ? rowData.to_us_msat : '') + (rowData.to_them_msat ? rowData.to_them_msat : '') +
(rowData.total_msat ? rowData.total_msat : '') + (rowData.their_reserve_msat ? rowData.their_reserve_msat : '') +
(rowData.our_reserve_msat ? rowData.our_reserve_msat : '') + (rowData.spendable_msat ? rowData.spendable_msat : '');
break;
case 'private':
@ -197,10 +197,19 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
break;
case 'msatoshi_total':
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['total_msat'] || 0)) / 1000)?.toString() || '';
break;
case 'spendable_msatoshi':
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['spendable_msat'] || 0)) / 1000)?.toString() || '';
break;
case 'msatoshi_to_us':
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['to_us_msat'] || 0)) / 1000)?.toString() || '';
break;
case 'msatoshi_to_them':
rowToFilter = ((+(rowData[this.selFilterBy] || 0)) / 1000)?.toString() || '';
rowToFilter = ((+(rowData[this.selFilterBy] || rowData['to_them_msat'] || 0)) / 1000)?.toString() || '';
break;
case 'state':
@ -220,6 +229,18 @@ export class CLNChannelPendingTableComponent implements OnInit, AfterViewInit, O
this.channels.sort = this.sort;
this.channels.sortingDataAccessor = (data: any, sortHeaderId: string) => {
switch (sortHeaderId) {
case 'msatoshi_total':
return data['msatoshi_total'] || data['total_msat'];
case 'spendable_msatoshi':
return data['spendable_msatoshi'] || data['spendable_msat'];
case 'msatoshi_to_us':
return data['msatoshi_to_us'] || data['to_us_msat'];
case 'msatoshi_to_them':
return data['msatoshi_to_them'] || data['to_them_msat'];
case 'state':
return this.CLNChannelPendingState[data.state];

@ -71,7 +71,7 @@
<mat-label>Coin Selection</mat-label>
<mat-select tabindex="6" multiple [(value)]="selUTXOs" (selectionChange)="onUTXOSelectionChange($event)">
<mat-select-trigger>{{totalSelectedUTXOAmount | number}} Sats ({{selUTXOs.length > 1 ? selUTXOs.length + ' UTXOs' : '1 UTXO'}})</mat-select-trigger>
<mat-option *ngFor="let utxo of utxos" [value]="utxo">{{utxo.value | number}} Sats</mat-option>
<mat-option *ngFor="let utxo of utxos" [value]="utxo">{{utxo.amount_msat / 1000 | number:'1.0-0'}} Sats</mat-option>
</mat-select>
</mat-form-field>
<div fxFlex="41" fxLayout="row" fxLayoutAlign="start center">

@ -331,9 +331,16 @@ export class CLNEffects implements OnDestroy {
map((channels: Channel[]) => {
this.logger.info(channels);
this.store.dispatch(updateCLAPICallStatus({ payload: { action: 'FetchChannels', status: APICallStatusEnum.COMPLETED } }));
// this.store.dispatch(getForwardingHistory({ payload: { status: CLNForwardingEventsStatusEnum.SETTLED } }));
const sortedChannels = { activeChannels: <Channel[]>[], pendingChannels: <Channel[]>[], inactiveChannels: <Channel[]>[] };
channels.forEach((channel) => {
if (channel.id) { channel.peer_id = channel.id; }
if (channel.connected) { channel.peer_connected = channel.connected; }
if (channel.msatoshi_to_us) { channel.to_us_msat = channel.msatoshi_to_us; }
if (channel.msatoshi_to_them) { channel.to_them_msat = channel.msatoshi_to_them; }
if (channel.msatoshi_total) { channel.total_msat = channel.msatoshi_total; }
if (channel.their_channel_reserve_satoshis) { channel.their_reserve_msat = +channel.their_channel_reserve_satoshis; }
if (channel.our_channel_reserve_satoshis) { channel.our_reserve_msat = +channel.our_channel_reserve_satoshis; }
if (channel.spendable_msatoshi) { channel.spendable_msat = +channel.spendable_msatoshi; }
if (channel.state === 'CHANNELD_NORMAL') {
if (channel.peer_connected) {
sortedChannels.activeChannels.push(channel);
@ -722,6 +729,7 @@ export class CLNEffects implements OnDestroy {
this.store.dispatch(updateCLAPICallStatus({ payload: { action: 'SaveNewInvoice', status: APICallStatusEnum.COMPLETED } }));
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.ADD_INVOICE }));
postRes.msatoshi = action.payload.amount;
postRes.amount_msat = action.payload.amount;
postRes.label = action.payload.label;
postRes.expires_at = Math.round((new Date().getTime() / 1000) + action.payload.expiry);
postRes.description = action.payload.description;
@ -926,6 +934,11 @@ export class CLNEffects implements OnDestroy {
map((utxos: any) => {
this.logger.info(utxos);
this.store.dispatch(updateCLAPICallStatus({ payload: { action: 'FetchUTXOs', status: APICallStatusEnum.COMPLETED } }));
utxos.outputs.forEach((output) => { // For backward compatibility
if (output.value) {
output.amount_msat = output.value;
}
});
return {
type: CLNActions.SET_UTXOS_CLN,
payload: utxos.outputs || []

@ -99,7 +99,7 @@ export class CLNCreateInvoiceComponent implements OnInit, OnDestroy {
pipe(takeUntil(this.unSubs[3])).
subscribe({
next: (data) => {
this.invoiceValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;
this.invoiceValueHint = '= ' + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;
}, error: (err) => {
this.invoiceValueHint = 'Conversion Error: ' + err;
}

@ -33,7 +33,7 @@
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">{{screenSize === screenSizeEnum.XS ? 'Amount' : 'Amount Requested'}}</h4>
<span class="foreground-secondary-text">
{{(invoice?.msatoshi/1000 || 0) | number}} Sats<ng-container *ngIf="!invoice?.msatoshi || invoice?.msatoshi === '0'"> (zero amount) </ng-container>
{{(invoice?.amount_msat/1000 || 0) | number}} Sats<ng-container *ngIf="!invoice?.amount_msat || invoice?.amount_msat === '0'"> (zero amount) </ng-container>
</span>
</div>
<div fxFlex="50">
@ -42,11 +42,11 @@
<ng-container *ngIf="invoice?.status === 'paid'">
<div *ngIf="flgInvoicePaid" class="invoice-animation-container">
<div class="invoice-animation-div">
<span class="wiggle">{{invoice?.msatoshi_received/1000 | number}} Sats</span>
<span class="wiggle">{{invoice?.amount_received_msat/1000 | number}} Sats</span>
<span *ngFor="let i of [].constructor(35)" class="particles-circle"></span>
</div>
</div>
<div *ngIf="!flgInvoicePaid">{{invoice?.msatoshi_received/1000 | number}} Sats</div>
<div *ngIf="!flgInvoicePaid">{{invoice?.amount_received_msat/1000 | number}} Sats</div>
</ng-container>
<ng-container *ngIf="invoice?.status !== 'paid'">
<span *ngIf="invoice?.status !== 'unpaid' || !flgVersionCompatible">-</span>

@ -97,11 +97,11 @@
</ng-container>
<ng-container matColumnDef="msatoshi">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Amount (Sats)</th>
<td *matCellDef="let invoice" mat-cell><span fxLayoutAlign="end center">{{invoice?.msatoshi/1000 | number:invoice?.msatoshi < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
<td *matCellDef="let invoice" mat-cell><span fxLayoutAlign="end center">{{invoice?.amount_msat/1000 | number:invoice?.amount_msat < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
</ng-container>
<ng-container matColumnDef="msatoshi_received">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Amount Settled (Sats)</th>
<td *matCellDef="let invoice" mat-cell><span fxLayoutAlign="end center">{{invoice?.msatoshi_received/1000 | number:invoice?.msatoshi_received < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
<td *matCellDef="let invoice" mat-cell><span fxLayoutAlign="end center">{{invoice?.amount_received_msat/1000 | number:invoice?.amount_received_msat < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
</ng-container>
<ng-container matColumnDef="actions">
<th *matHeaderCellDef mat-header-cell>

@ -175,7 +175,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
onInvoiceClick(selInvoice: Invoice) {
const reCreatedInvoice: Invoice = {
msatoshi: selInvoice.msatoshi,
amount_msat: selInvoice.amount_msat,
label: selInvoice.label,
expires_at: selInvoice.expires_at,
paid_at: selInvoice.paid_at,
@ -183,7 +183,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
payment_hash: selInvoice.payment_hash,
description: selInvoice.description,
status: selInvoice.status,
msatoshi_received: selInvoice.msatoshi_received
amount_received_msat: selInvoice.amount_received_msat
};
this.store.dispatch(openAlert({
payload: {
@ -237,8 +237,11 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
break;
case 'msatoshi':
rowToFilter = ((rowData['msatoshi'] || rowData['amount_msat'] || 0) / 1000)?.toString() || '';
break;
case 'msatoshi_received':
rowToFilter = ((+(rowData[this.selFilterBy] || 0)) / 1000)?.toString() || '';
rowToFilter = ((rowData['msatoshi_received'] || rowData['amount_received_msat'] || 0) / 1000)?.toString() || '';
break;
default:
@ -256,7 +259,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
pipe(takeUntil(this.unSubs[6])).
subscribe({
next: (data) => {
this.invoiceValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;
this.invoiceValueHint = '= ' + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;
}, error: (err) => {
this.invoiceValueHint = 'Conversion Error: ' + err;
}
@ -275,7 +278,18 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
loadInvoicesTable(invs: Invoice[]) {
this.invoices = (invs) ? new MatTableDataSource<Invoice>([...invs]) : new MatTableDataSource([]);
this.invoices.sort = this.sort;
this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => {
switch (sortHeaderId) {
case 'msatoshi':
return data['msatoshi'] || data['amount_msat'];
case 'msatoshi_received':
return data['msatoshi_received'] || data['amount_received_msat'];
default:
return (data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null;
}
};
this.invoices.paginator = this.paginator;
this.applyFilter();
this.setFilterPredicate();

@ -82,7 +82,7 @@ export class CLNCreateOfferComponent implements OnInit, OnDestroy {
pipe(takeUntil(this.unSubs[3])).
subscribe({
next: (data) => {
this.offerValueHint = '= ' + data.symbol + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;
this.offerValueHint = '= ' + this.decimalPipe.transform(data.OTHER, CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit;
}, error: (err) => {
this.offerValueHint = 'Conversion Error: ' + err;
}

@ -22,7 +22,7 @@
<div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">Amount Requested (Sats)</h4>
<span class="foreground-secondary-text">
{{ !offerDecoded?.offer_amount_msat || offerDecoded?.offer_amount === 0 ? 'Open Offer' : ((offerDecoded?.offer_amount / 1000) | number) }}
{{ !offerDecoded?.offer_amount_msat || offerDecoded?.offer_amount_msat === 0 ? 'Open Offer' : (((offerDecoded?.offer_amount || offerDecoded?.offer_amount_msat) / 1000) | number) }}
</span>
</div>
<div fxFlex="50">

@ -47,10 +47,10 @@ export class CLNOfferInformationComponent implements OnInit, OnDestroy {
pipe(takeUntil(this.unSubs[1])).subscribe((decodedOffer: OfferRequest) => {
this.offerDecoded = decodedOffer;
if (this.offerDecoded.offer_id && !this.offerDecoded.offer_amount_msat) {
this.offerDecoded.offer_amount_msat = '0msat';
this.offerDecoded.offer_amount_msat = 0;
this.offerDecoded.offer_amount = 0;
} else {
this.offerDecoded.offer_amount = this.offerDecoded.offer_amount ? +this.offerDecoded.offer_amount : this.offerDecoded.offer_amount_msat ? +this.offerDecoded.offer_amount_msat.slice(0, -4) : null;
this.offerDecoded.offer_amount = this.offerDecoded.offer_amount || this.offerDecoded.offer_amount_msat || null;
}
});
}

@ -180,10 +180,10 @@ export class CLNOffersTableComponent implements OnInit, AfterViewInit, OnDestroy
this.dataService.decodePayment(selOffer.bolt12!, false).
pipe(take(1)).subscribe((offerDecoded: OfferRequest) => {
if (offerDecoded.offer_id && !offerDecoded.offer_amount_msat) {
offerDecoded.offer_amount_msat = '0msat';
offerDecoded.offer_amount_msat = 0;
offerDecoded.offer_amount = 0;
} else {
offerDecoded.offer_amount = offerDecoded.offer_amount ? +offerDecoded.offer_amount : offerDecoded.offer_amount_msat ? +offerDecoded.offer_amount_msat.slice(0, -4) : null;
offerDecoded.offer_amount = offerDecoded.offer_amount || offerDecoded.offer_amount_msat || null;
}
const documentDefinition = {
pageSize: 'A5',

@ -96,11 +96,11 @@
</ng-container>
<ng-container matColumnDef="msatoshi_sent">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Sats Sent</th>
<td *matCellDef="let payment" mat-cell><span fxLayoutAlign="end center">{{payment?.msatoshi_sent/1000 | number:payment?.msatoshi_sent < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
<td *matCellDef="let payment" mat-cell><span fxLayoutAlign="end center">{{payment?.amount_sent_msat/1000 | number:payment?.amount_sent_msat < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
</ng-container>
<ng-container matColumnDef="msatoshi">
<th *matHeaderCellDef mat-header-cell mat-sort-header arrowPosition="before">Sats Received</th>
<td *matCellDef="let payment" mat-cell><span fxLayoutAlign="end center">{{payment?.msatoshi/1000 | number:payment?.msatoshi < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
<td *matCellDef="let payment" mat-cell><span fxLayoutAlign="end center">{{payment?.amount_msat/1000 | number:payment?.amount_msat < 1000 ? '1.0-4' : '1.0-0'}}</span></td>
</ng-container>
<ng-container matColumnDef="actions">
<th *matHeaderCellDef mat-header-cell>
@ -218,20 +218,20 @@
</ng-container>
<ng-container matColumnDef="group_msatoshi_sent">
<td *matCellDef="let payment" mat-cell>
<span fxLayoutAlign="end center" class="mpp-row-span">{{payment?.msatoshi_sent/1000 | number:payment?.msatoshi_sent < 1000 ? '1.0-4' : '1.0-0'}}</span>
<span fxLayoutAlign="end center" class="mpp-row-span">{{payment?.amount_sent_msat/1000 | number:payment?.amount_sent_msat < 1000 ? '1.0-4' : '1.0-0'}}</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="end center" class="mpp-row-span">
{{mpp.msatoshi_sent/1000 | number:mpp.msatoshi_sent < 1000 ? '1.0-4' : '1.0-0'}}
{{mpp.amount_sent_msat/1000 | number:mpp.amount_sent_msat < 1000 ? '1.0-4' : '1.0-0'}}
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="group_msatoshi">
<td *matCellDef="let payment" mat-cell>
<span fxLayoutAlign="end center" class="mpp-row-span">{{payment?.msatoshi/1000 | number:payment?.msatoshi < 1000 ? '1.0-4' : '1.0-0'}}</span>
<span fxLayoutAlign="end center" class="mpp-row-span">{{payment?.amount_msat/1000 | number:payment?.amount_msat < 1000 ? '1.0-4' : '1.0-0'}}</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="end center" class="mpp-row-span">
{{mpp.msatoshi/1000 | number:mpp.msatoshi < 1000 ? '1.0-4' : '1.0-0'}}
{{mpp.amount_msat/1000 | number:mpp.amount_msat < 1000 ? '1.0-4' : '1.0-0'}}
</span>
</span>
</td>

@ -147,8 +147,8 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
pipe(takeUntil(this.unSubs[4])).subscribe((decodedPayment: PayRequest) => {
this.paymentDecoded = decodedPayment;
if (this.paymentDecoded.created_at) {
if (!this.paymentDecoded.msatoshi) {
this.paymentDecoded.msatoshi = 0;
if (!this.paymentDecoded.amount_msat) {
this.paymentDecoded.amount_msat = 0;
}
this.sendPayment();
} else {
@ -160,7 +160,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
sendPayment() {
this.newlyAddedPayment = this.paymentDecoded?.payment_hash || '';
if (!this.paymentDecoded.msatoshi || this.paymentDecoded.msatoshi === 0) {
if (!this.paymentDecoded.amount_msat || this.paymentDecoded.amount_msat === 0) {
const reorderedPaymentDecoded = [
[{ key: 'payment_hash', value: this.paymentDecoded.payment_hash, title: 'Payment Hash', width: 100 }],
[{ key: 'payee', value: this.paymentDecoded.payee, title: 'Payee', width: 100 }],
@ -190,7 +190,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
pipe(take(1)).
subscribe((confirmRes) => {
if (confirmRes) {
this.paymentDecoded.msatoshi = confirmRes[0].inputValue;
this.paymentDecoded.amount_msat = confirmRes[0].inputValue;
this.store.dispatch(sendPayment({ payload: { uiMessage: UI_MESSAGES.SEND_PAYMENT, paymentType: PaymentTypes.INVOICE, invoice: this.paymentRequest, amount: confirmRes[0].inputValue * 1000, fromDialog: false } }));
this.resetData();
}
@ -201,7 +201,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
[{ key: 'payee', value: this.paymentDecoded.payee, title: 'Payee', width: 100 }],
[{ key: 'description', value: this.paymentDecoded.description, title: 'Description', width: 100 }],
[{ key: 'created_at', value: this.paymentDecoded.created_at, title: 'Creation Date', width: 50, type: DataTypeEnum.DATE_TIME },
{ key: 'num_satoshis', value: this.paymentDecoded.msatoshi / 1000, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.NUMBER }],
{ key: 'num_satoshis', value: this.paymentDecoded.amount_msat / 1000, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.NUMBER }],
[{ key: 'expiry', value: this.paymentDecoded.expiry, title: 'Expiry', width: 50, type: DataTypeEnum.NUMBER },
{ key: 'min_finaltv_expiry', value: this.paymentDecoded.min_final_cltv_expiry, title: 'CLTV Expiry', width: 50 }]
];
@ -234,22 +234,22 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
this.dataService.decodePayment(this.paymentRequest, false).
pipe(takeUntil(this.unSubs[5])).subscribe((decodedPayment: PayRequest) => {
this.paymentDecoded = decodedPayment;
if (this.paymentDecoded.msatoshi) {
if (this.paymentDecoded.amount_msat) {
if (this.selNode?.fiatConversion) {
this.commonService.convertCurrency(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).
this.commonService.convertCurrency(this.paymentDecoded.amount_msat ? this.paymentDecoded.amount_msat / 1000 : 0, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).
pipe(takeUntil(this.unSubs[6])).
subscribe({
next: (data) => {
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.msatoshi ?
this.paymentDecoded.msatoshi / 1000 : 0) + ' Sats (' + data.symbol + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0),
CURRENCY_UNIT_FORMATS.OTHER) + ') | Memo: ' + this.paymentDecoded.description;
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount_msat ?
this.paymentDecoded.amount_msat / 1000 : 0) + ' Sats (' + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0),
CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit + ') | Memo: ' + this.paymentDecoded.description;
}, error: (error) => {
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0) +
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount_msat ? this.paymentDecoded.amount_msat / 1000 : 0) +
' Sats | Memo: ' + this.paymentDecoded.description + '. Unable to convert currency.';
}
});
} else {
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0) +
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount_msat ? this.paymentDecoded.amount_msat / 1000 : 0) +
' Sats | Memo: ' + this.paymentDecoded.description;
}
} else {
@ -282,8 +282,8 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
{ key: 'destination', value: selPayment.destination, title: 'Destination', width: 80, type: DataTypeEnum.STRING }],
[{ key: 'created_at', value: selPayment.created_at, title: 'Creation Date', width: 50, type: DataTypeEnum.DATE_TIME },
{ key: 'status', value: this.titleCasePipe.transform(selPayment.status), title: 'Status', width: 50, type: DataTypeEnum.STRING }],
[{ key: 'msatoshi', value: selPayment.msatoshi, title: 'Amount (mSats)', width: 50, type: DataTypeEnum.NUMBER },
{ key: 'msatoshi_sent', value: selPayment.msatoshi_sent, title: 'Amount Sent (mSats)', width: 50, type: DataTypeEnum.NUMBER }]
[{ key: 'amount_msat', value: selPayment.amount_msat, title: 'Amount (mSats)', width: 50, type: DataTypeEnum.NUMBER },
{ key: 'amount_sent_msat', value: selPayment.amount_sent_msat, title: 'Amount Sent (mSats)', width: 50, type: DataTypeEnum.NUMBER }]
];
if (selPayment.bolt11 && selPayment.bolt11 !== '') {
reorderedPayment?.unshift([{ key: 'bolt11', value: selPayment.bolt11, title: 'Bolt 11', width: 100, type: DataTypeEnum.STRING }]);
@ -337,8 +337,11 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
break;
case 'msatoshi_sent':
rowToFilter = ((rowData['msatoshi_sent'] || rowData['amount_sent_msat'] || 0) / 1000)?.toString() || '';
break;
case 'msatoshi':
rowToFilter = ((+(rowData[this.selFilterBy] || 0)) / 1000)?.toString() || '';
rowToFilter = ((rowData['msatoshi'] || rowData['amount_msat'] || 0) / 1000)?.toString() || '';
break;
case 'type':
@ -356,7 +359,18 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
loadPaymentsTable(payments: Payment[]) {
this.payments = (payments) ? new MatTableDataSource<Payment>([...payments]) : new MatTableDataSource([]);
this.payments.sort = this.sort;
this.payments.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
this.payments.sortingDataAccessor = (data: any, sortHeaderId: string) => {
switch (sortHeaderId) {
case 'msatoshi_sent':
return data['msatoshi_sent'] || data['amount_sent_msat'];
case 'msatoshi':
return data['msatoshi'] || data['amount_msat'];
default:
return (data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null;
}
};
this.payments.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();

@ -132,7 +132,7 @@ export class CLNLightningSendPaymentsComponent implements OnInit, OnDestroy {
}
if (action.type === CLNActions.UPDATE_API_CALL_STATUS_CLN && action.payload.status === APICallStatusEnum.ERROR) {
if (action.payload.action === 'SendPayment') {
delete this.paymentDecoded.msatoshi;
delete this.paymentDecoded.amount_msat;
this.paymentError = action.payload.message;
}
if (action.payload.action === 'DecodePayment') {
@ -292,14 +292,14 @@ export class CLNLightningSendPaymentsComponent implements OnInit, OnDestroy {
onAmountChange(event: any) {
if (this.paymentType === PaymentTypes.INVOICE) {
delete this.paymentDecoded.msatoshi;
this.paymentDecoded.msatoshi = +event.target.value;
delete this.paymentDecoded.amount_msat;
this.paymentDecoded.amount_msat = +event.target.value;
}
if (this.paymentType === PaymentTypes.OFFER) {
delete this.offerDecoded.offer_amount;
delete this.offerDecoded.offer_amount_msat;
this.offerDecoded.offer_amount = +event.target.value * 1000;
this.offerDecoded.offer_amount_msat = event.target.value + 'msat';
this.offerDecoded.offer_amount_msat = event.target.value;
}
}
@ -312,7 +312,7 @@ export class CLNLightningSendPaymentsComponent implements OnInit, OnDestroy {
setOfferDecodedDetails() {
if (this.offerDecoded.offer_id && !this.offerDecoded.offer_amount_msat) {
this.offerDecoded.offer_amount_msat = '0msat';
this.offerDecoded.offer_amount_msat = 0;
this.offerDecoded.offer_amount = 0;
this.zeroAmtOffer = true;
this.offerDescription = this.offerDecoded.offer_description || '';
@ -320,7 +320,7 @@ export class CLNLightningSendPaymentsComponent implements OnInit, OnDestroy {
this.offerDecodedHint = 'Zero Amount Offer | Description: ' + this.offerDecoded.offer_description;
} else {
this.zeroAmtOffer = false;
this.offerDecoded.offer_amount = this.offerDecoded.offer_amount ? +this.offerDecoded.offer_amount : this.offerDecoded.offer_amount_msat ? +this.offerDecoded.offer_amount_msat.slice(0, -4) : null;
this.offerDecoded.offer_amount = this.offerDecoded.offer_amount || this.offerDecoded.offer_amount_msat || null;
this.offerAmount = this.offerDecoded.offer_amount ? this.offerDecoded.offer_amount / 1000 : 0;
this.offerDescription = this.offerDecoded.offer_description || '';
this.offerIssuer = this.offerDecoded.offer_issuer ? this.offerDecoded.offer_issuer : '';
@ -329,7 +329,7 @@ export class CLNLightningSendPaymentsComponent implements OnInit, OnDestroy {
pipe(takeUntil(this.unSubs[7])).
subscribe({
next: (data) => {
this.offerDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.offerAmount) + ' Sats (' + data.symbol + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0), CURRENCY_UNIT_FORMATS.OTHER) + ') | Description: ' + this.offerDecoded.offer_description;
this.offerDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.offerAmount) + ' Sats (' + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0), CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit + ') | Description: ' + this.offerDecoded.offer_description;
}, error: (error) => {
this.offerDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.offerAmount) + ' Sats | Description: ' + this.offerDecoded.offer_description + '. Unable to convert currency.';
}
@ -341,24 +341,25 @@ export class CLNLightningSendPaymentsComponent implements OnInit, OnDestroy {
}
setPaymentDecodedDetails() {
if (this.paymentDecoded.created_at && !this.paymentDecoded.msatoshi) {
this.paymentDecoded.msatoshi = 0;
if (this.paymentDecoded.created_at && !this.paymentDecoded.amount_msat) {
this.paymentDecoded.amount_msat = 0;
this.zeroAmtInvoice = true;
this.paymentDecodedHint = 'Zero Amount Invoice | Memo: ' + this.paymentDecoded.description;
} else {
this.zeroAmtInvoice = false;
if (this.selNode && this.selNode.fiatConversion) {
this.commonService.convertCurrency(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).
this.commonService.convertCurrency(this.paymentDecoded.amount_msat ? this.paymentDecoded.amount_msat / 1000 : 0, CurrencyUnitEnum.SATS, CurrencyUnitEnum.OTHER, (this.selNode.currencyUnits && this.selNode.currencyUnits.length > 2 ? this.selNode.currencyUnits[2] : ''), this.selNode.fiatConversion).
pipe(takeUntil(this.unSubs[8])).
subscribe({
next: (data) => {
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0) + ' Sats (' + data.symbol + this.decimalPipe.transform((data.OTHER ? data.OTHER : 0), CURRENCY_UNIT_FORMATS.OTHER) + ') | Memo: ' + this.paymentDecoded.description;
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount_msat ? this.paymentDecoded.amount_msat / 1000 : 0) + ' Sats (' +
this.decimalPipe.transform((data.OTHER ? data.OTHER : 0), CURRENCY_UNIT_FORMATS.OTHER) + ' ' + data.unit + ') | Memo: ' + this.paymentDecoded.description;
}, error: (error) => {
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0) + ' Sats | Memo: ' + this.paymentDecoded.description + '. Unable to convert currency.';
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount_msat ? this.paymentDecoded.amount_msat / 1000 : 0) + ' Sats | Memo: ' + this.paymentDecoded.description + '. Unable to convert currency.';
}
});
} else {
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.msatoshi ? this.paymentDecoded.msatoshi / 1000 : 0) + ' Sats | Memo: ' + this.paymentDecoded.description;
this.paymentDecodedHint = 'Sending: ' + this.decimalPipe.transform(this.paymentDecoded.amount_msat ? this.paymentDecoded.amount_msat / 1000 : 0) + ' Sats | Memo: ' + this.paymentDecoded.description;
}
}
}

@ -77,12 +77,12 @@ export interface Invoice {
bolt11?: string;
bolt12?: string;
payment_hash?: string;
msatoshi?: number;
amount_msat?: string;
msatoshi?: number; // For backward compatibility
amount_msat?: number;
status?: string;
pay_index?: number;
msatoshi_received?: number;
amount_received_msat?: string;
msatoshi_received?: number; // For backward compatibility
amount_received_msat?: number;
paid_at?: number;
payment_preimage?: string;
description?: string;
@ -138,14 +138,14 @@ export interface Hop {
}
export interface MPP {
amount_msat?: string;
amount_sent_msat?: string;
bolt11?: string;
created_at?: number;
destination?: string;
id?: number;
msatoshi?: number;
msatoshi_sent?: number;
msatoshi?: number; // For Backward compatibility
amount_msat?: number;
msatoshi_sent?: number; // For Backward compatibility
amount_sent_msat?: number;
payment_hash?: string;
payment_preimage?: string;
status?: string;
@ -153,15 +153,15 @@ export interface MPP {
}
export interface Payment {
amount_msat?: string;
amount_sent_msat?: string;
bolt11?: string;
bolt12?: string;
created_at?: number;
destination?: string;
id?: number;
msatoshi?: number;
msatoshi_sent?: number;
msatoshi?: number; // For Backward compatibility
amount_msat?: number;
msatoshi_sent?: number; // For Backward compatibility
amount_sent_msat?: number;
payment_hash?: string;
payment_preimage?: string;
status?: string;
@ -180,7 +180,7 @@ export interface PayRequest {
expiry?: number;
payee?: string;
msatoshi?: number;
amount_msat?: string;
amount_msat?: number;
description?: string;
min_final_cltv_expiry?: number;
payment_hash?: string;
@ -212,8 +212,8 @@ interface Recurrence {
export interface OfferRequest {
offer_id?: string;
offer_amount?: number | null;
offer_amount_msat?: string;
offer_amount?: number | null; // For Backward compatibility
offer_amount_msat?: number;
type?: string;
valid?: boolean;
offer_node_id?: string;
@ -308,22 +308,34 @@ export interface ChannelHTLC {
}
export interface Channel {
id?: string;
id?: string; // For Backward compatibility
peer_id?: string;
alias?: string;
connected?: boolean; // For Backward compatibility
peer_connected?: boolean;
state?: string;
short_channel_id?: string;
channel_id?: string;
funding_txid?: string;
private?: boolean;
msatoshi_to_us?: number;
msatoshi_to_them?: number;
msatoshi_total?: number;
their_channel_reserve_satoshis?: string;
our_channel_reserve_satoshis?: string;
spendable_msatoshi?: string;
msatoshi_to_us?: number; // For Backward compatibility
to_us_msat?: number;
msatoshi_to_them?: number; // For Backward compatibility
to_them_msat?: number;
msatoshi_total?: number; // For Backward compatibility
total_msat?: number;
their_channel_reserve_satoshis?: string; // For Backward compatibility
their_reserve_msat?: number;
our_channel_reserve_satoshis?: string; // For Backward compatibility
our_reserve_msat?: number;
spendable_msatoshi?: string; // For Backward compatibility
spendable_msat?: number;
direction?: number;
htlcs?: ChannelHTLC[];
receivable_msat?: number;
fee_base_msat?: number;
fee_proportional_millionths?: number;
dust_limit_msat?: number;
balancedness?: number; // Between 0-1-0
}
@ -394,7 +406,8 @@ export interface FeeRates {
export interface UTXO {
txid?: string;
output?: number;
value?: number;
value?: number; // For Backward compatibility
amount_msat?: number;
status?: string;
blockheight?: string;
scriptpubkey?: string;

@ -178,6 +178,9 @@
}
button.mdc-button.mat-mdc-button-base.mat-mdc-outlined-button{
border-color: $foreground-disabled;
&.mat-warn {
border-color: $warn-color;
}
}
.mat-mdc-select-arrow svg {
fill: $foreground-base;

@ -99,8 +99,11 @@
color: $accent-color;
}
}
button.mdc-button.mat-mdc-button-base.mat-mdc-outlined-button{
button.mdc-button.mat-mdc-button-base.mat-mdc-outlined-button {
border-color: $primary-color;
&.mat-warn {
border-color: $warn-color;
}
}
.mat-tree-node:hover, .mat-nested-tree-node-parent:hover, .mat-select-panel .mat-option:hover, .mat-menu-panel .mat-menu-content .mat-menu-item:hover,
@ -118,10 +121,6 @@
}
}
.mat-mdc-progress-spinner .mdc-circular-progress__determinate-circle, .mat-mdc-progress-spinner .mdc-circular-progress__indeterminate-circle-graphic {
stroke: $background-color;
}
.spinner-container h2 {
color: $background-color;
}

Loading…
Cancel
Save