Merge branch 'master' into hunicus/txacc-faq

This commit is contained in:
hunicus 2024-04-08 14:00:00 +09:00 committed by GitHub
commit 6822c3a04b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
56 changed files with 16086 additions and 5825 deletions

View File

@ -103,7 +103,7 @@ In particular, make sure:
- the correct Bitcoin Core RPC credentials are specified in `CORE_RPC` - the correct Bitcoin Core RPC credentials are specified in `CORE_RPC`
- the correct `BACKEND` is specified in `MEMPOOL`: - the correct `BACKEND` is specified in `MEMPOOL`:
- "electrum" if you're using [romanz/electrs](https://github.com/romanz/electrs) or [cculianu/Fulcrum](https://github.com/cculianu/Fulcrum) - "electrum" if you're using [romanz/electrs](https://github.com/romanz/electrs) or [cculianu/Fulcrum](https://github.com/cculianu/Fulcrum)
- "esplora" if you're using [Blockstream/electrs](https://github.com/Blockstream/electrs) - "esplora" if you're using [mempool/electrs](https://github.com/mempool/electrs)
- "none" if you're not using any Electrum Server - "none" if you're not using any Electrum Server
### 6. Run Mempool Backend ### 6. Run Mempool Backend

View File

@ -373,6 +373,21 @@ export class Common {
].includes(pubkey); ].includes(pubkey);
} }
static isInscription(vin, flags): bigint {
// in taproot, if the last witness item begins with 0x50, it's an annex
const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50');
// script spends have more than one witness item, not counting the annex (if present)
if (vin.witness.length > (hasAnnex ? 2 : 1)) {
// the script itself is the second-to-last witness item, not counting the annex
const asm = vin.inner_witnessscript_asm || transactionUtils.convertScriptSigAsm(vin.witness[vin.witness.length - (hasAnnex ? 3 : 2)]);
// inscriptions smuggle data within an 'OP_0 OP_IF ... OP_ENDIF' envelope
if (asm?.includes('OP_0 OP_IF')) {
flags |= TransactionFlags.inscription;
}
}
return flags;
}
static getTransactionFlags(tx: TransactionExtended): number { static getTransactionFlags(tx: TransactionExtended): number {
let flags = tx.flags ? BigInt(tx.flags) : 0n; let flags = tx.flags ? BigInt(tx.flags) : 0n;
@ -409,30 +424,31 @@ export class Common {
if (vin.sequence < 0xfffffffe) { if (vin.sequence < 0xfffffffe) {
rbf = true; rbf = true;
} }
switch (vin.prevout?.scriptpubkey_type) { if (vin.prevout?.scriptpubkey_type) {
case 'p2pk': flags |= TransactionFlags.p2pk; break; switch (vin.prevout?.scriptpubkey_type) {
case 'multisig': flags |= TransactionFlags.p2ms; break; case 'p2pk': flags |= TransactionFlags.p2pk; break;
case 'p2pkh': flags |= TransactionFlags.p2pkh; break; case 'multisig': flags |= TransactionFlags.p2ms; break;
case 'p2sh': flags |= TransactionFlags.p2sh; break; case 'p2pkh': flags |= TransactionFlags.p2pkh; break;
case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break; case 'p2sh': flags |= TransactionFlags.p2sh; break;
case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break; case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break;
case 'v1_p2tr': { case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break;
if (!vin.witness?.length) { case 'v1_p2tr': {
throw new Error('Taproot input missing witness data'); if (!vin.witness?.length) {
} throw new Error('Taproot input missing witness data');
flags |= TransactionFlags.p2tr;
// in taproot, if the last witness item begins with 0x50, it's an annex
const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50');
// script spends have more than one witness item, not counting the annex (if present)
if (vin.witness.length > (hasAnnex ? 2 : 1)) {
// the script itself is the second-to-last witness item, not counting the annex
const asm = vin.inner_witnessscript_asm || transactionUtils.convertScriptSigAsm(vin.witness[vin.witness.length - (hasAnnex ? 3 : 2)]);
// inscriptions smuggle data within an 'OP_0 OP_IF ... OP_ENDIF' envelope
if (asm?.includes('OP_0 OP_IF')) {
flags |= TransactionFlags.inscription;
} }
flags |= TransactionFlags.p2tr;
flags = Common.isInscription(vin, flags);
} break;
}
} else {
// no prevouts, optimistically check witness-bearing inputs
if (vin.witness?.length >= 2) {
try {
flags = Common.isInscription(vin, flags);
} catch {
// witness script parsing will fail if this isn't really a taproot output
} }
} break; }
} }
// sighash flags // sighash flags

View File

@ -343,7 +343,7 @@ class MempoolBlocks {
if (txid in mempool) { if (txid in mempool) {
mempool[txid].cpfpDirty = (rate !== mempool[txid].effectiveFeePerVsize); mempool[txid].cpfpDirty = (rate !== mempool[txid].effectiveFeePerVsize);
mempool[txid].effectiveFeePerVsize = rate; mempool[txid].effectiveFeePerVsize = rate;
mempool[txid].cpfpChecked = false; mempool[txid].cpfpChecked = true;
} }
} }

View File

@ -739,7 +739,7 @@ class WebsocketHandler {
accelerated: mempoolTx.acceleration || undefined, accelerated: mempoolTx.acceleration || undefined,
} }
}; };
if (!mempoolTx.cpfpChecked) { if (!mempoolTx.cpfpChecked && !mempoolTx.acceleration) {
calculateCpfp(mempoolTx, newMempool); calculateCpfp(mempoolTx, newMempool);
} }
if (mempoolTx.cpfpDirty) { if (mempoolTx.cpfpDirty) {

3
contributors/daweilv.txt Normal file
View File

@ -0,0 +1,3 @@
I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of April 7, 2024.
Signed: daweilv

View File

@ -206,7 +206,7 @@
</ng-container> </ng-container>
<!-- LOGIN CTA --> <!-- LOGIN CTA -->
<ng-container *ngIf="stateService.isMempoolSpaceBuild && !isLoggedIn()"> <ng-container *ngIf="stateService.isMempoolSpaceBuild && !isLoggedIn() && paymentType === 'bitcoin'">
<tr class="group-first group-last" style="border-top: 1px dashed grey"> <tr class="group-first group-last" style="border-top: 1px dashed grey">
<td class="item"></td> <td class="item"></td>
<td class="amt"></td> <td class="amt"></td>
@ -229,13 +229,22 @@
</div> </div>
</div> </div>
<div class="row mb-3" *ngIf="isLoggedIn()"> <div class="row mb-3" *ngIf="isLoggedIn() && paymentType === 'bitcoin'">
<div class="col"> <div class="col">
<div class="d-flex justify-content-end" *ngIf="user && estimate.hasAccess"> <div class="d-flex justify-content-end" *ngIf="user && estimate.hasAccess">
<button class="btn btn-sm btn-primary btn-success" style="width: 150px" (click)="accelerate()" i18n="transaction.accelerate|Accelerate button label">Accelerate</button> <button class="btn btn-sm btn-primary btn-success" style="width: 150px" (click)="accelerate()" i18n="transaction.accelerate|Accelerate button label">Accelerate</button>
</div> </div>
</div> </div>
</div> </div>
<div class="row d-flex justify-content-end align-items-center mr-1" style="height: 48px" *ngIf="!hideCashApp && paymentType === 'cashapp'">
<div [style]="showSpinner ? 'opacity: 0' : 'opacity: 1'" class="p-2">Accelerate with</div>
<div id="cash-app-pay" style="max-width: 320px" [style]="showSpinner ? 'opacity: 0' : 'opacity: 1'"></div>
<div *ngIf="showSpinner" class="d-flex align-items-center">
<span class="mr-2">Loading</span>
<div class="spinner-border text-light" style="width: 25px; height: 25px"></div>
</div>
</div>
</div> </div>
</ng-container> </ng-container>

View File

@ -1,5 +1,4 @@
import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef } from '@angular/core'; import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges, HostListener, ChangeDetectorRef } from '@angular/core';
import { ApiService } from '../../services/api.service';
import { Subscription, catchError, of, tap } from 'rxjs'; import { Subscription, catchError, of, tap } from 'rxjs';
import { StorageService } from '../../services/storage.service'; import { StorageService } from '../../services/storage.service';
import { Transaction } from '../../interfaces/electrs.interface'; import { Transaction } from '../../interfaces/electrs.interface';
@ -63,18 +62,44 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
maxRateOptions: RateOption[] = []; maxRateOptions: RateOption[] = [];
// Cashapp payment
paymentType: 'bitcoin' | 'cashapp' = 'bitcoin';
cashAppSubscription: Subscription;
conversionsSubscription: Subscription;
payments: any;
showSpinner = false;
square: any;
cashAppPay: any;
hideCashApp = false;
constructor( constructor(
public stateService: StateService, public stateService: StateService,
private servicesApiService: ServicesApiServices, private servicesApiService: ServicesApiServices,
private storageService: StorageService, private storageService: StorageService,
private audioService: AudioService, private audioService: AudioService,
private cd: ChangeDetectorRef private cd: ChangeDetectorRef
) { } ) {
if (this.stateService.ref === 'https://cash.app/') {
this.insertSquare();
}
}
ngOnDestroy(): void { ngOnDestroy(): void {
if (this.estimateSubscription) { if (this.estimateSubscription) {
this.estimateSubscription.unsubscribe(); this.estimateSubscription.unsubscribe();
} }
if (this.cashAppPay) {
this.cashAppPay.destroy();
}
}
ngOnInit() {
if (this.stateService.ref === 'https://cash.app/') {
this.paymentType = 'cashapp';
this.stateService.ref = '';
} else {
this.paymentType = 'bitcoin';
}
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
@ -83,69 +108,87 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
} }
} }
ngOnInit() { ngAfterViewInit() {
if (this.paymentType === 'cashapp') {
this.showSpinner = true;
}
this.user = this.storageService.getAuth()?.user ?? null; this.user = this.storageService.getAuth()?.user ?? null;
this.estimateSubscription = this.servicesApiService.estimate$(this.tx.txid).pipe( this.servicesApiService.setupSquare$().subscribe(ids => {
tap((response) => { this.square = {
if (response.status === 204) { appId: ids.squareAppId,
this.estimate = undefined; locationId: ids.squareLocationId
this.error = `cannot_accelerate_tx`; };
this.scrollToPreviewWithTimeout('mempoolError', 'center'); this.estimateSubscription = this.servicesApiService.estimate$(this.tx.txid).pipe(
this.estimateSubscription.unsubscribe(); tap((response) => {
} else { if (response.status === 204) {
this.estimate = response.body; this.estimate = undefined;
if (!this.estimate) {
this.error = `cannot_accelerate_tx`; this.error = `cannot_accelerate_tx`;
this.scrollToPreviewWithTimeout('mempoolError', 'center'); this.scrollToPreviewWithTimeout('mempoolError', 'center');
this.estimateSubscription.unsubscribe(); this.estimateSubscription.unsubscribe();
} } else {
this.estimate = response.body;
if (this.estimate.hasAccess === true && this.estimate.userBalance <= 0) { if (!this.estimate) {
if (this.isLoggedIn()) { this.error = `cannot_accelerate_tx`;
this.error = `not_enough_balance`;
this.scrollToPreviewWithTimeout('mempoolError', 'center'); this.scrollToPreviewWithTimeout('mempoolError', 'center');
this.estimateSubscription.unsubscribe();
}
if (this.paymentType === 'cashapp') {
this.estimate.userBalance = 999999999;
this.estimate.enoughBalance = true;
}
if (this.estimate.hasAccess === true && this.estimate.userBalance <= 0) {
if (this.isLoggedIn()) {
this.error = `not_enough_balance`;
this.scrollToPreviewWithTimeout('mempoolError', 'center');
}
}
this.hasAncestors = this.estimate.txSummary.ancestorCount > 1;
// Make min extra fee at least 50% of the current tx fee
this.minExtraCost = nextRoundNumber(Math.max(this.estimate.cost * 2, this.estimate.txSummary.effectiveFee));
this.maxRateOptions = [1, 2, 4].map((multiplier, index) => {
return {
fee: this.minExtraCost * multiplier,
rate: (this.estimate.txSummary.effectiveFee + (this.minExtraCost * multiplier)) / this.estimate.txSummary.effectiveVsize,
index,
};
});
this.minBidAllowed = this.minExtraCost * MIN_BID_RATIO;
this.defaultBid = this.minExtraCost * DEFAULT_BID_RATIO;
this.maxBidAllowed = this.minExtraCost * MAX_BID_RATIO;
this.userBid = this.defaultBid;
if (this.userBid < this.minBidAllowed) {
this.userBid = this.minBidAllowed;
} else if (this.userBid > this.maxBidAllowed) {
this.userBid = this.maxBidAllowed;
}
this.maxCost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee;
if (!this.error) {
this.scrollToPreview('acceleratePreviewAnchor', 'start');
if (this.paymentType === 'cashapp') {
this.setupSquare();
}
} }
} }
}),
this.hasAncestors = this.estimate.txSummary.ancestorCount > 1; catchError((response) => {
this.estimate = undefined;
// Make min extra fee at least 50% of the current tx fee this.error = response.error;
this.minExtraCost = nextRoundNumber(Math.max(this.estimate.cost * 2, this.estimate.txSummary.effectiveFee)); this.scrollToPreviewWithTimeout('mempoolError', 'center');
this.estimateSubscription.unsubscribe();
this.maxRateOptions = [1, 2, 4].map((multiplier, index) => { return of(null);
return { })
fee: this.minExtraCost * multiplier, ).subscribe();
rate: (this.estimate.txSummary.effectiveFee + (this.minExtraCost * multiplier)) / this.estimate.txSummary.effectiveVsize, });
index,
};
});
this.minBidAllowed = this.minExtraCost * MIN_BID_RATIO;
this.defaultBid = this.minExtraCost * DEFAULT_BID_RATIO;
this.maxBidAllowed = this.minExtraCost * MAX_BID_RATIO;
this.userBid = this.defaultBid;
if (this.userBid < this.minBidAllowed) {
this.userBid = this.minBidAllowed;
} else if (this.userBid > this.maxBidAllowed) {
this.userBid = this.maxBidAllowed;
}
this.maxCost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee;
if (!this.error) {
this.scrollToPreview('acceleratePreviewAnchor', 'start');
}
}
}),
catchError((response) => {
this.estimate = undefined;
this.error = response.error;
this.scrollToPreviewWithTimeout('mempoolError', 'center');
this.estimateSubscription.unsubscribe();
return of(null);
})
).subscribe();
} }
/** /**
@ -216,4 +259,112 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
onResize(): void { onResize(): void {
this.isMobile = window.innerWidth <= 767.98; this.isMobile = window.innerWidth <= 767.98;
} }
/**
* CashApp payment
*/
setupSquare() {
const init = () => {
this.initSquare();
};
//@ts-ignore
if (!window.Square) {
console.warn('Square.js failed to load properly. Retrying in 1 second.');
setTimeout(init, 1000);
} else {
init();
}
}
async initSquare(): Promise<void> {
try {
//@ts-ignore
this.payments = window.Square.payments(this.square.appId, this.square.locationId)
await this.requestCashAppPayment();
} catch (e) {
console.error(e);
this.error = 'Error loading Square Payments';
return;
}
}
async requestCashAppPayment() {
if (this.cashAppSubscription) {
this.cashAppSubscription.unsubscribe();
}
if (this.conversionsSubscription) {
this.conversionsSubscription.unsubscribe();
}
this.hideCashApp = false;
this.conversionsSubscription = this.stateService.conversions$.subscribe(
async (conversions) => {
const maxCostUsd = this.maxCost / 100_000_000 * conversions.USD;
const paymentRequest = this.payments.paymentRequest({
countryCode: 'US',
currencyCode: 'USD',
total: {
amount: maxCostUsd.toString(),
label: 'Total',
pending: true,
productUrl: `https://mempool.space/tx/${this.tx.txid}`,
}
});
this.cashAppPay = await this.payments.cashAppPay(paymentRequest, {
redirectURL: `https://mempool.space/tx/${this.tx.txid}`,
referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`,
});
await this.cashAppPay.attach('#cash-app-pay');
this.showSpinner = false;
const that = this;
this.cashAppPay.addEventListener('ontokenization', function (event) {
const { tokenResult, error } = event.detail;
if (error) {
this.error = error;
} else if (tokenResult.status === 'OK') {
that.hideCashApp = true;
that.accelerationSubscription = that.servicesApiService.accelerateWithCashApp$(
that.tx.txid,
that.userBid,
tokenResult.token,
tokenResult.details.cashAppPay.cashtag,
tokenResult.details.cashAppPay.referenceId
).subscribe({
next: () => {
that.audioService.playSound('ascend-chime-cartoon');
that.showSuccess = true;
that.scrollToPreviewWithTimeout('successAlert', 'center');
that.estimateSubscription.unsubscribe();
},
error: (response) => {
if (response.status === 403 && response.error === 'not_available') {
that.error = 'waitlisted';
} else {
that.error = response.error;
}
that.scrollToPreviewWithTimeout('mempoolError', 'center');
}
});
}
});
}
);
}
insertSquare(): void {
let statsUrl = 'https://sandbox.web.squarecdn.com/v1/square.js';
if (document.location.hostname === 'mempool-staging.tk7.mempool.space' || document.location.hostname === 'mempool.space') {
statsUrl = 'https://web.squarecdn.com/v1/square.js';
}
(function() {
const d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
// @ts-ignore
g.type='text/javascript'; g.src=statsUrl; s.parentNode.insertBefore(g, s);
})();
}
} }

View File

@ -1,5 +1,5 @@
<div class="container-lg widget-container" [class.widget]="widget" [class.full-height]="!widget"> <div class="container-lg widget-container" [class.widget]="widget" [class.full-height]="!widget">
<h1 *ngIf="!widget" class="float-left" i18n="master-page.blocks">Accelerations</h1> <h1 *ngIf="!widget" class="float-left" i18n="accelerator.accelerations">Accelerations</h1>
<div *ngIf="!widget && isLoading" class="spinner-border ml-3" role="status"></div> <div *ngIf="!widget && isLoading" class="spinner-border ml-3" role="status"></div>
<div class="clearfix"></div> <div class="clearfix"></div>

View File

@ -38,7 +38,7 @@
<div class="card"> <div class="card">
<div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2"> <div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2">
<a class="title-link" href="" [routerLink]="['/mempool-block/0' | relativeUrl]"> <a class="title-link" href="" [routerLink]="['/mempool-block/0' | relativeUrl]">
<h5 class="card-title d-inline" i18n="dashboard.mempool-goggles-accelerations">Mempool Goggles&trade; : Accelerations</h5> <h5 class="card-title d-inline">Mempool Goggles&trade; : <ng-container i18n="accelerator.accelerations">Accelerations</ng-container></h5>
<span>&nbsp;</span> <span>&nbsp;</span>
<fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: 'text-top'; font-size: 13px; color: #4a68b9"></fa-icon> <fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: 'text-top'; font-size: 13px; color: #4a68b9"></fa-icon>
</a> </a>

View File

@ -11,6 +11,7 @@ import TxView from '../../block-overview-graph/tx-view';
import { feeLevels, mempoolFeeColors } from '../../../app.constants'; import { feeLevels, mempoolFeeColors } from '../../../app.constants';
import { ServicesApiServices } from '../../../services/services-api.service'; import { ServicesApiServices } from '../../../services/services-api.service';
import { detectWebGL } from '../../../shared/graphs.utils'; import { detectWebGL } from '../../../shared/graphs.utils';
import { AudioService } from '../../../services/audio.service';
const acceleratedColor: Color = hexToColor('8F5FF6'); const acceleratedColor: Color = hexToColor('8F5FF6');
const normalColors = mempoolFeeColors.map(hex => hexToColor(hex.slice(0,6) + '5F')); const normalColors = mempoolFeeColors.map(hex => hexToColor(hex.slice(0,6) + '5F'));
@ -32,6 +33,8 @@ export class AcceleratorDashboardComponent implements OnInit {
minedAccelerations$: Observable<Acceleration[]>; minedAccelerations$: Observable<Acceleration[]>;
loadingBlocks: boolean = true; loadingBlocks: boolean = true;
webGlEnabled = true; webGlEnabled = true;
seen: Set<string> = new Set();
firstLoad = true;
graphHeight: number = 300; graphHeight: number = 300;
@ -40,6 +43,7 @@ export class AcceleratorDashboardComponent implements OnInit {
private ogService: OpenGraphService, private ogService: OpenGraphService,
private websocketService: WebsocketService, private websocketService: WebsocketService,
private serviceApiServices: ServicesApiServices, private serviceApiServices: ServicesApiServices,
private audioService: AudioService,
private stateService: StateService, private stateService: StateService,
@Inject(PLATFORM_ID) private platformId: Object, @Inject(PLATFORM_ID) private platformId: Object,
) { ) {
@ -61,6 +65,15 @@ export class AcceleratorDashboardComponent implements OnInit {
}), }),
); );
}), }),
tap(accelerations => {
if (!this.firstLoad && accelerations.some(acc => !this.seen.has(acc.txid))) {
this.audioService.playSound('bright-harmony');
}
for(const acc of accelerations) {
this.seen.add(acc.txid);
}
this.firstLoad = false;
}),
share(), share(),
); );

View File

@ -6,6 +6,7 @@ import { ChainStats } from '../../interfaces/electrs.interface';
import { ElectrsApiService } from '../../services/electrs-api.service'; import { ElectrsApiService } from '../../services/electrs-api.service';
import { AmountShortenerPipe } from '../../shared/pipes/amount-shortener.pipe'; import { AmountShortenerPipe } from '../../shared/pipes/amount-shortener.pipe';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
@Component({ @Component({
selector: 'app-address-graph', selector: 'app-address-graph',
@ -46,6 +47,7 @@ export class AddressGraphComponent implements OnChanges {
private router: Router, private router: Router,
private amountShortenerPipe: AmountShortenerPipe, private amountShortenerPipe: AmountShortenerPipe,
private cd: ChangeDetectorRef, private cd: ChangeDetectorRef,
private relativeUrlPipe: RelativeUrlPipe,
) {} ) {}
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(changes: SimpleChanges): void {
@ -122,7 +124,7 @@ export class AddressGraphComponent implements OnChanges {
</div> </div>
<span>${date}</span> <span>${date}</span>
</div> </div>
`; `;
}.bind(this) }.bind(this)
}, },
xAxis: { xAxis: {
@ -178,7 +180,7 @@ export class AddressGraphComponent implements OnChanges {
onChartClick(e) { onChartClick(e) {
if (this.hoverData?.length && this.hoverData[0]?.[2]?.txid) { if (this.hoverData?.length && this.hoverData[0]?.[2]?.txid) {
this.router.navigate(['/tx/', this.hoverData[0][2].txid]); this.router.navigate([this.relativeUrlPipe.transform('/tx/'), this.hoverData[0][2].txid]);
} }
} }

View File

@ -20,8 +20,7 @@
<ng-template [ngIf]="(network === 'liquid' || network === 'liquidtestnet') && (satoshis === undefined || satoshis === null)" [ngIfElse]="default"> <ng-template [ngIf]="(network === 'liquid' || network === 'liquidtestnet') && (satoshis === undefined || satoshis === null)" [ngIfElse]="default">
<span i18n="shared.confidential">Confidential</span> <span i18n="shared.confidential">Confidential</span>
</ng-template> </ng-template>
<ng-template #default> <ng-template #default>&lrm;{{ addPlus && satoshis >= 0 ? '+' : '' }}{{ satoshis / 100000000 | number : digitsInfo }}
&lrm;{{ addPlus && satoshis >= 0 ? '+' : '' }}{{ satoshis / 100000000 | number : digitsInfo }}
<span class="symbol"><ng-template [ngIf]="network === 'liquid' && !forceBtc">L-</ng-template> <span class="symbol"><ng-template [ngIf]="network === 'liquid' && !forceBtc">L-</ng-template>
<ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template> <ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template>
<ng-template [ngIf]="network === 'testnet'">t</ng-template> <ng-template [ngIf]="network === 'testnet'">t</ng-template>

View File

@ -133,6 +133,10 @@ export function ageColorFunction(
auditColors: { [status: string]: Color } = defaultAuditColors, auditColors: { [status: string]: Color } = defaultAuditColors,
relativeTime?: number, relativeTime?: number,
): Color { ): Color {
if (tx.acc || tx.status === 'accelerated') {
return auditColors.accelerated;
}
const color = defaultColorFunction(tx, colors, auditColors, relativeTime); const color = defaultColorFunction(tx, colors, auditColors, relativeTime);
const ageLevel = (!tx.time ? 0 : (0.8 * Math.tanh((1 / 15) * Math.log2((Math.max(1, 0.6 * ((relativeTime - tx.time) - 60))))))); const ageLevel = (!tx.time ? 0 : (0.8 * Math.tanh((1 / 15) * Math.log2((Math.max(1, 0.6 * ((relativeTime - tx.time) - 60)))))));

View File

@ -7,7 +7,6 @@ import { EnterpriseService } from '../../services/enterprise.service';
import { NavigationService } from '../../services/navigation.service'; import { NavigationService } from '../../services/navigation.service';
import { MenuComponent } from '../menu/menu.component'; import { MenuComponent } from '../menu/menu.component';
import { StorageService } from '../../services/storage.service'; import { StorageService } from '../../services/storage.service';
import { ApiService } from '../../services/api.service';
@Component({ @Component({
selector: 'app-master-page', selector: 'app-master-page',
@ -45,7 +44,6 @@ export class MasterPageComponent implements OnInit, OnDestroy {
private enterpriseService: EnterpriseService, private enterpriseService: EnterpriseService,
private navigationService: NavigationService, private navigationService: NavigationService,
private storageService: StorageService, private storageService: StorageService,
private apiService: ApiService,
private router: Router, private router: Router,
) { } ) { }

View File

@ -40,64 +40,39 @@
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
<ng-template [ngIf]="!isLoadingTx && !error"> @if (!error) {
<div class="box">
<ng-template [ngIf]="tx?.status?.confirmed" [ngIfElse]="unconfirmedTemplate"> <div class="row">
@if (isMobile) {
<div class="box">
<div class="row">
<div class="col-sm"> <div class="col-sm">
<table class="table table-borderless table-striped"> <table class="table table-borderless table-striped">
<tbody> <tbody>
<tr> <ng-container *ngTemplateOutlet="detailsLeft"></ng-container>
<td i18n="block.timestamp">Timestamp</td> <ng-container *ngTemplateOutlet="detailsRight"></ng-container>
<td> </tbody>
&lrm;{{ tx.status.block_time * 1000 | date:'yyyy-MM-dd HH:mm' }} </table>
<div class="lg-inline"> </div>
<i class="symbol">(<app-time kind="since" [time]="tx.status.block_time" [fastRender]="true"></app-time>)</i> } @else {
</div> <div class="col-sm">
</td> <table class="table table-borderless table-striped">
</tr> <tbody>
<ng-template [ngIf]="transactionTime > 0"> <ng-container *ngTemplateOutlet="detailsLeft"></ng-container>
<tr>
<td i18n="transaction.confirmed|Transaction Confirmed state">Confirmed</td>
<td><app-time kind="span" [time]="tx.status.block_time - transactionTime" [fastRender]="true" [relative]="true"></app-time></td>
</tr>
</ng-template>
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet' && featuresEnabled">
<td class="td-width" i18n="transaction.features|Transaction features">Features</td>
<td>
<app-tx-features [tx]="tx"></app-tx-features>
</td>
</tr>
<tr *ngIf="network === '' && auditStatus">
<td class="td-width" i18n="block.toggle-audit|Toggle Audit">Audit</td>
<td *ngIf="pool" class="wrap-cell">
<ng-container>
<span *ngIf="auditStatus.coinbase; else expected" class="badge badge-primary mr-1" i18n="transactions-list.coinbase">Coinbase</span>
<ng-template #expected><span *ngIf="auditStatus.expected; else seen" class="badge badge-success mr-1" i18n-ngbTooltip="Expected in block tooltip" ngbTooltip="This transaction was projected to be included in the block" placement="bottom" i18n="tx-features.tag.expected|Expected in Block">Expected in Block</span></ng-template>
<ng-template #seen><span *ngIf="auditStatus.seen; else notSeen" class="badge badge-success mr-1" i18n-ngbTooltip="Seen in mempool tooltip" ngbTooltip="This transaction was seen in the mempool prior to mining" placement="bottom" i18n="tx-features.tag.seen|Seen in Mempool">Seen in Mempool</span></ng-template>
<ng-template #notSeen><span *ngIf="!auditStatus.conflict" class="badge badge-warning mr-1" i18n-ngbTooltip="Not seen in mempool tooltip" ngbTooltip="This transaction was missing from our mempool prior to mining" placement="bottom" i18n="tx-features.tag.not-seen|Not seen in Mempool">Not seen in Mempool</span></ng-template>
<span *ngIf="auditStatus.added" class="badge badge-warning mr-1" i18n-ngbTooltip="Added transaction tooltip" ngbTooltip="This transaction may have been added out-of-band" placement="bottom" i18n="tx-features.tag.added|Added">Added</span>
<span *ngIf="auditStatus.prioritized" class="badge badge-warning mr-1" i18n-ngbTooltip="Prioritized transaction tooltip" ngbTooltip="This transaction may have been prioritized out-of-band" placement="bottom" i18n="tx-features.tag.prioritized|Prioritized">Prioritized</span>
<span *ngIf="auditStatus.conflict" class="badge badge-warning mr-1" i18n-ngbTooltip="Conflict in mempool tooltip" ngbTooltip="This transaction conflicted with another version in our mempool" placement="bottom" i18n="tx-features.tag.conflict|Conflict">Conflict</span>
</ng-container>
</td>
<td *ngIf="!pool">
<span class="skeleton-loader"></span>
</td>
</tr>
<ng-container *ngTemplateOutlet="goggles"></ng-container>
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="col-sm"> <div class="col-sm">
<ng-container *ngTemplateOutlet="feeTable"></ng-container> <table class="table table-borderless table-striped">
<tbody>
<ng-container *ngTemplateOutlet="detailsRight"></ng-container>
</tbody>
</table>
</div> </div>
</div> }
</div> </div>
</div>
}
</ng-template> <ng-template [ngIf]="!isLoadingTx && !error">
<!-- Accelerator --> <!-- Accelerator -->
<ng-container *ngIf="!tx?.status?.confirmed && showAccelerationSummary"> <ng-container *ngIf="!tx?.status?.confirmed && showAccelerationSummary">
@ -113,69 +88,6 @@
</div> </div>
</ng-container> </ng-container>
<ng-template #unconfirmedTemplate>
<div class="box">
<div class="row">
<div class="col-sm">
<table class="table table-borderless table-striped">
<tbody>
<ng-template [ngIf]="transactionTime !== 0">
<tr *ngIf="transactionTime === -1; else firstSeenTmpl">
<td><span class="skeleton-loader"></span></td>
<td><span class="skeleton-loader"></span></td>
</tr>
<ng-template #firstSeenTmpl>
<tr>
<td i18n="transaction.first-seen|Transaction first seen">First seen</td>
<td><i><app-time kind="since" [time]="transactionTime" [fastRender]="true"></app-time></i></td>
</tr>
</ng-template>
</ng-template>
<tr *ngIf="!replaced && !isCached">
<td class="td-width align-items-center align-middle" i18n="transaction.eta|Transaction ETA">ETA</td>
<td>
<ng-template [ngIf]="this.mempoolPosition?.block == null" [ngIfElse]="estimationTmpl">
<span class="skeleton-loader"></span>
</ng-template>
<ng-template #estimationTmpl>
<ng-template [ngIf]="this.mempoolPosition.block >= 7" [ngIfElse]="belowBlockLimit">
<span [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'etaDeepMempool d-flex justify-content-end align-items-center' : ''">
<span i18n="transaction.eta.in-several-hours|Transaction ETA in several hours or more">In several hours (or more)</span>
<a *ngIf="!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration" [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerateDeepMempool btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
</span>
</ng-template>
<ng-template #belowBlockLimit>
<ng-template [ngIf]="network === 'liquid' || network === 'liquidtestnet'" [ngIfElse]="timeEstimateDefault">
<app-time kind="until" [time]="(60 * 1000 * this.mempoolPosition.block) + now" [fastRender]="false" [fixedRender]="true"></app-time>
</ng-template>
<ng-template #timeEstimateDefault>
<span class="eta justify-content-end" [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'd-flex align-items-center' : ''">
<app-time kind="until" *ngIf="(da$ | async) as da;" [time]="da.adjustedTimeAvg * (this.mempoolPosition.block + 1) + now + da.timeOffset" [fastRender]="false" [fixedRender]="true"></app-time>
<a *ngIf="!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration" [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerate btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
</span>
</ng-template>
</ng-template>
</ng-template>
</td>
</tr>
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet'" id="acceleratePreviewAnchor">
<td class="td-width" i18n="transaction.features|Transaction Features">Features</td>
<td>
<app-tx-features [tx]="tx"></app-tx-features>
</td>
</tr>
<ng-container *ngTemplateOutlet="goggles"></ng-container>
</tbody>
</table>
</div>
<div class="col-sm">
<ng-container *ngTemplateOutlet="feeTable"></ng-container>
</div>
</div>
</div>
</ng-template>
<ng-template [ngIf]="showCpfpDetails"> <ng-template [ngIf]="showCpfpDetails">
<br> <br>
@ -364,42 +276,7 @@
</ng-template> </ng-template>
<ng-template [ngIf]="(isLoadingTx && !error) || loadingCachedTx"> <ng-template [ngIf]="(isLoadingTx && !error) || loadingCachedTx">
<div class="box">
<div class="row">
<div class="col-sm">
<table class="table table-borderless table-striped">
<tbody>
<tr>
<td class="td-width"><span class="skeleton-loader"></span></td>
<td><span class="skeleton-loader"></span></td>
</tr>
<tr>
<td><span class="skeleton-loader"></span></td>
<td><span class="skeleton-loader"></span></td>
</tr>
</tbody>
</table>
</div>
<div class="col-sm">
<table class="table table-borderless table-striped">
<tbody>
<tr>
<td class="td-width"><span class="skeleton-loader"></span></td>
<td><span class="skeleton-loader"></span></td>
</tr>
<tr>
<td><span class="skeleton-loader"></span></td>
<td><span class="skeleton-loader"></span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<br> <br>
<ng-container *ngIf="flowEnabled"> <ng-container *ngIf="flowEnabled">
<div class="title"> <div class="title">
<h2 i18n="transaction.flow|Transaction flow">Flow</h2> <h2 i18n="transaction.flow|Transaction flow">Flow</h2>
@ -525,65 +402,264 @@
</div> </div>
<ng-template #feeTable> <ng-template #detailsLeft>
<table class="table table-borderless table-striped"> @if (tx?.status?.confirmed) {
<tbody> <ng-container *ngTemplateOutlet="timestampRow"></ng-container>
<tr *ngIf="isMobile && (network === 'liquid' || network === 'liquidtestnet' || !featuresEnabled || network === '')"></tr> <ng-container *ngTemplateOutlet="confirmedAfterRow"></ng-container>
} @else {
<ng-container *ngTemplateOutlet="firstSeenRow"></ng-container>
<ng-container *ngTemplateOutlet="etaRow"></ng-container>
}
<ng-container *ngTemplateOutlet="featuresRow"></ng-container>
@if (tx?.status?.confirmed) {
<ng-container *ngTemplateOutlet="auditRow"></ng-container>
}
<ng-container *ngTemplateOutlet="gogglesRow"></ng-container>
</ng-template>
<ng-template #detailsRight>
<ng-container *ngTemplateOutlet="feeRow"></ng-container>
<ng-container *ngTemplateOutlet="feeRateRow"></ng-container>
<ng-container *ngTemplateOutlet="effectiveRateRow"></ng-container>
@if (tx?.status?.confirmed) {
<ng-container *ngTemplateOutlet="minerRow"></ng-container>
}
</ng-template>
<ng-template #timestampRow>
@if (!isLoadingTx) {
<tr>
<td i18n="block.timestamp">Timestamp</td>
<td>
&lrm;{{ tx.status.block_time * 1000 | date:'yyyy-MM-dd HH:mm' }}
<div class="lg-inline">
<i class="symbol">(<app-time kind="since" [time]="tx.status.block_time" [fastRender]="true"></app-time>)</i>
</div>
</td>
</tr>
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
</ng-template>
<ng-template #confirmedAfterRow>
@if (!isLoadingTx) {
@if (transactionTime > 0) {
<tr> <tr>
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td> <td i18n="transaction.confirmed|Transaction Confirmed state">Confirmed</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> <td><app-time kind="span" [time]="tx.status.block_time - transactionTime" [fastRender]="true" [relative]="true"></app-time></td>
</tr> </tr>
}
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
</ng-template>
<ng-template #firstSeenRow>
@if (!isLoadingTx && transactionTime !== -1) {
<tr>
<td i18n="transaction.first-seen|Transaction first seen">First seen</td>
<td><i><app-time kind="since" [time]="transactionTime" [fastRender]="true"></app-time></i></td>
</tr>
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
</ng-template>
<ng-template #featuresRow>
@if (network !== 'liquid' && network !== 'liquidtestnet') {
@if (!isLoadingTx) {
@if (featuresEnabled) {
<tr>
<td class="td-width" i18n="transaction.features|Transaction features" id="acceleratePreviewAnchor">Features</td>
<td>
<app-tx-features [tx]="tx"></app-tx-features>
</td>
</tr>
}
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
}
</ng-template>
<ng-template #auditRow>
@if (network === '') {
@if (!isLoadingTx) {
@if (auditStatus) {
<tr>
<td class="td-width" i18n="block.toggle-audit|Toggle Audit">Audit</td>
<td class="wrap-cell">
<ng-container>
@if (auditStatus.coinbase) {
<span class="badge badge-primary mr-1" i18n="transactions-list.coinbase">Coinbase</span>
} @else if (auditStatus.expected) {
<span class="badge badge-success mr-1" i18n-ngbTooltip="Expected in block tooltip" ngbTooltip="This transaction was projected to be included in the block" placement="bottom" i18n="tx-features.tag.expected|Expected in Block">Expected in Block</span>
} @else if (auditStatus.seen) {
<span class="badge badge-success mr-1" i18n-ngbTooltip="Seen in mempool tooltip" ngbTooltip="This transaction was seen in the mempool prior to mining" placement="bottom" i18n="tx-features.tag.seen|Seen in Mempool">Seen in Mempool</span>
} @else if (!auditStatus.conflict) {
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Not seen in mempool tooltip" ngbTooltip="This transaction was missing from our mempool prior to mining" placement="bottom" i18n="tx-features.tag.not-seen|Not seen in Mempool">Not seen in Mempool</span>
}
@if (auditStatus.added) {
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Added transaction tooltip" ngbTooltip="This transaction may have been added out-of-band" placement="bottom" i18n="tx-features.tag.added|Added">Added</span>
}
@if (auditStatus.prioritized) {
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Prioritized transaction tooltip" ngbTooltip="This transaction may have been prioritized out-of-band" placement="bottom" i18n="tx-features.tag.prioritized|Prioritized">Prioritized</span>
}
@if (auditStatus.conflict) {
<span class="badge badge-warning mr-1" i18n-ngbTooltip="Conflict in mempool tooltip" ngbTooltip="This transaction conflicted with another version in our mempool" placement="bottom" i18n="tx-features.tag.conflict|Conflict">Conflict</span>
}
</ng-container>
</td>
</tr>
}
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
}
</ng-template>
<ng-template #etaRow>
@if (!isLoadingTx) {
@if (!replaced && !isCached) {
<tr> <tr>
<td i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td> <td class="td-width align-items-center align-middle" i18n="transaction.eta|Transaction ETA">ETA</td>
<td> <td>
<app-fee-rate [fee]="tx.feePerVsize"></app-fee-rate> @if (this.mempoolPosition?.block == null) {
<ng-template [ngIf]="tx?.status?.confirmed"> <span class="skeleton-loader"></span>
&nbsp; } @else if (this.mempoolPosition.block >= 7) {
<app-tx-fee-rating *ngIf="tx.fee && !hasEffectiveFeeRate && !accelerationInfo" [tx]="tx"></app-tx-fee-rating> <span [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'etaDeepMempool d-flex justify-content-end align-items-center' : ''">
</ng-template> <span i18n="transaction.eta.in-several-hours|Transaction ETA in several hours or more">In several hours (or more)</span>
@if (!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) {
<a [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerateDeepMempool btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
}
</span>
} @else if (network === 'liquid' || network === 'liquidtestnet') {
<app-time kind="until" [time]="(60 * 1000 * this.mempoolPosition.block) + now" [fastRender]="false" [fixedRender]="true"></app-time>
} @else {
<span class="eta justify-content-end" [class]="(acceleratorAvailable && accelerateCtaType === 'button') ? 'd-flex align-items-center' : ''">
<app-time kind="until" *ngIf="(da$ | async) as da;" [time]="da.adjustedTimeAvg * (this.mempoolPosition.block + 1) + now + da.timeOffset" [fastRender]="false" [fixedRender]="true"></app-time>
@if (!tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) {
<a [href]="'/services/accelerator/accelerate?txid=' + tx.txid" class="btn btn-sm accelerate btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
}
</span>
}
</td> </td>
</tr> </tr>
<tr *ngIf="(cpfpInfo && hasEffectiveFeeRate) || accelerationInfo"> }
<td *ngIf="tx.acceleration || accelerationInfo" i18n="transaction.accelerated-fee-rate|Accelerated transaction fee rate">Accelerated fee rate</td> } @else {
<td *ngIf="!(tx.acceleration || accelerationInfo)" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td> <ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
</ng-template>
<ng-template #gogglesRow>
@if (!isLoadingTx) {
@if (((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) || filters.length) {
<tr>
<td class="td-width">
<span class="goggles-icon"><app-svg-images name="goggles" width="100%" height="100%"></app-svg-images></span>
</td>
<td class="wrap-cell">
@if ((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) {
<span class="badge badge-accelerated mr-1" i18n="transaction.audit.accelerated">Accelerated</span>
}
<ng-container *ngFor="let filter of filters;">
<span class="badge badge-primary filter-tag mr-1">{{ filter.label }}</span>
</ng-container>
</td>
</tr>
}
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
</ng-template>
<ng-template #feeRow>
@if (!isLoadingTx) {
<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]="tx.price" [value]="tx.fee"></app-fiat></span></td>
</tr>
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
</ng-template>
<ng-template #feeRateRow>
@if (!isLoadingTx) {
<tr>
<td i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
<td>
<app-fee-rate [fee]="tx.feePerVsize"></app-fee-rate>
@if (tx?.status?.confirmed && tx.fee && !hasEffectiveFeeRate && !accelerationInfo) {
&nbsp;
<app-tx-fee-rating [tx]="tx"></app-tx-fee-rating>
}
</td>
</tr>
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
</ng-template>
<ng-template #effectiveRateRow>
@if (!isLoadingTx) {
@if ((cpfpInfo && hasEffectiveFeeRate) || accelerationInfo) {
<tr>
@if (tx.acceleration || accelerationInfo) {
<td i18n="transaction.accelerated-fee-rate|Accelerated transaction fee rate">Accelerated fee rate</td>
} @else {
<td i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
}
<td> <td>
<div class="effective-fee-container"> <div class="effective-fee-container">
<app-fee-rate *ngIf="accelerationInfo" [fee]="accelerationInfo.acceleratedFee" [weight]="accelerationInfo.effectiveVsize * 4"></app-fee-rate> @if (accelerationInfo) {
<app-fee-rate *ngIf="!accelerationInfo" [fee]="tx.effectiveFeePerVsize"></app-fee-rate> <app-fee-rate [fee]="accelerationInfo.acceleratedFee" [weight]="accelerationInfo.effectiveVsize * 4"></app-fee-rate>
} @else {
<app-fee-rate [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
}
<ng-template [ngIf]="tx?.status?.confirmed || tx.acceleration || accelerationInfo"> @if (tx?.status?.confirmed && !tx.acceleration && !accelerationInfo && tx.fee && tx.effectiveFeePerVsize) {
<app-tx-fee-rating *ngIf="!(tx.acceleration || accelerationInfo) && (tx.fee || tx.effectiveFeePerVsize)" class="ml-2 mr-2 effective-fee-rating" [tx]="tx"></app-tx-fee-rating> <app-tx-fee-rating class="ml-2 mr-2 effective-fee-rating" [tx]="tx"></app-tx-fee-rating>
</ng-template> }
</div> </div>
<button *ngIf="cpfpInfo?.bestDescendant || cpfpInfo?.descendants?.length || cpfpInfo?.ancestors?.length" type="button" class="btn btn-outline-info btn-sm btn-small-height float-right" (click)="showCpfpDetails = !showCpfpDetails">CPFP <fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon></button> @if (hasCpfp) {
<button type="button" class="btn btn-outline-info btn-sm btn-small-height float-right" (click)="showCpfpDetails = !showCpfpDetails">CPFP <fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon></button>
}
</td> </td>
</tr> </tr>
<tr *ngIf="network === '' && tx?.status?.confirmed"> }
<td class="td-width" i18n="block.miner">Miner</td> } @else {
<td *ngIf="pool" class="wrap-cell"> <ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
<a placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, pool.slug]" class="badge mr-1" }
[class]="pool.slug === 'unknown' ? 'badge-secondary' : 'badge-primary'">
{{ pool.name }}
</a>
</td>
<td *ngIf="!pool">
<span class="skeleton-loader"></span>
</td>
</tr>
</tbody>
</table>
</ng-template> </ng-template>
<ng-template #goggles> <ng-template #minerRow>
<tr *ngIf="((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration)) || filters.length"> @if (network === '') {
<td class="td-width"> @if (!isLoadingTx) {
<span class="goggles-icon"><app-svg-images name="goggles" width="100%" height="100%"></app-svg-images></span> <tr>
</td> <td class="td-width" i18n="block.miner">Miner</td>
<td class="wrap-cell"> @if (pool) {
<span *ngIf="((auditStatus && auditStatus.accelerated) || accelerationInfo || (tx && tx.acceleration))" class="badge badge-accelerated mr-1" i18n="transaction.audit.accelerated">Accelerated</span> <td class="wrap-cell">
<ng-container *ngFor="let filter of filters;"> <a placement="bottom" [routerLink]="['/mining/pool' | relativeUrl, pool.slug]" class="badge mr-1"
<span class="badge badge-primary filter-tag mr-1">{{ filter.label }}</span> [class]="pool.slug === 'unknown' ? 'badge-secondary' : 'badge-primary'">
</ng-container> {{ pool.name }}
</td> </a>
</tr> </td>
} @else {
<td>
<span class="skeleton-loader"></span>
</td>
}
</tr>
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
}
}
</ng-template> </ng-template>
<ng-template #skeletonDetailsRow>
<tr>
<td><span class="skeleton-loader"></span></td>
</tr>
</ng-template>

View File

@ -87,6 +87,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
rbfReplaces: string[]; rbfReplaces: string[];
rbfInfo: RbfTree; rbfInfo: RbfTree;
cpfpInfo: CpfpInfo | null; cpfpInfo: CpfpInfo | null;
hasCpfp: boolean = false;
accelerationInfo: Acceleration | null = null; accelerationInfo: Acceleration | null = null;
sigops: number | null; sigops: number | null;
adjustedVsize: number | null; adjustedVsize: number | null;
@ -491,10 +492,10 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
txFeePerVSize: tx.effectiveFeePerVsize, txFeePerVSize: tx.effectiveFeePerVsize,
mempoolPosition: this.mempoolPosition, mempoolPosition: this.mempoolPosition,
}); });
this.cpfpInfo = { this.setCpfpInfo({
ancestors: tx.ancestors, ancestors: tx.ancestors,
bestDescendant: tx.bestDescendant, bestDescendant: tx.bestDescendant,
}; });
const hasRelatives = !!(tx.ancestors?.length || tx.bestDescendant); const hasRelatives = !!(tx.ancestors?.length || tx.bestDescendant);
this.hasEffectiveFeeRate = hasRelatives || (tx.effectiveFeePerVsize && (Math.abs(tx.effectiveFeePerVsize - tx.feePerVsize) > 0.01)); this.hasEffectiveFeeRate = hasRelatives || (tx.effectiveFeePerVsize && (Math.abs(tx.effectiveFeePerVsize - tx.feePerVsize) > 0.01));
} else { } else {
@ -646,6 +647,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
setCpfpInfo(cpfpInfo: CpfpInfo): void { setCpfpInfo(cpfpInfo: CpfpInfo): void {
if (!cpfpInfo || !this.tx) { if (!cpfpInfo || !this.tx) {
this.cpfpInfo = null; this.cpfpInfo = null;
this.hasCpfp = false;
this.hasEffectiveFeeRate = false; this.hasEffectiveFeeRate = false;
return; return;
} }
@ -675,6 +677,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.sigops = this.cpfpInfo.sigops; this.sigops = this.cpfpInfo.sigops;
this.adjustedVsize = this.cpfpInfo.adjustedVsize; this.adjustedVsize = this.cpfpInfo.adjustedVsize;
} }
this.hasCpfp =!!(this.cpfpInfo && (this.cpfpInfo.bestDescendant || this.cpfpInfo.descendants?.length || this.cpfpInfo.ancestors?.length));
this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01)); this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
} }

View File

@ -18,7 +18,7 @@
<div class="card graph-card"> <div class="card graph-card">
<div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2"> <div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2">
<a class="title-link mb-0" style="margin-top: -2px" href="" [routerLink]="['/mempool-block/0' | relativeUrl]"> <a class="title-link mb-0" style="margin-top: -2px" href="" [routerLink]="['/mempool-block/0' | relativeUrl]">
<h5 class="card-title d-inline"><span i18n="dashboard.mempool-goggles">Mempool Goggles&trade;</span> : {{ goggleCycle[goggleIndex].name }}</h5> <h5 class="card-title d-inline"><span>Mempool Goggles&trade;</span> : {{ goggleCycle[goggleIndex].name }}</h5>
<span>&nbsp;</span> <span>&nbsp;</span>
<fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: text-top; font-size: 13px; color: #4a68b9"></fa-icon> <fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: text-top; font-size: 13px; color: #4a68b9"></fa-icon>
</a> </a>

View File

@ -418,5 +418,5 @@
</ng-template> </ng-template>
<ng-template type="address-lookup-issues"> <ng-template type="address-lookup-issues">
<p>If you're getting errors when doing address lookups, it's probably because of your Electrum server backend.</p><p>Mempool uses an Electrum server to do address lookups. There are several implementations of the Electrum server protocol, and Mempool can use any of them, but the implementation you use affects performance:</p><ol><li><a href="https://github.com/romanz/electrs" target="_blank">romanz/electrs</a>. This is a common choice for its low resource requirements, and most full-node distros use it. But while this implementation works great for basic queries, it will struggle with heavier ones (e.g. looking up addresses with many transactions)—especially when running on low-power hardware like a Raspberry Pi.</li><li><a href="https://github.com/cculianu/Fulcrum" target="_blank">Fulcrum</a>. Fulcrum requires more resources than romanz/electrs but it can still run on a Raspberry Pi, and it handles heavy queries much more efficiently. If you're having issues with romanz/electrs, Fulcrum is worth a try.</li><li><a href="https://github.com/Blockstream/electrs" target="_blank">blockstream/electrs</a>. If you have stronger hardware, consider running Blockstream's electrs implementation. It's the backend mempool.space uses, and is also what powers blockstream.info.</li></ol> <p>If you're getting errors when doing address lookups, it's probably because of your Electrum server backend.</p><p>Mempool uses an Electrum server to do address lookups. There are several implementations of the Electrum server protocol, and Mempool can use any of them, but the implementation you use affects performance:</p><ol><li><a href="https://github.com/romanz/electrs" target="_blank">romanz/electrs</a>. This is a common choice for its low resource requirements, and most full-node distros use it. But while this implementation works great for basic queries, it will struggle with heavier ones (e.g. looking up addresses with many transactions)—especially when running on low-power hardware like a Raspberry Pi.</li><li><a href="https://github.com/cculianu/Fulcrum" target="_blank">Fulcrum</a>. Fulcrum requires more resources than romanz/electrs but it can still run on a Raspberry Pi, and it handles heavy queries much more efficiently. If you're having issues with romanz/electrs, Fulcrum is worth a try.</li><li><a href="https://github.com/mempool/electrs" target="_blank">mempool/electrs</a>. If you have stronger hardware, you could consider running mempool/electrs, the backend that powers mempool.space. It's a fork of Blockstream's Esplora, which is in turn a fork of romanz/electrs, intended for maximum performance and larger-scale deployments.</li></ol>
</ng-template> </ng-template>

View File

@ -132,6 +132,10 @@ export class ServicesApiServices {
return this.httpClient.post<any>(`${SERVICES_API_PREFIX}/accelerator/accelerate`, { txInput: txInput, userBid: userBid }); return this.httpClient.post<any>(`${SERVICES_API_PREFIX}/accelerator/accelerate`, { txInput: txInput, userBid: userBid });
} }
accelerateWithCashApp$(txInput: string, userBid: number, token: string, cashtag: string, referenceId: string) {
return this.httpClient.post<any>(`${SERVICES_API_PREFIX}/accelerator/accelerate/cashapp`, { txInput: txInput, userBid: userBid, token: token, cashtag: cashtag, referenceId: referenceId });
}
getAccelerations$(): Observable<Acceleration[]> { getAccelerations$(): Observable<Acceleration[]> {
return this.httpClient.get<Acceleration[]>(`${SERVICES_API_PREFIX}/accelerator/accelerations`); return this.httpClient.get<Acceleration[]>(`${SERVICES_API_PREFIX}/accelerator/accelerations`);
} }
@ -151,4 +155,8 @@ export class ServicesApiServices {
getAccelerationStats$(): Observable<AccelerationStats> { getAccelerationStats$(): Observable<AccelerationStats> {
return this.httpClient.get<AccelerationStats>(`${SERVICES_API_PREFIX}/accelerator/accelerations/stats`); return this.httpClient.get<AccelerationStats>(`${SERVICES_API_PREFIX}/accelerator/accelerations/stats`);
} }
setupSquare$(): Observable<{squareAppId: string, squareLocationId: string}> {
return this.httpClient.get<{squareAppId: string, squareLocationId: string}>(`${SERVICES_API_PREFIX}/square/setup`);
}
} }

View File

@ -86,6 +86,7 @@ const defaultEnv: Env = {
providedIn: 'root' providedIn: 'root'
}) })
export class StateService { export class StateService {
ref: string = '';
isBrowser: boolean = isPlatformBrowser(this.platformId); isBrowser: boolean = isPlatformBrowser(this.platformId);
isMempoolSpaceBuild = window['isMempoolSpaceBuild'] ?? false; isMempoolSpaceBuild = window['isMempoolSpaceBuild'] ?? false;
backend: 'esplora' | 'electrum' | 'none' = 'esplora'; backend: 'esplora' | 'electrum' | 'none' = 'esplora';
@ -162,6 +163,8 @@ export class StateService {
private router: Router, private router: Router,
private storageService: StorageService, private storageService: StorageService,
) { ) {
this.ref = window.document.referrer;
const browserWindow = window || {}; const browserWindow = window || {};
// @ts-ignore // @ts-ignore
const browserWindowEnv = browserWindow.__env || {}; const browserWindowEnv = browserWindow.__env || {};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -453,40 +453,121 @@
<note priority="1" from="description">sat</note> <note priority="1" from="description">sat</note>
<note priority="1" from="meaning">shared.sat</note> <note priority="1" from="meaning">shared.sat</note>
</trans-unit> </trans-unit>
<trans-unit id="7159011509695804248" datatype="html">
<source>maximum</source>
<target>maximal</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-fee-graph.component.ts</context>
<context context-type="linenumber">55</context>
</context-group>
</trans-unit>
<trans-unit id="bdf0e930eb22431140a2eaeacd809cc5f8ebd38c" datatype="html">
<source>Next Block</source>
<target>Nästa block</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-fee-graph.component.ts</context>
<context context-type="linenumber">66</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
<context context-type="linenumber">12</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">28</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
<context context-type="linenumber">87</context>
</context-group>
</trans-unit>
<trans-unit id="f24773075af97666c0feca0e883c2585712fe597" datatype="html">
<source>Your transaction</source>
<target>Din transaktion</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">35</context>
</context-group>
<note priority="1" from="description">accelerator.your-transaction</note>
</trans-unit>
<trans-unit id="bee6b649ee82d9a7cde233070b665eec7c531b1d" datatype="html">
<source>Plus <x id="INTERPOLATION" equiv-text="{{ estimate.txSummary.ancestorCount - 1 }}"/> unconfirmed ancestor(s)</source>
<target>Plus <x id="INTERPOLATION" equiv-text="{{ estimate.txSummary.ancestorCount - 1 }}"/> obekräftade förfäder</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">39</context>
</context-group>
<note priority="1" from="description">accelerator.plus-unconfirmed-ancestors</note>
</trans-unit>
<trans-unit id="54c58b39481f1749fce23fa8a77f616eee84d761" datatype="html">
<source>Virtual size</source>
<target>Virtuell storlek</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">44</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-overview-tooltip/block-overview-tooltip.component.html</context>
<context context-type="linenumber">59</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/rbf-timeline/rbf-timeline-tooltip.component.html</context>
<context context-type="linenumber">25</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">189</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">317</context>
</context-group>
<note priority="1" from="description">Transaction Virtual Size</note>
<note priority="1" from="meaning">transaction.vsize</note>
</trans-unit>
<trans-unit id="adbeb446bf941afda4d4a923b5e4ce0cf4a1c1b8" datatype="html">
<source>In-band fees</source>
<target>In-band avgifter</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">53</context>
</context-group>
<note priority="1" from="description">accelerator.in-band-fees</note>
</trans-unit>
<trans-unit id="e4b2d9e6a2ab9e6ca34027ec03beaac42b7badd4" datatype="html"> <trans-unit id="e4b2d9e6a2ab9e6ca34027ec03beaac42b7badd4" datatype="html">
<source>sats</source> <source>sats</source>
<target>sats</target> <target>sats</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">59</context> <context context-type="linenumber">55</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">84</context> <context context-type="linenumber">77</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">118</context> <context context-type="linenumber">109</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">138</context> <context context-type="linenumber">127</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">150</context> <context context-type="linenumber">139</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">167</context> <context context-type="linenumber">156</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">190</context> <context context-type="linenumber">179</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">213</context> <context context-type="linenumber">200</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/calculator/calculator.component.html</context> <context context-type="sourcefile">src/app/components/calculator/calculator.component.html</context>
@ -550,20 +631,39 @@
</context-group> </context-group>
<note priority="1" from="description">shared.sats</note> <note priority="1" from="description">shared.sats</note>
</trans-unit> </trans-unit>
<trans-unit id="8611a038eb243bbed95bf5ff49af4129f22dc55a" datatype="html">
<source>How much more are you willing to pay?</source>
<target>Hur mycket mer är du villig att betala?</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">68</context>
</context-group>
<note priority="1" from="description">accelerator.pay-how-much</note>
</trans-unit>
<trans-unit id="4487eb902b70d33b4bb7a0828b66afec3a96fc18" datatype="html">
<source>Choose the maximum extra transaction fee you're willing to pay to get into the next block.</source>
<target>Välj den maximala extra transaktionsavgift du är villig att betala för att komma med i nästa block.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">71</context>
</context-group>
<note priority="1" from="description">accelerator.transaction-fee-description</note>
</trans-unit>
<trans-unit id="0b537472d5f7518ed2c2c2b747997b0447ec5ee8" datatype="html">
<source>Next block market rate</source>
<target>Marknadspriset för nästa block</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">95</context>
</context-group>
<note priority="1" from="description">accelerator.next-block-rate</note>
</trans-unit>
<trans-unit id="d2eb45d1cd8cd146b7cb0223ab97a4b03b614060" datatype="html"> <trans-unit id="d2eb45d1cd8cd146b7cb0223ab97a4b03b614060" datatype="html">
<source>sat/vB</source> <source>sat/vB</source>
<target>sat/vB</target> <target>sat/vB</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">108</context> <context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">173</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">198</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/fee-rate/fee-rate.component.html</context> <context context-type="sourcefile">src/app/shared/components/fee-rate/fee-rate.component.html</context>
@ -576,6 +676,130 @@
<note priority="1" from="description">sat/vB</note> <note priority="1" from="description">sat/vB</note>
<note priority="1" from="meaning">shared.sat-vbyte</note> <note priority="1" from="meaning">shared.sat-vbyte</note>
</trans-unit> </trans-unit>
<trans-unit id="c2836a2964adf9e369ee0a1ce67f991cf2aa435d" datatype="html">
<source>Estimated extra fee required</source>
<target>Uppskattad extra avgift som krävs</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">103</context>
</context-group>
<note priority="1" from="description">accelerator.estimated-extra-fee-required</note>
</trans-unit>
<trans-unit id="26e50fa97db4eecde26ff892d725e61ca9201c48" datatype="html">
<source>Mempool Accelerator™ fees</source>
<target>Mempool Accelerator™ avgifter</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">117</context>
</context-group>
<note priority="1" from="description">accelerator.mempool-accelerator-fees</note>
</trans-unit>
<trans-unit id="1ec82428244c76064090ea5a55827e3fada82306" datatype="html">
<source>Accelerator Service Fee</source>
<target>Acceleratorserviceavgift</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">121</context>
</context-group>
<note priority="1" from="description">accelerator.service-fee</note>
</trans-unit>
<trans-unit id="7d07b80b17dfab3582807759420b8d723c9e4414" datatype="html">
<source>Transaction Size Surcharge</source>
<target>Transaktionsstorlekstillägg</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">133</context>
</context-group>
<note priority="1" from="description">accelerator.tx-size-surcharge</note>
</trans-unit>
<trans-unit id="004732b44df582a2d24e2abbd3f46bc42ae8c546" datatype="html">
<source>Estimated acceleration cost</source>
<target>Beräknad accelerationskostnad</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">148</context>
</context-group>
<note priority="1" from="description">accelerator.estimated-cost</note>
</trans-unit>
<trans-unit id="c9ec95585f57bd87212693db7cb00d9ed70d49b1" datatype="html">
<source>Maximum acceleration cost</source>
<target>Maximal accelerationskostnad</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">171</context>
</context-group>
<note priority="1" from="description">accelerator.maximum-cost</note>
</trans-unit>
<trans-unit id="f3ff11006f77909b9fca2e0fda0a72b097cd76de" datatype="html">
<source>Available balance</source>
<target>Tillgängligt saldo</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">195</context>
</context-group>
<note priority="1" from="description">accelerator.available-balance</note>
</trans-unit>
<trans-unit id="ba4f24bf9bf3dc4db3d6bc1b8b63339295f0b806" datatype="html">
<source>Sign In</source>
<target>Logga in</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">214</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/menu/menu.component.html</context>
<context context-type="linenumber">21</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">26</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">31</context>
</context-group>
<note priority="1" from="description">shared.sign-in</note>
</trans-unit>
<trans-unit id="2504ca478a61c5e53f9ed55e9aeb3e8f2d01b3eb" datatype="html">
<source>Accelerate on mempool.space</source>
<target>Accelerera på mempool.space</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">223</context>
</context-group>
<note priority="1" from="description">accelerator.accelerate-on-mempoolspace</note>
</trans-unit>
<trans-unit id="913e89d2d1ae354079cccf48b3d3f4ebf2e74080" datatype="html">
<source>Accelerate</source>
<target>Accelerera</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">235</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">106</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">145</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">155</context>
</context-group>
<note priority="1" from="description">Accelerate button label</note>
<note priority="1" from="meaning">transaction.accelerate</note>
</trans-unit>
<trans-unit id="2bec172478fbbbe6536a662f5d4d3d711c208b09" datatype="html">
<source>If your tx is accelerated to ~<x id="INTERPOLATION" equiv-text="{{ i | number : '1.0-0' }}"/> sat/vB</source>
<target>Om din tx accelereras till ~<x id="INTERPOLATION" equiv-text="{{ i | number : '1.0-0' }}"/> sat/vB</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-preview/accelerate-preview.component.html</context>
<context context-type="linenumber">249</context>
</context-group>
<note priority="1" from="description">accelerator.accelerated-to-description</note>
</trans-unit>
<trans-unit id="bcf34abc2d9ed8f45a2f65dd464c46694e9a181e" datatype="html"> <trans-unit id="bcf34abc2d9ed8f45a2f65dd464c46694e9a181e" datatype="html">
<source>Acceleration Fees</source> <source>Acceleration Fees</source>
<target>Accelerationsavgifter</target> <target>Accelerationsavgifter</target>
@ -735,7 +959,11 @@
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context> <context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">2</context> <context context-type="linenumber">2</context>
</context-group> </context-group>
<note priority="1" from="description">master-page.blocks</note> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">41</context>
</context-group>
<note priority="1" from="description">accelerator.accelerations</note>
</trans-unit> </trans-unit>
<trans-unit id="94c248797dd2b6af49068cb49c3b4bc26bec6a16" datatype="html"> <trans-unit id="94c248797dd2b6af49068cb49c3b4bc26bec6a16" datatype="html">
<source>TXID</source> <source>TXID</source>
@ -750,11 +978,11 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">70</context> <context context-type="linenumber">71</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">133</context> <context context-type="linenumber">134</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.latest-transactions.txid</note> <note priority="1" from="description">dashboard.latest-transactions.txid</note>
</trans-unit> </trans-unit>
@ -831,7 +1059,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">73</context> <context context-type="linenumber">74</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context> <context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
@ -915,15 +1143,6 @@
</context-group> </context-group>
<note priority="1" from="description">mining.3-months</note> <note priority="1" from="description">mining.3-months</note>
</trans-unit> </trans-unit>
<trans-unit id="f26767fd3fbdc174a0f961fc538d10f80eaec6d8" datatype="html">
<source>Mempool Goggles: Accelerations</source>
<target>Mempool Goggles: Accelerationer</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">41</context>
</context-group>
<note priority="1" from="description">dashboard.mempool-goggles-accelerations</note>
</trans-unit>
<trans-unit id="97ff5554c708164d58b14e45072acbcbf9f4d137" datatype="html"> <trans-unit id="97ff5554c708164d58b14e45072acbcbf9f4d137" datatype="html">
<source>View more »</source> <source>View more »</source>
<target>Visa mer »</target> <target>Visa mer »</target>
@ -1213,7 +1432,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">145</context> <context context-type="linenumber">146</context>
</context-group> </context-group>
<note priority="1" from="description">shared.confidential</note> <note priority="1" from="description">shared.confidential</note>
</trans-unit> </trans-unit>
@ -1735,7 +1954,7 @@
<context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context> <context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context>
<context context-type="linenumber">2</context> <context context-type="linenumber">2</context>
</context-group> </context-group>
<note priority="1" from="description">Mempool Goggles tooltip</note> <note priority="1" from="description">Mempool Goggles tooltip</note>
</trans-unit> </trans-unit>
<trans-unit id="7cbedd89f60daafaf0e56363900d666a4e02ffb1" datatype="html"> <trans-unit id="7cbedd89f60daafaf0e56363900d666a4e02ffb1" datatype="html">
<source>beta</source> <source>beta</source>
@ -1772,23 +1991,23 @@
</context-group> </context-group>
<note priority="1" from="description">mempool-goggles.any</note> <note priority="1" from="description">mempool-goggles.any</note>
</trans-unit> </trans-unit>
<trans-unit id="f6314b04b5349b89ea90a88eca7abd4a8e1129c0" datatype="html"> <trans-unit id="360b9f5c32209001518dbd1dc512f25291473b79" datatype="html">
<source>Gradient</source> <source>Tint</source>
<target>Gradient</target> <target>Färgton</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context> <context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context>
<context context-type="linenumber">30</context> <context context-type="linenumber">30</context>
</context-group> </context-group>
<note priority="1" from="description">mempool-goggles.gradient</note> <note priority="1" from="description">mempool-goggles.tint</note>
</trans-unit> </trans-unit>
<trans-unit id="ff7cee38a2259526c519f878e71b964f41db4348" datatype="html"> <trans-unit id="4cfabb48965febabe67eb491a3b7e58555d3d52a" datatype="html">
<source>Default</source> <source>Classic</source>
<target>Standard</target> <target>Klassisk</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context> <context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context>
<context context-type="linenumber">33</context> <context context-type="linenumber">33</context>
</context-group> </context-group>
<note priority="1" from="description">mempool-goggles.default</note> <note priority="1" from="description">mempool-goggles.classic</note>
</trans-unit> </trans-unit>
<trans-unit id="2e6be334a2152f179a557167f98ce4459ff9a2f9" datatype="html"> <trans-unit id="2e6be334a2152f179a557167f98ce4459ff9a2f9" datatype="html">
<source>Age</source> <source>Age</source>
@ -2008,7 +2227,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">134</context> <context context-type="linenumber">135</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.latest-transactions.amount</note> <note priority="1" from="description">dashboard.latest-transactions.amount</note>
</trans-unit> </trans-unit>
@ -2037,7 +2256,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">136</context> <context context-type="linenumber">137</context>
</context-group> </context-group>
<note priority="1" from="description">Transaction fee</note> <note priority="1" from="description">Transaction fee</note>
<note priority="1" from="meaning">transaction.fee</note> <note priority="1" from="meaning">transaction.fee</note>
@ -2096,28 +2315,6 @@
<note priority="1" from="description">Effective transaction fee rate</note> <note priority="1" from="description">Effective transaction fee rate</note>
<note priority="1" from="meaning">transaction.effective-fee-rate</note> <note priority="1" from="meaning">transaction.effective-fee-rate</note>
</trans-unit> </trans-unit>
<trans-unit id="54c58b39481f1749fce23fa8a77f616eee84d761" datatype="html">
<source>Virtual size</source>
<target>Virtuell storlek</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-overview-tooltip/block-overview-tooltip.component.html</context>
<context context-type="linenumber">59</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/rbf-timeline/rbf-timeline-tooltip.component.html</context>
<context context-type="linenumber">25</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">189</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">317</context>
</context-group>
<note priority="1" from="description">Transaction Virtual Size</note>
<note priority="1" from="meaning">transaction.vsize</note>
</trans-unit>
<trans-unit id="13f5a75f3e01e5924e45052d2f336eda8bac37e8" datatype="html"> <trans-unit id="13f5a75f3e01e5924e45052d2f336eda8bac37e8" datatype="html">
<source>Weight</source> <source>Weight</source>
<target>Vikt</target> <target>Vikt</target>
@ -2357,7 +2554,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">107</context> <context context-type="linenumber">108</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="919f2fd60a898850c24b1584362bbf18a4628bcb" datatype="html"> <trans-unit id="919f2fd60a898850c24b1584362bbf18a4628bcb" datatype="html">
@ -2579,23 +2776,6 @@
<note priority="1" from="description">Block reorg</note> <note priority="1" from="description">Block reorg</note>
<note priority="1" from="meaning">block.reorged</note> <note priority="1" from="meaning">block.reorged</note>
</trans-unit> </trans-unit>
<trans-unit id="bdf0e930eb22431140a2eaeacd809cc5f8ebd38c" datatype="html">
<source>Next Block</source>
<target>Nästa block</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
<context context-type="linenumber">12</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">28</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
<context context-type="linenumber">87</context>
</context-group>
<note priority="1" from="description">Next Block</note>
</trans-unit>
<trans-unit id="a0e07a711d171f4d40dd388d70ed32f9b8101e0a" datatype="html"> <trans-unit id="a0e07a711d171f4d40dd388d70ed32f9b8101e0a" datatype="html">
<source>Previous Block</source> <source>Previous Block</source>
<target>Föregående block</target> <target>Föregående block</target>
@ -2671,6 +2851,14 @@
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">323</context> <context context-type="linenumber">323</context>
</context-group> </context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/api.service.ts</context>
<context context-type="linenumber">254</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/services/api.service.ts</context>
<context context-type="linenumber">267</context>
</context-group>
<note priority="1" from="description">unknown</note> <note priority="1" from="description">unknown</note>
</trans-unit> </trans-unit>
<trans-unit id="b2cb12c1680a46464cae5aa0d0d1d6914733a75d" datatype="html"> <trans-unit id="b2cb12c1680a46464cae5aa0d0d1d6914733a75d" datatype="html">
@ -3052,7 +3240,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">104</context> <context context-type="linenumber">105</context>
</context-group> </context-group>
<note priority="1" from="description">latest-blocks.height</note> <note priority="1" from="description">latest-blocks.height</note>
</trans-unit> </trans-unit>
@ -3144,11 +3332,11 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">106</context> <context context-type="linenumber">107</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">283</context> <context context-type="linenumber">284</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.txs</note> <note priority="1" from="description">dashboard.txs</note>
</trans-unit> </trans-unit>
@ -3223,7 +3411,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">287</context> <context context-type="linenumber">288</context>
</context-group> </context-group>
<note priority="1" from="description">Memory usage</note> <note priority="1" from="description">Memory usage</note>
<note priority="1" from="meaning">dashboard.memory-usage</note> <note priority="1" from="meaning">dashboard.memory-usage</note>
@ -3241,7 +3429,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">281</context> <context context-type="linenumber">282</context>
</context-group> </context-group>
<note priority="1" from="description">Unconfirmed count</note> <note priority="1" from="description">Unconfirmed count</note>
<note priority="1" from="meaning">dashboard.unconfirmed</note> <note priority="1" from="meaning">dashboard.unconfirmed</note>
@ -3621,7 +3809,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">47</context> <context context-type="linenumber">48</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.incoming-transactions</note> <note priority="1" from="description">dashboard.incoming-transactions</note>
</trans-unit> </trans-unit>
@ -4474,23 +4662,6 @@
<context context-type="linenumber">328</context> <context context-type="linenumber">328</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="ba4f24bf9bf3dc4db3d6bc1b8b63339295f0b806" datatype="html">
<source>Sign In</source>
<target>Logga in</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/menu/menu.component.html</context>
<context context-type="linenumber">21</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">26</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">31</context>
</context-group>
<note priority="1" from="description">shared.sign-in</note>
</trans-unit>
<trans-unit id="26e78cd052d05a0c1a7db43fac8df52ec6950672" datatype="html"> <trans-unit id="26e78cd052d05a0c1a7db43fac8df52ec6950672" datatype="html">
<source>Reward stats</source> <source>Reward stats</source>
<target>Belöningsstats</target> <target>Belöningsstats</target>
@ -4518,7 +4689,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">98</context> <context context-type="linenumber">99</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context> <context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
@ -4741,23 +4912,27 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">205</context> <context context-type="linenumber">206</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">208</context> <context context-type="linenumber">209</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3666195172774554282" datatype="html"> <trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source> <source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<target>Övriga (<x id="PH" equiv-text="percentage"/>)</target> <target>Annat (<x id="PH" equiv-text="percentage"/>)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">203</context> <context context-type="linenumber">186</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">207</context> <context context-type="linenumber">204</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">208</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context> <context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
@ -4950,11 +5125,11 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">85</context> <context context-type="linenumber">86</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">105</context> <context context-type="linenumber">106</context>
</context-group> </context-group>
<note priority="1" from="description">latest-blocks.mined</note> <note priority="1" from="description">latest-blocks.mined</note>
</trans-unit> </trans-unit>
@ -5065,7 +5240,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">86</context> <context context-type="linenumber">87</context>
</context-group> </context-group>
<note priority="1" from="description">transaction.full-rbf</note> <note priority="1" from="description">transaction.full-rbf</note>
</trans-unit> </trans-unit>
@ -5107,7 +5282,7 @@
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">87</context> <context context-type="linenumber">88</context>
</context-group> </context-group>
<note priority="1" from="description">RBF</note> <note priority="1" from="description">RBF</note>
<note priority="1" from="meaning">tx-features.tag.rbf</note> <note priority="1" from="meaning">tx-features.tag.rbf</note>
@ -5789,7 +5964,7 @@
</trans-unit> </trans-unit>
<trans-unit id="08c516e1fe345b4ae1fcae5fd4e5a0cd22e646dd" datatype="html"> <trans-unit id="08c516e1fe345b4ae1fcae5fd4e5a0cd22e646dd" datatype="html">
<source>Seen in Mempool</source> <source>Seen in Mempool</source>
<target>Sett i mempoolen</target> <target>Sedd i mempoolen</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context> <context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">79</context> <context context-type="linenumber">79</context>
@ -5808,7 +5983,7 @@
</trans-unit> </trans-unit>
<trans-unit id="53d5fe49e4a07a663eb2f26ceeb76afceef86334" datatype="html"> <trans-unit id="53d5fe49e4a07a663eb2f26ceeb76afceef86334" datatype="html">
<source>Not seen in Mempool</source> <source>Not seen in Mempool</source>
<target>Inte sett i mempoolen</target> <target>Inte sedd i mempoolen</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context> <context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">80</context> <context context-type="linenumber">80</context>
@ -5872,20 +6047,6 @@
<note priority="1" from="description">Transaction ETA in several hours or more</note> <note priority="1" from="description">Transaction ETA in several hours or more</note>
<note priority="1" from="meaning">transaction.eta.in-several-hours</note> <note priority="1" from="meaning">transaction.eta.in-several-hours</note>
</trans-unit> </trans-unit>
<trans-unit id="913e89d2d1ae354079cccf48b3d3f4ebf2e74080" datatype="html">
<source>Accelerate</source>
<target>Accelerera</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">145</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">155</context>
</context-group>
<note priority="1" from="description">Accelerate button label</note>
<note priority="1" from="meaning">transaction.accelerate</note>
</trans-unit>
<trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html"> <trans-unit id="f61c6867295f3b53d23557021f2f4e0aa1d0b8fc" datatype="html">
<source>Type</source> <source>Type</source>
<target>Typ</target> <target>Typ</target>
@ -5975,7 +6136,7 @@
</trans-unit> </trans-unit>
<trans-unit id="31d8d7f29ddbd3f64d374a132ddacd5e4a0835a2" datatype="html"> <trans-unit id="31d8d7f29ddbd3f64d374a132ddacd5e4a0835a2" datatype="html">
<source>Inputs &amp; Outputs</source> <source>Inputs &amp; Outputs</source>
<target>In- och utdata</target> <target>Inputs &amp; Outputs</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context> <context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">292</context> <context context-type="linenumber">292</context>
@ -6203,7 +6364,7 @@
</trans-unit> </trans-unit>
<trans-unit id="ac0c4b49e44c42db35ddf590fb5f78375a891b01" datatype="html"> <trans-unit id="ac0c4b49e44c42db35ddf590fb5f78375a891b01" datatype="html">
<source>other inputs</source> <source>other inputs</source>
<target>annan indata</target> <target>andra inputs</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context> <context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context>
<context context-type="linenumber">12</context> <context context-type="linenumber">12</context>
@ -6440,21 +6601,12 @@
</context-group> </context-group>
<note priority="1" from="description">fees-box.transaction-fees</note> <note priority="1" from="description">fees-box.transaction-fees</note>
</trans-unit> </trans-unit>
<trans-unit id="c385e9c0bacd3003ae141bcef7b2193aec618937" datatype="html">
<source>Mempool Goggles</source>
<target>Mempool Goggles</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">21</context>
</context-group>
<note priority="1" from="description">dashboard.mempool-goggles</note>
</trans-unit>
<trans-unit id="4fe744df6d36b5e9b0afab728b77fc635b99f040" datatype="html"> <trans-unit id="4fe744df6d36b5e9b0afab728b77fc635b99f040" datatype="html">
<source>Recent Replacements</source> <source>Recent Replacements</source>
<target>Senaste ersättningarna</target> <target>Senaste ersättningarna</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">64</context> <context context-type="linenumber">65</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.recent-rbf-replacements</note> <note priority="1" from="description">dashboard.recent-rbf-replacements</note>
</trans-unit> </trans-unit>
@ -6463,7 +6615,7 @@
<target>Tidigare avgift</target> <target>Tidigare avgift</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">71</context> <context context-type="linenumber">72</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.previous-transaction-fee</note> <note priority="1" from="description">dashboard.previous-transaction-fee</note>
</trans-unit> </trans-unit>
@ -6472,7 +6624,7 @@
<target>Ny avgift</target> <target>Ny avgift</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">72</context> <context context-type="linenumber">73</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.new-transaction-fee</note> <note priority="1" from="description">dashboard.new-transaction-fee</note>
</trans-unit> </trans-unit>
@ -6481,7 +6633,7 @@
<target>Senaste transaktionerna</target> <target>Senaste transaktionerna</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">130</context> <context context-type="linenumber">131</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.recent-transactions</note> <note priority="1" from="description">dashboard.recent-transactions</note>
</trans-unit> </trans-unit>
@ -6490,11 +6642,11 @@
<target>Liquidfederationsinnehav</target> <target>Liquidfederationsinnehav</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">164</context> <context context-type="linenumber">165</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">304</context> <context context-type="linenumber">305</context>
</context-group> </context-group>
<note priority="1" from="description">liquid.federation-holdings</note> <note priority="1" from="description">liquid.federation-holdings</note>
</trans-unit> </trans-unit>
@ -6503,11 +6655,11 @@
<target>Federationens timelock-utgågna UTXOs</target> <target>Federationens timelock-utgågna UTXOs</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">173</context> <context context-type="linenumber">174</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">313</context> <context context-type="linenumber">314</context>
</context-group> </context-group>
<note priority="1" from="description">liquid.federation-expired-utxos</note> <note priority="1" from="description">liquid.federation-expired-utxos</note>
</trans-unit> </trans-unit>
@ -6516,11 +6668,11 @@
<target>L-BTC-tillgångar mot BTC-tillgångar</target> <target>L-BTC-tillgångar mot BTC-tillgångar</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">183</context> <context context-type="linenumber">184</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">323</context> <context context-type="linenumber">324</context>
</context-group> </context-group>
<note priority="1" from="description">dashboard.lbtc-supply-against-btc-holdings</note> <note priority="1" from="description">dashboard.lbtc-supply-against-btc-holdings</note>
</trans-unit> </trans-unit>
@ -6529,7 +6681,7 @@
<target>Minimumavgift</target> <target>Minimumavgift</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">274</context> <context context-type="linenumber">275</context>
</context-group> </context-group>
<note priority="1" from="description">Minimum mempool fee</note> <note priority="1" from="description">Minimum mempool fee</note>
<note priority="1" from="meaning">dashboard.minimum-fee</note> <note priority="1" from="meaning">dashboard.minimum-fee</note>
@ -6539,7 +6691,7 @@
<target>Förkastar</target> <target>Förkastar</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">275</context> <context context-type="linenumber">276</context>
</context-group> </context-group>
<note priority="1" from="description">Purgin below fee</note> <note priority="1" from="description">Purgin below fee</note>
<note priority="1" from="meaning">dashboard.purging</note> <note priority="1" from="meaning">dashboard.purging</note>
@ -6549,7 +6701,7 @@
<target>Indexering pågår</target> <target>Indexering pågår</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context> <context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">363</context> <context context-type="linenumber">364</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context> <context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -879,7 +879,11 @@
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context> <context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">2</context> <context context-type="linenumber">2</context>
</context-group> </context-group>
<note priority="1" from="description">master-page.blocks</note> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">41</context>
</context-group>
<note priority="1" from="description">accelerator.accelerations</note>
</trans-unit> </trans-unit>
<trans-unit id="94c248797dd2b6af49068cb49c3b4bc26bec6a16" datatype="html"> <trans-unit id="94c248797dd2b6af49068cb49c3b4bc26bec6a16" datatype="html">
<source>TXID</source> <source>TXID</source>
@ -1044,14 +1048,6 @@
</context-group> </context-group>
<note priority="1" from="description">mining.3-months</note> <note priority="1" from="description">mining.3-months</note>
</trans-unit> </trans-unit>
<trans-unit id="f26767fd3fbdc174a0f961fc538d10f80eaec6d8" datatype="html">
<source>Mempool Goggles: Accelerations</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">41</context>
</context-group>
<note priority="1" from="description">dashboard.mempool-goggles-accelerations</note>
</trans-unit>
<trans-unit id="97ff5554c708164d58b14e45072acbcbf9f4d137" datatype="html"> <trans-unit id="97ff5554c708164d58b14e45072acbcbf9f4d137" datatype="html">
<source>View more »</source> <source>View more »</source>
<context-group purpose="location"> <context-group purpose="location">
@ -1801,7 +1797,7 @@
<context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context> <context context-type="sourcefile">src/app/components/block-filters/block-filters.component.html</context>
<context context-type="linenumber">2</context> <context context-type="linenumber">2</context>
</context-group> </context-group>
<note priority="1" from="description">Mempool Goggles tooltip</note> <note priority="1" from="description">Mempool Goggles tooltip</note>
</trans-unit> </trans-unit>
<trans-unit id="7cbedd89f60daafaf0e56363900d666a4e02ffb1" datatype="html"> <trans-unit id="7cbedd89f60daafaf0e56363900d666a4e02ffb1" datatype="html">
<source>beta</source> <source>beta</source>
@ -6108,14 +6104,6 @@
</context-group> </context-group>
<note priority="1" from="description">fees-box.transaction-fees</note> <note priority="1" from="description">fees-box.transaction-fees</note>
</trans-unit> </trans-unit>
<trans-unit id="c385e9c0bacd3003ae141bcef7b2193aec618937" datatype="html">
<source>Mempool Goggles</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
<context context-type="linenumber">21</context>
</context-group>
<note priority="1" from="description">dashboard.mempool-goggles</note>
</trans-unit>
<trans-unit id="4fe744df6d36b5e9b0afab728b77fc635b99f040" datatype="html"> <trans-unit id="4fe744df6d36b5e9b0afab728b77fc635b99f040" datatype="html">
<source>Recent Replacements</source> <source>Recent Replacements</source>
<context-group purpose="location"> <context-group purpose="location">

File diff suppressed because it is too large Load Diff

View File

@ -7,15 +7,15 @@
"declaration": false, "declaration": false,
"downlevelIteration": true, "downlevelIteration": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"module": "ES2022", "module": "ES2020",
"moduleResolution": "node", "moduleResolution": "node",
"importHelpers": true, "importHelpers": true,
"target": "ES2022", "target": "ES2020",
"typeRoots": [ "typeRoots": [
"node_modules/@types" "node_modules/@types"
], ],
"lib": [ "lib": [
"ES2022", "ES2020",
"dom", "dom",
"dom.iterable" "dom.iterable"
] ]

View File

@ -2,7 +2,7 @@
"extends": "./tsconfig.app.json", "extends": "./tsconfig.app.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/server", "outDir": "./out-tsc/server",
"target": "ES2022", "target": "ES2020",
"sourceMap": true, "sourceMap": true,
"types": [ "types": [
"node" "node"