2024-04-25 20:20:41 +00:00
|
|
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
2024-10-22 21:05:01 +09:00
|
|
|
import { StateService } from '@app/services/state.service';
|
2024-10-23 11:09:38 +09:00
|
|
|
import { Address, AddressTxSummary } from '@interfaces/electrs.interface';
|
2024-10-22 21:05:01 +09:00
|
|
|
import { ElectrsApiService } from '@app/services/electrs-api.service';
|
2024-04-26 19:16:09 +00:00
|
|
|
import { Observable, catchError, of } from 'rxjs';
|
2024-04-25 20:20:41 +00:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-balance-widget',
|
|
|
|
templateUrl: './balance-widget.component.html',
|
|
|
|
styleUrls: ['./balance-widget.component.scss'],
|
|
|
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
|
|
})
|
|
|
|
export class BalanceWidgetComponent implements OnInit, OnChanges {
|
|
|
|
@Input() address: string;
|
|
|
|
@Input() addressInfo: Address;
|
2024-04-26 19:16:09 +00:00
|
|
|
@Input() addressSummary$: Observable<AddressTxSummary[]> | null;
|
2024-04-25 20:20:41 +00:00
|
|
|
@Input() isPubkey: boolean = false;
|
|
|
|
|
|
|
|
isLoading: boolean = true;
|
|
|
|
error: any;
|
|
|
|
|
2024-07-25 22:34:52 +00:00
|
|
|
total: number = 0;
|
2024-04-25 20:20:41 +00:00
|
|
|
delta7d: number = 0;
|
|
|
|
delta30d: number = 0;
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
public stateService: StateService,
|
|
|
|
private electrsApiService: ElectrsApiService,
|
|
|
|
private cd: ChangeDetectorRef,
|
|
|
|
) { }
|
|
|
|
|
|
|
|
ngOnInit(): void {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnChanges(changes: SimpleChanges): void {
|
|
|
|
this.isLoading = true;
|
2024-07-25 22:34:52 +00:00
|
|
|
if (!this.addressSummary$ && (!this.address || !this.addressInfo)) {
|
2024-04-25 20:20:41 +00:00
|
|
|
return;
|
|
|
|
}
|
2024-04-26 19:16:09 +00:00
|
|
|
(this.addressSummary$ || (this.isPubkey
|
2024-04-25 20:20:41 +00:00
|
|
|
? 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);
|
|
|
|
}),
|
2024-04-26 19:16:09 +00:00
|
|
|
)).subscribe(addressSummary => {
|
2024-04-25 20:20:41 +00:00
|
|
|
if (addressSummary) {
|
|
|
|
this.error = null;
|
|
|
|
this.calculateStats(addressSummary);
|
|
|
|
}
|
|
|
|
this.isLoading = false;
|
|
|
|
this.cd.markForCheck();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
calculateStats(summary: AddressTxSummary[]): void {
|
|
|
|
let weekTotal = 0;
|
|
|
|
let monthTotal = 0;
|
2024-07-25 22:34:52 +00:00
|
|
|
this.total = this.addressInfo ? this.addressInfo.chain_stats.funded_txo_sum - this.addressInfo.chain_stats.spent_txo_sum : summary.reduce((acc, tx) => acc + tx.value, 0);
|
2024-05-12 16:27:57 +00:00
|
|
|
|
|
|
|
const weekAgo = (new Date(new Date().setHours(0, 0, 0, 0) - (7 * 24 * 60 * 60 * 1000)).getTime()) / 1000;
|
|
|
|
const monthAgo = (new Date(new Date().setHours(0, 0, 0, 0) - (30 * 24 * 60 * 60 * 1000)).getTime()) / 1000;
|
2024-04-25 20:20:41 +00:00
|
|
|
for (let i = 0; i < summary.length && summary[i].time >= monthAgo; i++) {
|
|
|
|
monthTotal += summary[i].value;
|
|
|
|
if (summary[i].time >= weekAgo) {
|
|
|
|
weekTotal += summary[i].value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.delta7d = weekTotal;
|
|
|
|
this.delta30d = monthTotal;
|
|
|
|
}
|
|
|
|
}
|