diff --git a/src/app/lnd/store/lnd.effects.ts b/src/app/lnd/store/lnd.effects.ts index 7eee6bbc..c6989fbb 100644 --- a/src/app/lnd/store/lnd.effects.ts +++ b/src/app/lnd/store/lnd.effects.ts @@ -1203,6 +1203,7 @@ export class LNDEffects implements OnDestroy { this.invoicesPageSize = (settings.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices') || LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices')).recordsPerPage; this.paymentsPageSize = (settings.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments') || LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments')).recordsPerPage; this.store.dispatch(fetchInvoices({ payload: { num_max_invoices: this.invoicesPageSize, reversed: true } })); + // this.store.dispatch(fetchPayments({ payload: { max_payments: 100000, reversed: true } })); return { type: LNDActions.SET_PAGE_SETTINGS_LND, payload: settings || [] @@ -1228,6 +1229,16 @@ export class LNDEffects implements OnDestroy { this.store.dispatch(updateLNDAPICallStatus({ payload: { action: 'SavePageSettings', status: APICallStatusEnum.COMPLETED } })); this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.UPDATE_PAGE_SETTINGS })); this.store.dispatch(openSnackBar({ payload: 'Page Layout Updated Successfully!' })); + const invPgSz = (postRes.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices') || LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices')).recordsPerPage; + const payPgSz = (postRes.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments') || LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments')).recordsPerPage; + if (invPgSz !== this.invoicesPageSize) { + this.invoicesPageSize = invPgSz; + this.store.dispatch(fetchInvoices({ payload: { num_max_invoices: this.invoicesPageSize, reversed: true } })); + } + if (payPgSz !== this.paymentsPageSize) { + this.paymentsPageSize = payPgSz; + // this.store.dispatch(fetchPayments({ payload: { max_payments: 100000, reversed: true } })); + } return { type: LNDActions.SET_PAGE_SETTINGS_LND, payload: postRes || [] diff --git a/src/app/lnd/transactions/payments/lightning-payments.component.html b/src/app/lnd/transactions/payments/lightning-payments.component.html index 912e7210..ae9c7227 100644 --- a/src/app/lnd/transactions/payments/lightning-payments.component.html +++ b/src/app/lnd/transactions/payments/lightning-payments.component.html @@ -43,11 +43,53 @@ Payment Hash - + {{payment?.payment_hash}} + + Payment Request + + + {{payment?.payment_request}} + + + + + Payment Preimage + + + {{payment?.payment_preimage}} + + + + + Description + + + {{payment?.description}} + + + + + Description Hash + + + {{payment?.description_hash}} + + + + + Failure Reason + + {{payment?.failure_reason | camelcaseWithReplace:'failure_reason':'_'}} + + + + Payment Index + {{payment?.payment_index | number}} + Fee (Sats) {{payment?.fee | number}} @@ -81,25 +123,35 @@ - + - Total Attempts: {{payment?.htlcs?.length}} - {{(htlc.attempt_time * 1000) | date:'dd/MMM/y HH:mm'}} - + - + + Total Attempts: {{payment?.htlcs?.length}} + + + + {{(htlc.attempt_time_ns / 1000000) | date:'dd/MMM/y HH:mm'}} + + + + + + + {{payment?.payment_hash}} @@ -109,7 +161,73 @@ - + + + + {{payment?.payment_request}} + + + + + + + + + + + {{payment?.payment_preimage}} + + + + {{htlc?.preimage}} + + + + + + + + {{payment?.description}} + + + + + + + + + + + {{payment?.description_hash}} + + + + + + + + + + + {{payment?.failure_reason | camelcaseWithReplace:'failure_reason':'_'}} + + + + + + + + + + {{payment?.payment_index | number}} + + + {{htlc.attempt_id | number}} + + + + + {{payment?.fee | number:'1.0-0'}} @@ -119,7 +237,7 @@ - + {{payment?.value | number:'1.0-0'}} @@ -129,7 +247,7 @@ - + - @@ -139,7 +257,7 @@ - + diff --git a/src/app/lnd/transactions/payments/lightning-payments.component.scss b/src/app/lnd/transactions/payments/lightning-payments.component.scss index 8f54d7fd..7876676c 100644 --- a/src/app/lnd/transactions/payments/lightning-payments.component.scss +++ b/src/app/lnd/transactions/payments/lightning-payments.component.scss @@ -1,16 +1,20 @@ -.mat-column-actions { - min-height: 4.8rem; +.mat-column-status, .mat-column-group_status { + width: 1.5rem; } -.mat-column-payment_hash { - flex: 0 0 20%; - width: 20%; +.mat-column-payment_hash, .mat-column-payment_request, .mat-column-payment_preimage, .mat-column-description, .mat-column-description_hash { + flex: 0 0 10%; + width: 10%; & .ellipsis-parent { display: flex; } } -.mat-column-groupActions { +.mat-column-actions { + min-height: 4.8rem; +} + +.mat-column-group_actions { min-height: 4.8rem; & .btn-htlc-expand { @@ -29,8 +33,15 @@ min-height: 4.2rem; place-content: center flex-start; align-items: center; + &.ellipsis-parent { + display: flex; + } + & .dot { + margin-top: -0.4rem; + position: absolute; + } } -.mat-column-groupTotal { +.mat-column-group_creation_date { min-width: 17rem; } diff --git a/src/app/lnd/transactions/payments/lightning-payments.component.ts b/src/app/lnd/transactions/payments/lightning-payments.component.ts index 2f361228..3c959c32 100644 --- a/src/app/lnd/transactions/payments/lightning-payments.component.ts +++ b/src/app/lnd/transactions/payments/lightning-payments.component.ts @@ -69,15 +69,6 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest constructor(private logger: LoggerService, private commonService: CommonService, private dataService: DataService, private store: Store, private rtlEffects: RTLEffects, private lndEffects: LNDEffects, private decimalPipe: DecimalPipe, private datePipe: DatePipe) { this.screenSize = this.commonService.getScreenSize(); - // if (this.screenSize === ScreenSizeEnum.XS) { - // this.htlcColumns = ['groupTotal', 'groupFee', 'groupActions']; - // } else if (this.screenSize === ScreenSizeEnum.SM) { - // this.htlcColumns = ['groupTotal', 'groupFee', 'groupValue', 'groupHops', 'groupActions']; - // } else if (this.screenSize === ScreenSizeEnum.MD) { - // this.htlcColumns = ['groupTotal', 'groupFee', 'groupValue', 'groupHops', 'groupActions']; - // } else { - // this.htlcColumns = ['groupTotal', 'groupHash', 'groupFee', 'groupValue', 'groupHops', 'groupActions']; - // } } ngOnInit() { @@ -102,6 +93,8 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest } this.displayedColumns.unshift('status'); this.displayedColumns.push('actions'); + this.htlcColumns = []; + this.displayedColumns.map((col) => this.htlcColumns.push('group_' + col)); this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE; this.logger.info(this.displayedColumns); }); @@ -300,21 +293,21 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest this.form.resetForm(); } - getHopDetails(hops: Hop[]) { + getHopDetails(currentHop: Hop) { const self = this; - return hops?.reduce((accumulator: any[], currentHop: Hop) => { + return new Promise((resolve, reject) => { const peerFound = self.peers.find((peer) => peer.pub_key === currentHop.pub_key); if (peerFound && peerFound.alias) { - accumulator.push('
Channel: ' + peerFound.alias.padEnd(20) + '			Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '
'); + resolve('
Channel: ' + peerFound.alias.padEnd(20) + '			Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '
'); } else { self.dataService.getAliasesFromPubkeys((currentHop.pub_key || ''), false). pipe(takeUntil(self.unSubs[7])). - subscribe((res: any) => { - accumulator.push('
Channel: ' + (res.node && res.node.alias ? res.node.alias.padEnd(20) : (currentHop.pub_key?.substring(0, 17) + '...')) + '			Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '
'); + subscribe({ + next: (res: any) => resolve('
Channel: ' + (res.node && res.node.alias ? res.node.alias.padEnd(20) : (currentHop.pub_key?.substring(0, 17) + '...')) + '			Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '
'), + error: (error) => resolve('
Channel: ' + (currentHop.pub_key ? (currentHop.pub_key?.substring(0, 17) + '...') : '') + '			Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '
') }); } - return accumulator; - }, []); + }); } onHTLCClick(selHtlc: PaymentHTLC, selPayment: Payment) { @@ -335,7 +328,35 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest } showHTLCView(selHtlc: PaymentHTLC, selPayment: Payment, decodedPayment?: PayRequest) { - const reorderedHTLC = [ + if (selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length) { + Promise.all(selHtlc.route.hops.map((hop) => this.getHopDetails(hop))).then((detailsAll: any) => { + this.store.dispatch(openAlert({ + payload: { + data: { + type: AlertTypeEnum.INFORMATION, + alertTitle: 'HTLC Information', + message: this.prepareData(selHtlc, selPayment, decodedPayment, detailsAll), + scrollable: selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length > 1 + } + } + })); + }); + } else { + this.store.dispatch(openAlert({ + payload: { + data: { + type: AlertTypeEnum.INFORMATION, + alertTitle: 'HTLC Information', + message: this.prepareData(selHtlc, selPayment, decodedPayment, []), + scrollable: selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length > 1 + } + } + })); + } + } + + prepareData(selHtlc: PaymentHTLC, selPayment: Payment, decodedPayment?: PayRequest, hopsDetails?: any) { + const modifiedData = [ [{ key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }], [{ key: 'preimage', value: selHtlc.preimage, title: 'Preimage', width: 100, type: DataTypeEnum.STRING }], [{ key: 'payment_request', value: selPayment.payment_request, title: 'Payment Request', width: 100, type: DataTypeEnum.STRING }], @@ -345,21 +366,12 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest [{ key: 'total_amt', value: selHtlc.route?.total_amt, title: 'Amount (Sats)', width: 33, type: DataTypeEnum.NUMBER }, { key: 'total_fees', value: selHtlc.route?.total_fees, title: 'Fee (Sats)', width: 33, type: DataTypeEnum.NUMBER }, { key: 'total_time_lock', value: selHtlc.route?.total_time_lock, title: 'Total Time Lock', width: 34, type: DataTypeEnum.NUMBER }], - [{ key: 'hops', value: this.getHopDetails(selHtlc.route?.hops || []), title: 'Hops', width: 100, type: DataTypeEnum.ARRAY }] + [{ key: 'hops', value: hopsDetails, title: 'Hops', width: 100, type: DataTypeEnum.ARRAY }] ]; if (decodedPayment && decodedPayment.description && decodedPayment.description !== '') { - reorderedHTLC.splice(3, 0, [{ key: 'description', value: decodedPayment.description, title: 'Description', width: 100, type: DataTypeEnum.STRING }]); + modifiedData.splice(3, 0, [{ key: 'description', value: decodedPayment.description, title: 'Description', width: 100, type: DataTypeEnum.STRING }]); } - this.store.dispatch(openAlert({ - payload: { - data: { - type: AlertTypeEnum.INFORMATION, - alertTitle: 'HTLC Information', - message: reorderedHTLC, - scrollable: selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length > 1 - } - } - })); + return modifiedData; } onPaymentClick(selPayment: Payment) { diff --git a/src/app/shared/pipes/app.pipe.ts b/src/app/shared/pipes/app.pipe.ts index e5a2a520..2e9b62ae 100644 --- a/src/app/shared/pipes/app.pipe.ts +++ b/src/app/shared/pipes/app.pipe.ts @@ -27,8 +27,15 @@ export class CamelCasePipe implements PipeTransform { }) export class CamelCaseWithReplacePipe implements PipeTransform { - transform(value: string, args?: any): string { - return value?.replace(/\s+/g, '')?.replace(/-/g, ' ').replace(new RegExp(args, 'g'), ' ').replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase())); + transform(value: string, arg1?: string, arg2?: string): string { + value = value?.toLowerCase().replace(/\s+/g, '')?.replace(/-/g, ' '); + if (arg1) { + value = value.replace(new RegExp(arg1, 'g'), ' '); + } + if (arg2) { + value = value.replace(new RegExp(arg2, 'g'), ' '); + } + return value.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase())); } } diff --git a/src/app/shared/services/consts-enums-functions.ts b/src/app/shared/services/consts-enums-functions.ts index d0e47aad..1c4d3721 100644 --- a/src/app/shared/services/consts-enums-functions.ts +++ b/src/app/shared/services/consts-enums-functions.ts @@ -980,8 +980,8 @@ export const LND_TABLES_DEF = { }, transactions: { payments: { - maxColumns: 5, - allowedColumns: ['creation_date', 'payment_hash', 'fee', 'value', 'hops'] + maxColumns: 8, + allowedColumns: ['creation_date', 'payment_hash', 'payment_request', 'payment_preimage', 'description', 'description_hash', 'failure_reason', 'payment_index', 'fee', 'value', 'hops'] }, invoices: { maxColumns: 9,