From 39c5792e6f4904b93b37de23da2cdabc53a01f2e Mon Sep 17 00:00:00 2001 From: ncois Date: Wed, 13 Dec 2023 12:45:36 +0100 Subject: [PATCH 1/4] Include % ownership in statistics table on LN dashboard and on ranking pages --- .../lightning-dashboard.component.html | 4 ++-- .../nodes-ranking/nodes-ranking.component.html | 4 ++-- .../lightning/nodes-ranking/nodes-ranking.component.ts | 10 +++++++++- .../top-nodes-per-capacity.component.html | 2 ++ .../top-nodes-per-capacity.component.scss | 5 +++++ .../top-nodes-per-capacity.component.ts | 8 ++++++++ .../top-nodes-per-channels.component.html | 2 ++ .../top-nodes-per-channels.component.scss | 5 +++++ .../top-nodes-per-channels.component.ts | 8 ++++++++ 9 files changed, 43 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html index f7d318073..89059185e 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.html @@ -63,7 +63,7 @@   - + @@ -77,7 +77,7 @@   - + diff --git a/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.html b/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.html index 5bd03941e..51836880d 100644 --- a/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.html +++ b/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.html @@ -1,7 +1,7 @@ - + - + diff --git a/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts b/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts index 373751be9..e59e89786 100644 --- a/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts @@ -1,5 +1,8 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { LightningApiService } from '../lightning-api.service'; +import { share } from 'rxjs/operators'; +import { Observable } from 'rxjs'; @Component({ selector: 'app-nodes-ranking', @@ -9,10 +12,15 @@ import { ActivatedRoute } from '@angular/router'; }) export class NodesRanking implements OnInit { type: string; + statistics$: Observable; - constructor(private route: ActivatedRoute) {} + constructor( + private route: ActivatedRoute, + private lightningApiService: LightningApiService, + ) {} ngOnInit(): void { + this.statistics$ = this.lightningApiService.getLatestStatistics$().pipe(share()); this.route.data.subscribe(data => { this.type = data.type; }); diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html index 3efbc8594..56fb091ee 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html @@ -27,12 +27,14 @@ +  ({{ (node.capacity / totalCapacity * 100) | number:'1.1-1' }}%) {{ node.channels | number }} +  ({{ (node?.channels / totalChannels * 100) | number:'1.1-1' }}%) diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.scss b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.scss index 3547c447f..89f144135 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.scss +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.scss @@ -41,6 +41,11 @@ tr, td, th { } } +.capacity-ratio { + font-size: 12px; + color: darkgrey; +} + .fiat { width: 15%; @media (min-width: 768px) and (max-width: 991px) { diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts index 054fa2f3c..780b9d1cd 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts @@ -14,11 +14,14 @@ import { LightningApiService } from '../../lightning-api.service'; }) export class TopNodesPerCapacity implements OnInit { @Input() nodes$: Observable; + @Input() statistics$: Observable; @Input() widget: boolean = false; topNodesPerCapacity$: Observable; skeletonRows: number[] = []; currency$: Observable; + totalCapacity: number; + totalChannels: number; constructor( private apiService: LightningApiService, @@ -59,6 +62,11 @@ export class TopNodesPerCapacity implements OnInit { }) ); } + + this.statistics$?.subscribe((data) => { + this.totalCapacity = data.latest.total_capacity; + this.totalChannels = data.latest.channel_count; + }); } } diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html index 94a887bb3..76b032552 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html @@ -27,9 +27,11 @@ {{ node.channels ? (node.channels | number) : '~' }} +  ({{ (node?.channels / totalChannels * 100) | number:'1.1-1' }}%) +  ({{ (node.capacity / totalCapacity * 100) | number:'1.1-1' }}%) diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.scss b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.scss index a42599d69..63d65bcf8 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.scss +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.scss @@ -44,6 +44,11 @@ tr, td, th { } } +.capacity-ratio { + font-size: 12px; + color: darkgrey; +} + .geolocation { @media (min-width: 768px) and (max-width: 991px) { display: none !important; diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts index 3de177cc7..f2d00f6f0 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts @@ -14,11 +14,14 @@ import { LightningApiService } from '../../lightning-api.service'; }) export class TopNodesPerChannels implements OnInit { @Input() nodes$: Observable; + @Input() statistics$: Observable; @Input() widget: boolean = false; topNodesPerChannels$: Observable; skeletonRows: number[] = []; currency$: Observable; + totalChannels: number; + totalCapacity: number; constructor( private apiService: LightningApiService, @@ -65,6 +68,11 @@ export class TopNodesPerChannels implements OnInit { }) ); } + + this.statistics$?.subscribe((data) => { + this.totalChannels = data.latest.channel_count; + this.totalCapacity = data.latest.total_capacity; + }); } } From 97053ab5cfe4b68961bfa9ee4cefb976e6f7cb7e Mon Sep 17 00:00:00 2001 From: natsee Date: Wed, 13 Dec 2023 15:13:01 +0100 Subject: [PATCH 2/4] Update contributor agreement file --- contributors/{ncois.txt => natsee.txt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename contributors/{ncois.txt => natsee.txt} (91%) diff --git a/contributors/ncois.txt b/contributors/natsee.txt similarity index 91% rename from contributors/ncois.txt rename to contributors/natsee.txt index 04a436613..c391ce823 100644 --- a/contributors/ncois.txt +++ b/contributors/natsee.txt @@ -1,3 +1,3 @@ I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of November 16, 2023. -Signed: ncois +Signed: natsee From 464cffb5c1c5be14d4f88ae55cef0ff5c41192c3 Mon Sep 17 00:00:00 2001 From: natsee Date: Thu, 14 Dec 2023 12:22:00 +0100 Subject: [PATCH 3/4] Add LN statistics interface --- .../src/app/interfaces/node-api.interface.ts | 23 +++++++++++++++++++ .../channels-statistics.component.ts | 3 ++- .../lightning-dashboard.component.ts | 4 ++-- .../node-statistics.component.ts | 3 ++- .../nodes-ranking/nodes-ranking.component.ts | 3 ++- .../top-nodes-per-capacity.component.ts | 4 ++-- .../top-nodes-per-channels.component.ts | 4 ++-- 7 files changed, 35 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts index 862272330..37d2f29ed 100644 --- a/frontend/src/app/interfaces/node-api.interface.ts +++ b/frontend/src/app/interfaces/node-api.interface.ts @@ -254,6 +254,29 @@ export interface INodesRanking { topByChannels: ITopNodesPerChannels[]; } +export interface INodesStatisticsEntry { + added: string; + avg_base_fee_mtokens: number; + avg_capacity: number; + avg_fee_rate: number; + channel_count: number; + clearnet_nodes: number; + clearnet_tor_nodes: number; + id: number; + med_base_fee_mtokens: number; + med_capacity: number; + med_fee_rate: number; + node_count: number; + tor_nodes: number; + total_capacity: number; + unannounced_nodes: number; +} + +export interface INodesStatistics { + latest: INodesStatisticsEntry; + previous: INodesStatisticsEntry; +} + export interface IOldestNodes { publicKey: string, alias: string, diff --git a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.ts b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.ts index 4059e9420..f2b78f53c 100644 --- a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.ts +++ b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.ts @@ -1,5 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; +import { INodesStatistics } from '../../interfaces/node-api.interface'; @Component({ selector: 'app-channels-statistics', @@ -8,7 +9,7 @@ import { Observable } from 'rxjs'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class ChannelsStatisticsComponent implements OnInit { - @Input() statistics$: Observable; + @Input() statistics$: Observable; mode: string = 'avg'; constructor() { } diff --git a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts index 26a67cee6..dece98ddb 100644 --- a/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts +++ b/frontend/src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts @@ -1,7 +1,7 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { share } from 'rxjs/operators'; -import { INodesRanking } from '../../interfaces/node-api.interface'; +import { INodesRanking, INodesStatistics } from '../../interfaces/node-api.interface'; import { SeoService } from '../../services/seo.service'; import { StateService } from '../../services/state.service'; import { LightningApiService } from '../lightning-api.service'; @@ -13,7 +13,7 @@ import { LightningApiService } from '../lightning-api.service'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class LightningDashboardComponent implements OnInit, AfterViewInit { - statistics$: Observable; + statistics$: Observable; nodesRanking$: Observable; officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE; diff --git a/frontend/src/app/lightning/node-statistics/node-statistics.component.ts b/frontend/src/app/lightning/node-statistics/node-statistics.component.ts index c42720427..338e17ab8 100644 --- a/frontend/src/app/lightning/node-statistics/node-statistics.component.ts +++ b/frontend/src/app/lightning/node-statistics/node-statistics.component.ts @@ -1,5 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; +import { INodesStatistics } from '../../interfaces/node-api.interface'; @Component({ selector: 'app-node-statistics', @@ -8,7 +9,7 @@ import { Observable } from 'rxjs'; changeDetection: ChangeDetectionStrategy.OnPush, }) export class NodeStatisticsComponent implements OnInit { - @Input() statistics$: Observable; + @Input() statistics$: Observable; constructor() { } diff --git a/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts b/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts index e59e89786..8a1eae3dc 100644 --- a/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/nodes-ranking.component.ts @@ -3,6 +3,7 @@ import { ActivatedRoute } from '@angular/router'; import { LightningApiService } from '../lightning-api.service'; import { share } from 'rxjs/operators'; import { Observable } from 'rxjs'; +import { INodesStatistics } from '../../interfaces/node-api.interface'; @Component({ selector: 'app-nodes-ranking', @@ -12,7 +13,7 @@ import { Observable } from 'rxjs'; }) export class NodesRanking implements OnInit { type: string; - statistics$: Observable; + statistics$: Observable; constructor( private route: ActivatedRoute, diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts index 780b9d1cd..a52ba9398 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { map, Observable } from 'rxjs'; -import { INodesRanking, ITopNodesPerCapacity } from '../../../interfaces/node-api.interface'; +import { INodesRanking, INodesStatistics, ITopNodesPerCapacity } from '../../../interfaces/node-api.interface'; import { SeoService } from '../../../services/seo.service'; import { StateService } from '../../../services/state.service'; import { GeolocationData } from '../../../shared/components/geolocation/geolocation.component'; @@ -14,7 +14,7 @@ import { LightningApiService } from '../../lightning-api.service'; }) export class TopNodesPerCapacity implements OnInit { @Input() nodes$: Observable; - @Input() statistics$: Observable; + @Input() statistics$: Observable; @Input() widget: boolean = false; topNodesPerCapacity$: Observable; diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts index f2d00f6f0..ca1b6d6a4 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts @@ -1,6 +1,6 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; import { map, Observable } from 'rxjs'; -import { INodesRanking, ITopNodesPerChannels } from '../../../interfaces/node-api.interface'; +import { INodesRanking, INodesStatistics, ITopNodesPerChannels } from '../../../interfaces/node-api.interface'; import { SeoService } from '../../../services/seo.service'; import { StateService } from '../../../services/state.service'; import { GeolocationData } from '../../../shared/components/geolocation/geolocation.component'; @@ -14,7 +14,7 @@ import { LightningApiService } from '../../lightning-api.service'; }) export class TopNodesPerChannels implements OnInit { @Input() nodes$: Observable; - @Input() statistics$: Observable; + @Input() statistics$: Observable; @Input() widget: boolean = false; topNodesPerChannels$: Observable; From 3eb6241c987a25bf320e06cb1ed70d007ef4bc33 Mon Sep 17 00:00:00 2001 From: natsee Date: Thu, 14 Dec 2023 12:29:21 +0100 Subject: [PATCH 4/4] Delete variables and use observables in top nodes components --- .../top-nodes-per-capacity.component.html | 8 ++-- .../top-nodes-per-capacity.component.ts | 42 +++++++++++------- .../top-nodes-per-channels.component.html | 8 ++-- .../top-nodes-per-channels.component.ts | 44 ++++++++++++------- 4 files changed, 63 insertions(+), 39 deletions(-) diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html index 56fb091ee..27af80564 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html @@ -16,8 +16,8 @@ Last update Location - - + +
@@ -27,14 +27,14 @@ -  ({{ (node.capacity / totalCapacity * 100) | number:'1.1-1' }}%) +  ({{ (node?.capacity / data.statistics.totalCapacity * 100) | number:'1.1-1' }}%) {{ node.channels | number }} -  ({{ (node?.channels / totalChannels * 100) | number:'1.1-1' }}%) +  ({{ (node?.channels / data.statistics.totalChannels * 100) | number:'1.1-1' }}%) diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts index a52ba9398..0b8c03bbd 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; -import { map, Observable } from 'rxjs'; +import { combineLatest, map, Observable } from 'rxjs'; import { INodesRanking, INodesStatistics, ITopNodesPerCapacity } from '../../../interfaces/node-api.interface'; import { SeoService } from '../../../services/seo.service'; import { StateService } from '../../../services/state.service'; @@ -17,11 +17,9 @@ export class TopNodesPerCapacity implements OnInit { @Input() statistics$: Observable; @Input() widget: boolean = false; - topNodesPerCapacity$: Observable; + topNodesPerCapacity$: Observable<{ nodes: ITopNodesPerCapacity[]; statistics: { totalCapacity: number; totalChannels?: number; } }>; skeletonRows: number[] = []; currency$: Observable; - totalCapacity: number; - totalChannels: number; constructor( private apiService: LightningApiService, @@ -42,8 +40,12 @@ export class TopNodesPerCapacity implements OnInit { } if (this.widget === false) { - this.topNodesPerCapacity$ = this.apiService.getTopNodesByCapacity$().pipe( - map((ranking) => { + this.topNodesPerCapacity$ = combineLatest([ + this.apiService.getTopNodesByCapacity$(), + this.statistics$ + ]) + .pipe( + map(([ranking, statistics]) => { for (const i in ranking) { ranking[i].geolocation = { country: ranking[i].country?.en, @@ -52,21 +54,31 @@ export class TopNodesPerCapacity implements OnInit { iso: ranking[i].iso_code, }; } - return ranking; + return { + nodes: ranking, + statistics: { + totalCapacity: statistics.latest.total_capacity, + totalChannels: statistics.latest.channel_count, + } + } }) ); } else { - this.topNodesPerCapacity$ = this.nodes$.pipe( - map((ranking) => { - return ranking.topByCapacity.slice(0, 6); + this.topNodesPerCapacity$ = combineLatest([ + this.nodes$, + this.statistics$ + ]) + .pipe( + map(([ranking, statistics]) => { + return { + nodes: ranking.topByCapacity.slice(0, 6), + statistics: { + totalCapacity: statistics.latest.total_capacity, + } + } }) ); } - - this.statistics$?.subscribe((data) => { - this.totalCapacity = data.latest.total_capacity; - this.totalChannels = data.latest.channel_count; - }); } } diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html index 76b032552..87f7f1ad2 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html @@ -16,8 +16,8 @@ Last update Location - - + +
@@ -27,11 +27,11 @@ {{ node.channels ? (node.channels | number) : '~' }} -  ({{ (node?.channels / totalChannels * 100) | number:'1.1-1' }}%) +  ({{ (node?.channels / data.statistics.totalChannels * 100) | number:'1.1-1' }}%) -  ({{ (node.capacity / totalCapacity * 100) | number:'1.1-1' }}%) +  ({{ (node.capacity / data.statistics.totalCapacity * 100) | number:'1.1-1' }}%) diff --git a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts index ca1b6d6a4..56d55a5d3 100644 --- a/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts +++ b/frontend/src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core'; -import { map, Observable } from 'rxjs'; +import { combineLatest, map, Observable } from 'rxjs'; import { INodesRanking, INodesStatistics, ITopNodesPerChannels } from '../../../interfaces/node-api.interface'; import { SeoService } from '../../../services/seo.service'; import { StateService } from '../../../services/state.service'; @@ -17,12 +17,10 @@ export class TopNodesPerChannels implements OnInit { @Input() statistics$: Observable; @Input() widget: boolean = false; - topNodesPerChannels$: Observable; + topNodesPerChannels$: Observable<{ nodes: ITopNodesPerChannels[]; statistics: { totalChannels: number; totalCapacity?: number; } }>; skeletonRows: number[] = []; currency$: Observable; - totalChannels: number; - totalCapacity: number; - + constructor( private apiService: LightningApiService, private stateService: StateService, @@ -40,8 +38,12 @@ export class TopNodesPerChannels implements OnInit { this.seoService.setTitle($localize`:@@c50bf442cf99f6fc5f8b687c460f33234b879869:Connectivity Ranking`); this.seoService.setDescription($localize`:@@meta.description.lightning.ranking.channels:See Lightning nodes with the most channels open along with high-level stats like total node capacity, node age, and more.`); - this.topNodesPerChannels$ = this.apiService.getTopNodesByChannels$().pipe( - map((ranking) => { + this.topNodesPerChannels$ = combineLatest([ + this.apiService.getTopNodesByChannels$(), + this.statistics$ + ]) + .pipe( + map(([ranking, statistics]) => { for (const i in ranking) { ranking[i].geolocation = { country: ranking[i].country?.en, @@ -50,12 +52,22 @@ export class TopNodesPerChannels implements OnInit { iso: ranking[i].iso_code, }; } - return ranking; + return { + nodes: ranking, + statistics: { + totalChannels: statistics.latest.channel_count, + totalCapacity: statistics.latest.total_capacity, + } + } }) ); } else { - this.topNodesPerChannels$ = this.nodes$.pipe( - map((ranking) => { + this.topNodesPerChannels$ = combineLatest([ + this.nodes$, + this.statistics$ + ]) + .pipe( + map(([ranking, statistics]) => { for (const i in ranking.topByChannels) { ranking.topByChannels[i].geolocation = { country: ranking.topByChannels[i].country?.en, @@ -64,15 +76,15 @@ export class TopNodesPerChannels implements OnInit { iso: ranking.topByChannels[i].iso_code, }; } - return ranking.topByChannels.slice(0, 6); + return { + nodes: ranking.topByChannels.slice(0, 6), + statistics: { + totalChannels: statistics.latest.channel_count, + } + } }) ); } - - this.statistics$?.subscribe((data) => { - this.totalChannels = data.latest.channel_count; - this.totalCapacity = data.latest.total_capacity; - }); } }