mirror of
https://github.com/mempool/mempool.git
synced 2024-11-20 10:21:52 +01:00
Merge branch 'master' into nymkappa/feature/10min-blocktime-after-adjustment
This commit is contained in:
commit
dddf83a2d3
2
.github/workflows/cypress.yml
vendored
2
.github/workflows/cypress.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16.10.0
|
||||
node-version: 16.15.0
|
||||
cache: 'npm'
|
||||
cache-dependency-path: frontend/package-lock.json
|
||||
- name: ${{ matrix.browser }} browser tests (Mempool)
|
||||
|
@ -404,7 +404,6 @@ class Blocks {
|
||||
if (Common.indexingEnabled()) {
|
||||
const dbBlock = await blocksRepository.$getBlockByHash(hash);
|
||||
if (dbBlock != null) {
|
||||
logger.info('GET BLOCK: already indexed');
|
||||
return prepareBlock(dbBlock);
|
||||
}
|
||||
}
|
||||
@ -413,12 +412,10 @@ class Blocks {
|
||||
|
||||
// Not Bitcoin network, return the block as it
|
||||
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false) {
|
||||
logger.info('GET BLOCK: using bitcoin backend');
|
||||
return block;
|
||||
}
|
||||
|
||||
// Bitcoin network, add our custom data on top
|
||||
logger.info('GET BLOCK: index block on the fly');
|
||||
const transactions = await this.$getTransactionsExtended(hash, block.height, true);
|
||||
const blockExtended = await this.$getBlockExtended(block, transactions);
|
||||
if (Common.indexingEnabled()) {
|
||||
|
@ -300,24 +300,12 @@ class Server {
|
||||
|
||||
if (Common.indexingEnabled()) {
|
||||
this.app
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/24h', routes.$getPools.bind(routes, '24h'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3d', routes.$getPools.bind(routes, '3d'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1w', routes.$getPools.bind(routes, '1w'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1m', routes.$getPools.bind(routes, '1m'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3m', routes.$getPools.bind(routes, '3m'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/6m', routes.$getPools.bind(routes, '6m'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1y', routes.$getPools.bind(routes, '1y'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/2y', routes.$getPools.bind(routes, '2y'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3y', routes.$getPools.bind(routes, '3y'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/all', routes.$getPools.bind(routes, 'all'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/:interval', routes.$getPools)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/hashrate', routes.$getPoolHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/blocks', routes.$getPoolBlocks)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/blocks/:height', routes.$getPoolBlocks)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug', routes.$getPool)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/:interval', routes.$getPool)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools', routes.$getPoolsHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools/:interval', routes.$getPoolsHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate', routes.$getHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/:interval', routes.$getHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/reward-stats/:blockCount', routes.$getRewardStats)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fees/:interval', routes.$getHistoricalBlockFees)
|
||||
|
@ -572,9 +572,9 @@ class Routes {
|
||||
}
|
||||
}
|
||||
|
||||
public async $getPools(interval: string, req: Request, res: Response) {
|
||||
public async $getPools(req: Request, res: Response) {
|
||||
try {
|
||||
const stats = await miningStats.$getPoolsStats(interval);
|
||||
const stats = await miningStats.$getPoolsStats(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -588,7 +588,7 @@ class Routes {
|
||||
|
||||
public async $getPoolsHistoricalHashrate(req: Request, res: Response) {
|
||||
try {
|
||||
const hashrates = await HashratesRepository.$getPoolsWeeklyHashrate(req.params.interval ?? null);
|
||||
const hashrates = await HashratesRepository.$getPoolsWeeklyHashrate(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -620,8 +620,8 @@ class Routes {
|
||||
|
||||
public async $getHistoricalHashrate(req: Request, res: Response) {
|
||||
try {
|
||||
const hashrates = await HashratesRepository.$getNetworkDailyHashrate(req.params.interval ?? null);
|
||||
const difficulty = await BlocksRepository.$getBlocksDifficulty(req.params.interval ?? null);
|
||||
const hashrates = await HashratesRepository.$getNetworkDailyHashrate(req.params.interval);
|
||||
const difficulty = await BlocksRepository.$getBlocksDifficulty(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -640,7 +640,7 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockFees(req: Request, res: Response) {
|
||||
try {
|
||||
const blockFees = await mining.$getHistoricalBlockFees(req.params.interval ?? null);
|
||||
const blockFees = await mining.$getHistoricalBlockFees(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -654,7 +654,7 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockRewards(req: Request, res: Response) {
|
||||
try {
|
||||
const blockRewards = await mining.$getHistoricalBlockRewards(req.params.interval ?? null);
|
||||
const blockRewards = await mining.$getHistoricalBlockRewards(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -668,7 +668,7 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockFeeRates(req: Request, res: Response) {
|
||||
try {
|
||||
const blockFeeRates = await mining.$getHistoricalBlockFeeRates(req.params.interval ?? null);
|
||||
const blockFeeRates = await mining.$getHistoricalBlockFeeRates(req.params.interval);
|
||||
const oldestIndexedBlockTimestamp = await BlocksRepository.$oldestBlockTimestamp();
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -684,8 +684,8 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockSizeAndWeight(req: Request, res: Response) {
|
||||
try {
|
||||
const blockSizes = await mining.$getHistoricalBlockSizes(req.params.interval ?? null);
|
||||
const blockWeights = await mining.$getHistoricalBlockWeights(req.params.interval ?? null);
|
||||
const blockSizes = await mining.$getHistoricalBlockSizes(req.params.interval);
|
||||
const blockWeights = await mining.$getHistoricalBlockWeights(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:16.10.0-buster-slim AS builder
|
||||
FROM node:16.15.0-buster-slim AS builder
|
||||
|
||||
ARG commitHash
|
||||
ENV DOCKER_COMMIT_HASH=${commitHash}
|
||||
@ -11,7 +11,7 @@ RUN apt-get install -y build-essential python3 pkg-config
|
||||
RUN npm install
|
||||
RUN npm run build
|
||||
|
||||
FROM node:16.10.0-buster-slim
|
||||
FROM node:16.15.0-buster-slim
|
||||
|
||||
WORKDIR /backend
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM node:16.10.0-buster-slim AS builder
|
||||
FROM node:16.15.0-buster-slim AS builder
|
||||
|
||||
ARG commitHash
|
||||
ENV DOCKER_COMMIT_HASH=${commitHash}
|
||||
|
@ -67,6 +67,7 @@ import { HashrateChartPoolsComponent } from './components/hashrates-chart-pools/
|
||||
import { MiningStartComponent } from './components/mining-start/mining-start.component';
|
||||
import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe';
|
||||
import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe';
|
||||
import { CapAddressPipe } from './shared/pipes/cap-address-pipe/cap-address-pipe';
|
||||
import { GraphsComponent } from './components/graphs/graphs.component';
|
||||
import { DifficultyAdjustmentsTable } from './components/difficulty-adjustments-table/difficulty-adjustments-table.components';
|
||||
import { BlocksList } from './components/blocks-list/blocks-list.component';
|
||||
@ -161,6 +162,7 @@ import { BlockSizesWeightsGraphComponent } from './components/block-sizes-weight
|
||||
StorageService,
|
||||
LanguageService,
|
||||
ShortenStringPipe,
|
||||
CapAddressPipe,
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true }
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
|
@ -20,7 +20,7 @@
|
||||
<td><a [routerLink]="['/block/' | relativeUrl, block.hash]" title="{{ block.hash }}">{{ block.hash | shortenString : 13 }}</a> <app-clipboard class="d-none d-sm-inline-block" [text]="block.hash"></app-clipboard></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="transaction.timestamp|Transaction Timestamp">Timestamp</td>
|
||||
<td i18n="block.timestamp">Timestamp</td>
|
||||
<td>
|
||||
‎{{ block.time | date:'yyyy-MM-dd HH:mm' }}
|
||||
<div class="lg-inline">
|
||||
@ -83,7 +83,7 @@
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="transaction.timestamp|Transaction Timestamp">Timestamp</td>
|
||||
<td i18n="block.timestamp">Timestamp</td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -89,7 +89,7 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="text-center"><a href="" [routerLink]="['/markets' | relativeUrl]" i18n="dashboard.view-all">View all »</a></div>
|
||||
<div class="text-center"><a href="" [routerLink]="['/markets' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -98,7 +98,7 @@
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center" i18n="Latest Trades header">Latest Trades</h5>
|
||||
<app-bisq-trades [trades$]="trades$" view="small"></app-bisq-trades>
|
||||
<div class="text-center"><a href="" [routerLink]="['/markets' | relativeUrl]" i18n="dashboard.view-all">View all »</a></div>
|
||||
<div class="text-center"><a href="" [routerLink]="['/markets' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -31,7 +31,7 @@
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td i18n="transaction.timestamp|Transaction Timestamp">Timestamp</td>
|
||||
<td i18n="block.timestamp">Timestamp</td>
|
||||
<td>
|
||||
‎{{ bisqTx.time | date:'yyyy-MM-dd HH:mm' }}
|
||||
<div class="lg-inline">
|
||||
|
@ -18,7 +18,7 @@
|
||||
<th style="width: 20%;" i18n>TXID</th>
|
||||
<th class="d-none d-md-block" style="width: 100%;" i18n>Type</th>
|
||||
<th style="width: 20%;" i18n>Amount</th>
|
||||
<th style="width: 20%;" i18n>Confirmed</th>
|
||||
<th style="width: 20%;" i18n="transaction.confirmed|Transaction Confirmed state">Confirmed</th>
|
||||
<th class="d-none d-md-block" i18n>Height</th>
|
||||
</thead>
|
||||
<tbody *ngIf="transactions.value; else loadingTmpl">
|
||||
|
@ -118,7 +118,7 @@ export class AddressLabelsComponent implements OnInit {
|
||||
}
|
||||
const m = parseInt(opM.match(/[0-9]+/)[0], 10);
|
||||
|
||||
this.label = `multisig ${m} of ${n}`;
|
||||
this.label = $localize`:@@address-label.multisig:Multisig ${m}:multisigM: of ${n}:multisigN:`
|
||||
}
|
||||
|
||||
handleVout() {
|
||||
|
@ -1,11 +1,13 @@
|
||||
<div *ngIf="group$ | async as group; else loading">
|
||||
<div *ngIf="group$ | async as group; else loading;">
|
||||
|
||||
<div class="main-title">
|
||||
<h2>{{ group.group.name }}</h2>
|
||||
|
||||
<div class="sub-title" i18n>Group of {{ group.group.assets.length | number }} assets</div>
|
||||
</div>
|
||||
<ng-container *ngTemplateOutlet="title; context: group.group"></ng-container>
|
||||
|
||||
<ng-template #title>
|
||||
<div class="main-title">
|
||||
<h2>{{ group.name }}</h2>
|
||||
<div class="sub-title" i18n>Group of {{ group.assets.length | number }} assets</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
<div class="full-container">
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-fee-rates">Block fee rates</span>
|
||||
<span i18n="mining.block-fee-rates">Block Fee Rates</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.availableTimespanDay >= 1">
|
||||
|
@ -62,7 +62,7 @@ export class BlockFeeRatesGraphComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.seoService.setTitle($localize`:@@mining.block-fee-rates:Block Fee Rates`);
|
||||
this.seoService.setTitle($localize`:@@ed8e33059967f554ff06b4f5b6049c465b92d9b3:Block Fee Rates`);
|
||||
this.miningWindowPreference = this.miningService.getDefaultTimespan('24h');
|
||||
this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference });
|
||||
this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference);
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
<div class="full-container">
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-fees">Block fees</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<span i18n="mining.block-fees">Block Fees</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 144">
|
||||
|
@ -55,7 +55,7 @@ export class BlockFeesGraphComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.seoService.setTitle($localize`:@@mining.block-fees:Block Fees`);
|
||||
this.seoService.setTitle($localize`:@@6c453b11fd7bd159ae30bc381f367bc736d86909:Block Fees`);
|
||||
this.miningWindowPreference = this.miningService.getDefaultTimespan('24h');
|
||||
this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference });
|
||||
this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference);
|
||||
|
@ -3,11 +3,10 @@
|
||||
<div class="full-container">
|
||||
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-rewards">Block rewards</span>
|
||||
<span i18n="mining.block-rewards">Block Rewards</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(statsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 144">
|
||||
|
@ -53,7 +53,7 @@ export class BlockRewardsGraphComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.seoService.setTitle($localize`:@@mining.block-reward:Block Reward`);
|
||||
this.seoService.setTitle($localize`:@@8ba8fe810458280a83df7fdf4c614dfc1a826445:Block Rewards`);
|
||||
this.miningWindowPreference = this.miningService.getDefaultTimespan('24h');
|
||||
this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference });
|
||||
this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="full-container">
|
||||
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.block-size-weight">Block Sizes and Weights</span>
|
||||
<span i18n="mining.block-sizes-weights">Block Sizes and Weights</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
@ -62,7 +62,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit {
|
||||
ngOnInit(): void {
|
||||
let firstRun = true;
|
||||
|
||||
this.seoService.setTitle($localize`:@@mining.hashrate-difficulty:Hashrate and Weight`);
|
||||
this.seoService.setTitle($localize`:@@56fa1cd221491b6478998679cba2dc8d55ba330d:Block Sizes and Weights`);
|
||||
this.miningWindowPreference = this.miningService.getDefaultTimespan('24h');
|
||||
this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference });
|
||||
this.radioGroupForm.controls.dateSpan.setValue(this.miningWindowPreference);
|
||||
|
@ -1,27 +1,25 @@
|
||||
<app-indexing-progress *ngIf="!widget"></app-indexing-progress>
|
||||
|
||||
<div class="container-xl" [class]="widget ? 'widget' : 'full-height'">
|
||||
<h1 *ngIf="!widget" class="float-left" i18n="latest-blocks.blocks">Blocks</h1>
|
||||
<h1 *ngIf="!widget" class="float-left" i18n="master-page.blocks">Blocks</h1>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div style="min-height: 295px">
|
||||
<table class="table table-borderless">
|
||||
<thead>
|
||||
<th class="height" [class]="widget ? 'widget' : ''" i18n="latest-blocks.height">Height</th>
|
||||
<th class="pool text-left" [class]="widget ? 'widget' : ''" i18n="mining.pool-name">
|
||||
Pool</th>
|
||||
<th class="height text-left" [class]="widget ? 'widget' : ''" i18n="latest-blocks.height">Height</th>
|
||||
<th class="pool text-left" [class]="widget ? 'widget' : ''" i18n="mining.pool-name">Pool</th>
|
||||
<th class="timestamp" i18n="latest-blocks.timestamp" *ngIf="!widget">Timestamp</th>
|
||||
<th class="mined" i18n="latest-blocks.mined" *ngIf="!widget">Mined</th>
|
||||
<th class="reward text-right" i18n="latest-blocks.reward" [class]="widget ? 'widget' : ''">
|
||||
Reward</th>
|
||||
<th class="reward text-right" i18n="latest-blocks.reward" [class]="widget ? 'widget' : ''">Reward</th>
|
||||
<th class="fees text-right" i18n="latest-blocks.fees" *ngIf="!widget">Fees</th>
|
||||
<th class="txs text-right" i18n="latest-blocks.transactions" [class]="widget ? 'widget' : ''">Txs</th>
|
||||
<th class="txs text-right" i18n="dashboard.txs" [class]="widget ? 'widget' : ''">TXs</th>
|
||||
<th class="size" i18n="latest-blocks.size" *ngIf="!widget">Size</th>
|
||||
</thead>
|
||||
<tbody *ngIf="blocks$ | async as blocks; else skeleton" [style]="isLoading ? 'opacity: 0.75' : ''">
|
||||
<tr *ngFor="let block of blocks; let i= index; trackBy: trackByBlock">
|
||||
<td [class]="widget ? 'widget' : ''">
|
||||
<td class="text-left" [class]="widget ? 'widget' : ''">
|
||||
<a [routerLink]="['/block' | relativeUrl, block.height]">{{ block.height
|
||||
}}</a>
|
||||
</td>
|
||||
@ -42,10 +40,10 @@
|
||||
<app-time-since [time]="block.timestamp" [fastRender]="true"></app-time-since>
|
||||
</td>
|
||||
<td class="reward text-right" [class]="widget ? 'widget' : ''">
|
||||
<app-amount [satoshis]="block.extras.reward" digitsInfo="1.2-2"></app-amount>
|
||||
<app-amount [satoshis]="block.extras.reward" [noFiat]="true" digitsInfo="1.2-2"></app-amount>
|
||||
</td>
|
||||
<td class="fees text-right" *ngIf="!widget">
|
||||
<app-amount [satoshis]="block.extras.totalFees" digitsInfo="1.2-2"></app-amount>
|
||||
<app-amount [satoshis]="block.extras.totalFees" [noFiat]="true" digitsInfo="1.2-2"></app-amount>
|
||||
</td>
|
||||
<td class="txs text-right" [class]="widget ? 'widget' : ''">
|
||||
{{ block.tx_count | number }}
|
||||
@ -62,7 +60,7 @@
|
||||
<ng-template #skeleton>
|
||||
<tbody>
|
||||
<tr *ngFor="let item of skeletonLines">
|
||||
<td class="height" [class]="widget ? 'widget' : ''">
|
||||
<td class="height text-left" [class]="widget ? 'widget' : ''">
|
||||
<span class="skeleton-loader" style="max-width: 75px"></span>
|
||||
</td>
|
||||
<td class="pool text-left" [class]="widget ? 'widget' : ''">
|
||||
|
@ -11,13 +11,10 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
td {
|
||||
padding-top: 0.7rem !important;
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.7rem !important;
|
||||
@media (max-width: 376px) {
|
||||
padding-top: 0.73rem !important;
|
||||
padding-bottom: 0.73rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
.clear-link {
|
||||
@ -41,7 +38,7 @@ td {
|
||||
}
|
||||
.pool.widget {
|
||||
width: 40%;
|
||||
padding-left: 30px;
|
||||
padding-left: 24px;
|
||||
@media (max-width: 376px) {
|
||||
width: 60%;
|
||||
}
|
||||
@ -56,7 +53,7 @@ td {
|
||||
width: 10%;
|
||||
}
|
||||
.height.widget {
|
||||
width: 20%;
|
||||
width: 15%;
|
||||
@media (max-width: 576px) {
|
||||
width: 10%;
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ export class BlocksList implements OnInit {
|
||||
this.websocketService.want(['blocks']);
|
||||
}
|
||||
|
||||
this.skeletonLines = this.widget === true ? [...Array(5).keys()] : [...Array(15).keys()];
|
||||
this.skeletonLines = this.widget === true ? [...Array(6).keys()] : [...Array(15).keys()];
|
||||
this.paginationMaxSize = window.matchMedia('(max-width: 670px)').matches ? 3 : 5;
|
||||
|
||||
this.blocks$ = combineLatest([
|
||||
@ -61,7 +61,7 @@ export class BlocksList implements OnInit {
|
||||
block.extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg';
|
||||
}
|
||||
if (this.widget) {
|
||||
return blocks.slice(0, 5);
|
||||
return blocks.slice(0, 6);
|
||||
}
|
||||
return blocks;
|
||||
}),
|
||||
@ -85,7 +85,7 @@ export class BlocksList implements OnInit {
|
||||
blocks[1][0].extras.pool.logo = `./resources/mining-pools/` +
|
||||
blocks[1][0].extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg';
|
||||
acc.unshift(blocks[1][0]);
|
||||
acc = acc.slice(0, this.widget ? 5 : 15);
|
||||
acc = acc.slice(0, this.widget ? 6 : 15);
|
||||
return acc;
|
||||
}, [])
|
||||
);
|
||||
|
@ -22,7 +22,7 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody *ngIf="isLoading">
|
||||
<tr *ngFor="let item of [1,2,3,4,5]">
|
||||
<tr *ngFor="let item of [1,2,3,4,5,6]">
|
||||
<td class="d-none d-md-block w-75"><span class="skeleton-loader"></span></td>
|
||||
<td class="text-left"><span class="skeleton-loader w-75"></span></td>
|
||||
<td class="text-right"><span class="skeleton-loader w-75"></span></td>
|
||||
|
@ -2,10 +2,15 @@
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
table-layout:fixed;
|
||||
tr, td, th {
|
||||
tr, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.7rem !important;
|
||||
}
|
||||
td {
|
||||
border: 0px;
|
||||
padding-top: 0.71rem !important;
|
||||
padding-bottom: 0.75rem !important;
|
||||
width: 25%;
|
||||
@media (max-width: 376px) {
|
||||
padding: 0.85rem;
|
||||
|
@ -54,7 +54,7 @@ export class DifficultyAdjustmentsTable implements OnInit {
|
||||
|
||||
return {
|
||||
availableTimespanDay: availableTimespanDay,
|
||||
difficulty: tableData.slice(0, 5),
|
||||
difficulty: tableData.slice(0, 6),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
@ -5,33 +5,19 @@
|
||||
<button class="btn btn-primary w-100" id="dropdownBasic1" ngbDropdownToggle i18n="mining">Mining</button>
|
||||
<div ngbDropdownMenu aria-labelledby="dropdownBasic1">
|
||||
<a class="dropdown-item" routerLinkActive="active" [routerLink]="['/graphs/mining/pools' | relativeUrl]"
|
||||
i18n="mining.pools">
|
||||
Pools ranking
|
||||
</a>
|
||||
i18n="mining.pools">Pools Ranking</a>
|
||||
<a class="dropdown-item" routerLinkActive="active" [routerLink]="['/graphs/mining/pools-dominance' | relativeUrl]"
|
||||
i18n="mining.pools-dominance">
|
||||
Pools dominance
|
||||
</a>
|
||||
i18n="mining.pools-dominance">Pools Dominance</a>
|
||||
<a class="dropdown-item" routerLinkActive="active"
|
||||
[routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="mining.hashrate-difficulty">
|
||||
Hashrate & Difficulty
|
||||
</a>
|
||||
[routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="mining.hashrate-difficulty">Hashrate & Difficulty</a>
|
||||
<a class="dropdown-item" routerLinkActive="active"
|
||||
[routerLink]="['/graphs/mining/block-fee-rates' | relativeUrl]" i18n="mining.block-fee-rates">
|
||||
Block Fee Rates
|
||||
</a>
|
||||
[routerLink]="['/graphs/mining/block-fee-rates' | relativeUrl]" i18n="mining.block-fee-rates">Block Fee Rates</a>
|
||||
<a class="dropdown-item" routerLinkActive="active"
|
||||
[routerLink]="['/graphs/mining/block-fees' | relativeUrl]" i18n="mining.block-fees">
|
||||
Block Fees
|
||||
</a>
|
||||
[routerLink]="['/graphs/mining/block-fees' | relativeUrl]" i18n="mining.block-fees">Block Fees</a>
|
||||
<a class="dropdown-item" routerLinkActive="active"
|
||||
[routerLink]="['/graphs/mining/block-rewards' | relativeUrl]" i18n="mining.block-rewards">
|
||||
Block Rewards
|
||||
</a>
|
||||
[routerLink]="['/graphs/mining/block-rewards' | relativeUrl]" i18n="mining.block-rewards">Block Rewards</a>
|
||||
<a class="dropdown-item" routerLinkActive="active"
|
||||
[routerLink]="['/graphs/mining/block-sizes-weights' | relativeUrl]" i18n="mining.block-sizes-weights">
|
||||
Block Sizes and Weights
|
||||
</a>
|
||||
[routerLink]="['/graphs/mining/block-sizes-weights' | relativeUrl]" i18n="mining.block-sizes-weights">Block Sizes and Weights</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -52,7 +52,7 @@
|
||||
.chart-widget {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 270px;
|
||||
height: 240px;
|
||||
}
|
||||
|
||||
.formRadioGroup {
|
||||
|
@ -64,7 +64,7 @@ export class HashrateChartComponent implements OnInit {
|
||||
if (this.widget) {
|
||||
this.miningWindowPreference = '1y';
|
||||
} else {
|
||||
this.seoService.setTitle($localize`:@@mining.hashrate-difficulty:Hashrate and Difficulty`);
|
||||
this.seoService.setTitle($localize`:@@3510fc6daa1d975f331e3a717bdf1a34efa06dff:Hashrate & Difficulty`);
|
||||
this.miningWindowPreference = this.miningService.getDefaultTimespan('1m');
|
||||
}
|
||||
this.radioGroupForm = this.formBuilder.group({ dateSpan: this.miningWindowPreference });
|
||||
|
@ -3,11 +3,11 @@
|
||||
<div class="full-container">
|
||||
|
||||
<div class="card-header mb-0 mb-md-4">
|
||||
<span i18n="mining.pools-dominance">Mining pools dominance</span>
|
||||
<span i18n="mining.pools-dominance">Pools Dominance</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<span i18n="mining.pools-dominance">Pools Dominance</span>
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 4320">
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="container-xl">
|
||||
<h1 class="float-left" i18n="latest-blocks.blocks">Blocks</h1>
|
||||
<h1 class="float-left" i18n="master-page.blocks">Blocks</h1>
|
||||
<br>
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
@ -36,7 +36,7 @@ export class LatestBlocksComponent implements OnInit, OnDestroy {
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.seoService.setTitle($localize`:@@f4cba7faeb126346f09cc6af30124f9a343f7a28:Blocks`);
|
||||
this.seoService.setTitle($localize`:@@8a7b4bd44c0ac71b2e72de0398b303257f7d2f54:Blocks`);
|
||||
this.websocketService.want(['blocks']);
|
||||
|
||||
this.network$ = merge(of(''), this.stateService.networkChanged$);
|
||||
|
@ -32,7 +32,7 @@
|
||||
<a class="nav-link" [routerLink]="['/' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'tachometer-alt']" [fixedWidth]="true" i18n-title="master-page.dashboard" title="Dashboard"></fa-icon></a>
|
||||
</li>
|
||||
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}" id="btn-pools" *ngIf="stateService.env.MINING_DASHBOARD">
|
||||
<a class="nav-link" [routerLink]="['/mining' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'hammer']" [fixedWidth]="true" i18n-title="master-page.mining-dashboard" title="Mining Dashboard"></fa-icon></a>
|
||||
<a class="nav-link" [routerLink]="['/mining' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'hammer']" [fixedWidth]="true" i18n-title="mining.mining-dashboard" title="Mining Dashboard"></fa-icon></a>
|
||||
</li>
|
||||
<li class="nav-item" routerLinkActive="active" id="btn-blocks" *ngIf="!stateService.env.MINING_DASHBOARD">
|
||||
<a class="nav-link" [routerLink]="['/blocks' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'cubes']" [fixedWidth]="true" i18n-title="master-page.blocks" title="Blocks"></fa-icon></a>
|
||||
|
@ -21,7 +21,7 @@
|
||||
<td><span class="yellow-color">{{ mempoolBlock.feeRange[0] | number:'1.0-0' }} - {{ mempoolBlock.feeRange[mempoolBlock.feeRange.length - 1] | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="mempool-block.total-fees">Total fees</td>
|
||||
<td i18n="block.total-fees|Total fees in a block">Total fees</td>
|
||||
<td><app-amount [satoshis]="mempoolBlock.totalFees" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount> <span class="fiat"><app-fiat [value]="mempoolBlock.totalFees" digitsInfo="1.0-0"></app-fiat></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -68,7 +68,7 @@ export class MempoolBlockComponent implements OnInit, OnDestroy {
|
||||
getOrdinal(mempoolBlock: MempoolBlock): string {
|
||||
const blocksInBlock = Math.ceil(mempoolBlock.blockVSize / this.stateService.blockVSize);
|
||||
if (this.mempoolBlockIndex === 0) {
|
||||
return $localize`:@@mempool-block.next.block:Next block`;
|
||||
return $localize`:@@bdf0e930eb22431140a2eaeacd809cc5f8ebd38c:Next Block`;
|
||||
} else if (this.mempoolBlockIndex === this.stateService.env.KEEP_BLOCKS_AMOUNT - 1 && blocksInBlock > 1) {
|
||||
return $localize`:@@mempool-block.stack.of.blocks:Stack of ${blocksInBlock}:INTERPOLATION: mempool blocks`;
|
||||
} else {
|
||||
|
@ -11,7 +11,7 @@
|
||||
<span style="font-size: xx-small" i18n="mining.144-blocks">(144 blocks)</span>
|
||||
</div>
|
||||
<div class="card-wrapper">
|
||||
<div class="card" style="height: 123px">
|
||||
<div class="card">
|
||||
<div class="card-body more-padding">
|
||||
<app-reward-stats></app-reward-stats>
|
||||
</div>
|
||||
@ -22,29 +22,25 @@
|
||||
<!-- difficulty adjustment -->
|
||||
<div class="col">
|
||||
<div class="main-title" i18n="dashboard.difficulty-adjustment">Difficulty Adjustment</div>
|
||||
<div class="card" style="height: 123px">
|
||||
<app-difficulty [showTitle]="false" [showProgress]="false" [showHalving]="true"></app-difficulty>
|
||||
</div>
|
||||
<app-difficulty [showTitle]="false" [showProgress]="false" [showHalving]="true"></app-difficulty>
|
||||
</div>
|
||||
|
||||
<!-- pool distribution -->
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="col" style="margin-bottom: 1.47rem">
|
||||
<div class="card graph-card">
|
||||
<div class="card-body pl-2 pr-2">
|
||||
<app-pool-ranking [widget]=true></app-pool-ranking>
|
||||
<div class="mt-1"><a [routerLink]="['/graphs/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more
|
||||
»</a></div>
|
||||
<div class="mt-1"><a [routerLink]="['/graphs/mining/pools' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- hashrate -->
|
||||
<div class="col">
|
||||
<div class="col" style="margin-bottom: 1.47rem">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<app-hashrate-chart [widget]=true></app-hashrate-chart>
|
||||
<div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more
|
||||
»</a></div>
|
||||
<div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2">
|
||||
<app-hashrate-chart [widget]="true"></app-hashrate-chart>
|
||||
<div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -53,12 +49,9 @@
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
Latest blocks
|
||||
</h5>
|
||||
<h5 class="card-title" i18n="dashboard.latest-blocks">Latest blocks</h5>
|
||||
<app-blocks-list [widget]=true></app-blocks-list>
|
||||
<div><a [routerLink]="['/mining/blocks' | relativeUrl]" i18n="dashboard.view-more">View
|
||||
more »</a></div>
|
||||
<div><a [routerLink]="['/mining/blocks' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -67,12 +60,9 @@
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
Adjustments
|
||||
</h5>
|
||||
<h5 class="card-title" i18n="dashboard.adjustments">Adjustments</h5>
|
||||
<app-difficulty-adjustments-table></app-difficulty-adjustments-table>
|
||||
<div><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more
|
||||
»</a></div>
|
||||
<div><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,6 +14,13 @@
|
||||
background-color: #1d1f31;
|
||||
}
|
||||
|
||||
.graph-card {
|
||||
height: 100%;
|
||||
@media (min-width: 992px) {
|
||||
height: 385px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1rem;
|
||||
color: #4a68b9;
|
||||
@ -22,9 +29,6 @@
|
||||
color: #4a68b9;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 1.25rem 1rem 0.75rem 1rem;
|
||||
}
|
||||
.card-body.pool-ranking {
|
||||
padding: 1.25rem 0.25rem 0.75rem 0.25rem;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ export class MiningDashboardComponent implements OnInit {
|
||||
private seoService: SeoService,
|
||||
private websocketService: WebsocketService,
|
||||
) {
|
||||
this.seoService.setTitle($localize`:@@mining.mining-dashboard:Mining Dashboard`);
|
||||
this.seoService.setTitle($localize`:@@a681a4e2011bb28157689dbaa387de0dd0aa0c11:Mining Dashboard`);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -5,7 +5,7 @@
|
||||
<div *ngIf="widget">
|
||||
<div class="pool-distribution" *ngIf="(miningStatsObservable$ | async) as miningStats; else loadingReward">
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="mining.miners-luck">Pools luck (1w)</h5>
|
||||
<h5 class="card-title" i18n="mining.miners-luck">Pools Luck (1w)</h5>
|
||||
<p class="card-text">
|
||||
{{ miningStats['minersLuck'] }}%
|
||||
</p>
|
||||
@ -17,7 +17,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="mining.miners-count">Pools count (1w)</h5>
|
||||
<h5 class="card-title" i18n="mining.miners-count">Pools Count (1w)</h5>
|
||||
<p class="card-text">
|
||||
{{ miningStats.pools.length }}
|
||||
</p>
|
||||
@ -26,11 +26,10 @@
|
||||
</div>
|
||||
|
||||
<div class="card-header" *ngIf="!widget">
|
||||
<span i18n="mining.mining-pool-share">Mining pools share</span>
|
||||
<span i18n="mining.pools">Pools Ranking</span>
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup"
|
||||
*ngIf="!widget && (miningStatsObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
@ -62,7 +61,7 @@
|
||||
<input ngbButton type="radio" [value]="'3y'" fragment="3y"> 3Y
|
||||
</label>
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.totalBlockCount > 157680">
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all"> ALL
|
||||
<input ngbButton type="radio" [value]="'all'" fragment="all"><span i18n>All</span>
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
@ -87,7 +86,7 @@
|
||||
<th class="" i18n="mining.pool-name">Pool</th>
|
||||
<th class="" *ngIf="this.miningWindowPreference === '24h'" i18n="mining.hashrate">Hashrate</th>
|
||||
<th class="" i18n="master-page.blocks">Blocks</th>
|
||||
<th class="d-none d-md-block" i18n="mining.empty-blocks">Empty Blocks</th>
|
||||
<th class="d-none d-md-block" i18n="mining.empty-blocks">Empty blocks</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody *ngIf="(miningStatsObservable$ | async) as miningStats">
|
||||
@ -105,7 +104,7 @@
|
||||
<tr style="border-top: 1px solid #555">
|
||||
<td class="d-none d-md-block"></td>
|
||||
<td class="text-right"></td>
|
||||
<td class="" i18n="mining.all-miners"><b>All miners</b></td>
|
||||
<td class=""><b i18n="mining.all-miners">All miners</b></td>
|
||||
<td class="" *ngIf="this.miningWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{
|
||||
miningStats.miningUnits.hashrateUnit }}</b></td>
|
||||
<td class=""><b>{{ miningStats.blockCount }}</b></td>
|
||||
@ -122,7 +121,7 @@
|
||||
<ng-template #loadingReward>
|
||||
<div class="pool-distribution">
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="mining.miners-luck">Pools luck (1w)</h5>
|
||||
<h5 class="card-title" i18n="mining.miners-luck">Pools Luck (1w)</h5>
|
||||
<p class="card-text">
|
||||
<span class="skeleton-loader skeleton-loader-big"></span>
|
||||
</p>
|
||||
@ -134,7 +133,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="mining.miners-count">Pools count (1w)</h5>
|
||||
<h5 class="card-title" i18n="mining.miners-count">Pools Count (1w)</h5>
|
||||
<p class="card-text">
|
||||
<span class="skeleton-loader skeleton-loader-big"></span>
|
||||
</p>
|
||||
|
@ -27,7 +27,7 @@
|
||||
.chart-widget {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-height: 270px;
|
||||
height: 240px;
|
||||
@media (max-width: 485px) {
|
||||
max-height: 200px;
|
||||
}
|
||||
|
@ -93,10 +93,8 @@
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.estimated">Estimated
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.estimated">Estimated</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported</th>
|
||||
<th scope="col" class="block-count-title" style="width: 26%" i18n="mining.luck">Luck</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -117,10 +115,8 @@
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title" style="width: 33%" i18n="mining.estimated">Estimated
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 33%" i18n="mining.estimated">Estimated</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported</th>
|
||||
<th scope="col" class="block-count-title" style="width: 30%" i18n="mining.luck">Luck</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -142,7 +138,7 @@
|
||||
|
||||
<!-- Mined blocks desktop -->
|
||||
<tr *ngIf="!isMobile()" class="taller-row">
|
||||
<td class="label" i18n="mining.mined-blocks">Mined Blocks</td>
|
||||
<td class="label" i18n="mining.mined-blocks">Mined blocks</td>
|
||||
<td class="data">
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
@ -166,7 +162,7 @@
|
||||
<!-- Mined blocks mobile -->
|
||||
<tr *ngIf="isMobile()">
|
||||
<td colspan=2>
|
||||
<span class="label" i18n="mining.mined-blocks">Mined Blocks</span>
|
||||
<span class="label" i18n="mining.mined-blocks">Mined blocks</span>
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -216,12 +212,10 @@
|
||||
<th class="height" i18n="latest-blocks.height">Height</th>
|
||||
<th class="timestamp" i18n="latest-blocks.timestamp">Timestamp</th>
|
||||
<th class="mined" i18n="latest-blocks.mined">Mined</th>
|
||||
<th class="coinbase text-left" i18n="latest-blocks.coinbasetag">
|
||||
Coinbase Tag</th>
|
||||
<th class="reward text-right" i18n="latest-blocks.reward">
|
||||
Reward</th>
|
||||
<th class="coinbase text-left" i18n="latest-blocks.coinbasetag">Coinbase tag</th>
|
||||
<th class="reward text-right" i18n="latest-blocks.reward">Reward</th>
|
||||
<th class="fees text-right" i18n="latest-blocks.fees">Fees</th>
|
||||
<th class="txs text-right" i18n="latest-blocks.transactions">Txs</th>
|
||||
<th class="txs text-right" i18n="dashboard.txs">TXs</th>
|
||||
<th class="size" i18n="latest-blocks.size">Size</th>
|
||||
</thead>
|
||||
<tbody [style]="isLoading ? 'opacity: 0.75' : ''">
|
||||
@ -266,12 +260,10 @@
|
||||
<th class="height" i18n="latest-blocks.height">Height</th>
|
||||
<th class="timestamp" i18n="latest-blocks.timestamp">Timestamp</th>
|
||||
<th class="mined" i18n="latest-blocks.mined">Mined</th>
|
||||
<th class="coinbase text-left" i18n="latest-blocks.coinbasetag">
|
||||
Coinbase Tag</th>
|
||||
<th class="reward text-right" i18n="latest-blocks.reward">
|
||||
Reward</th>
|
||||
<th class="coinbase text-left" i18n="latest-blocks.coinbasetag">Coinbase tag</th>
|
||||
<th class="reward text-right" i18n="latest-blocks.reward">Reward</th>
|
||||
<th class="fees text-right" i18n="latest-blocks.fees">Fees</th>
|
||||
<th class="txs text-right" i18n="latest-blocks.transactions">Txs</th>
|
||||
<th class="txs text-right" i18n="dashboard.txs">TXs</th>
|
||||
<th class="size" i18n="latest-blocks.size">Size</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -378,10 +370,8 @@
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.estimated">Estimated
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.estimated">Estimated</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported</th>
|
||||
<th scope="col" class="block-count-title" style="width: 26%" i18n="mining.luck">Luck</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -406,10 +396,8 @@
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title" style="width: 33%" i18n="mining.estimated">Estimated
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported
|
||||
</th>
|
||||
<th scope="col" class="block-count-title" style="width: 33%" i18n="mining.estimated">Estimated</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported</th>
|
||||
<th scope="col" class="block-count-title" style="width: 30%" i18n="mining.luck">Luck</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -430,13 +418,13 @@
|
||||
|
||||
<!-- Mined blocks desktop -->
|
||||
<tr *ngIf="!isMobile()" class="taller-row">
|
||||
<td class="label" i18n="mining.mined-blocks">Mined Blocks</td>
|
||||
<td class="label" i18n="mining.mined-blocks">Mined blocks</td>
|
||||
<td class="data">
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="24h">24h</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="1w">1w</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%">24h</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%">1w</th>
|
||||
<th scope="col" class="block-count-title" style="width: 26%" i18n="all">All</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -457,12 +445,12 @@
|
||||
<!-- Mined blocks mobile -->
|
||||
<tr *ngIf="isMobile()">
|
||||
<td colspan=2>
|
||||
<span class="label" i18n="mining.mined-blocks">Mined Blocks</span>
|
||||
<span class="label" i18n="mining.mined-blocks">Mined blocks</span>
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title" style="width: 33%" i18n="24h">24h</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%" i18n="1w">1w</th>
|
||||
<th scope="col" class="block-count-title" style="width: 33%">24h</th>
|
||||
<th scope="col" class="block-count-title" style="width: 37%">1w</th>
|
||||
<th scope="col" class="block-count-title" style="width: 30%" i18n="all">All</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
<form [formGroup]="pushTxForm" (submit)="pushTxForm.valid && postTx()" novalidate>
|
||||
<div class="mb-3">
|
||||
<textarea formControlName="txHash" class="form-control" rows="5" i18n-placeholder="transaction.hex" placeholder="Transaction Hex"></textarea>
|
||||
<textarea formControlName="txHash" class="form-control" rows="5" i18n-placeholder="transaction.hex" placeholder="Transaction hex"></textarea>
|
||||
</div>
|
||||
<button [disabled]="isLoading" type="submit" class="btn btn-primary mr-2" i18n="shared.broadcast-transaction|Broadcast Transaction">Broadcast Transaction</button>
|
||||
<p class="red-color d-inline">{{ error }}</p> <a *ngIf="txId" [routerLink]="['/tx/' | relativeUrl, txId]">{{ txId }}</a>
|
||||
|
@ -26,7 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="mining.average-fee">Average Fee</h5>
|
||||
<h5 class="card-title" i18n="mining.average-fee">Reward Per Tx</h5>
|
||||
<div class="card-text" i18n-ngbTooltip="mining.average-fee"
|
||||
ngbTooltip="Fee paid on average for each transaction in the past 144 blocks" placement="bottom">
|
||||
<div class="fee-text">{{ rewardStats.feePerTx | amountShortener: 2 }}
|
||||
@ -57,7 +57,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="mining.average-fee">Average Fee</h5>
|
||||
<h5 class="card-title" i18n="mining.average-fee">Reward Per Tx</h5>
|
||||
<div class="card-text">
|
||||
<div class="skeleton-loader"></div>
|
||||
<div class="skeleton-loader"></div>
|
||||
|
@ -46,7 +46,7 @@
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td i18n="transaction.timestamp|Transaction Timestamp">Timestamp</td>
|
||||
<td i18n="block.timestamp">Timestamp</td>
|
||||
<td>
|
||||
‎{{ tx.status.block_time * 1000 | date:'yyyy-MM-dd HH:mm' }}
|
||||
<div class="lg-inline">
|
||||
@ -209,7 +209,7 @@
|
||||
<table class="table table-borderless table-striped">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td i18n="transaction.size|Transaction Size">Size</td>
|
||||
<td i18n="block.size">Size</td>
|
||||
<td [innerHTML]="'‎' + (tx.size | bytes: 2)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -217,7 +217,7 @@
|
||||
<td [innerHTML]="'‎' + (tx.weight / 4 | vbytes: 2)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="transaction.weight|Transaction Weight">Weight</td>
|
||||
<td i18n="block.weight">Weight</td>
|
||||
<td [innerHTML]="'‎' + (tx.weight | wuBytes: 2)"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -235,7 +235,7 @@
|
||||
<td [innerHTML]="'‎' + (tx.locktime | number)"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="transaction.hex">Transaction Hex</td>
|
||||
<td i18n="transaction.hex">Transaction hex</td>
|
||||
<td><a target="_blank" href="{{ network === '' ? '' : '/' + network }}/api/tx/{{ txId }}/hex"><fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true"></fa-icon></a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -383,7 +383,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
|
||||
<td>{{ tx.fee | number }} <span class="symbol" i18n="transaction.fee.sat|Transaction Fee sat">sat</span> <span class="fiat"><app-fiat [value]="tx.fee"></app-fiat></span></td>
|
||||
<td>{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [value]="tx.fee"></app-fiat></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
|
||||
|
@ -65,7 +65,10 @@
|
||||
<ng-template #defaultAddress>
|
||||
<a [routerLink]="['/address/' | relativeUrl, vin.prevout.scriptpubkey_address]" title="{{ vin.prevout.scriptpubkey_address }}">
|
||||
<span class="d-block d-lg-none">{{ vin.prevout.scriptpubkey_address | shortenString : 16 }}</span>
|
||||
<span class="d-none d-lg-block">{{ vin.prevout.scriptpubkey_address | shortenString : 35 }}</span>
|
||||
<span class="d-none d-lg-flex justify-content-start">
|
||||
<span class="addr-left flex-grow-1" [style]="vin.prevout.scriptpubkey_address.length > 40 ? 'max-width: 235px' : ''">{{ vin.prevout.scriptpubkey_address }}</span>
|
||||
<span *ngIf="vin.prevout.scriptpubkey_address.length > 40" class="addr-right">{{ vin.prevout.scriptpubkey_address | capAddress: 40: 10 }}</span>
|
||||
</span>
|
||||
</a>
|
||||
<div>
|
||||
<app-address-labels [vin]="vin"></app-address-labels>
|
||||
@ -138,7 +141,7 @@
|
||||
</ng-template>
|
||||
<tr *ngIf="tx.vin.length > 12 && tx['@vinLimit']">
|
||||
<td colspan="3" class="text-center">
|
||||
<button class="btn btn-sm btn-primary mt-2" (click)="tx['@vinLimit'] = false;"><span i18n="transactions-list.load-all">Load all</span> ({{ tx.vin.length - 10 }})</button>
|
||||
<button class="btn btn-sm btn-primary mt-2" (click)="tx['@vinLimit'] = false;"><span i18n="show-all">Show all</span> ({{ tx.vin.length - 10 }})</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@ -156,7 +159,10 @@
|
||||
<td>
|
||||
<a *ngIf="vout.scriptpubkey_address; else scriptpubkey_type" [routerLink]="['/address/' | relativeUrl, vout.scriptpubkey_address]" title="{{ vout.scriptpubkey_address }}">
|
||||
<span class="d-block d-lg-none">{{ vout.scriptpubkey_address | shortenString : 16 }}</span>
|
||||
<span class="d-none d-lg-block">{{ vout.scriptpubkey_address | shortenString : 35 }}</span>
|
||||
<span class="d-none d-lg-flex justify-content-start">
|
||||
<span class="addr-left flex-grow-1" [style]="vout.scriptpubkey_address.length > 40 ? 'max-width: 235px' : ''">{{ vout.scriptpubkey_address }}</span>
|
||||
<span *ngIf="vout.scriptpubkey_address.length > 40" class="addr-right">{{ vout.scriptpubkey_address | capAddress: 40: 10 }}</span>
|
||||
</span>
|
||||
</a>
|
||||
<div>
|
||||
<app-address-labels [vout]="vout"></app-address-labels>
|
||||
@ -232,7 +238,7 @@
|
||||
<td style="text-align: left;">{{ vout.scriptpubkey }}</td>
|
||||
</tr>
|
||||
<tr *ngIf="vout.scriptpubkey_type == 'op_return'">
|
||||
<td>OP_RETURN <span i18n="transactions-list.vout.scriptpubkey-type.data">data</span></td>
|
||||
<td>OP_RETURN <span>data</span></td>
|
||||
<td style="text-align: left;">{{ vout.scriptpubkey_asm | hex2ascii }}</td>
|
||||
</tr>
|
||||
<tr *ngIf="vout.scriptpubkey_type">
|
||||
@ -246,7 +252,7 @@
|
||||
</ng-template>
|
||||
<tr *ngIf="tx.vout.length > 12 && tx['@voutLimit'] && !outputIndex">
|
||||
<td colspan="3" class="text-center">
|
||||
<button class="btn btn-sm btn-primary mt-2" (click)="tx['@voutLimit'] = false;"><span i18n="transactions-list.load-all">Load all</span> ({{ tx.vout.length - 10 }})</button>
|
||||
<button class="btn btn-sm btn-primary mt-2" (click)="tx['@voutLimit'] = false;"><span i18n="show-all">Show all</span> ({{ tx.vout.length - 10 }})</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -129,3 +129,14 @@ h2 {
|
||||
.summary {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.addr-left {
|
||||
font-family: monospace;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: -7px
|
||||
}
|
||||
|
||||
.addr-right {
|
||||
font-family: monospace;
|
||||
}
|
@ -121,7 +121,7 @@
|
||||
<td *ngIf="!stateService.env.MINING_DASHBOARD" class="table-cell-mined" ><app-time-since [time]="block.timestamp" [fastRender]="true"></app-time-since></td>
|
||||
<td *ngIf="stateService.env.MINING_DASHBOARD" class="table-cell-mined pl-lg-4">
|
||||
<a class="clear-link" [routerLink]="[('/mining/pool/' + block.extras.pool.slug) | relativeUrl]">
|
||||
<img width="20" height="20" src="{{ block.extras.pool['logo'] }}"
|
||||
<img width="22" height="22" src="{{ block.extras.pool['logo'] }}"
|
||||
onError="this.src = './resources/mining-pools/default.svg'">
|
||||
<span class="pool-name">{{ block.extras.pool.name }}</span>
|
||||
</a>
|
||||
@ -136,7 +136,7 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class=""><a href="" [routerLink]="[(stateService.env.MINING_DASHBOARD ? '/mining/blocks' : '/blocks') | relativeUrl]" i18n="dashboard.view-all">View all »</a></div>
|
||||
<div class=""><a href="" [routerLink]="[(stateService.env.MINING_DASHBOARD ? '/mining/blocks' : '/blocks') | relativeUrl]" i18n="dashboard.view-more">View more »</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -134,6 +134,8 @@
|
||||
table-layout:fixed;
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.71rem !important;
|
||||
padding-bottom: 0.75rem !important;
|
||||
}
|
||||
td {
|
||||
overflow:hidden;
|
||||
@ -182,16 +184,15 @@
|
||||
text-align: left;
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.7rem !important;
|
||||
}
|
||||
.table-cell-height {
|
||||
width: 15%;
|
||||
}
|
||||
.table-cell-mined {
|
||||
width: 35%;
|
||||
text-align: right;
|
||||
@media (min-width: 376px) {
|
||||
text-align: left;
|
||||
}
|
||||
text-align: left;
|
||||
}
|
||||
.table-cell-transaction-count {
|
||||
display: none;
|
||||
|
@ -39,7 +39,7 @@ export class ApiDocsComponent implements OnInit {
|
||||
}
|
||||
window.addEventListener('scroll', function() {
|
||||
that.desktopDocsNavPosition = ( window.pageYOffset > 182 ) ? "fixed" : "relative";
|
||||
});
|
||||
}, { passive: true} );
|
||||
}, 1 );
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'capAddress' })
|
||||
export class CapAddressPipe implements PipeTransform {
|
||||
transform(str: string, cap: number, leftover: number) {
|
||||
if (!str) { return; }
|
||||
if (str.length <= cap) {
|
||||
return str;
|
||||
}
|
||||
return str.slice(-Math.max(cap - str.length, leftover));
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ import { MempoolBlocksComponent } from '../components/mempool-blocks/mempool-blo
|
||||
import { BlockchainBlocksComponent } from '../components/blockchain-blocks/blockchain-blocks.component';
|
||||
import { AmountComponent } from '../components/amount/amount.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { CapAddressPipe } from './pipes/cap-address-pipe/cap-address-pipe';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -51,6 +52,7 @@ import { RouterModule } from '@angular/router';
|
||||
WuBytesPipe,
|
||||
CeilPipe,
|
||||
ShortenStringPipe,
|
||||
CapAddressPipe,
|
||||
Decimal2HexPipe,
|
||||
FeeRoundingPipe,
|
||||
ColoredPriceDirective,
|
||||
@ -103,6 +105,7 @@ import { RouterModule } from '@angular/router';
|
||||
WuBytesPipe,
|
||||
CeilPipe,
|
||||
ShortenStringPipe,
|
||||
CapAddressPipe,
|
||||
Decimal2HexPipe,
|
||||
FeeRoundingPipe,
|
||||
ColoredPriceDirective,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -82,11 +82,11 @@ pkg install -y zsh sudo git screen curl wget neovim rsync nginx openssl openssh-
|
||||
|
||||
### Node.js + npm
|
||||
|
||||
Build Node.js v16.10 and npm v7 from source using `nvm`:
|
||||
Build Node.js v16.15 and npm v8 from source using `nvm`:
|
||||
```
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh
|
||||
source $HOME/.zshrc
|
||||
nvm install v16.10.0
|
||||
nvm install v16.15.0
|
||||
nvm alias default node
|
||||
```
|
||||
|
||||
|
@ -854,7 +854,7 @@ echo "[*] Installing nvm.sh from GitHub"
|
||||
osSudo "${MEMPOOL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh'
|
||||
|
||||
echo "[*] Building NodeJS via nvm.sh"
|
||||
osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v16.10.0'
|
||||
osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v16.15.0'
|
||||
|
||||
####################
|
||||
# Tor installation #
|
||||
|
Loading…
Reference in New Issue
Block a user