LND update fee policy with min max htlc

LND update fee policy with min max htlc
This commit is contained in:
ShahanaFarooqui 2022-08-13 22:19:31 -07:00
parent 07f8d326d8
commit 89e7ebadaa
23 changed files with 79 additions and 51 deletions

View File

@ -239,16 +239,28 @@ export const postChanPolicy = (req, res, next) => {
const breakPoint = req.body.chanPoint.indexOf(':'); const breakPoint = req.body.chanPoint.indexOf(':');
const txid_str = req.body.chanPoint.substring(0, breakPoint); const txid_str = req.body.chanPoint.substring(0, breakPoint);
const output_idx = req.body.chanPoint.substring(breakPoint + 1, req.body.chanPoint.length); const output_idx = req.body.chanPoint.substring(breakPoint + 1, req.body.chanPoint.length);
options.form = JSON.stringify({ const optionsBody = {
base_fee_msat: req.body.baseFeeMsat, base_fee_msat: req.body.baseFeeMsat,
fee_rate: parseFloat((req.body.feeRate / 1000000).toString()), fee_rate: parseFloat((req.body.feeRate / 1000000).toString()),
time_lock_delta: parseInt(req.body.timeLockDelta), time_lock_delta: parseInt(req.body.timeLockDelta),
chan_point: { funding_txid_str: txid_str, output_index: parseInt(output_idx) } chan_point: { funding_txid_str: txid_str, output_index: parseInt(output_idx) }
}); };
if (req.body.max_htlc_msat) {
optionsBody['max_htlc_msat'] = req.body.max_htlc_msat;
}
if (req.body.min_htlc_msat) {
optionsBody['min_htlc_msat'] = req.body.min_htlc_msat;
optionsBody['min_htlc_msat_specified'] = true;
}
options.form = JSON.stringify(optionsBody);
} }
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Channel Policy Updated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Channel Policy Updated', data: body });
if (body.failed_updates && body.failed_updates.length && body.failed_updates[0].update_error) {
const err = common.handleError({ error: body.failed_updates[0].update_error }, 'Channels', 'Update Channel Policy Error', req.session.selectedNode);
return res.status(500).json({ message: err.message, error: err.error });
}
res.status(201).json(body); res.status(201).json(body);
}).catch((errRes) => { }).catch((errRes) => {
const err = common.handleError(errRes, 'Channels', 'Update Channel Policy Error', req.session.selectedNode); const err = common.handleError(errRes, 'Channels', 'Update Channel Policy Error', req.session.selectedNode);

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

View File

@ -13,6 +13,6 @@
<style>@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}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;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}</style><link rel="stylesheet" href="styles.76b4c7ddb718ef83.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.76b4c7ddb718ef83.css"></noscript></head> <style>@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}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;height:100%;margin:0;overflow:hidden}*{margin:0;padding:0}</style><link rel="stylesheet" href="styles.76b4c7ddb718ef83.css" media="print" onload="this.media='all'"><noscript><link rel="stylesheet" href="styles.76b4c7ddb718ef83.css"></noscript></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.379f748f82de1ce5.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.a45f905361ad3a22.js" type="module"></script> <script src="runtime.ddd1bc6afbf193d0.js" type="module"></script><script src="polyfills.eddc63f1737a019a.js" type="module"></script><script src="main.389f972785df38ec.js" type="module"></script>
</body></html> </body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(()=>{"use strict";var e,v={},g={};function r(e){var n=g[e];if(void 0!==n)return n.exports;var t=g[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=(n,t,f,o)=>{if(!t){var a=1/0;for(i=0;i<e.length;i++){for(var[t,f,o]=e[i],c=!0,u=0;u<t.length;u++)(!1&o||a>=o)&&Object.keys(r.O).every(b=>r.O[b](t[u]))?t.splice(u--,1):(c=!1,o<a&&(a=o));if(c){e.splice(i--,1);var d=f();void 0!==d&&(n=d)}}return n}o=o||0;for(var i=e.length;i>0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,f,o]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>e+"."+{564:"d224f537513d1972",636:"d70da2a07ddfc5b5",893:"9a615c46b89a5a79",924:"6a3e6171c436f405"}[e]+".js",r.miniCssF=e=>{},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="RTLApp:";r.l=(t,f,o,i)=>{if(e[t])e[t].push(f);else{var a,c;if(void 0!==o)for(var u=document.getElementsByTagName("script"),d=0;d<u.length;d++){var l=u[d];if(l.getAttribute("src")==t||l.getAttribute("data-webpack")==n+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",n+o),a.src=r.tu(t)),e[t]=[f];var s=(m,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(_=>_(b)),m)return m(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=>{"undefined"!=typeof Symbol&&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:n=>n},"undefined"!=typeof trustedTypes&&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=(f,o)=>{var i=r.o(e,f)?e[f]:void 0;if(0!==i)if(i)o.push(i[2]);else if(666!=f){var a=new Promise((l,s)=>i=e[f]=[l,s]);o.push(i[2]=a);var c=r.p+r.u(f),u=new Error;r.l(c,l=>{if(r.o(e,f)&&(0!==(i=e[f])&&(e[f]=void 0),i)){var s=l&&("load"===l.type?"missing":l.type),p=l&&l.target&&l.target.src;u.message="Loading chunk "+f+" failed.\n("+s+": "+p+")",u.name="ChunkLoadError",u.type=s,u.request=p,i[1](u)}},"chunk-"+f,f)}else e[f]=0},r.O.j=f=>0===e[f];var n=(f,o)=>{var u,d,[i,a,c]=o,l=0;if(i.some(p=>0!==e[p])){for(u in a)r.o(a,u)&&(r.m[u]=a[u]);if(c)var s=c(r)}for(f&&f(o);l<i.length;l++)r.o(e,d=i[l])&&e[d]&&e[d][0](),e[d]=0;return r.O(s)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})(); (()=>{"use strict";var e,v={},g={};function r(e){var n=g[e];if(void 0!==n)return n.exports;var t=g[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=(n,t,f,o)=>{if(!t){var a=1/0;for(i=0;i<e.length;i++){for(var[t,f,o]=e[i],s=!0,u=0;u<t.length;u++)(!1&o||a>=o)&&Object.keys(r.O).every(b=>r.O[b](t[u]))?t.splice(u--,1):(s=!1,o<a&&(a=o));if(s){e.splice(i--,1);var d=f();void 0!==d&&(n=d)}}return n}o=o||0;for(var i=e.length;i>0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,f,o]},r.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return r.d(n,{a:n}),n},r.d=(e,n)=>{for(var t in n)r.o(n,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((n,t)=>(r.f[t](e,n),n),[])),r.u=e=>e+"."+{564:"d70179bdc8de435e",636:"fca59f1c7f67eb50",893:"9a615c46b89a5a79",924:"7e273146133fd37e"}[e]+".js",r.miniCssF=e=>{},r.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),(()=>{var e={},n="RTLApp:";r.l=(t,f,o,i)=>{if(e[t])e[t].push(f);else{var a,s;if(void 0!==o)for(var u=document.getElementsByTagName("script"),d=0;d<u.length;d++){var l=u[d];if(l.getAttribute("src")==t||l.getAttribute("data-webpack")==n+o){a=l;break}}a||(s=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",n+o),a.src=r.tu(t)),e[t]=[f];var c=(m,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(_=>_(b)),m)return m(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{"undefined"!=typeof Symbol&&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:n=>n},"undefined"!=typeof trustedTypes&&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=(f,o)=>{var i=r.o(e,f)?e[f]:void 0;if(0!==i)if(i)o.push(i[2]);else if(666!=f){var a=new Promise((l,c)=>i=e[f]=[l,c]);o.push(i[2]=a);var s=r.p+r.u(f),u=new Error;r.l(s,l=>{if(r.o(e,f)&&(0!==(i=e[f])&&(e[f]=void 0),i)){var c=l&&("load"===l.type?"missing":l.type),p=l&&l.target&&l.target.src;u.message="Loading chunk "+f+" failed.\n("+c+": "+p+")",u.name="ChunkLoadError",u.type=c,u.request=p,i[1](u)}},"chunk-"+f,f)}else e[f]=0},r.O.j=f=>0===e[f];var n=(f,o)=>{var u,d,[i,a,s]=o,l=0;if(i.some(p=>0!==e[p])){for(u in a)r.o(a,u)&&(r.m[u]=a[u]);if(s)var c=s(r)}for(f&&f(o);l<i.length;l++)r.o(e,d=i[l])&&e[d]&&e[d][0](),e[d]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(n.bind(null,0)),t.push=n.bind(null,t.push.bind(t))})()})();

View File

@ -220,19 +220,29 @@ export const postChanPolicy = (req, res, next) => {
const breakPoint = req.body.chanPoint.indexOf(':'); const breakPoint = req.body.chanPoint.indexOf(':');
const txid_str = req.body.chanPoint.substring(0, breakPoint); const txid_str = req.body.chanPoint.substring(0, breakPoint);
const output_idx = req.body.chanPoint.substring(breakPoint + 1, req.body.chanPoint.length); const output_idx = req.body.chanPoint.substring(breakPoint + 1, req.body.chanPoint.length);
options.form = JSON.stringify({ const optionsBody = {
base_fee_msat: req.body.baseFeeMsat, base_fee_msat: req.body.baseFeeMsat,
fee_rate: parseFloat((req.body.feeRate / 1000000).toString()), fee_rate: parseFloat((req.body.feeRate / 1000000).toString()),
time_lock_delta: parseInt(req.body.timeLockDelta), time_lock_delta: parseInt(req.body.timeLockDelta),
max_htlc_msat: req.body.max_htlc_msat,
min_htlc_msat: req.body.min_htlc_msat,
min_htlc_msat_specified: true,
chan_point: { funding_txid_str: txid_str, output_index: parseInt(output_idx) } chan_point: { funding_txid_str: txid_str, output_index: parseInt(output_idx) }
}); };
if (req.body.max_htlc_msat) {
optionsBody['max_htlc_msat'] = req.body.max_htlc_msat;
}
if (req.body.min_htlc_msat) {
optionsBody['min_htlc_msat'] = req.body.min_htlc_msat;
optionsBody['min_htlc_msat_specified'] = true;
}
options.form = JSON.stringify(optionsBody);
} }
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.form }); logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Channels', msg: 'Update Channel Policy Options', data: options.form });
request.post(options).then((body) => { request.post(options).then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Channel Policy Updated', data: body }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Channels', msg: 'Channel Policy Updated', data: body });
if (body.failed_updates && body.failed_updates.length && body.failed_updates[0].update_error) {
const err = common.handleError({ error: body.failed_updates[0].update_error }, 'Channels', 'Update Channel Policy Error', req.session.selectedNode);
return res.status(500).json({ message: err.message, error: err.error });
}
res.status(201).json(body); res.status(201).json(body);
}).catch((errRes) => { }).catch((errRes) => {
const err = common.handleError(errRes, 'Channels', 'Update Channel Policy Error', req.session.selectedNode); const err = common.handleError(errRes, 'Channels', 'Update Channel Policy Error', req.session.selectedNode);

View File

@ -56,7 +56,7 @@ export class CLNLiquidityAdsListComponent implements OnInit, OnDestroy {
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()]; private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private dataService: DataService, private commonService: CommonService, private rtlEffects: RTLEffects) { constructor(private logger: LoggerService, private store: Store<RTLState>, private dataService: DataService, private commonService: CommonService, private rtlEffects: RTLEffects) {
this.askTooltipMsg = 'Specify the liquidity requirements for your node: \n 1. Channel Amount - Amount in Sats you need for the channel opened to your node \n 2. Channel opening fee rate - Rate in Sats/vByte that you are willing to pay to open the channel to you'; this.askTooltipMsg = 'Specify the liquidity requirements for your node: \n 1. Channel Amount - Amount in Sats you need on the channel opened to your node \n 2. Channel opening fee rate - Rate in Sats/vByte that you are willing to pay to open the channel to you';
this.nodesTooltipMsg = 'These nodes are advertising their liquidity offering on the network.\nYou should pay attention to the following aspects to evaluate each node offer: \n- The total bitcoin deployed on the node, the more the better\n'; this.nodesTooltipMsg = 'These nodes are advertising their liquidity offering on the network.\nYou should pay attention to the following aspects to evaluate each node offer: \n- The total bitcoin deployed on the node, the more the better\n';
this.nodesTooltipMsg = this.nodesTooltipMsg + '- The number of channels open on the node, the more the better\n- The channel open fee which the node will charge from you\n- The routing fee which the node will charge on the payments, the lesser the better\n- The reliability of the node, ideally uptime. Refer to the information being provided by the node explorers'; this.nodesTooltipMsg = this.nodesTooltipMsg + '- The number of channels open on the node, the more the better\n- The channel open fee which the node will charge from you\n- The routing fee which the node will charge on the payments, the lesser the better\n- The reliability of the node, ideally uptime. Refer to the information being provided by the node explorers';
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();

View File

@ -25,7 +25,7 @@
<mat-hint>Remaining Bal: {{totalBalance - ((localAmount) ? localAmount : 0) | number}}</mat-hint> <mat-hint>Remaining Bal: {{totalBalance - ((localAmount) ? localAmount : 0) | number}}</mat-hint>
<span matSuffix> Sats </span> <span matSuffix> Sats </span>
<mat-error *ngIf="lamount.errors?.required">Local amount is required.</mat-error> <mat-error *ngIf="lamount.errors?.required">Local amount is required.</mat-error>
<mat-error *ngIf="lamount.errors?.min">Local amount must be greater than or equal to 20000. This estimate covers force close fee for the provider.</mat-error> <mat-error *ngIf="lamount.errors?.min">Local amount must be greater than or equal to 20,000 Sats. It's required to cover the channel force close fee, if needed.</mat-error>
<mat-error *ngIf="lamount.errors?.max">Local amount must be less than or equal to {{totalBalance}}.</mat-error> <mat-error *ngIf="lamount.errors?.max">Local amount must be less than or equal to {{totalBalance}}.</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>

View File

@ -159,7 +159,7 @@ export class CLNLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
flgShowInput: true, flgShowInput: true,
titleMessage: titleMsg, titleMessage: titleMsg,
getInputs: [ getInputs: [
{ placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: '', width: 30 } { placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER, inputValue: '', width: 30 }
] ]
} }
} }

