-
- BTC Reserves
-
-
- {{ +(currentReserves.amount) / 100000000 | number: '1.2-2' }} BTC
-
+
+
+
+
+
+
+ Audit in progress: Bitcoin block height #{{ auditStatus.lastBlockAudit }} / #{{ auditStatus.bitcoinHeaders }}
+
+
+
\ No newline at end of file
diff --git a/frontend/src/app/dashboard/dashboard.component.scss b/frontend/src/app/dashboard/dashboard.component.scss
index fd20b629e..019a79994 100644
--- a/frontend/src/app/dashboard/dashboard.component.scss
+++ b/frontend/src/app/dashboard/dashboard.component.scss
@@ -413,3 +413,39 @@
margin-top: 5px;
margin-bottom: 6px;
}
+
+.card-liquid {
+ background-color: #1d1f31;
+ height: 418px;
+ @media (min-width: 992px) {
+ height: 512px;
+ }
+ &.smaller {
+ height: 408px;
+ }
+}
+
+.card-title-liquid {
+ padding-top: 20px;
+}
+
+.peg-historical-data {
+ font-size: 18px;
+
+ @media (min-width: 768px) {
+ padding-top: 22px;
+ }
+
+ @media (min-width: 992px) {
+ padding-top: 27px;
+ }
+}
+
+.in-progress-message {
+ position: relative;
+ color: #ffffff91;
+ margin-top: 20px;
+ text-align: center;
+ padding-bottom: 3px;
+ font-weight: 500;
+}
diff --git a/frontend/src/app/dashboard/dashboard.component.ts b/frontend/src/app/dashboard/dashboard.component.ts
index 5dfd68419..89d6de96e 100644
--- a/frontend/src/app/dashboard/dashboard.component.ts
+++ b/frontend/src/app/dashboard/dashboard.component.ts
@@ -1,7 +1,7 @@
import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, OnDestroy, OnInit } from '@angular/core';
-import { combineLatest, EMPTY, fromEvent, merge, Observable, of, Subject, Subscription, timer } from 'rxjs';
+import { combineLatest, EMPTY, fromEvent, interval, merge, Observable, of, Subject, Subscription, timer } from 'rxjs';
import { catchError, delayWhen, distinctUntilChanged, filter, map, scan, share, shareReplay, startWith, switchMap, takeUntil, tap, throttleTime } from 'rxjs/operators';
-import { AuditStatus, BlockExtended, CurrentPegs, OptimizedMempoolStats } from '../interfaces/node-api.interface';
+import { AuditStatus, BlockExtended, CurrentPegs, FederationAddress, OptimizedMempoolStats, PegsVolume, RecentPeg } from '../interfaces/node-api.interface';
import { MempoolInfo, TransactionStripped, ReplacementInfo } from '../interfaces/websocket.interface';
import { ApiService } from '../services/api.service';
import { StateService } from '../services/state.service';
@@ -32,8 +32,6 @@ interface MempoolStatsData {
changeDetection: ChangeDetectionStrategy.OnPush
})
export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
- featuredAssets$: Observable
;
- nbFeaturedAssets = 6;
network$: Observable;
mempoolBlocksData$: Observable;
mempoolInfoData$: Observable;
@@ -53,13 +51,18 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
auditUpdated$: Observable;
liquidReservesMonth$: Observable;
currentReserves$: Observable;
+ recentPegsList$: Observable;
+ pegsVolume$: Observable;
+ federationAddresses$: Observable;
+ federationAddressesNumber$: Observable;
+ federationUtxosNumber$: Observable;
fullHistory$: Observable;
isLoad: boolean = true;
mempoolInfoSubscription: Subscription;
currencySubscription: Subscription;
currency: string;
incomingGraphHeight: number = 300;
- lbtcPegGraphHeight: number = 320;
+ lbtcPegGraphHeight: number = 250;
private lastPegBlockUpdate: number = 0;
private lastPegAmount: string = '';
private lastReservesBlockUpdate: number = 0;
@@ -155,26 +158,6 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
})
);
- const windowResize$ = fromEvent(window, 'resize').pipe(
- distinctUntilChanged(),
- startWith(null)
- );
-
- this.featuredAssets$ = combineLatest([
- this.apiService.listFeaturedAssets$(),
- windowResize$
- ]).pipe(
- map(([featured, _]) => {
- const newArray = [];
- for (const feature of featured) {
- if (feature.ticker !== 'L-BTC' && feature.asset) {
- newArray.push(feature);
- }
- }
- return newArray.slice(0, this.nbFeaturedAssets);
- }),
- );
-
this.transactions$ = this.stateService.transactions$
.pipe(
scan((acc, tx) => {
@@ -240,7 +223,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
share(),
);
- if (this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet') {
+ if (this.stateService.network === 'liquid') {
this.auditStatus$ = this.stateService.blocks$.pipe(
takeUntil(this.destroy$),
throttleTime(40000),
@@ -250,22 +233,6 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
shareReplay(1)
);
- ////////// Pegs historical data //////////
- this.liquidPegsMonth$ = this.auditStatus$.pipe(
- throttleTime(60 * 60 * 1000),
- switchMap(() => this.apiService.listLiquidPegsMonth$()),
- map((pegs) => {
- const labels = pegs.map(stats => stats.date);
- const series = pegs.map(stats => parseFloat(stats.amount) / 100000000);
- series.reduce((prev, curr, i) => series[i] = prev + curr, 0);
- return {
- series,
- labels
- };
- }),
- share(),
- );
-
this.currentPeg$ = this.auditStatus$.pipe(
switchMap(_ =>
this.apiService.liquidPegs$().pipe(
@@ -278,7 +245,6 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
share()
);
- ////////// BTC Reserves historical data //////////
this.auditUpdated$ = combineLatest([
this.auditStatus$,
this.currentPeg$
@@ -293,21 +259,6 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
const amountCheck = currentPegAmount !== this.lastPegAmount;
this.lastPegAmount = currentPegAmount;
return of(blockAuditCheck || amountCheck);
- })
- );
-
- this.liquidReservesMonth$ = this.auditStatus$.pipe(
- throttleTime(60 * 60 * 1000),
- switchMap((auditStatus) => {
- return auditStatus.isAuditSynced ? this.apiService.listLiquidReservesMonth$() : EMPTY;
- }),
- map(reserves => {
- const labels = reserves.map(stats => stats.date);
- const series = reserves.map(stats => parseFloat(stats.amount) / 100000000);
- return {
- series,
- labels
- };
}),
share()
);
@@ -326,11 +277,78 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
share()
);
- this.fullHistory$ = combineLatest([this.liquidPegsMonth$, this.currentPeg$, this.liquidReservesMonth$.pipe(startWith(null)), this.currentReserves$.pipe(startWith(null))])
+ this.recentPegsList$ = this.auditUpdated$.pipe(
+ filter(auditUpdated => auditUpdated === true),
+ throttleTime(40000),
+ switchMap(_ => this.apiService.recentPegsList$()),
+ share()
+ );
+
+ this.pegsVolume$ = this.auditUpdated$.pipe(
+ filter(auditUpdated => auditUpdated === true),
+ throttleTime(40000),
+ switchMap(_ => this.apiService.pegsVolume$()),
+ share()
+ );
+
+ this.federationAddresses$ = this.auditUpdated$.pipe(
+ filter(auditUpdated => auditUpdated === true),
+ throttleTime(40000),
+ switchMap(_ => this.apiService.federationAddresses$()),
+ share()
+ );
+
+ this.federationAddressesNumber$ = this.auditUpdated$.pipe(
+ filter(auditUpdated => auditUpdated === true),
+ throttleTime(40000),
+ switchMap(_ => this.apiService.federationAddressesNumber$()),
+ map(count => count.address_count),
+ share()
+ );
+
+ this.federationUtxosNumber$ = this.auditUpdated$.pipe(
+ filter(auditUpdated => auditUpdated === true),
+ throttleTime(40000),
+ switchMap(_ => this.apiService.federationUtxosNumber$()),
+ map(count => count.utxo_count),
+ share()
+ );
+
+ this.liquidPegsMonth$ = interval(60 * 60 * 1000)
+ .pipe(
+ startWith(0),
+ switchMap(() => this.apiService.listLiquidPegsMonth$()),
+ map((pegs) => {
+ const labels = pegs.map(stats => stats.date);
+ const series = pegs.map(stats => parseFloat(stats.amount) / 100000000);
+ series.reduce((prev, curr, i) => series[i] = prev + curr, 0);
+ return {
+ series,
+ labels
+ };
+ }),
+ share(),
+ );
+
+ this.liquidReservesMonth$ = interval(60 * 60 * 1000).pipe(
+ startWith(0),
+ switchMap(() => this.apiService.listLiquidReservesMonth$()),
+ map(reserves => {
+ const labels = reserves.map(stats => stats.date);
+ const series = reserves.map(stats => parseFloat(stats.amount) / 100000000);
+ return {
+ series,
+ labels
+ };
+ }),
+ share()
+ );
+
+ this.fullHistory$ = combineLatest([this.liquidPegsMonth$, this.currentPeg$, this.liquidReservesMonth$, this.currentReserves$])
.pipe(
map(([liquidPegs, currentPeg, liquidReserves, currentReserves]) => {
liquidPegs.series[liquidPegs.series.length - 1] = parseFloat(currentPeg.amount) / 100000000;
-
+
if (liquidPegs.series.length === liquidReserves?.series.length) {
liquidReserves.series[liquidReserves.series.length - 1] = parseFloat(currentReserves?.amount) / 100000000;
} else if (liquidPegs.series.length === liquidReserves?.series.length + 1) {
@@ -342,7 +360,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
labels: []
};
}
-
+
return {
liquidPegs,
liquidReserves
@@ -374,24 +392,21 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit {
getArrayFromNumber(num: number): number[] {
return Array.from({ length: num }, (_, i) => i + 1);
}
-
+
@HostListener('window:resize', ['$event'])
onResize(): void {
if (window.innerWidth >= 992) {
this.incomingGraphHeight = 300;
this.goggleResolution = 82;
- this.lbtcPegGraphHeight = 320;
- this.nbFeaturedAssets = 6;
+ this.lbtcPegGraphHeight = 270;
} else if (window.innerWidth >= 768) {
this.incomingGraphHeight = 215;
this.goggleResolution = 80;
- this.lbtcPegGraphHeight = 230;
- this.nbFeaturedAssets = 4;
+ this.lbtcPegGraphHeight = 190;
} else {
this.incomingGraphHeight = 180;
this.goggleResolution = 86;
- this.lbtcPegGraphHeight = 220;
- this.nbFeaturedAssets = 4;
+ this.lbtcPegGraphHeight = 200;
}
}
}
diff --git a/frontend/src/app/graphs/graphs.module.ts b/frontend/src/app/graphs/graphs.module.ts
index 85905d1f1..42aebe613 100644
--- a/frontend/src/app/graphs/graphs.module.ts
+++ b/frontend/src/app/graphs/graphs.module.ts
@@ -12,6 +12,13 @@ import { FeeDistributionGraphComponent } from '../components/fee-distribution-gr
import { IncomingTransactionsGraphComponent } from '../components/incoming-transactions-graph/incoming-transactions-graph.component';
import { MempoolGraphComponent } from '../components/mempool-graph/mempool-graph.component';
import { LbtcPegsGraphComponent } from '../components/lbtc-pegs-graph/lbtc-pegs-graph.component';
+import { ReservesSupplyStatsComponent } from '../components/liquid-reserves-audit/reserves-supply-stats/reserves-supply-stats.component';
+import { ReservesRatioStatsComponent } from '../components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component';
+import { ReservesRatioComponent } from '../components/liquid-reserves-audit/reserves-ratio/reserves-ratio.component';
+import { RecentPegsStatsComponent } from '../components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component';
+import { RecentPegsListComponent } from '../components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component';
+import { FederationAddressesStatsComponent } from '../components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component';
+import { FederationAddressesListComponent } from '../components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component';
import { GraphsComponent } from '../components/graphs/graphs.component';
import { StatisticsComponent } from '../components/statistics/statistics.component';
import { MempoolBlockComponent } from '../components/mempool-block/mempool-block.component';
@@ -48,6 +55,13 @@ import { CommonModule } from '@angular/common';
IncomingTransactionsGraphComponent,
MempoolGraphComponent,
LbtcPegsGraphComponent,
+ ReservesSupplyStatsComponent,
+ ReservesRatioStatsComponent,
+ ReservesRatioComponent,
+ RecentPegsStatsComponent,
+ RecentPegsListComponent,
+ FederationAddressesStatsComponent,
+ FederationAddressesListComponent,
HashrateChartComponent,
HashrateChartPoolsComponent,
BlockHealthGraphComponent,
diff --git a/frontend/src/app/liquid/liquid-master-page.module.ts b/frontend/src/app/liquid/liquid-master-page.module.ts
index 0134365bc..8988cb05c 100644
--- a/frontend/src/app/liquid/liquid-master-page.module.ts
+++ b/frontend/src/app/liquid/liquid-master-page.module.ts
@@ -15,17 +15,10 @@ import { AssetsComponent } from '../components/assets/assets.component';
import { AssetsFeaturedComponent } from '../components/assets/assets-featured/assets-featured.component'
import { AssetComponent } from '../components/asset/asset.component';
import { AssetsNavComponent } from '../components/assets/assets-nav/assets-nav.component';
-import { ReservesAuditDashboardComponent } from '../components/liquid-reserves-audit/reserves-audit-dashboard/reserves-audit-dashboard.component';
-import { ReservesSupplyStatsComponent } from '../components/liquid-reserves-audit/reserves-supply-stats/reserves-supply-stats.component';
-import { RecentPegsStatsComponent } from '../components/liquid-reserves-audit/recent-pegs-stats/recent-pegs-stats.component';
import { RecentPegsListComponent } from '../components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component';
import { FederationWalletComponent } from '../components/liquid-reserves-audit/federation-wallet/federation-wallet.component';
import { FederationUtxosListComponent } from '../components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component';
-import { FederationAddressesStatsComponent } from '../components/liquid-reserves-audit/federation-addresses-stats/federation-addresses-stats.component';
import { FederationAddressesListComponent } from '../components/liquid-reserves-audit/federation-addresses-list/federation-addresses-list.component';
-import { ReservesRatioComponent } from '../components/liquid-reserves-audit/reserves-ratio/reserves-ratio.component';
-import { ReservesRatioStatsComponent } from '../components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component';
-import { ReservesRatioGraphComponent } from '../components/liquid-reserves-audit/reserves-ratio/reserves-ratio-graph.component';
const routes: Routes = [
{
@@ -77,18 +70,6 @@ const routes: Routes = [
data: { preload: true, networkSpecific: true },
loadChildren: () => import('../components/block/block.module').then(m => m.BlockModule),
},
- {
- path: 'audit',
- data: { networks: ['liquid'] },
- component: StartComponent,
- children: [
- {
- path: '',
- data: { networks: ['liquid'] },
- component: ReservesAuditDashboardComponent,
- }
- ]
- },
{
path: 'audit/wallet',
data: { networks: ['liquid'] },
@@ -180,17 +161,8 @@ export class LiquidRoutingModule { }
],
declarations: [
LiquidMasterPageComponent,
- ReservesAuditDashboardComponent,
- ReservesSupplyStatsComponent,
- RecentPegsStatsComponent,
- RecentPegsListComponent,
FederationWalletComponent,
FederationUtxosListComponent,
- FederationAddressesStatsComponent,
- FederationAddressesListComponent,
- ReservesRatioComponent,
- ReservesRatioStatsComponent,
- ReservesRatioGraphComponent,
]
})
export class LiquidMasterPageModule { }
\ No newline at end of file