Merge pull request #1741 from mempool/nymkappa/feature/remove-fee-calculation-frontend
Remove fee calculation from the frontend
This commit is contained in:
commit
dbce727695
@ -13,6 +13,7 @@ import config from '../config';
|
|||||||
import transactionUtils from './transaction-utils';
|
import transactionUtils from './transaction-utils';
|
||||||
import rbfCache from './rbf-cache';
|
import rbfCache from './rbf-cache';
|
||||||
import difficultyAdjustment from './difficulty-adjustment';
|
import difficultyAdjustment from './difficulty-adjustment';
|
||||||
|
import feeApi from './fee-api';
|
||||||
|
|
||||||
class WebsocketHandler {
|
class WebsocketHandler {
|
||||||
private wss: WebSocket.Server | undefined;
|
private wss: WebSocket.Server | undefined;
|
||||||
@ -236,6 +237,7 @@ class WebsocketHandler {
|
|||||||
const rbfTransactions = Common.findRbfTransactions(newTransactions, deletedTransactions);
|
const rbfTransactions = Common.findRbfTransactions(newTransactions, deletedTransactions);
|
||||||
const da = difficultyAdjustment.getDifficultyAdjustment();
|
const da = difficultyAdjustment.getDifficultyAdjustment();
|
||||||
memPool.handleRbfTransactions(rbfTransactions);
|
memPool.handleRbfTransactions(rbfTransactions);
|
||||||
|
const recommendedFees = feeApi.getRecommendedFee();
|
||||||
|
|
||||||
this.wss.clients.forEach(async (client: WebSocket) => {
|
this.wss.clients.forEach(async (client: WebSocket) => {
|
||||||
if (client.readyState !== WebSocket.OPEN) {
|
if (client.readyState !== WebSocket.OPEN) {
|
||||||
@ -249,6 +251,7 @@ class WebsocketHandler {
|
|||||||
response['vBytesPerSecond'] = vBytesPerSecond;
|
response['vBytesPerSecond'] = vBytesPerSecond;
|
||||||
response['transactions'] = newTransactions.slice(0, 6).map((tx) => Common.stripTransaction(tx));
|
response['transactions'] = newTransactions.slice(0, 6).map((tx) => Common.stripTransaction(tx));
|
||||||
response['da'] = da;
|
response['da'] = da;
|
||||||
|
response['fees'] = recommendedFees;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (client['want-mempool-blocks']) {
|
if (client['want-mempool-blocks']) {
|
||||||
@ -413,6 +416,7 @@ class WebsocketHandler {
|
|||||||
'block': block,
|
'block': block,
|
||||||
'mempoolInfo': memPool.getMempoolInfo(),
|
'mempoolInfo': memPool.getMempoolInfo(),
|
||||||
'da': difficultyAdjustment.getDifficultyAdjustment(),
|
'da': difficultyAdjustment.getDifficultyAdjustment(),
|
||||||
|
'fees': feeApi.getRecommendedFee(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mBlocks && client['want-mempool-blocks']) {
|
if (mBlocks && client['want-mempool-blocks']) {
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
<div class="fee-estimation-wrapper">
|
<div class="fee-estimation-wrapper">
|
||||||
<div class="fee-estimation-container" *ngIf="(isLoadingWebSocket$ | async) === false && (feeEstimations$ | async) as feeEstimations; else loadingFees">
|
<div class="fee-estimation-container" *ngIf="(isLoadingWebSocket$ | async) === false && (recommendedFees$ | async) as recommendedFees; else loadingFees">
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h5 class="card-title" i18n="fees-box.low-priority">Low priority</h5>
|
<h5 class="card-title" i18n="fees-box.low-priority">Low priority</h5>
|
||||||
<div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
|
<div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
|
||||||
<div class="fee-text">{{ feeEstimations.hourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="feeEstimations.hourFee * 140" ></app-fiat></span>
|
<div class="fee-text">{{ recommendedFees.hourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="recommendedFees.hourFee * 140" ></app-fiat></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h5 class="card-title" i18n="fees-box.medium-priority">Medium priority</h5>
|
<h5 class="card-title" i18n="fees-box.medium-priority">Medium priority</h5>
|
||||||
<div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
|
<div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
|
||||||
<div class="fee-text">{{ feeEstimations.halfHourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="feeEstimations.halfHourFee * 140" ></app-fiat></span>
|
<div class="fee-text">{{ recommendedFees.halfHourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="recommendedFees.halfHourFee * 140" ></app-fiat></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<h5 class="card-title" i18n="fees-box.high-priority">High priority</h5>
|
<h5 class="card-title" i18n="fees-box.high-priority">High priority</h5>
|
||||||
<div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
|
<div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
|
||||||
<div class="fee-text">{{ feeEstimations.fastestFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="feeEstimations.fastestFee * 140" ></app-fiat></span>
|
<div class="fee-text">{{ recommendedFees.fastestFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="recommendedFees.fastestFee * 140" ></app-fiat></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { StateService } from 'src/app/services/state.service';
|
import { StateService } from 'src/app/services/state.service';
|
||||||
import { map, filter } from 'rxjs/operators';
|
import { map, filter, tap } from 'rxjs/operators';
|
||||||
import { merge, Observable } from 'rxjs';
|
import { merge, Observable } from 'rxjs';
|
||||||
import { MempoolBlock } from 'src/app/interfaces/websocket.interface';
|
import { MempoolBlock, Recommendedfees } from 'src/app/interfaces/websocket.interface';
|
||||||
|
|
||||||
interface FeeEstimations {
|
interface FeeEstimations {
|
||||||
fastestFee: number;
|
fastestFee: number;
|
||||||
@ -17,8 +17,8 @@ interface FeeEstimations {
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class FeesBoxComponent implements OnInit {
|
export class FeesBoxComponent implements OnInit {
|
||||||
feeEstimations$: Observable<FeeEstimations>;
|
|
||||||
isLoadingWebSocket$: Observable<boolean>;
|
isLoadingWebSocket$: Observable<boolean>;
|
||||||
|
recommendedFees$: Observable<Recommendedfees>;
|
||||||
defaultFee: number;
|
defaultFee: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -29,40 +29,6 @@ export class FeesBoxComponent implements OnInit {
|
|||||||
this.defaultFee = this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet' ? 0.1 : 1;
|
this.defaultFee = this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet' ? 0.1 : 1;
|
||||||
|
|
||||||
this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$;
|
this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$;
|
||||||
this.feeEstimations$ = this.stateService.mempoolBlocks$
|
this.recommendedFees$ = this.stateService.recommendedFees$;
|
||||||
.pipe(
|
|
||||||
map((pBlocks) => {
|
|
||||||
if (!pBlocks.length) {
|
|
||||||
return {
|
|
||||||
'fastestFee': this.defaultFee,
|
|
||||||
'halfHourFee': this.defaultFee,
|
|
||||||
'hourFee': this.defaultFee,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstMedianFee = this.optimizeMedianFee(pBlocks[0], pBlocks[1]);
|
|
||||||
const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], pBlocks[2], firstMedianFee) : this.defaultFee;
|
|
||||||
const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], pBlocks[3], secondMedianFee) : this.defaultFee;
|
|
||||||
|
|
||||||
return {
|
|
||||||
'fastestFee': firstMedianFee,
|
|
||||||
'halfHourFee': secondMedianFee,
|
|
||||||
'hourFee': thirdMedianFee,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private optimizeMedianFee(pBlock: MempoolBlock, nextBlock: MempoolBlock | undefined, previousFee?: number): number {
|
|
||||||
const useFee = previousFee ? (pBlock.medianFee + previousFee) / 2 : pBlock.medianFee;
|
|
||||||
if (pBlock.blockVSize <= 500000) {
|
|
||||||
return this.defaultFee;
|
|
||||||
}
|
|
||||||
if (pBlock.blockVSize <= 950000 && !nextBlock) {
|
|
||||||
const multiplier = (pBlock.blockVSize - 500000) / 500000;
|
|
||||||
return Math.max(Math.round(useFee * multiplier), this.defaultFee);
|
|
||||||
}
|
|
||||||
return Math.ceil(useFee);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ export interface WebsocketResponse {
|
|||||||
loadingIndicators?: ILoadingIndicators;
|
loadingIndicators?: ILoadingIndicators;
|
||||||
backendInfo?: IBackendInfo;
|
backendInfo?: IBackendInfo;
|
||||||
da?: DifficultyAdjustment;
|
da?: DifficultyAdjustment;
|
||||||
|
fees?: Recommendedfees;
|
||||||
'track-tx'?: string;
|
'track-tx'?: string;
|
||||||
'track-address'?: string;
|
'track-address'?: string;
|
||||||
'track-asset'?: string;
|
'track-asset'?: string;
|
||||||
@ -65,3 +66,11 @@ export interface IBackendInfo {
|
|||||||
gitCommit: string;
|
gitCommit: string;
|
||||||
version: string;
|
version: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Recommendedfees {
|
||||||
|
fastestFee: number;
|
||||||
|
halfHourFee: number;
|
||||||
|
hourFee: number;
|
||||||
|
minimumFee: number;
|
||||||
|
economyFee: number;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
|
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
|
||||||
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable } from 'rxjs';
|
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable } from 'rxjs';
|
||||||
import { Transaction } from '../interfaces/electrs.interface';
|
import { Transaction } from '../interfaces/electrs.interface';
|
||||||
import { IBackendInfo, MempoolBlock, MempoolInfo, ReplacedTransaction, TransactionStripped } from '../interfaces/websocket.interface';
|
import { IBackendInfo, MempoolBlock, MempoolInfo, Recommendedfees, ReplacedTransaction, TransactionStripped } from '../interfaces/websocket.interface';
|
||||||
import { BlockExtended, DifficultyAdjustment, OptimizedMempoolStats } from '../interfaces/node-api.interface';
|
import { BlockExtended, DifficultyAdjustment, OptimizedMempoolStats } from '../interfaces/node-api.interface';
|
||||||
import { Router, NavigationStart } from '@angular/router';
|
import { Router, NavigationStart } from '@angular/router';
|
||||||
import { isPlatformBrowser } from '@angular/common';
|
import { isPlatformBrowser } from '@angular/common';
|
||||||
@ -90,6 +90,7 @@ export class StateService {
|
|||||||
previousRetarget$ = new ReplaySubject<number>(1);
|
previousRetarget$ = new ReplaySubject<number>(1);
|
||||||
backendInfo$ = new ReplaySubject<IBackendInfo>(1);
|
backendInfo$ = new ReplaySubject<IBackendInfo>(1);
|
||||||
loadingIndicators$ = new ReplaySubject<ILoadingIndicators>(1);
|
loadingIndicators$ = new ReplaySubject<ILoadingIndicators>(1);
|
||||||
|
recommendedFees$ = new ReplaySubject<Recommendedfees>(1);
|
||||||
|
|
||||||
live2Chart$ = new Subject<OptimizedMempoolStats>();
|
live2Chart$ = new Subject<OptimizedMempoolStats>();
|
||||||
|
|
||||||
|
@ -263,6 +263,10 @@ export class WebsocketService {
|
|||||||
this.stateService.difficultyAdjustment$.next(response.da);
|
this.stateService.difficultyAdjustment$.next(response.da);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.fees) {
|
||||||
|
this.stateService.recommendedFees$.next(response.fees);
|
||||||
|
}
|
||||||
|
|
||||||
if (response.backendInfo) {
|
if (response.backendInfo) {
|
||||||
this.stateService.backendInfo$.next(response.backendInfo);
|
this.stateService.backendInfo$.next(response.backendInfo);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user