Merge branch 'master' into mononaut/accelerator-audit-pools

This commit is contained in:
wiz
2024-03-16 17:19:56 +09:00
committed by GitHub
31 changed files with 996 additions and 101 deletions

View File

@@ -50,9 +50,8 @@
</td>
<td class="status text-right">
<span *ngIf="acceleration.status === 'accelerating'" class="badge badge-warning" i18n="accelerator.pending">Pending</span>
<span *ngIf="acceleration.status === 'mined'" class="badge badge-info" i18n="transaction.rbf.mined">Mined</span>
<span *ngIf="acceleration.status === 'completed'" class="badge badge-success" i18n="">Completed</span>
<span *ngIf="acceleration.status === 'failed'" class="badge badge-danger" i18n="accelerator.canceled">Canceled</span>
<span *ngIf="acceleration.status.includes('completed')" class="badge badge-success" i18n="">Completed <span *ngIf="acceleration.status === 'completed_provisional'">🔄</span></span>
<span *ngIf="acceleration.status.includes('failed')" class="badge badge-danger" i18n="accelerator.canceled">Failed <span *ngIf="acceleration.status === 'failed_provisional'">🔄</span></span>
</td>
<td class="date text-right" *ngIf="!this.widget">
<app-time kind="since" [time]="acceleration.added" [fastRender]="true"></app-time>

View File

@@ -74,7 +74,7 @@ export class AcceleratorDashboardComponent implements OnInit {
this.minedAccelerations$ = this.accelerations$.pipe(
map(accelerations => {
return accelerations.filter(acc => ['mined', 'completed'].includes(acc.status));
return accelerations.filter(acc => ['completed_provisional', 'completed'].includes(acc.status));
})
);
@@ -103,7 +103,7 @@ export class AcceleratorDashboardComponent implements OnInit {
}
const accelerationsByBlock: { [ hash: string ]: Acceleration[] } = {};
for (const acceleration of accelerations) {
if (['mined', 'completed'].includes(acceleration.status) && acceleration.pools.includes(blockMap[acceleration.blockHash]?.extras.pool.id)) {
if (['completed_provisional', 'failed_provisional', 'completed'].includes(acceleration.status) && acceleration.pools.includes(blockMap[acceleration.blockHash]?.extras.pool.id)) {
if (!accelerationsByBlock[acceleration.blockHash]) {
accelerationsByBlock[acceleration.blockHash] = [];
}

View File

@@ -335,7 +335,7 @@
</div>
<div class="clearfix"></div>
<app-transactions-list [transactions]="transactions" [paginated]="true"></app-transactions-list>
<app-transactions-list [transactions]="transactions" [paginated]="true" [blockTime]="block.timestamp"></app-transactions-list>
<ng-template [ngIf]="transactionsError">
<div class="text-center">

View File

@@ -533,9 +533,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;
})

View File

@@ -35,6 +35,11 @@ export class FiatSelectorComponent implements OnInit {
this.stateService.fiatCurrency$.subscribe((fiat) => {
this.fiatForm.get('fiat')?.setValue(fiat);
});
if (!this.stateService.env.ADDITIONAL_CURRENCIES) {
this.currencies = this.currencies.filter((currency: any) => {
return ['AUD', 'CAD', 'EUR', 'JPY', 'GBP', 'CHF', 'USD'].includes(currency[0]);
});
}
}
changeFiat() {

View File

@@ -533,7 +533,7 @@
<tr *ngIf="isMobile && (network === 'liquid' || network === 'liquidtestnet' || !featuresEnabled || network === '')"></tr>
<tr>
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
<td>{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="blockConversion" [value]="tx.fee"></app-fiat></span></td>
<td>{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span></td>
</tr>
<tr>
<td i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>

View File

@@ -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;
@@ -108,7 +109,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
hideFlow: boolean = this.stateService.hideFlow.value;
overrideFlowPreference: boolean = null;
flowEnabled: boolean;
blockConversion: Price;
tooltipPosition: { x: number, y: number };
isMobile: boolean;
@@ -281,7 +281,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
})
).subscribe((accelerationHistory) => {
for (const acceleration of accelerationHistory) {
if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'mined') && acceleration.feePaid > 0) {
if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional')) {
acceleration.acceleratedFee = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + acceleration.feePaid - acceleration.baseFee - acceleration.vsizeFee);
this.accelerationInfo = acceleration;
}
@@ -493,10 +493,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();
@@ -518,7 +520,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
block_time: block.timestamp,
};
this.stateService.markBlock$.next({ blockHeight: block.height });
if (this.tx.acceleration || (this.accelerationInfo && ['accelerating', 'mined', 'completed'].includes(this.accelerationInfo.status))) {
if (this.tx.acceleration || (this.accelerationInfo && ['accelerating', 'completed_provisional', 'completed'].includes(this.accelerationInfo.status))) {
this.audioService.playSound('wind-chimes-harp-ascend');
} else {
this.audioService.playSound('magic');
@@ -810,6 +812,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.mempoolBlocksSubscription.unsubscribe();
this.blocksSubscription.unsubscribe();
this.miningSubscription?.unsubscribe();
this.currencyChangeSubscription?.unsubscribe();
this.leaveTransaction();
}
}

View File

@@ -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<BlockExtended>;
outspendsSubscription: Subscription;
currencyChangeSubscription: Subscription;
currency: string;
refreshOutspends$: ReplaySubject<string[]> = new ReplaySubject();
refreshChannels$: ReplaySubject<string[]> = new ReplaySubject();
showDetails$ = new BehaviorSubject<boolean>(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();
}
}

View File

@@ -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) {