diff --git a/frontend/custom-sv-config.json b/frontend/custom-sv-config.json index c39ea9c44..be10cbb48 100644 --- a/frontend/custom-sv-config.json +++ b/frontend/custom-sv-config.json @@ -32,7 +32,10 @@ "component": "blocks" }, { - "component": "transactions" + "component": "addressTransactions", + "props": { + "address": "32ixEdVJWo3kmvJGMTZq5jAQVZZeuwnqzo" + } } ] } diff --git a/frontend/src/app/components/address-graph/address-graph.component.ts b/frontend/src/app/components/address-graph/address-graph.component.ts index 5098bd850..3db5491e1 100644 --- a/frontend/src/app/components/address-graph/address-graph.component.ts +++ b/frontend/src/app/components/address-graph/address-graph.component.ts @@ -1,8 +1,8 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, Input, LOCALE_ID, OnChanges, SimpleChanges } from '@angular/core'; import { echarts, EChartsOption } from '../../graphs/echarts'; -import { of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { catchError } from 'rxjs/operators'; -import { ChainStats } from '../../interfaces/electrs.interface'; +import { AddressTxSummary, ChainStats } from '../../interfaces/electrs.interface'; import { ElectrsApiService } from '../../services/electrs-api.service'; import { AmountShortenerPipe } from '../../shared/pipes/amount-shortener.pipe'; import { Router } from '@angular/router'; @@ -36,6 +36,7 @@ export class AddressGraphComponent implements OnChanges { @Input() address: string; @Input() isPubkey: boolean = false; @Input() stats: ChainStats; + @Input() addressSummary$: Observable | null; @Input() period: '1d' | '3d' | '1w' | '1m' | '6m' | '1y' | 'all' = 'all'; @Input() height: number = 200; @Input() right: number | string = 10; @@ -69,14 +70,14 @@ export class AddressGraphComponent implements OnChanges { if (!this.address || !this.stats) { return; } - (this.isPubkey + (this.addressSummary$ || (this.isPubkey ? this.electrsApiService.getScriptHashSummary$((this.address.length === 66 ? '21' : '41') + this.address + 'ac') : this.electrsApiService.getAddressSummary$(this.address)).pipe( catchError(e => { this.error = `Failed to fetch address balance history: ${e?.status || ''} ${e?.statusText || 'unknown error'}`; return of(null); }), - ).subscribe(addressSummary => { + )).subscribe(addressSummary => { if (addressSummary) { this.error = null; this.prepareChartOptions(addressSummary); diff --git a/frontend/src/app/components/balance-widget/balance-widget.component.ts b/frontend/src/app/components/balance-widget/balance-widget.component.ts index 1cdfae525..c48cbc869 100644 --- a/frontend/src/app/components/balance-widget/balance-widget.component.ts +++ b/frontend/src/app/components/balance-widget/balance-widget.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges import { StateService } from '../../services/state.service'; import { Address, AddressTxSummary } from '../../interfaces/electrs.interface'; import { ElectrsApiService } from '../../services/electrs-api.service'; -import { catchError, of } from 'rxjs'; +import { Observable, catchError, of } from 'rxjs'; @Component({ selector: 'app-balance-widget', @@ -13,6 +13,7 @@ import { catchError, of } from 'rxjs'; export class BalanceWidgetComponent implements OnInit, OnChanges { @Input() address: string; @Input() addressInfo: Address; + @Input() addressSummary$: Observable | null; @Input() isPubkey: boolean = false; isLoading: boolean = true; @@ -36,14 +37,14 @@ export class BalanceWidgetComponent implements OnInit, OnChanges { if (!this.address || !this.addressInfo) { return; } - (this.isPubkey + (this.addressSummary$ || (this.isPubkey ? this.electrsApiService.getScriptHashSummary$((this.address.length === 66 ? '21' : '41') + this.address + 'ac') : this.electrsApiService.getAddressSummary$(this.address)).pipe( catchError(e => { this.error = `Failed to fetch address balance history: ${e?.status || ''} ${e?.statusText || 'unknown error'}`; return of(null); }), - ).subscribe(addressSummary => { + )).subscribe(addressSummary => { if (addressSummary) { this.error = null; this.calculateStats(addressSummary); diff --git a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html index b21dd1fa3..f881a0071 100644 --- a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html +++ b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.html @@ -226,7 +226,7 @@ @case ('balance') {
Treasury
- +
} @case ('address') { @@ -234,7 +234,17 @@
Balance History
- + +
+
+ + } + @case ('addressTransactions') { +
+
+
+
Treasury Transactions
+
diff --git a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts index 20ea25ebd..4aeb18b20 100644 --- a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts +++ b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts @@ -1,6 +1,6 @@ import { AfterViewInit, ChangeDetectionStrategy, Component, HostListener, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core'; import { combineLatest, merge, Observable, of, Subject, Subscription } from 'rxjs'; -import { catchError, filter, map, scan, shareReplay, switchMap, tap } from 'rxjs/operators'; +import { catchError, filter, map, scan, share, shareReplay, switchMap, tap } from 'rxjs/operators'; import { BlockExtended, OptimizedMempoolStats, TransactionStripped } from '../../interfaces/node-api.interface'; import { MempoolInfo, ReplacementInfo } from '../../interfaces/websocket.interface'; import { ApiService } from '../../services/api.service'; @@ -9,7 +9,7 @@ import { WebsocketService } from '../../services/websocket.service'; import { SeoService } from '../../services/seo.service'; import { ActiveFilter, FilterMode, GradientMode, toFlags } from '../../shared/filters.utils'; import { detectWebGL } from '../../shared/graphs.utils'; -import { Address } from '../../interfaces/electrs.interface'; +import { Address, AddressTxSummary } from '../../interfaces/electrs.interface'; import { ElectrsApiService } from '../../services/electrs-api.service'; interface MempoolBlocksData { @@ -61,6 +61,7 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni widgets; addressSubscription: Subscription; + addressSummary$: Observable; address: Address; goggleResolution = 82; @@ -298,6 +299,16 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni this.websocketService.startTrackAddress(address.address); this.address = address; }); + + this.addressSummary$ = ( + addressString.match(/04[a-fA-F0-9]{128}|(02|03)[a-fA-F0-9]{64}/) + ? this.electrsApiService.getScriptHashSummary$((addressString.length === 66 ? '21' : '41') + addressString + 'ac') + : this.electrsApiService.getAddressSummary$(addressString)).pipe( + catchError(e => { + return of(null); + }), + share(), + ); } } diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts index c900090a3..80d6ca3cd 100644 --- a/frontend/src/app/shared/shared.module.ts +++ b/frontend/src/app/shared/shared.module.ts @@ -66,6 +66,7 @@ import { DifficultyComponent } from '../components/difficulty/difficulty.compone import { DifficultyTooltipComponent } from '../components/difficulty/difficulty-tooltip.component'; import { DifficultyMiningComponent } from '../components/difficulty-mining/difficulty-mining.component'; import { BalanceWidgetComponent } from '../components/balance-widget/balance-widget.component'; +import { AddressTransactionsWidgetComponent } from '../components/address-transactions-widget/address-transactions-widget.component'; import { RbfTimelineComponent } from '../components/rbf-timeline/rbf-timeline.component'; import { RbfTimelineTooltipComponent } from '../components/rbf-timeline/rbf-timeline-tooltip.component'; import { PushTransactionComponent } from '../components/push-transaction/push-transaction.component'; @@ -175,6 +176,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir DifficultyMiningComponent, DifficultyTooltipComponent, BalanceWidgetComponent, + AddressTransactionsWidgetComponent, RbfTimelineComponent, RbfTimelineTooltipComponent, PushTransactionComponent, @@ -312,6 +314,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir DifficultyMiningComponent, DifficultyTooltipComponent, BalanceWidgetComponent, + AddressTransactionsWidgetComponent, RbfTimelineComponent, RbfTimelineTooltipComponent, PushTransactionComponent,