diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts
index 1eb1c4798..3cb60e048 100644
--- a/frontend/src/app/components/block/block.component.ts
+++ b/frontend/src/app/components/block/block.component.ts
@@ -526,9 +526,9 @@ export class BlockComponent implements OnInit, OnDestroy {
if (this.priceSubscription) {
this.priceSubscription.unsubscribe();
}
- this.priceSubscription = block$.pipe(
- switchMap((block) => {
- return this.priceService.getBlockPrice$(block.timestamp).pipe(
+ this.priceSubscription = combineLatest([this.stateService.fiatCurrency$, block$]).pipe(
+ switchMap(([currency, block]) => {
+ return this.priceService.getBlockPrice$(block.timestamp, true, currency).pipe(
tap((price) => {
this.blockConversion = price;
})
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index 0167a3d43..ea397ee90 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -76,6 +76,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
mempoolBlocksSubscription: Subscription;
blocksSubscription: Subscription;
miningSubscription: Subscription;
+ currencyChangeSubscription: Subscription;
fragmentParams: URLSearchParams;
rbfTransaction: undefined | Transaction;
replaced: boolean = false;
@@ -493,10 +494,12 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}
}
this.fetchRbfHistory$.next(this.tx.txid);
-
- this.priceService.getBlockPrice$(tx.status?.block_time, true).pipe(
- tap((price) => {
- this.blockConversion = price;
+ this.currencyChangeSubscription?.unsubscribe();
+ this.currencyChangeSubscription = this.stateService.fiatCurrency$.pipe(
+ switchMap((currency) => {
+ return tx.status.block_time ? this.priceService.getBlockPrice$(tx.status.block_time, true, currency).pipe(
+ tap((price) => tx['price'] = price),
+ ) : of(undefined);
})
).subscribe();
@@ -810,6 +813,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.mempoolBlocksSubscription.unsubscribe();
this.blocksSubscription.unsubscribe();
this.miningSubscription?.unsubscribe();
+ this.currencyChangeSubscription?.unsubscribe();
this.leaveTransaction();
}
}
diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.ts b/frontend/src/app/components/transactions-list/transactions-list.component.ts
index da9bdfe04..8f91489c1 100644
--- a/frontend/src/app/components/transactions-list/transactions-list.component.ts
+++ b/frontend/src/app/components/transactions-list/transactions-list.component.ts
@@ -32,11 +32,14 @@ export class TransactionsListComponent implements OnInit, OnChanges {
@Input() outputIndex: number;
@Input() address: string = '';
@Input() rowLimit = 12;
+ @Input() blockTime: number = 0; // Used for price calculation if all the transactions are in the same block
@Output() loadMore = new EventEmitter();
latestBlock$: Observable
;
outspendsSubscription: Subscription;
+ currencyChangeSubscription: Subscription;
+ currency: string;
refreshOutspends$: ReplaySubject = new ReplaySubject();
refreshChannels$: ReplaySubject = new ReplaySubject();
showDetails$ = new BehaviorSubject(false);
@@ -125,6 +128,35 @@ export class TransactionsListComponent implements OnInit, OnChanges {
)
,
).subscribe(() => this.ref.markForCheck());
+
+ this.currencyChangeSubscription = this.stateService.fiatCurrency$
+ .subscribe(currency => {
+ this.currency = currency;
+ this.refreshPrice();
+ });
+ }
+
+ refreshPrice(): void {
+ // Loop over all transactions
+ if (!this.transactions || !this.transactions.length || !this.currency) {
+ return;
+ }
+ const confirmedTxs = this.transactions.filter((tx) => tx.status.confirmed).length;
+ if (!this.blockTime) {
+ this.transactions.forEach((tx) => {
+ if (!this.blockTime) {
+ if (tx.status.block_time) {
+ this.priceService.getBlockPrice$(tx.status.block_time, confirmedTxs < 10, this.currency).pipe(
+ tap((price) => tx['price'] = price),
+ ).subscribe();
+ }
+ }
+ });
+ } else {
+ this.priceService.getBlockPrice$(this.blockTime, true, this.currency).pipe(
+ tap((price) => this.transactions.forEach((tx) => tx['price'] = price)),
+ ).subscribe();
+ }
}
ngOnChanges(changes): void {
@@ -148,6 +180,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
this.transactionsLength = this.transactions.length;
this.cacheService.setTxCache(this.transactions);
+ const confirmedTxs = this.transactions.filter((tx) => tx.status.confirmed).length;
this.transactions.forEach((tx) => {
tx['@voutLimit'] = true;
tx['@vinLimit'] = true;
@@ -197,10 +230,18 @@ export class TransactionsListComponent implements OnInit, OnChanges {
}
}
- this.priceService.getBlockPrice$(tx.status.block_time).pipe(
- tap((price) => tx['price'] = price)
- ).subscribe();
+ if (!this.blockTime && tx.status.block_time && this.currency) {
+ this.priceService.getBlockPrice$(tx.status.block_time, confirmedTxs < 10, this.currency).pipe(
+ tap((price) => tx['price'] = price),
+ ).subscribe();
+ }
});
+
+ if (this.blockTime && this.transactions?.length && this.currency) {
+ this.priceService.getBlockPrice$(this.blockTime, true, this.currency).pipe(
+ tap((price) => this.transactions.forEach((tx) => tx['price'] = price)),
+ ).subscribe();
+ }
const txIds = this.transactions.filter((tx) => !tx._outspends).map((tx) => tx.txid);
if (txIds.length && !this.cached) {
this.refreshOutspends$.next(txIds);
@@ -308,5 +349,6 @@ export class TransactionsListComponent implements OnInit, OnChanges {
ngOnDestroy(): void {
this.outspendsSubscription.unsubscribe();
+ this.currencyChangeSubscription?.unsubscribe();
}
}
diff --git a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts
index 924982983..aa98779ca 100644
--- a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts
+++ b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts
@@ -1,5 +1,5 @@
import { Component, ElementRef, ViewChild, Input, OnChanges, OnInit } from '@angular/core';
-import { tap } from 'rxjs';
+import { Subscription, of, switchMap, tap } from 'rxjs';
import { Price, PriceService } from '../../services/price.service';
import { StateService } from '../../services/state.service';
import { environment } from '../../../environments/environment';
@@ -35,6 +35,7 @@ export class TxBowtieGraphTooltipComponent implements OnChanges {
tooltipPosition = { x: 0, y: 0 };
blockConversion: Price;
+ currencyChangeSubscription: Subscription;
nativeAssetId = this.stateService.network === 'liquidtestnet' ? environment.nativeTestAssetId : environment.nativeAssetId;
@@ -47,11 +48,14 @@ export class TxBowtieGraphTooltipComponent implements OnChanges {
ngOnChanges(changes): void {
if (changes.line?.currentValue) {
- this.priceService.getBlockPrice$(changes.line?.currentValue.timestamp, true).pipe(
- tap((price) => {
- this.blockConversion = price;
- })
- ).subscribe();
+ this.currencyChangeSubscription?.unsubscribe();
+ this.currencyChangeSubscription = this.stateService.fiatCurrency$.pipe(
+ switchMap((currency) => {
+ return changes.line?.currentValue.timestamp ? this.priceService.getBlockPrice$(changes.line?.currentValue.timestamp, true, currency).pipe(
+ tap((price) => this.blockConversion = price),
+ ) : of(undefined);
+ })
+ ).subscribe();
}
if (changes.cursorPosition && changes.cursorPosition.currentValue) {
diff --git a/frontend/src/app/services/price.service.ts b/frontend/src/app/services/price.service.ts
index 41f928343..7a2f42c95 100644
--- a/frontend/src/app/services/price.service.ts
+++ b/frontend/src/app/services/price.service.ts
@@ -98,6 +98,8 @@ export class PriceService {
lastQueriedTimestamp: number;
lastPriceHistoryUpdate: number;
+ lastQueriedCurrency: string;
+ lastQueriedHistoricalCurrency: string;
historicalPrice: ConversionDict = {
prices: null,
@@ -130,7 +132,7 @@ export class PriceService {
};
}
- getBlockPrice$(blockTimestamp: number, singlePrice = false): Observable {
+ getBlockPrice$(blockTimestamp: number, singlePrice = false, currency: string): Observable {
if (this.stateService.env.BASE_MODULE !== 'mempool' || !this.stateService.env.HISTORICAL_PRICE) {
return of(undefined);
}
@@ -142,9 +144,10 @@ export class PriceService {
* query a different timestamp than the last one
*/
if (singlePrice) {
- if (!this.singlePriceObservable$ || (this.singlePriceObservable$ && blockTimestamp !== this.lastQueriedTimestamp)) {
- this.singlePriceObservable$ = this.apiService.getHistoricalPrice$(blockTimestamp).pipe(shareReplay());
+ if (!this.singlePriceObservable$ || (this.singlePriceObservable$ && (blockTimestamp !== this.lastQueriedTimestamp || currency !== this.lastQueriedCurrency))) {
+ this.singlePriceObservable$ = this.apiService.getHistoricalPrice$(blockTimestamp, currency).pipe(shareReplay());
this.lastQueriedTimestamp = blockTimestamp;
+ this.lastQueriedCurrency = currency;
}
return this.singlePriceObservable$.pipe(
@@ -177,9 +180,10 @@ export class PriceService {
* Query all price history only once. The observable is invalidated after 1 hour
*/
else {
- if (!this.priceObservable$ || (this.priceObservable$ && (now - this.lastPriceHistoryUpdate > 3600))) {
- this.priceObservable$ = this.apiService.getHistoricalPrice$(undefined).pipe(shareReplay());
+ if (!this.priceObservable$ || (this.priceObservable$ && (now - this.lastPriceHistoryUpdate > 3600 || currency !== this.lastQueriedHistoricalCurrency))) {
+ this.priceObservable$ = this.apiService.getHistoricalPrice$(undefined, currency).pipe(shareReplay());
this.lastPriceHistoryUpdate = new Date().getTime() / 1000;
+ this.lastQueriedHistoricalCurrency = currency;
}
return this.priceObservable$.pipe(