mirror of
https://github.com/mempool/mempool.git
synced 2025-05-02 08:10:17 +02:00
Add address transactions widget
This commit is contained in:
parent
ccb27dbdb9
commit
139c384e97
frontend
@ -32,7 +32,10 @@
|
||||
"component": "blocks"
|
||||
},
|
||||
{
|
||||
"component": "transactions"
|
||||
"component": "addressTransactions",
|
||||
"props": {
|
||||
"address": "32ixEdVJWo3kmvJGMTZq5jAQVZZeuwnqzo"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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<AddressTxSummary[]> | 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);
|
||||
|
@ -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<AddressTxSummary[]> | 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);
|
||||
|
@ -226,7 +226,7 @@
|
||||
@case ('balance') {
|
||||
<div class="col card-wrapper">
|
||||
<div class="main-title" i18n="dashboard.treasury">Treasury</div>
|
||||
<app-balance-widget [address]="widget.props.address" [addressInfo]="address"></app-balance-widget>
|
||||
<app-balance-widget [address]="widget.props.address" [addressSummary$]="addressSummary$" [addressInfo]="address"></app-balance-widget>
|
||||
</div>
|
||||
}
|
||||
@case ('address') {
|
||||
@ -234,7 +234,17 @@
|
||||
<div class="card graph-card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title mb-4" i18n="dashboard.balance-history">Balance History</h5>
|
||||
<app-address-graph [address]="widget.props.address" [period]="widget.props.period || 'all'" [stats]="address?.chain_stats" [widget]="true" [height]="graphHeight"></app-address-graph>
|
||||
<app-address-graph [address]="widget.props.address" [addressSummary$]="addressSummary$" [period]="widget.props.period || 'all'" [stats]="address?.chain_stats" [widget]="true" [height]="graphHeight"></app-address-graph>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@case ('addressTransactions') {
|
||||
<div class="col" style="max-height: 410px">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title" i18n="dashboard.treasury-transactions">Treasury Transactions</h5>
|
||||
<app-address-transactions-widget [address]="widget.props.address" [addressSummary$]="addressSummary$" [addressInfo]="address"></app-address-transactions-widget>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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<AddressTxSummary[]>;
|
||||
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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user