diff --git a/backend/src/api/bitcoin/bitcoin.routes.ts b/backend/src/api/bitcoin/bitcoin.routes.ts
index 69d42f570..e6075ffa2 100644
--- a/backend/src/api/bitcoin/bitcoin.routes.ts
+++ b/backend/src/api/bitcoin/bitcoin.routes.ts
@@ -129,17 +129,7 @@ class BitcoinRoutes {
res.send('Service Unavailable');
return;
}
- let minFee = 0;
- if (req.query.min) {
- try {
- minFee = parseFloat(req.query.min as string);
- } catch (e) {
- res.statusCode = 400;
- res.send('Invalid minimum fee');
- return;
- }
- }
- const result = feeApi.getPreciseRecommendedFee(minFee);
+ const result = feeApi.getPreciseRecommendedFee();
res.json(result);
}
diff --git a/backend/src/api/fee-api.ts b/backend/src/api/fee-api.ts
index 2edb8c0e4..0914a1098 100644
--- a/backend/src/api/fee-api.ts
+++ b/backend/src/api/fee-api.ts
@@ -18,6 +18,9 @@ class FeeApi {
constructor() { }
minimumIncrement = isLiquid ? 0.1 : 1;
+ minFastestFee = isLiquid ? 0.1 : 1;
+ minHalfHourFee = isLiquid ? 0.1 : 0.5;
+ priorityFactor = isLiquid ? 0 : 0.5;
public getRecommendedFee(): RecommendedFees {
const pBlocks = projectedBlocks.getMempoolBlocks();
@@ -26,17 +29,17 @@ class FeeApi {
return this.calculateRecommendedFee(pBlocks, mPool);
}
- public getPreciseRecommendedFee(minimum: number = 0): RecommendedFees {
+ public getPreciseRecommendedFee(): RecommendedFees {
const pBlocks = projectedBlocks.getMempoolBlocks();
const mPool = mempool.getMempoolInfo();
// minimum non-zero minrelaytxfee / incrementalrelayfee is 1 sat/kvB = 0.001 sat/vB
- return this.calculateRecommendedFee(pBlocks, mPool, minimum, 0.001);
+ return this.calculateRecommendedFee(pBlocks, mPool, 0.001);
}
- public calculateRecommendedFee(pBlocks: MempoolBlock[], mPool: IBitcoinApi.MempoolInfo, minimumRecommendation: number = 0, minIncrement: number = this.minimumIncrement): RecommendedFees {
+ public calculateRecommendedFee(pBlocks: MempoolBlock[], mPool: IBitcoinApi.MempoolInfo, minIncrement: number = this.minimumIncrement): RecommendedFees {
const purgeRate = this.roundUpToNearest(mPool.mempoolminfee * 100000, minIncrement);
- const minimumFee = Math.max(purgeRate, minimumRecommendation, minIncrement);
+ const minimumFee = Math.max(purgeRate, minIncrement);
if (!pBlocks.length) {
return {
@@ -67,8 +70,8 @@ class FeeApi {
hourFee = Math.max(hourFee, economyFee);
return {
- 'fastestFee': this.roundToNearest(fastestFee, minIncrement),
- 'halfHourFee': this.roundToNearest(halfHourFee, minIncrement),
+ 'fastestFee': Math.max(this.roundToNearest(fastestFee + this.priorityFactor, minIncrement), this.minFastestFee),
+ 'halfHourFee': Math.max(this.roundToNearest(halfHourFee + (this.priorityFactor / 2), minIncrement), this.minHalfHourFee),
'hourFee': this.roundToNearest(hourFee, minIncrement),
'economyFee': this.roundToNearest(economyFee, minIncrement),
'minimumFee': this.roundToNearest(minimumFee, minIncrement),
diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts
index 57fd46730..532d6d4a1 100644
--- a/backend/src/api/websocket-handler.ts
+++ b/backend/src/api/websocket-handler.ts
@@ -102,7 +102,7 @@ class WebsocketHandler {
'backendInfo': backendInfo.getBackendInfo(),
'loadingIndicators': loadingIndicators.getLoadingIndicators(),
'da': da?.previousTime ? da : undefined,
- 'fees': feeApi.getRecommendedFee(),
+ 'fees': feeApi.getPreciseRecommendedFee(),
});
}
@@ -639,7 +639,7 @@ class WebsocketHandler {
}
memPool.removeFromSpendMap(deletedTransactions);
memPool.addToSpendMap(newTransactions);
- const recommendedFees = feeApi.getRecommendedFee();
+ const recommendedFees = feeApi.getPreciseRecommendedFee();
const latestTransactions = memPool.getLatestTransactions();
@@ -1137,7 +1137,7 @@ class WebsocketHandler {
const mBlockDeltas = mempoolBlocks.getMempoolBlockDeltas();
const da = difficultyAdjustment.getDifficultyAdjustment();
- const fees = feeApi.getRecommendedFee();
+ const fees = feeApi.getPreciseRecommendedFee();
const mempoolInfo = memPool.getMempoolInfo();
// pre-compute address transactions
diff --git a/frontend/src/app/components/clock/clock.component.html b/frontend/src/app/components/clock/clock.component.html
index 376d72bfc..3d23f68dc 100644
--- a/frontend/src/app/components/clock/clock.component.html
+++ b/frontend/src/app/components/clock/clock.component.html
@@ -46,7 +46,7 @@
diff --git a/frontend/src/app/components/fees-box/fees-box.component.html b/frontend/src/app/components/fees-box/fees-box.component.html
index 580307df5..a3b2a5286 100644
--- a/frontend/src/app/components/fees-box/fees-box.component.html
+++ b/frontend/src/app/components/fees-box/fees-box.component.html
@@ -10,26 +10,27 @@
High Priority
+
diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts
index b82b32dd5..8979ce4cf 100644
--- a/frontend/src/app/services/websocket.service.ts
+++ b/frontend/src/app/services/websocket.service.ts
@@ -428,7 +428,9 @@ export class WebsocketService {
}
if (response.fees) {
- this.stateService.recommendedFees$.next(response.fees);
+ this.stateService.recommendedFees$.next({
+ ...response.fees,
+ });
}
if (response.backendInfo) {
diff --git a/frontend/src/app/shared/components/fee-rate/fee-rate.component.html b/frontend/src/app/shared/components/fee-rate/fee-rate.component.html
index f9e86cc2b..0f4491dd1 100644
--- a/frontend/src/app/shared/components/fee-rate/fee-rate.component.html
+++ b/frontend/src/app/shared/components/fee-rate/fee-rate.component.html
@@ -1,7 +1,7 @@
- {{ fee / (weight / 4) | feeRounding:rounding }} sat/vB
- {{ fee / weight | feeRounding:rounding }} sat/WU
+ {{ fee / (weight / 4) | feeRounding:rounding:dp }} sat/vB
+ {{ fee / weight | feeRounding:rounding:dp }} sat/WU
- sat/vB
diff --git a/frontend/src/app/shared/components/fee-rate/fee-rate.component.ts b/frontend/src/app/shared/components/fee-rate/fee-rate.component.ts
index 857b653c3..c71f5f5f9 100644
--- a/frontend/src/app/shared/components/fee-rate/fee-rate.component.ts
+++ b/frontend/src/app/shared/components/fee-rate/fee-rate.component.ts
@@ -1,6 +1,7 @@
import { Component, Input, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { StateService } from '@app/services/state.service';
+import { FeeRoundingPipe } from '@app/shared/pipes/fee-rounding/fee-rounding.pipe';
@Component({
selector: 'app-fee-rate',
@@ -12,6 +13,8 @@ export class FeeRateComponent implements OnInit {
@Input() fee: number | undefined;
@Input() weight: number = 4;
@Input() rounding: string = null;
+ @Input() dp: number = null;
+ @Input() softDecimals: boolean = false;
@Input() showUnit: boolean = true;
@Input() unitClass: string = 'symbol';
@Input() unitStyle: any;
@@ -20,9 +23,22 @@ export class FeeRateComponent implements OnInit {
constructor(
private stateService: StateService,
+ private feeRoundingPipe: FeeRoundingPipe,
) { }
ngOnInit() {
this.rateUnits$ = this.stateService.rateUnits$;
}
+
+ getIntegerPart(rate: number): string {
+ const formatted = this.feeRoundingPipe.transform(rate, this.rounding, this.dp);
+ const decimalIndex = formatted.indexOf('.');
+ return decimalIndex === -1 ? formatted : formatted.substring(0, decimalIndex);
+ }
+
+ getDecimalPart(rate: number): string {
+ const formatted = this.feeRoundingPipe.transform(rate, this.rounding, this.dp);
+ const decimalIndex = formatted.indexOf('.');
+ return decimalIndex === -1 ? ' ' : formatted.substring(decimalIndex) + ' ';
+ }
}
diff --git a/frontend/src/app/shared/pipes/fee-rounding/fee-rounding.pipe.ts b/frontend/src/app/shared/pipes/fee-rounding/fee-rounding.pipe.ts
index e2a6e9968..1e7a51e9b 100644
--- a/frontend/src/app/shared/pipes/fee-rounding/fee-rounding.pipe.ts
+++ b/frontend/src/app/shared/pipes/fee-rounding/fee-rounding.pipe.ts
@@ -10,16 +10,16 @@ export class FeeRoundingPipe implements PipeTransform {
@Inject(LOCALE_ID) private locale: string,
) {}
- transform(fee: number, rounding = null): string {
+ transform(fee: number, rounding = null, dp = 3): string {
if (rounding) {
return formatNumber(fee, this.locale, rounding);
}
- if (fee >= 100) {
- return formatNumber(fee, this.locale, '1.0-0')
- } else if (fee < 10) {
- return formatNumber(fee, this.locale, '1.2-2')
+ if (fee >= Math.pow(10, (dp || 3) - 1)) {
+ return formatNumber(fee, this.locale, '1.0-0');
+ } else if (fee < Math.pow(10, (dp || 3) - 2)) {
+ return formatNumber(fee, this.locale, '1.2-2');
}
- return formatNumber(fee, this.locale, '1.1-1')
+ return formatNumber(fee, this.locale, '1.1-1');
}
}
diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts
index 6ac11ca90..146c4c9b6 100644
--- a/frontend/src/app/shared/shared.module.ts
+++ b/frontend/src/app/shared/shared.module.ts
@@ -279,6 +279,7 @@ import { GithubLogin } from '@components/github-login.component/github-login.com
ShortenStringPipe,
CapAddressPipe,
AmountShortenerPipe,
+ FeeRoundingPipe,
],
exports: [
MenuComponent,