Invoices, payments and invoice notification

clnrest-migration
ShahanaFarooqui 7 months ago
parent e1cc56b8d5
commit d31f1b3c70

@ -99,10 +99,26 @@ export const postPayment = (req, res, next) => {
if (options.error) { if (options.error) {
return res.status(options.statusCode).json({ message: options.message, error: options.error }); return res.status(options.statusCode).json({ message: options.message, error: options.error });
} }
const options_body = JSON.parse(JSON.stringify(req.body));
if (req.body.paymentType === 'KEYSEND') { if (req.body.paymentType === 'KEYSEND') {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/keysend'; options.url = req.session.selectedNode.ln_server_url + '/v1/keysend';
options.body = req.body; delete options_body.uiMessage;
delete options_body.fromDialog;
delete options_body.paymentType;
delete options_body.title;
delete options_body.issuer;
delete options_body.bolt11;
delete options_body.description;
delete options_body.bolt12;
delete options_body.zeroAmtOffer;
delete options_body.pubkey;
delete options_body.riskfactor;
delete options_body.localinvreqid;
delete options_body.exclude;
delete options_body.maxfee;
delete options_body.saveToDB;
options.body = options_body;
} }
else { else {
if (req.body.paymentType === 'OFFER') { if (req.body.paymentType === 'OFFER') {
@ -111,7 +127,18 @@ export const postPayment = (req, res, next) => {
else { else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' });
} }
options.body = req.body; delete options_body.uiMessage;
delete options_body.fromDialog;
delete options_body.paymentType;
delete options_body.destination;
delete options_body.extratlvs;
delete options_body.title;
delete options_body.issuer;
delete options_body.bolt12;
delete options_body.zeroAmtOffer;
delete options_body.pubkey;
delete options_body.saveToDB;
options.body = options_body;
options.url = req.session.selectedNode.ln_server_url + '/v1/pay'; options.url = req.session.selectedNode.ln_server_url + '/v1/pay';
} }
request.post(options).then((body) => { request.post(options).then((body) => {

@ -51,7 +51,7 @@ export class CLWebSocketClient {
clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path); clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path);
} }
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, { clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, {
extraHeaders: { rune: '9ISqFS53IFIfBS0yhwgM_XaNHFAUoFU_Bzfyhe-s8u49MA==' }, extraHeaders: { rune: clWsClt.selectedNode.rune_value },
transports: ['websocket'], transports: ['websocket'],
secure: true, secure: true,
rejectUnauthorized: false rejectUnauthorized: false

@ -163,7 +163,7 @@ export class RTLWebSocketServer {
try { try {
this.webSocketServer.clients.forEach((client) => { this.webSocketServer.clients.forEach((client) => {
if (+client.clientNodeIndex === +selectedNode.index) { if (+client.clientNodeIndex === +selectedNode.index) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId }); this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage });
client.send(newMessage); client.send(newMessage);
} }
}); });

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

@ -1 +1 @@
(()=>{"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],s=!0,l=0;l<t.length;l++)(!1&o||a>=o)&&Object.keys(r.O).every(b=>r.O[b](t[l]))?t.splice(l--,1):(s=!1,o<a&&(a=o));if(s){e.splice(n--,1);var d=i();void 0!==d&&(f=d)}}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+"."+{125:"649839951b94fd32",456:"16212571f65d0b5f",570:"a719a189ca60c55b",758:"2801e2da6f8bba94"}[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,s;if(void 0!==o)for(var l=document.getElementsByTagName("script"),d=0;d<l.length;d++){var u=l[d];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==f+o){a=u;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",f+o),a.src=r.tu(t)),e[t]=[i];var c=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL: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((u,c)=>n=e[i]=[u,c]);o.push(n[2]=a);var s=r.p+r.u(i),l=new Error;r.l(s,u=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var c=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;l.message="Loading chunk "+i+" failed.\n("+c+": "+p+")",l.name="ChunkLoadError",l.type=c,l.request=p,n[1](l)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var f=(i,o)=>{var l,d,[n,a,s]=o,u=0;if(n.some(p=>0!==e[p])){for(l in a)r.o(a,l)&&(r.m[l]=a[l]);if(s)var c=s(r)}for(i&&i(o);u<n.length;u++)r.o(e,d=n[u])&&e[d]&&e[d][0](),e[d]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(f.bind(null,0)),t.push=f.bind(null,t.push.bind(t))})()})(); (()=>{"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],s=!0,l=0;l<t.length;l++)(!1&o||a>=o)&&Object.keys(r.O).every(b=>r.O[b](t[l]))?t.splice(l--,1):(s=!1,o<a&&(a=o));if(s){e.splice(n--,1);var d=i();void 0!==d&&(f=d)}}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+"."+{125:"e77d478f0dec10a6",456:"16212571f65d0b5f",570:"a719a189ca60c55b",758:"2801e2da6f8bba94"}[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,s;if(void 0!==o)for(var l=document.getElementsByTagName("script"),d=0;d<l.length;d++){var u=l[d];if(u.getAttribute("src")==t||u.getAttribute("data-webpack")==f+o){a=u;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",f+o),a.src=r.tu(t)),e[t]=[i];var c=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(c.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=c.bind(null,a.onerror),a.onload=c.bind(null,a.onload),s&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL: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((u,c)=>n=e[i]=[u,c]);o.push(n[2]=a);var s=r.p+r.u(i),l=new Error;r.l(s,u=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var c=u&&("load"===u.type?"missing":u.type),p=u&&u.target&&u.target.src;l.message="Loading chunk "+i+" failed.\n("+c+": "+p+")",l.name="ChunkLoadError",l.type=c,l.request=p,n[1](l)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var f=(i,o)=>{var l,d,[n,a,s]=o,u=0;if(n.some(p=>0!==e[p])){for(l in a)r.o(a,l)&&(r.m[l]=a[l]);if(s)var c=s(r)}for(i&&i(o);u<n.length;u++)r.o(e,d=n[u])&&e[d]&&e[d][0](),e[d]=0;return r.O(c)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(f.bind(null,0)),t.push=f.bind(null,t.push.bind(t))})()})();

@ -91,17 +91,44 @@ export const listPayments = (req, res, next) => {
export const postPayment = (req, res, next) => { export const postPayment = (req, res, next) => {
options = common.getOptions(req); options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); } if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
const options_body = JSON.parse(JSON.stringify(req.body));
if (req.body.paymentType === 'KEYSEND') { if (req.body.paymentType === 'KEYSEND') {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Keysend Payment..' });
options.url = req.session.selectedNode.ln_server_url + '/v1/keysend'; options.url = req.session.selectedNode.ln_server_url + '/v1/keysend';
options.body = req.body; delete options_body.uiMessage;
delete options_body.fromDialog;
delete options_body.paymentType;
delete options_body.title;
delete options_body.issuer;
delete options_body.bolt11;
delete options_body.description;
delete options_body.bolt12;
delete options_body.zeroAmtOffer;
delete options_body.pubkey;
delete options_body.riskfactor;
delete options_body.localinvreqid;
delete options_body.exclude;
delete options_body.maxfee;
delete options_body.saveToDB;
options.body = options_body;
} else { } else {
if (req.body.paymentType === 'OFFER') { if (req.body.paymentType === 'OFFER') {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Offer Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Offer Payment..' });
} else { } else {
logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' }); logger.log({ selectedNode: req.session.selectedNode, level: 'INFO', fileName: 'Payments', msg: 'Sending Invoice Payment..' });
} }
options.body = req.body; delete options_body.uiMessage;
delete options_body.fromDialog;
delete options_body.paymentType;
delete options_body.destination;
delete options_body.extratlvs;
delete options_body.title;
delete options_body.issuer;
delete options_body.bolt12;
delete options_body.zeroAmtOffer;
delete options_body.pubkey;
delete options_body.saveToDB;
options.body = options_body;
options.url = req.session.selectedNode.ln_server_url + '/v1/pay'; options.url = req.session.selectedNode.ln_server_url + '/v1/pay';
} }
request.post(options).then((body) => { request.post(options).then((body) => {

@ -61,7 +61,7 @@ export class CLWebSocketClient {
clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path); clWsClt.selectedNode.rune_value = this.common.getRuneValue(clWsClt.selectedNode.rune_path);
} }
clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, { clWsClt.webSocketClient = socketIOClient(clWsClt.selectedNode.ln_server_url, {
extraHeaders: { rune: '9ISqFS53IFIfBS0yhwgM_XaNHFAUoFU_Bzfyhe-s8u49MA==' }, extraHeaders: { rune: clWsClt.selectedNode.rune_value },
transports: ['websocket'], transports: ['websocket'],
secure: true, secure: true,
rejectUnauthorized: false rejectUnauthorized: false

@ -167,7 +167,7 @@ export class RTLWebSocketServer {
try { try {
this.webSocketServer.clients.forEach((client) => { this.webSocketServer.clients.forEach((client) => {
if (+client.clientNodeIndex === +selectedNode.index) { if (+client.clientNodeIndex === +selectedNode.index) {
this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId }); this.logger.log({ selectedNode: !selectedNode ? this.common.initSelectedNode : selectedNode, level: 'DEBUG', fileName: 'WebSocketServer', msg: 'Broadcasting message to client...: ' + client.clientId + ', Message: ' + newMessage });
client.send(newMessage); client.send(newMessage);
} }
}); });

@ -3,7 +3,7 @@ import { createAction, props } from '@ngrx/store';
import { CLNActions } from '../../shared/services/consts-enums-functions'; import { CLNActions } from '../../shared/services/consts-enums-functions';
import { ApiCallStatusPayload } from '../../shared/models/apiCallsPayload'; import { ApiCallStatusPayload } from '../../shared/models/apiCallsPayload';
import { SelNodeChild } from '../../shared/models/RTLconfig'; import { SelNodeChild } from '../../shared/models/RTLconfig';
import { GetInfo, Fees, Peer, Payment, QueryRoutes, Channel, FeeRates, Invoice, ListInvoices, OnChain, UTXO, SaveChannel, import { GetInfo, Fees, Peer, Payment, QueryRoutes, Channel, FeeRates, Invoice, InvoicePaymentNotification, ListInvoices, OnChain, UTXO, SaveChannel,
GetNewAddress, DetachPeer, UpdateChannel, CloseChannel, SendPayment, GetQueryRoutes, ChannelLookup, OfferInvoice, Offer, OfferBookmark, ListForwards, FetchListForwards } from '../../shared/models/clnModels'; GetNewAddress, DetachPeer, UpdateChannel, CloseChannel, SendPayment, GetQueryRoutes, ChannelLookup, OfferInvoice, Offer, OfferBookmark, ListForwards, FetchListForwards } from '../../shared/models/clnModels';
import { PageSettings } from '../../shared/models/pageSettings'; import { PageSettings } from '../../shared/models/pageSettings';
@ -85,11 +85,11 @@ export const fetchInvoices = createAction(CLNActions.FETCH_INVOICES_CLN);
export const setInvoices = createAction(CLNActions.SET_INVOICES_CLN, props<{ payload: ListInvoices }>()); export const setInvoices = createAction(CLNActions.SET_INVOICES_CLN, props<{ payload: ListInvoices }>());
export const saveNewInvoice = createAction(CLNActions.SAVE_NEW_INVOICE_CLN, props<{ payload: { amount_msat: number, label: string, description: string, expiry: number, exposeprivatechannels: boolean } }>()); export const saveNewInvoice = createAction(CLNActions.SAVE_NEW_INVOICE_CLN, props<{ payload: { amount_msat: number | 'any', label: string, description: string, expiry: number, exposeprivatechannels: boolean } }>());
export const addInvoice = createAction(CLNActions.ADD_INVOICE_CLN, props<{ payload: Invoice }>()); export const addInvoice = createAction(CLNActions.ADD_INVOICE_CLN, props<{ payload: Invoice }>());
export const updateInvoice = createAction(CLNActions.UPDATE_INVOICE_CLN, props<{ payload: Invoice }>()); export const updateInvoice = createAction(CLNActions.UPDATE_INVOICE_CLN, props<{ payload: InvoicePaymentNotification }>());
export const deleteExpiredInvoice = createAction(CLNActions.DELETE_EXPIRED_INVOICE_CLN, props<{ payload?: number | null }>()); export const deleteExpiredInvoice = createAction(CLNActions.DELETE_EXPIRED_INVOICE_CLN, props<{ payload?: number | null }>());

@ -59,8 +59,8 @@ export class CLNEffects implements OnDestroy {
subscribe((newMessage) => { subscribe((newMessage) => {
this.logger.info('Received new message from the service: ' + JSON.stringify(newMessage)); this.logger.info('Received new message from the service: ' + JSON.stringify(newMessage));
if (newMessage && newMessage.data) { if (newMessage && newMessage.data) {
if (newMessage.data[CLNWSEventTypeEnum.INVOICE_PAYMENT] && newMessage.data.label) { if (newMessage.data[CLNWSEventTypeEnum.INVOICE_PAYMENT] && newMessage.data[CLNWSEventTypeEnum.INVOICE_PAYMENT].label) {
this.store.dispatch(updateInvoice({ payload: newMessage.data })); this.store.dispatch(updateInvoice({ payload: newMessage.data[CLNWSEventTypeEnum.INVOICE_PAYMENT] }));
} }
} }
}); });

@ -146,7 +146,14 @@ export const CLNReducer = createReducer(initCLNState,
})), })),
on(updateInvoice, (state, { payload }) => { on(updateInvoice, (state, { payload }) => {
const modifiedInvoices = state.invoices; const modifiedInvoices = state.invoices;
modifiedInvoices.invoices = modifiedInvoices.invoices?.map((invoice) => ((invoice.label === payload.label) ? payload : invoice)); modifiedInvoices.invoices = modifiedInvoices.invoices?.map((invoice) => {
if (invoice.label === payload.label) {
invoice.amount_received_msat = +payload.msat.substring(0, payload.msat.length - 4);
invoice.payment_preimage = payload.preimage;
invoice.status = 'paid';
}
return invoice;
});
return { return {
...state, ...state,
invoices: modifiedInvoices invoices: modifiedInvoices

@ -77,7 +77,7 @@ export class CLNCreateInvoiceComponent implements OnInit, OnDestroy {
} }
this.store.dispatch(saveNewInvoice({ this.store.dispatch(saveNewInvoice({
payload: { payload: {
label: ('ulbl' + Math.random().toString(36).slice(2) + Date.now()), amount_msat: this.invoiceValue * 1000, description: this.description, expiry: expiryInSecs, exposeprivatechannels: this.private label: ('ulbl' + Math.random().toString(36).slice(2) + Date.now()), amount_msat: (this.invoiceValue ? this.invoiceValue * 1000 : 'any'), description: this.description, expiry: expiryInSecs, exposeprivatechannels: this.private
} }
})); }));
} }

@ -33,7 +33,7 @@
<div fxFlex="50"> <div fxFlex="50">
<h4 fxLayoutAlign="start" class="font-bold-500">{{screenSize === screenSizeEnum.XS ? 'Amount' : 'Amount Requested'}}</h4> <h4 fxLayoutAlign="start" class="font-bold-500">{{screenSize === screenSizeEnum.XS ? 'Amount' : 'Amount Requested'}}</h4>
<span class="foreground-secondary-text"> <span class="foreground-secondary-text">
{{(invoice?.amount_msat/1000 || 0) | number}} Sats<ng-container *ngIf="!invoice?.amount_msat || invoice?.amount_msat === '0'"> (zero amount) </ng-container> {{(invoice?.amount_msat/1000 || 0) | number}} Sats<ng-container *ngIf="!invoice?.amount_msat || invoice?.amount_msat === '0' || invoice?.amount_msat === 'any'"> (zero amount) </ng-container>
</span> </span>
</div> </div>
<div fxFlex="50"> <div fxFlex="50">

@ -28,6 +28,7 @@ export class CLNInvoiceInformationComponent implements OnInit, OnDestroy {
public showAdvanced = false; public showAdvanced = false;
public newlyAdded = false; public newlyAdded = false;
public invoice: Invoice; public invoice: Invoice;
public invoiceStatus = '';
public qrWidth = 240; public qrWidth = 240;
public screenSize = ''; public screenSize = '';
public screenSizeEnum = ScreenSizeEnum; public screenSizeEnum = ScreenSizeEnum;
@ -38,6 +39,7 @@ export class CLNInvoiceInformationComponent implements OnInit, OnDestroy {
ngOnInit() { ngOnInit() {
this.invoice = this.data.invoice; this.invoice = this.data.invoice;
this.invoiceStatus = this.invoice.status;
this.newlyAdded = !!this.data.newlyAdded; this.newlyAdded = !!this.data.newlyAdded;
this.screenSize = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if (this.screenSize === ScreenSizeEnum.XS) { if (this.screenSize === ScreenSizeEnum.XS) {
@ -45,14 +47,16 @@ export class CLNInvoiceInformationComponent implements OnInit, OnDestroy {
} }
this.store.select(listInvoices).pipe(takeUntil(this.unSubs[1])). this.store.select(listInvoices).pipe(takeUntil(this.unSubs[1])).
subscribe((invoicesSelector: { listInvoices: ListInvoices, apiCallStatus: ApiCallStatusPayload }) => { subscribe((invoicesSelector: { listInvoices: ListInvoices, apiCallStatus: ApiCallStatusPayload }) => {
const invoiceStatus = this.invoice.status;
const invoices = invoicesSelector.listInvoices.invoices || []; const invoices = invoicesSelector.listInvoices.invoices || [];
const foundInvoice = invoices?.find((invoice) => invoice.payment_hash === this.invoice.payment_hash) || null; const foundInvoice = invoices?.find((invoice) => invoice.payment_hash === this.invoice.payment_hash) || null;
if (foundInvoice) { this.invoice = foundInvoice; } if (foundInvoice) { this.invoice = foundInvoice; }
if (invoiceStatus !== this.invoice.status && this.invoice.status === 'paid') { if (this.invoiceStatus !== this.invoice.status && this.invoice.status === 'paid') {
this.flgInvoicePaid = true; this.flgInvoicePaid = true;
setTimeout(() => { this.flgInvoicePaid = false; }, 4000); setTimeout(() => { this.flgInvoicePaid = false; }, 4000);
} }
this.logger.info(this.invoice);
this.logger.info(this.invoiceStatus);
this.logger.info(foundInvoice);
this.logger.info(invoicesSelector); this.logger.info(invoicesSelector);
}); });
} }

@ -152,7 +152,7 @@ export class CLNLightningInvoicesTableComponent implements OnInit, AfterViewInit
this.newlyAddedInvoiceValue = this.invoiceValue; this.newlyAddedInvoiceValue = this.invoiceValue;
this.store.dispatch(saveNewInvoice({ this.store.dispatch(saveNewInvoice({
payload: { payload: {
label: this.newlyAddedInvoiceMemo, amount_msat: this.invoiceValue * 1000, description: this.description, expiry: expiryInSecs, exposeprivatechannels: this.private label: this.newlyAddedInvoiceMemo, amount_msat: (this.invoiceValue ? this.invoiceValue * 1000 : 'any'), description: this.description, expiry: expiryInSecs, exposeprivatechannels: this.private
} }
})); }));
this.resetData(); this.resetData();

@ -6,7 +6,7 @@
<mat-hint *ngIf="paymentRequest && paymentDecodedHint !== ''">{{paymentDecodedHint}}</mat-hint> <mat-hint *ngIf="paymentRequest && paymentDecodedHint !== ''">{{paymentDecodedHint}}</mat-hint>
<mat-error *ngIf="!paymentRequest">Payment request is required.</mat-error> <mat-error *ngIf="!paymentRequest">Payment request is required.</mat-error>
</mat-form-field> </mat-form-field>
<div fxLayout="row" class="mt-1"> <div fxLayout="row" class="mt-3">
<button class="mr-1" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button> <button class="mr-1" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
<button mat-flat-button color="primary" tabindex="3" (click)="onSendPayment()">Send Payment</button> <button mat-flat-button color="primary" tabindex="3" (click)="onSendPayment()">Send Payment</button>
</div> </div>

@ -107,6 +107,12 @@ export interface OfferBookmark {
description?: string; description?: string;
} }
export interface InvoicePaymentNotification {
msat?: string;
preimage?: string;
label?: string;
}
export interface ListInvoices { export interface ListInvoices {
invoices?: Invoice[]; invoices?: Invoice[];
last_index_offset?: string; last_index_offset?: string;

Loading…
Cancel
Save