diff --git a/frontend/src/app/app-routing.module.ts b/frontend/src/app/app-routing.module.ts
index 7ca9e107b..7c2ac1274 100644
--- a/frontend/src/app/app-routing.module.ts
+++ b/frontend/src/app/app-routing.module.ts
@@ -5,6 +5,7 @@ import { StartComponent } from './components/start/start.component';
import { TransactionComponent } from './components/transaction/transaction.component';
import { BlockComponent } from './components/block/block.component';
import { BlockViewComponent } from './components/block-view/block-view.component';
+import { MempoolBlockViewComponent } from './components/mempool-block-view/mempool-block-view.component';
import { ClockComponent } from './components/clock/clock.component';
import { AddressComponent } from './components/address/address.component';
import { MasterPageComponent } from './components/master-page/master-page.component';
@@ -378,6 +379,10 @@ let routes: Routes = [
path: 'view/block/:id',
component: BlockViewComponent,
},
+ {
+ path: 'view/mempool-block/:index',
+ component: MempoolBlockViewComponent,
+ },
{
path: 'status',
data: { networks: ['bitcoin', 'liquid'] },
diff --git a/frontend/src/app/components/mempool-block-view/mempool-block-view.component.html b/frontend/src/app/components/mempool-block-view/mempool-block-view.component.html
new file mode 100644
index 000000000..9d51ff4e9
--- /dev/null
+++ b/frontend/src/app/components/mempool-block-view/mempool-block-view.component.html
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/frontend/src/app/components/mempool-block-view/mempool-block-view.component.scss b/frontend/src/app/components/mempool-block-view/mempool-block-view.component.scss
new file mode 100644
index 000000000..782d416d8
--- /dev/null
+++ b/frontend/src/app/components/mempool-block-view/mempool-block-view.component.scss
@@ -0,0 +1,22 @@
+.block-wrapper {
+ width: 100vw;
+ height: 100vh;
+ background: #181b2d;
+}
+
+.block-container {
+ flex-grow: 0;
+ flex-shrink: 0;
+ width: 100vw;
+ max-width: 100vh;
+ height: 100vh;
+ padding: 0;
+ margin: auto;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ * {
+ flex-grow: 1;
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/app/components/mempool-block-view/mempool-block-view.component.ts b/frontend/src/app/components/mempool-block-view/mempool-block-view.component.ts
new file mode 100644
index 000000000..ebeb0801c
--- /dev/null
+++ b/frontend/src/app/components/mempool-block-view/mempool-block-view.component.ts
@@ -0,0 +1,85 @@
+import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';
+import { ActivatedRoute, ParamMap } from '@angular/router';
+import { Subscription, filter, map, switchMap, tap } from 'rxjs';
+import { StateService } from '../../services/state.service';
+import { WebsocketService } from '../../services/websocket.service';
+
+function bestFitResolution(min, max, n): number {
+ const target = (min + max) / 2;
+ let bestScore = Infinity;
+ let best = null;
+ for (let i = min; i <= max; i++) {
+ const remainder = (n % i);
+ if (remainder < bestScore || (remainder === bestScore && (Math.abs(i - target) < Math.abs(best - target)))) {
+ bestScore = remainder;
+ best = i;
+ }
+ }
+ return best;
+}
+
+@Component({
+ selector: 'app-mempool-block-view',
+ templateUrl: './mempool-block-view.component.html',
+ styleUrls: ['./mempool-block-view.component.scss']
+})
+export class MempoolBlockViewComponent implements OnInit, OnDestroy {
+ autofit: boolean = false;
+ resolution: number = 80;
+ index: number = 0;
+
+ routeParamsSubscription: Subscription;
+ queryParamsSubscription: Subscription;
+
+ constructor(
+ private route: ActivatedRoute,
+ private websocketService: WebsocketService,
+ public stateService: StateService,
+ ) { }
+
+ ngOnInit(): void {
+ this.websocketService.want(['blocks', 'mempool-blocks']);
+
+ this.routeParamsSubscription = this.route.paramMap
+ .pipe(
+ switchMap((params: ParamMap) => {
+ this.index = parseInt(params.get('index'), 10) || 0;
+ return this.stateService.mempoolBlocks$
+ .pipe(
+ map((blocks) => {
+ if (!blocks.length) {
+ return [{ index: 0, blockSize: 0, blockVSize: 0, feeRange: [0, 0], medianFee: 0, nTx: 0, totalFees: 0 }];
+ }
+ return blocks;
+ }),
+ filter((mempoolBlocks) => mempoolBlocks.length > 0),
+ tap((mempoolBlocks) => {
+ while (!mempoolBlocks[this.index]) {
+ this.index--;
+ }
+ })
+ );
+ })
+ ).subscribe();
+
+ this.queryParamsSubscription = this.route.queryParams.subscribe((params) => {
+ this.autofit = params.autofit === 'true';
+ if (this.autofit) {
+ this.onResize();
+ }
+ });
+ }
+
+
+ @HostListener('window:resize', ['$event'])
+ onResize(): void {
+ if (this.autofit) {
+ this.resolution = bestFitResolution(64, 96, Math.min(window.innerWidth, window.innerHeight));
+ }
+ }
+
+ ngOnDestroy(): void {
+ this.routeParamsSubscription.unsubscribe();
+ this.queryParamsSubscription.unsubscribe();
+ }
+}
diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts
index bba70a2ce..dce65bfae 100644
--- a/frontend/src/app/shared/shared.module.ts
+++ b/frontend/src/app/shared/shared.module.ts
@@ -98,6 +98,7 @@ import { AccelerateFeeGraphComponent } from '../components/accelerate-preview/ac
import { MempoolErrorComponent } from './components/mempool-error/mempool-error.component';
import { BlockViewComponent } from '../components/block-view/block-view.component';
+import { MempoolBlockViewComponent } from '../components/mempool-block-view/mempool-block-view.component';
import { MempoolBlockOverviewComponent } from '../components/mempool-block-overview/mempool-block-overview.component';
import { ClockchainComponent } from '../components/clockchain/clockchain.component';
import { ClockFaceComponent } from '../components/clock-face/clock-face.component';
@@ -136,6 +137,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
ColoredPriceDirective,
BlockchainComponent,
BlockViewComponent,
+ MempoolBlockViewComponent,
MempoolBlocksComponent,
BlockchainBlocksComponent,
AmountComponent,
@@ -199,6 +201,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
CalculatorComponent,
BitcoinsatoshisPipe,
BlockViewComponent,
+ MempoolBlockViewComponent,
MempoolBlockOverviewComponent,
ClockchainComponent,
ClockComponent,