View File

@ -206,7 +206,7 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
flgShowInput: true, flgShowInput: true,
titleMessage: titleMsg, titleMessage: titleMsg,
getInputs: [ getInputs: [
{ placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: '', width: 30 } { placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER, inputValue: '', width: 30 }
] ]
} }
} }

View File

@ -181,9 +181,9 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
titleMessage: 'Update fee policy for all channels', titleMessage: 'Update fee policy for all channels',
flgShowInput: true, flgShowInput: true,
getInputs: [ getInputs: [
{ placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1000, width: 32 }, { placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER, inputValue: 1000, width: 32 },
{ placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1, min: 1, width: 32, hintFunction: this.percentHintFunction }, { placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER, inputValue: 1, min: 1, width: 32, hintFunction: this.percentHintFunction },
{ placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 40, width: 32 } { placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER, inputValue: 40, width: 32 }
] ]
} }
} }
@ -225,11 +225,11 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
flgShowInput: true, flgShowInput: true,
hasAdvanced: true, hasAdvanced: true,
getInputs: [ getInputs: [
{ placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat, width: 32 }, { placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER, inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat, width: 32 },
{ placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1, width: 32, hintFunction: this.percentHintFunction }, { placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER, inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1, width: 32, hintFunction: this.percentHintFunction },
{ placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: this.myChanPolicy.time_lock_delta, width: 32 }, { placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER, inputValue: this.myChanPolicy.time_lock_delta, width: 32 },
{ placeholder: 'Minimum HTLC (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: (this.myChanPolicy.min_htlc === '') ? 0 : this.myChanPolicy.min_htlc, width: 32, advancedField: true }, { placeholder: 'Minimum HTLC (mSat)', inputType: DataTypeEnum.NUMBER, inputValue: (this.myChanPolicy.min_htlc === '') ? 0 : this.myChanPolicy.min_htlc, width: 49, advancedField: true },
{ placeholder: 'Maximum HTLC (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: (this.myChanPolicy.max_htlc_msat === '') ? 0 : this.myChanPolicy.max_htlc_msat, width: 32, advancedField: true } { placeholder: 'Maximum HTLC (mSat)', inputType: DataTypeEnum.NUMBER, inputValue: (this.myChanPolicy.max_htlc_msat === '') ? 0 : this.myChanPolicy.max_htlc_msat, width: 49, advancedField: true }
] ]
} }
} }
@ -238,21 +238,19 @@ export class ChannelOpenTableComponent implements OnInit, AfterViewInit, OnDestr
}); });
this.rtlEffects.closeConfirm. this.rtlEffects.closeConfirm.
pipe(takeUntil(this.unSubs[6])). pipe(takeUntil(this.unSubs[6])).
subscribe((confirmRes) => { subscribe((confirmRes: boolean | any[]) => {
if (confirmRes) { if (confirmRes) {
const base_fee = confirmRes[0].inputValue; const updateChanPayload = {
const fee_rate = confirmRes[1].inputValue; baseFeeMsat: confirmRes[0].inputValue,
const time_lock_delta = confirmRes[2].inputValue; feeRate: confirmRes[1].inputValue,
const min_htlc = confirmRes[3].inputValue; timeLockDelta: confirmRes[2].inputValue,
const max_htlc_msat = confirmRes[4].inputValue; chanPoint: channelToUpdate.channel_point
this.store.dispatch(updateChannel({ payload: { };
baseFeeMsat: base_fee, if ((<any[]>confirmRes).length > 3 && confirmRes[3] && confirmRes[4]) {
feeRate: fee_rate, updateChanPayload['minHtlcMsat'] = confirmRes[3].inputValue;
timeLockDelta: time_lock_delta, updateChanPayload['maxHtlcMsat'] = confirmRes[4].inputValue;
minHtlcMsat: min_htlc, }
maxHtlcMsat: max_htlc_msat, this.store.dispatch(updateChannel({ payload: updateChanPayload }));
chanPoint: channelToUpdate.channel_point
} }));
} }
}); });
} }

