diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html
index 2d1b31a5a..b496ec6d1 100644
--- a/frontend/src/app/components/transaction/transaction.component.html
+++ b/frontend/src/app/components/transaction/transaction.component.html
@@ -512,18 +512,32 @@
-
+
-
+ Accelerated fee rate |
+ Effective fee rate |
diff --git a/frontend/src/app/components/transaction/transaction.component.scss b/frontend/src/app/components/transaction/transaction.component.scss
index 542c2601d..d78edf85b 100644
--- a/frontend/src/app/components/transaction/transaction.component.scss
+++ b/frontend/src/app/components/transaction/transaction.component.scss
@@ -60,6 +60,11 @@
top: -1px;
}
+.badge.badge-accelerated {
+ background-color: #653b9c;
+ color: white;
+}
+
.btn-small-height {
line-height: 1;
}
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index cf111468c..282b50968 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -21,7 +21,7 @@ import { ApiService } from '../../services/api.service';
import { SeoService } from '../../services/seo.service';
import { StorageService } from '../../services/storage.service';
import { seoDescriptionNetwork } from '../../shared/common.utils';
-import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment } from '../../interfaces/node-api.interface';
+import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration } from '../../interfaces/node-api.interface';
import { LiquidUnblinding } from './liquid-ublinding';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
import { Price, PriceService } from '../../services/price.service';
@@ -49,6 +49,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
fetchCpfpSubscription: Subscription;
fetchRbfSubscription: Subscription;
fetchCachedTxSubscription: Subscription;
+ fetchAccelerationSubscription: Subscription;
txReplacedSubscription: Subscription;
txRbfInfoSubscription: Subscription;
mempoolPositionSubscription: Subscription;
@@ -62,12 +63,14 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
rbfReplaces: string[];
rbfInfo: RbfTree;
cpfpInfo: CpfpInfo | null;
+ accelerationInfo: Acceleration | null = null;
sigops: number | null;
adjustedVsize: number | null;
showCpfpDetails = false;
fetchCpfp$ = new Subject();
fetchRbfHistory$ = new Subject();
fetchCachedTx$ = new Subject();
+ fetchAcceleration$ = new Subject();
isCached: boolean = false;
now = Date.now();
da$: Observable;
@@ -238,6 +241,24 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}
});
+ this.fetchAccelerationSubscription = this.fetchAcceleration$.pipe(
+ tap(() => {
+ this.accelerationInfo = null;
+ }),
+ switchMap((blockHash: string) => {
+ return this.apiService.getAccelerationHistory$({ blockHash });
+ }),
+ catchError(() => {
+ return of(null);
+ })
+ ).subscribe((accelerationHistory) => {
+ for (const acceleration of accelerationHistory) {
+ if (acceleration.txid === this.txId) {
+ this.accelerationInfo = acceleration;
+ }
+ }
+ });
+
this.mempoolPositionSubscription = this.stateService.mempoolTxPosition$.subscribe(txPosition => {
this.now = Date.now();
if (txPosition && txPosition.txid === this.txId && txPosition.position) {
@@ -365,6 +386,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.getTransactionTime();
}
} else {
+ this.fetchAcceleration$.next(tx.status.block_hash);
this.transactionTime = 0;
}
@@ -417,6 +439,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
};
this.stateService.markBlock$.next({ blockHeight: block.height });
this.audioService.playSound('magic');
+ this.fetchAcceleration$.next(block.id);
}
});
@@ -585,6 +608,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.rbfInfo = null;
this.rbfReplaces = [];
this.showCpfpDetails = false;
+ this.accelerationInfo = null;
this.txInBlockIndex = null;
this.mempoolPosition = null;
document.body.scrollTo(0, 0);
@@ -664,6 +688,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.fetchCpfpSubscription.unsubscribe();
this.fetchRbfSubscription.unsubscribe();
this.fetchCachedTxSubscription.unsubscribe();
+ this.fetchAccelerationSubscription.unsubscribe();
this.txReplacedSubscription.unsubscribe();
this.txRbfInfoSubscription.unsubscribe();
this.queryParamsSubscription.unsubscribe();
diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts
index 08de11a6a..8b98b6761 100644
--- a/frontend/src/app/interfaces/node-api.interface.ts
+++ b/frontend/src/app/interfaces/node-api.interface.ts
@@ -302,3 +302,26 @@ export interface INode {
funding_balance?: number;
closing_balance?: number;
}
+
+export interface Acceleration {
+ txid: string;
+ status: 'requested' | 'accelerating' | 'mined' | 'completed' | 'failed';
+ pools: number[];
+ feePaid: number;
+ added: number; // timestamp
+ lastUpdated: number; // timestamp
+ baseFee: number;
+ vsizeFee: number;
+ effectiveFee: number;
+ effectiveVsize: number;
+ feeDelta: number;
+ blockHash: string;
+ blockHeight: number;
+}
+
+export interface AccelerationHistoryParams {
+ timeframe?: string,
+ status?: string,
+ pool?: string,
+ blockHash?: string,
+}
\ No newline at end of file
diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts
index 5cdf3d21a..854d15c2a 100644
--- a/frontend/src/app/services/api.service.ts
+++ b/frontend/src/app/services/api.service.ts
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
import { CpfpInfo, OptimizedMempoolStats, AddressInformation, LiquidPegs, ITranslators,
- PoolStat, BlockExtended, TransactionStripped, RewardStats, AuditScore, BlockSizesAndWeights, RbfTree, BlockAudit } from '../interfaces/node-api.interface';
+ PoolStat, BlockExtended, TransactionStripped, RewardStats, AuditScore, BlockSizesAndWeights, RbfTree, BlockAudit, Acceleration, AccelerationHistoryParams } from '../interfaces/node-api.interface';
import { BehaviorSubject, Observable, catchError, filter, of, shareReplay, take, tap } from 'rxjs';
import { StateService } from './state.service';
import { IBackendInfo, WebsocketResponse } from '../interfaces/websocket.interface';
@@ -428,4 +428,12 @@ export class ApiService {
accelerate$(txInput: string, userBid: number) {
return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/accelerate`, { txInput: txInput, userBid: userBid });
}
+
+ getAccelerations$(): Observable {
+ return this.httpClient.get(`${SERVICES_API_PREFIX}/accelerator/accelerations`);
+ }
+
+ getAccelerationHistory$(params: AccelerationHistoryParams): Observable {
+ return this.httpClient.get(`${SERVICES_API_PREFIX}/accelerator/accelerations/history`, { params: { ...params } });
+ }
}
|