View File

@ -302,9 +302,9 @@ export class LNDEffects implements OnDestroy {
mergeMap((action: { type: string, payload: any }) => { mergeMap((action: { type: string, payload: any }) => {
this.store.dispatch(openSpinner({ payload: UI_MESSAGES.UPDATE_CHAN_POLICY })); this.store.dispatch(openSpinner({ payload: UI_MESSAGES.UPDATE_CHAN_POLICY }));
return this.httpClient.post(this.CHILD_API_URL + environment.CHANNELS_API + '/chanPolicy', return this.httpClient.post(this.CHILD_API_URL + environment.CHANNELS_API + '/chanPolicy',
{ baseFeeMsat: action.payload.baseFeeMsat, { baseFeeMsat: action.payload.baseFeeMsat,
feeRate: action.payload.feeRate, feeRate: action.payload.feeRate,
timeLockDelta: action.payload.timeLockDelta, timeLockDelta: action.payload.timeLockDelta,
max_htlc_msat: action.payload.maxHtlcMsat, max_htlc_msat: action.payload.maxHtlcMsat,
min_htlc_msat: action.payload.minHtlcMsat, min_htlc_msat: action.payload.minHtlcMsat,
chanPoint: action.payload.chanPoint } chanPoint: action.payload.chanPoint }

View File

@ -169,7 +169,7 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
yesBtnText: 'Send Payment', yesBtnText: 'Send Payment',
flgShowInput: true, flgShowInput: true,
getInputs: [ getInputs: [
{ placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: '', width: 30 } { placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER, inputValue: '', width: 30 }
] ]
} }
} }

View File

@ -43,7 +43,7 @@
</div> </div>
<div *ngIf="flgShowInput" fxLayout="column" class="bordered-box my-2 p-2"> <div *ngIf="flgShowInput" fxLayout="column" class="bordered-box my-2 p-2">
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p> <p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p>
<div [fxLayout]="showAdvanced ? 'column' : 'row'" [fxLayoutAlign]="showAdvanced ? 'start' : 'space-between center'"> <div fxLayout="row wrap" fxLayoutAlign="space-between center">
<ng-container *ngFor="let getInput of getInputs; index as i"> <ng-container *ngFor="let getInput of getInputs; index as i">
<mat-form-field *ngIf="!getInput.advancedField || showAdvanced" [fxFlex]="getInput.width"> <mat-form-field *ngIf="!getInput.advancedField || showAdvanced" [fxFlex]="getInput.width">
<input matInput [autoFocus]="i === 0" [placeholder]="getInput.placeholder" name="input{{i}}" [min]="getInput.min" [step]="getInput.step" [type]="getInput.inputType | lowercase" [(ngModel)]="getInput.inputValue" [tabindex]="i+1" required> <input matInput [autoFocus]="i === 0" [placeholder]="getInput.placeholder" name="input{{i}}" [min]="getInput.min" [step]="getInput.step" [type]="getInput.inputType | lowercase" [(ngModel)]="getInput.inputValue" [tabindex]="i+1" required>
@ -54,11 +54,11 @@
</div> </div>
</div> </div>
<div fxLayout="row" fxLayoutAlign="end center"> <div fxLayout="row" fxLayoutAlign="end center">
<button *ngIf="hasAdvanced" mat-button color="primary" type="button" class="mr-1" (click)="onShowAdvanced()" tabindex="1" > <button mat-button color="primary" type="reset" class="mr-1" (click)="onClose(false)" tabindex="1">{{noBtnText}}</button>
<button *ngIf="hasAdvanced" mat-button color="primary" type="button" class="mr-1" (click)="onShowAdvanced()" tabindex="2">
<p *ngIf="!showAdvanced; else hideAdvancedText">Show Advanced</p> <p *ngIf="!showAdvanced; else hideAdvancedText">Show Advanced</p>
<ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template> <ng-template #hideAdvancedText><p>Hide Advanced</p></ng-template>
</button> </button>
<button mat-button color="primary" type="reset" class="mr-1" (click)="onClose(false)" tabindex="2">{{noBtnText}}</button>
<button autoFocus *ngIf="flgShowInput" mat-button color="primary" type="submit" tabindex="3" (click)="onClose(getInputs)" default>{{yesBtnText}}</button> <button autoFocus *ngIf="flgShowInput" mat-button color="primary" type="submit" tabindex="3" (click)="onClose(getInputs)" default>{{yesBtnText}}</button>
<button autoFocus *ngIf="!flgShowInput" mat-button color="primary" type="submit" tabindex="4" (click)="onClose(true)" default>{{yesBtnText}}</button> <button autoFocus *ngIf="!flgShowInput" mat-button color="primary" type="submit" tabindex="4" (click)="onClose(true)" default>{{yesBtnText}}</button>
</div> </div>

View File

@ -29,7 +29,7 @@ export class ConfirmationMessageComponent implements OnInit {
public alertTypeEnum = AlertTypeEnum; public alertTypeEnum = AlertTypeEnum;
public dataTypeEnum = DataTypeEnum; public dataTypeEnum = DataTypeEnum;
public getInputs: Array<InputData> = [{ placeholder: '', inputType: 'text', inputValue: '', hintText: '', hintFunction: null, advancedField: false }]; public getInputs: Array<InputData> = [{ placeholder: '', inputType: 'text', inputValue: '', hintText: '', hintFunction: null, advancedField: false }];
private showAdvanced = false; private showAdvanced = false;
constructor( constructor(
@ -52,15 +52,23 @@ export class ConfirmationMessageComponent implements OnInit {
} }
} }
} }
onShowAdvanced() { onShowAdvanced() {
this.showAdvanced = !this.showAdvanced; this.showAdvanced = !this.showAdvanced;
} }
onClose(dialogRes: any): boolean | void { onClose(dialogRes: any): boolean | any[] | void {
if (dialogRes && this.getInputs && this.getInputs.some((input) => typeof input.inputValue === 'undefined')) { if (dialogRes && this.getInputs && this.getInputs.some((input) => typeof input.inputValue === 'undefined')) {
return true; return true;
} }
if (!this.showAdvanced && dialogRes.length) {
dialogRes = dialogRes.reduce((accumulator, current) => {
if (!current.advancedField) {
accumulator.push(current);
}
return accumulator;
}, []);
}
this.store.dispatch(closeConfirmation({ payload: dialogRes })); this.store.dispatch(closeConfirmation({ payload: dialogRes }));
} }

View File

@ -26,7 +26,7 @@ export const closeAlert = createAction(RTLActions.CLOSE_ALERT, props<{ payload:
export const openConfirmation = createAction(RTLActions.OPEN_CONFIRMATION, props<{ payload: DialogConfig }>()); export const openConfirmation = createAction(RTLActions.OPEN_CONFIRMATION, props<{ payload: DialogConfig }>());
export const closeConfirmation = createAction(RTLActions.CLOSE_CONFIRMATION, props<{ payload: boolean }>()); export const closeConfirmation = createAction(RTLActions.CLOSE_CONFIRMATION, props<{ payload: boolean | any[] }>());
export const showPubkey = createAction(RTLActions.SHOW_PUBKEY); export const showPubkey = createAction(RTLActions.SHOW_PUBKEY);

View File

@ -164,7 +164,7 @@ export class RTLEffects implements OnDestroy {
() => this.actions.pipe( () => this.actions.pipe(
ofType(RTLActions.CLOSE_CONFIRMATION), ofType(RTLActions.CLOSE_CONFIRMATION),
take(1), take(1),
map((action: { type: string, payload: boolean }) => { map((action: { type: string, payload: boolean | any[] }) => {
if (this.dialogRef) { if (this.dialogRef) {
this.dialogRef.close(); this.dialogRef.close();
} }