Compare commits

..

7 Commits

Author SHA1 Message Date
natsoni
4fded37cda Use decimal recommended fee in websocket and on dashboard 2024-08-23 16:08:05 +02:00
natsoni
e3c06eb93b Add V2 API endpoint for decimal recommended fees 2024-08-23 16:06:36 +02:00
natsoni
2664f52a23 Proxy /api/v2/ on dev and prod environments 2024-08-23 15:42:25 +02:00
natsoni
37030356dd Add API V2 URL prefix to production backend 2024-08-23 14:14:42 +02:00
natsoni
cfe4228a4c Add API V2 URL prefix to backend config 2024-08-23 14:12:38 +02:00
softsimon
5452d7f524 pull from transifex 2024-08-20 09:32:56 +02:00
wiz
ff9e2456b9 ops: Tweak build script to support tags 2024-08-20 15:22:16 +09:00
27 changed files with 179 additions and 35 deletions

View File

@@ -7,6 +7,7 @@
"HTTP_PORT": 8999, "HTTP_PORT": 8999,
"SPAWN_CLUSTER_PROCS": 0, "SPAWN_CLUSTER_PROCS": 0,
"API_URL_PREFIX": "/api/v1/", "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/",
"POLL_RATE_MS": 2000, "POLL_RATE_MS": 2000,
"CACHE_DIR": "./cache", "CACHE_DIR": "./cache",
"CACHE_ENABLED": true, "CACHE_ENABLED": true,

View File

@@ -10,6 +10,7 @@
"UNIX_SOCKET_PATH": "/mempool/socket/mempool-bitcoin-mainnet", "UNIX_SOCKET_PATH": "/mempool/socket/mempool-bitcoin-mainnet",
"SPAWN_CLUSTER_PROCS": 2, "SPAWN_CLUSTER_PROCS": 2,
"API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__", "API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__",
"API_V2_URL_PREFIX": "__MEMPOOL_API_V2_URL_PREFIX__",
"AUTOMATIC_POOLS_UPDATE": false, "AUTOMATIC_POOLS_UPDATE": false,
"POLL_RATE_MS": 3, "POLL_RATE_MS": 3,
"CACHE_DIR": "__MEMPOOL_CACHE_DIR__", "CACHE_DIR": "__MEMPOOL_CACHE_DIR__",

View File

@@ -23,6 +23,7 @@ describe('Mempool Backend Config', () => {
UNIX_SOCKET_PATH: '', UNIX_SOCKET_PATH: '',
SPAWN_CLUSTER_PROCS: 0, SPAWN_CLUSTER_PROCS: 0,
API_URL_PREFIX: '/api/v1/', API_URL_PREFIX: '/api/v1/',
API_V2_URL_PREFIX: '/api/v2/',
AUTOMATIC_POOLS_UPDATE: false, AUTOMATIC_POOLS_UPDATE: false,
POLL_RATE_MS: 2000, POLL_RATE_MS: 2000,
CACHE_DIR: './cache', CACHE_DIR: './cache',

View File

@@ -47,6 +47,9 @@ class BitcoinRoutes {
.post(config.MEMPOOL.API_URL_PREFIX + 'psbt/addparents', this.postPsbtCompletion) .post(config.MEMPOOL.API_URL_PREFIX + 'psbt/addparents', this.postPsbtCompletion)
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from', this.getBlocksByBulk.bind(this)) .get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from', this.getBlocksByBulk.bind(this))
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from/:to', this.getBlocksByBulk.bind(this)) .get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from/:to', this.getBlocksByBulk.bind(this))
// V2 API
.get(config.MEMPOOL.API_V2_URL_PREFIX + 'fees/recommended', this.getRecommendedFeesDecimal)
; ;
if (config.MEMPOOL.BACKEND !== 'esplora') { if (config.MEMPOOL.BACKEND !== 'esplora') {
@@ -100,6 +103,16 @@ class BitcoinRoutes {
res.json(result); res.json(result);
} }
private getRecommendedFeesDecimal(req: Request, res: Response) {
if (!mempool.isInSync()) {
res.statusCode = 503;
res.send('Service Unavailable');
return;
}
const result = feeApi.getRecommendedFee(true);
res.json(result);
}
private getMempoolBlocks(req: Request, res: Response) { private getMempoolBlocks(req: Request, res: Response) {
try { try {
const result = mempoolBlocks.getMempoolBlocks(); const result = mempoolBlocks.getMempoolBlocks();

View File

@@ -19,10 +19,12 @@ class FeeApi {
defaultFee = isLiquid ? 0.1 : 1; defaultFee = isLiquid ? 0.1 : 1;
minimumIncrement = isLiquid ? 0.1 : 1; minimumIncrement = isLiquid ? 0.1 : 1;
public getRecommendedFee(): RecommendedFees { public getRecommendedFee(decimal: boolean = false): RecommendedFees {
const pBlocks = projectedBlocks.getMempoolBlocks(); const pBlocks = projectedBlocks.getMempoolBlocks();
const mPool = mempool.getMempoolInfo(); const mPool = mempool.getMempoolInfo();
const minimumFee = this.roundUpToNearest(mPool.mempoolminfee * 100000, this.minimumIncrement); const minimumFee = decimal ?
this.roundUpToNearestDecimal(mPool.mempoolminfee * 100000) :
this.roundUpToNearest(mPool.mempoolminfee * 100000, this.minimumIncrement);
const defaultMinFee = Math.max(minimumFee, this.defaultFee); const defaultMinFee = Math.max(minimumFee, this.defaultFee);
if (!pBlocks.length) { if (!pBlocks.length) {
@@ -35,9 +37,9 @@ class FeeApi {
}; };
} }
const firstMedianFee = this.optimizeMedianFee(pBlocks[0], pBlocks[1]); const firstMedianFee = this.optimizeMedianFee(pBlocks[0], pBlocks[1], undefined, decimal);
const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], pBlocks[2], firstMedianFee) : this.defaultFee; const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], pBlocks[2], firstMedianFee, decimal) : this.defaultFee;
const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], pBlocks[3], secondMedianFee) : this.defaultFee; const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], pBlocks[3], secondMedianFee, decimal) : this.defaultFee;
let fastestFee = Math.max(minimumFee, firstMedianFee); let fastestFee = Math.max(minimumFee, firstMedianFee);
let halfHourFee = Math.max(minimumFee, secondMedianFee); let halfHourFee = Math.max(minimumFee, secondMedianFee);
@@ -62,7 +64,7 @@ class FeeApi {
}; };
} }
private optimizeMedianFee(pBlock: MempoolBlock, nextBlock: MempoolBlock | undefined, previousFee?: number): number { private optimizeMedianFee(pBlock: MempoolBlock, nextBlock: MempoolBlock | undefined, previousFee?: number, decimal: boolean = false): number {
const useFee = previousFee ? (pBlock.medianFee + previousFee) / 2 : pBlock.medianFee; const useFee = previousFee ? (pBlock.medianFee + previousFee) / 2 : pBlock.medianFee;
if (pBlock.blockVSize <= 500000) { if (pBlock.blockVSize <= 500000) {
return this.defaultFee; return this.defaultFee;
@@ -71,12 +73,18 @@ class FeeApi {
const multiplier = (pBlock.blockVSize - 500000) / 500000; const multiplier = (pBlock.blockVSize - 500000) / 500000;
return Math.max(Math.round(useFee * multiplier), this.defaultFee); return Math.max(Math.round(useFee * multiplier), this.defaultFee);
} }
return this.roundUpToNearest(useFee, this.minimumIncrement); return decimal ?
this.roundUpToNearestDecimal(useFee) :
this.roundUpToNearest(useFee, this.minimumIncrement);
} }
private roundUpToNearest(value: number, nearest: number): number { private roundUpToNearest(value: number, nearest: number): number {
return Math.ceil(value / nearest) * nearest; return Math.ceil(value / nearest) * nearest;
} }
private roundUpToNearestDecimal(value: number): number {
return Number(this.roundUpToNearest(value, 0.1).toFixed(1)); // avoid floating point errors
}
} }
export default new FeeApi(); export default new FeeApi();

View File

@@ -95,7 +95,7 @@ class WebsocketHandler {
'backendInfo': backendInfo.getBackendInfo(), 'backendInfo': backendInfo.getBackendInfo(),
'loadingIndicators': loadingIndicators.getLoadingIndicators(), 'loadingIndicators': loadingIndicators.getLoadingIndicators(),
'da': da?.previousTime ? da : undefined, 'da': da?.previousTime ? da : undefined,
'fees': feeApi.getRecommendedFee(), 'fees': feeApi.getRecommendedFee(true),
}); });
} }
@@ -567,7 +567,7 @@ class WebsocketHandler {
} }
memPool.removeFromSpendMap(deletedTransactions); memPool.removeFromSpendMap(deletedTransactions);
memPool.addToSpendMap(newTransactions); memPool.addToSpendMap(newTransactions);
const recommendedFees = feeApi.getRecommendedFee(); const recommendedFees = feeApi.getRecommendedFee(true);
const latestTransactions = memPool.getLatestTransactions(); const latestTransactions = memPool.getLatestTransactions();
@@ -1048,7 +1048,7 @@ class WebsocketHandler {
const mBlockDeltas = mempoolBlocks.getMempoolBlockDeltas(); const mBlockDeltas = mempoolBlocks.getMempoolBlockDeltas();
const da = difficultyAdjustment.getDifficultyAdjustment(); const da = difficultyAdjustment.getDifficultyAdjustment();
const fees = feeApi.getRecommendedFee(); const fees = feeApi.getRecommendedFee(true);
const mempoolInfo = memPool.getMempoolInfo(); const mempoolInfo = memPool.getMempoolInfo();
// pre-compute address transactions // pre-compute address transactions

View File

@@ -12,6 +12,7 @@ interface IConfig {
UNIX_SOCKET_PATH: string; UNIX_SOCKET_PATH: string;
SPAWN_CLUSTER_PROCS: number; SPAWN_CLUSTER_PROCS: number;
API_URL_PREFIX: string; API_URL_PREFIX: string;
API_V2_URL_PREFIX: string;
POLL_RATE_MS: number; POLL_RATE_MS: number;
CACHE_DIR: string; CACHE_DIR: string;
CACHE_ENABLED: boolean; CACHE_ENABLED: boolean;
@@ -172,6 +173,7 @@ const defaults: IConfig = {
'UNIX_SOCKET_PATH': '', 'UNIX_SOCKET_PATH': '',
'SPAWN_CLUSTER_PROCS': 0, 'SPAWN_CLUSTER_PROCS': 0,
'API_URL_PREFIX': '/api/v1/', 'API_URL_PREFIX': '/api/v1/',
'API_V2_URL_PREFIX': '/api/v2/',
'POLL_RATE_MS': 2000, 'POLL_RATE_MS': 2000,
'CACHE_DIR': './cache', 'CACHE_DIR': './cache',
'CACHE_ENABLED': true, 'CACHE_ENABLED': true,

View File

@@ -8,6 +8,7 @@
"SPAWN_CLUSTER_PROCS": __MEMPOOL_SPAWN_CLUSTER_PROCS__, "SPAWN_CLUSTER_PROCS": __MEMPOOL_SPAWN_CLUSTER_PROCS__,
"UNIX_SOCKET_PATH": "__MEMPOOL_UNIX_SOCKET_PATH__", "UNIX_SOCKET_PATH": "__MEMPOOL_UNIX_SOCKET_PATH__",
"API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__", "API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__",
"API_V2_URL_PREFIX": "__MEMPOOL_API_V2_URL_PREFIX__",
"POLL_RATE_MS": __MEMPOOL_POLL_RATE_MS__, "POLL_RATE_MS": __MEMPOOL_POLL_RATE_MS__,
"CACHE_DIR": "__MEMPOOL_CACHE_DIR__", "CACHE_DIR": "__MEMPOOL_CACHE_DIR__",
"CACHE_ENABLED": __MEMPOOL_CACHE_ENABLED__, "CACHE_ENABLED": __MEMPOOL_CACHE_ENABLED__,

View File

@@ -9,6 +9,7 @@ __MEMPOOL_HTTP_PORT__=${BACKEND_HTTP_PORT:=8999}
__MEMPOOL_SPAWN_CLUSTER_PROCS__=${MEMPOOL_SPAWN_CLUSTER_PROCS:=0} __MEMPOOL_SPAWN_CLUSTER_PROCS__=${MEMPOOL_SPAWN_CLUSTER_PROCS:=0}
__MEMPOOL_UNIX_SOCKET_PATH__=${MEMPOOL_UNIX_SOCKET_PATH:=""} __MEMPOOL_UNIX_SOCKET_PATH__=${MEMPOOL_UNIX_SOCKET_PATH:=""}
__MEMPOOL_API_URL_PREFIX__=${MEMPOOL_API_URL_PREFIX:=/api/v1/} __MEMPOOL_API_URL_PREFIX__=${MEMPOOL_API_URL_PREFIX:=/api/v1/}
__MEMPOOL_API_V2_URL_PREFIX__=${MEMPOOL_API_V2_URL_PREFIX:=/api/v2/}
__MEMPOOL_POLL_RATE_MS__=${MEMPOOL_POLL_RATE_MS:=2000} __MEMPOOL_POLL_RATE_MS__=${MEMPOOL_POLL_RATE_MS:=2000}
__MEMPOOL_CACHE_DIR__=${MEMPOOL_CACHE_DIR:=./cache} __MEMPOOL_CACHE_DIR__=${MEMPOOL_CACHE_DIR:=./cache}
__MEMPOOL_CACHE_ENABLED__=${MEMPOOL_CACHE_ENABLED:=true} __MEMPOOL_CACHE_ENABLED__=${MEMPOOL_CACHE_ENABLED:=true}
@@ -167,6 +168,7 @@ sed -i "s!__MEMPOOL_HTTP_PORT__!${__MEMPOOL_HTTP_PORT__}!g" mempool-config.json
sed -i "s!__MEMPOOL_SPAWN_CLUSTER_PROCS__!${__MEMPOOL_SPAWN_CLUSTER_PROCS__}!g" mempool-config.json sed -i "s!__MEMPOOL_SPAWN_CLUSTER_PROCS__!${__MEMPOOL_SPAWN_CLUSTER_PROCS__}!g" mempool-config.json
sed -i "s!__MEMPOOL_UNIX_SOCKET_PATH__!${__MEMPOOL_UNIX_SOCKET_PATH__}!g" mempool-config.json sed -i "s!__MEMPOOL_UNIX_SOCKET_PATH__!${__MEMPOOL_UNIX_SOCKET_PATH__}!g" mempool-config.json
sed -i "s!__MEMPOOL_API_URL_PREFIX__!${__MEMPOOL_API_URL_PREFIX__}!g" mempool-config.json sed -i "s!__MEMPOOL_API_URL_PREFIX__!${__MEMPOOL_API_URL_PREFIX__}!g" mempool-config.json
sed -i "s!__MEMPOOL_API_V2_URL_PREFIX__!${__MEMPOOL_API_V2_URL_PREFIX__}!g" mempool-config.json
sed -i "s!__MEMPOOL_POLL_RATE_MS__!${__MEMPOOL_POLL_RATE_MS__}!g" mempool-config.json sed -i "s!__MEMPOOL_POLL_RATE_MS__!${__MEMPOOL_POLL_RATE_MS__}!g" mempool-config.json
sed -i "s!__MEMPOOL_CACHE_DIR__!${__MEMPOOL_CACHE_DIR__}!g" mempool-config.json sed -i "s!__MEMPOOL_CACHE_DIR__!${__MEMPOOL_CACHE_DIR__}!g" mempool-config.json
sed -i "s!__MEMPOOL_CACHE_ENABLED__!${__MEMPOOL_CACHE_ENABLED__}!g" mempool-config.json sed -i "s!__MEMPOOL_CACHE_ENABLED__!${__MEMPOOL_CACHE_ENABLED__}!g" mempool-config.json

View File

@@ -33,6 +33,17 @@ if (configContent && configContent.BASE_MODULE === 'liquid') {
"^/liquid": "" "^/liquid": ""
}, },
}, },
{
context: ['/liquid/api/v2/**'],
target: `http://127.0.0.1:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
pathRewrite: {
"^/liquid": ""
},
},
{ {
context: ['/liquid/api/**'], context: ['/liquid/api/**'],
target: `http://127.0.0.1:3000`, target: `http://127.0.0.1:3000`,
@@ -54,6 +65,17 @@ if (configContent && configContent.BASE_MODULE === 'liquid') {
"^/liquidtestnet": "" "^/liquidtestnet": ""
}, },
}, },
{
context: ['/liquidtestnet/api/v2/**'],
target: `http://127.0.0.1:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
pathRewrite: {
"^/liquidtestnet": ""
},
},
{ {
context: ['/liquidtestnet/api/**'], context: ['/liquidtestnet/api/**'],
target: `http://127.0.0.1:3000`, target: `http://127.0.0.1:3000`,
@@ -106,6 +128,14 @@ PROXY_CONFIG.push(...[
changeOrigin: true, changeOrigin: true,
proxyTimeout: 30000, proxyTimeout: 30000,
}, },
{
context: ['/api/v2/**'],
target: `http://127.0.0.1:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
},
{ {
context: ['/api/**'], context: ['/api/**'],
target: `http://127.0.0.1:3000`, target: `http://127.0.0.1:3000`,

View File

@@ -33,6 +33,17 @@ if (configContent && configContent.BASE_MODULE === 'liquid') {
"^/liquid": "" "^/liquid": ""
}, },
}, },
{
context: ['/liquid/api/v2/**'],
target: `http://localhost:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
pathRewrite: {
"^/liquid": ""
},
},
{ {
context: ['/liquid/api/**'], context: ['/liquid/api/**'],
target: `http://localhost:8999`, target: `http://localhost:8999`,
@@ -54,6 +65,17 @@ if (configContent && configContent.BASE_MODULE === 'liquid') {
"^/liquidtestnet": "" "^/liquidtestnet": ""
}, },
}, },
{
context: ['/liquidtestnet/api/v2/**'],
target: `http://localhost:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
pathRewrite: {
"^/liquidtestnet": ""
},
},
{ {
context: ['/liquidtestnet/api/**'], context: ['/liquidtestnet/api/**'],
target: `http://localhost:8999`, target: `http://localhost:8999`,
@@ -94,6 +116,14 @@ PROXY_CONFIG.push(...[
changeOrigin: true, changeOrigin: true,
proxyTimeout: 30000, proxyTimeout: 30000,
}, },
{
context: ['/api/v2/**'],
target: `http://localhost:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
},
{ {
context: ['/api/**'], context: ['/api/**'],
target: `http://localhost:8999`, target: `http://localhost:8999`,

View File

@@ -33,6 +33,17 @@ if (configContent && configContent.BASE_MODULE === 'liquid') {
"^/liquid": "" "^/liquid": ""
}, },
}, },
{
context: ['/liquid/api/v2/**'],
target: `http://localhost:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
pathRewrite: {
"^/liquid": ""
},
},
{ {
context: ['/liquid/api/**'], context: ['/liquid/api/**'],
target: `https://liquid.network`, target: `https://liquid.network`,
@@ -51,6 +62,17 @@ if (configContent && configContent.BASE_MODULE === 'liquid') {
"^/liquidtestnet": "" "^/liquidtestnet": ""
}, },
}, },
{
context: ['/liquidtestnet/api/v2/**'],
target: `http://localhost:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
pathRewrite: {
"^/liquidtestnet": ""
},
},
{ {
context: ['/liquidtestnet/api/**'], context: ['/liquidtestnet/api/**'],
target: `https://liquid.network`, target: `https://liquid.network`,
@@ -78,6 +100,14 @@ PROXY_CONFIG.push(...[
changeOrigin: true, changeOrigin: true,
proxyTimeout: 30000, proxyTimeout: 30000,
}, },
{
context: ['/api/v2/**'],
target: `http://localhost:8999`,
secure: false,
ws: true,
changeOrigin: true,
proxyTimeout: 30000,
},
{ {
context: ['/api/**'], context: ['/api/**'],
target: `https://mempool.space`, target: `https://mempool.space`,

View File

@@ -13,23 +13,23 @@
<div class="fee-estimation-container"> <div class="fee-estimation-container">
<div class="item"> <div class="item">
<div class="card-text"> <div class="card-text">
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.economyFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.economyFee * 140" ></app-fiat></span> <div class="fee-text"><app-fee-rate [fee]="recommendedFees.economyFee" rounding="1.0-1"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.economyFee * 140" ></app-fiat></span>
</div> </div>
</div> </div>
<div class="band-separator"></div> <div class="band-separator"></div>
<div class="item"> <div class="item">
<div class="card-text"> <div class="card-text">
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.hourFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.hourFee * 140" ></app-fiat></span> <div class="fee-text"><app-fee-rate [fee]="recommendedFees.hourFee" rounding="1.0-1"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.hourFee * 140" ></app-fiat></span>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<div class="card-text"> <div class="card-text">
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.halfHourFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.halfHourFee * 140" ></app-fiat></span> <div class="fee-text"><app-fee-rate [fee]="recommendedFees.halfHourFee" rounding="1.0-1"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.halfHourFee * 140" ></app-fiat></span>
</div> </div>
</div> </div>
<div class="item"> <div class="item">
<div class="card-text"> <div class="card-text">
<div class="fee-text"><app-fee-rate [fee]="recommendedFees.fastestFee" rounding="1.0-0"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.fastestFee * 140" ></app-fiat></span> <div class="fee-text"><app-fee-rate [fee]="recommendedFees.fastestFee" rounding="1.0-1"></app-fee-rate></div> <span class="fiat"><app-fiat i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom" [value]="recommendedFees.fastestFee * 140" ></app-fiat></span>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -36,7 +36,7 @@ export class FeesBoxComponent implements OnInit, OnDestroy {
this.recommendedFees$ = this.stateService.recommendedFees$ this.recommendedFees$ = this.stateService.recommendedFees$
.pipe( .pipe(
tap((fees) => { tap((fees) => {
this.fees = fees; this.fees = this.roundFees(fees);
this.setFeeGradient(); this.setFeeGradient();
} }
) )
@@ -61,6 +61,19 @@ export class FeesBoxComponent implements OnInit, OnDestroy {
this.cd.markForCheck(); this.cd.markForCheck();
} }
roundFees(fees: Recommendedfees): Recommendedfees {
fees.fastestFee = this.roundFeeValue(fees.fastestFee);
fees.halfHourFee = this.roundFeeValue(fees.halfHourFee);
fees.hourFee = this.roundFeeValue(fees.hourFee);
fees.economyFee = this.roundFeeValue(fees.economyFee);
fees.minimumFee = this.roundFeeValue(fees.minimumFee);
return fees;
}
roundFeeValue(fee: number): number {
return fee >= 10.0 ? Math.ceil(fee) : fee;
}
ngOnDestroy(): void { ngOnDestroy(): void {
this.themeSubscription.unsubscribe(); this.themeSubscription.unsubscribe();
} }

View File

@@ -1567,7 +1567,7 @@
</trans-unit> </trans-unit>
<trans-unit id="bdb8bbb38e4ca3c73e19dc4167fbe4aec316f818" datatype="html"> <trans-unit id="bdb8bbb38e4ca3c73e19dc4167fbe4aec316f818" datatype="html">
<source>Total Bid Boost</source> <source>Total Bid Boost</source>
<target>Ukupno povećanje ponude</target> <target>Total Bid Boost</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-stats/acceleration-stats.component.html</context> <context context-type="sourcefile">src/app/components/acceleration/acceleration-stats/acceleration-stats.component.html</context>
<context context-type="linenumber">11</context> <context context-type="linenumber">11</context>
@@ -1969,7 +1969,7 @@
</trans-unit> </trans-unit>
<trans-unit id="841f2a74ae5095e6e37f5749f3cc1851cf36a420" datatype="html"> <trans-unit id="841f2a74ae5095e6e37f5749f3cc1851cf36a420" datatype="html">
<source>Avg Max Bid</source> <source>Avg Max Bid</source>
<target>Prosječna maks. ponuda</target> <target>Prosj. max ponuda</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/pending-stats/pending-stats.component.html</context> <context context-type="sourcefile">src/app/components/acceleration/pending-stats/pending-stats.component.html</context>
<context context-type="linenumber">11</context> <context context-type="linenumber">11</context>
@@ -3622,7 +3622,7 @@
</trans-unit> </trans-unit>
<trans-unit id="14779b0ce4cbc4d975a35a8fe074426228a324f3" datatype="html"> <trans-unit id="14779b0ce4cbc4d975a35a8fe074426228a324f3" datatype="html">
<source><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> transactions</source> <source><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> transactions</source>
<target><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> transakcije</target> <target><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> transakcija</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block-transactions.component.html</context> <context context-type="sourcefile">src/app/components/block/block-transactions.component.html</context>
<context context-type="linenumber">5</context> <context context-type="linenumber">5</context>
@@ -4046,7 +4046,7 @@
</trans-unit> </trans-unit>
<trans-unit id="8a7b4bd44c0ac71b2e72de0398b303257f7d2f54" datatype="html"> <trans-unit id="8a7b4bd44c0ac71b2e72de0398b303257f7d2f54" datatype="html">
<source>Blocks</source> <source>Blocks</source>
<target>Blokovi</target> <target>Blokova</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.html</context> <context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.html</context>
<context context-type="linenumber">4</context> <context context-type="linenumber">4</context>
@@ -4360,7 +4360,7 @@
</trans-unit> </trans-unit>
<trans-unit id="23c872b0336e20284724607f2887da39bd8142c3" datatype="html"> <trans-unit id="23c872b0336e20284724607f2887da39bd8142c3" datatype="html">
<source>Previous fee</source> <source>Previous fee</source>
<target>Prethodna naknada</target> <target>Preth. naknada</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context> <context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">107</context> <context context-type="linenumber">107</context>
@@ -4594,7 +4594,7 @@
</trans-unit> </trans-unit>
<trans-unit id="1bb6965f8e1bbe40c076528ffd841da86f57f119" datatype="html"> <trans-unit id="1bb6965f8e1bbe40c076528ffd841da86f57f119" datatype="html">
<source><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;blocks&lt;/span&gt;&lt;/ng-template&gt; &lt;ng-"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>blocks<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source> <source><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;blocks&lt;/span&gt;&lt;/ng-template&gt; &lt;ng-"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>blocks<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
<target><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;blocks&lt;/span&gt;&lt;/ng-template&gt; &lt;ng-"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>blokovi<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target> <target><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;blocks&lt;/span&gt;&lt;/ng-template&gt; &lt;ng-"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>blokova<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context> <context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="linenumber">10,11</context> <context context-type="linenumber">10,11</context>
@@ -4671,7 +4671,7 @@
</trans-unit> </trans-unit>
<trans-unit id="df71fa93f0503396ea2bb3ba5161323330314d6c" datatype="html"> <trans-unit id="df71fa93f0503396ea2bb3ba5161323330314d6c" datatype="html">
<source>Next Halving</source> <source>Next Halving</source>
<target>Sljedeće prepolovljenje</target> <target>Slj prepolovljenje</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context> <context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="linenumber">47</context> <context context-type="linenumber">47</context>
@@ -5465,7 +5465,7 @@
</trans-unit> </trans-unit>
<trans-unit id="1a8246eba9a999ee881248c4767d63b875ef07fe" datatype="html"> <trans-unit id="1a8246eba9a999ee881248c4767d63b875ef07fe" datatype="html">
<source>blocks</source> <source>blocks</source>
<target>blokovi</target> <target>blokova</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component.html</context> <context context-type="sourcefile">src/app/components/liquid-reserves-audit/federation-utxos-list/federation-utxos-list.component.html</context>
<context context-type="linenumber">63</context> <context context-type="linenumber">63</context>
@@ -5885,7 +5885,7 @@
</trans-unit> </trans-unit>
<trans-unit id="9ef8b357c32266f8423e24bf654006d3aa8fcd0b" datatype="html"> <trans-unit id="9ef8b357c32266f8423e24bf654006d3aa8fcd0b" datatype="html">
<source>Blocks (1w)</source> <source>Blocks (1w)</source>
<target>Blokova (1w)</target> <target>Blokova (1 tj)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context> <context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
<context context-type="linenumber">25</context> <context context-type="linenumber">25</context>
@@ -6165,7 +6165,7 @@
</trans-unit> </trans-unit>
<trans-unit id="3dc78651b2810cbb6e830fe7e57499d8cf6a8e4d" datatype="html"> <trans-unit id="3dc78651b2810cbb6e830fe7e57499d8cf6a8e4d" datatype="html">
<source>Blocks (24h)</source> <source>Blocks (24h)</source>
<target>Blokovi (24h)</target> <target>Blokova (24h)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context> <context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
<context context-type="linenumber">120</context> <context context-type="linenumber">120</context>
@@ -6815,7 +6815,7 @@
</trans-unit> </trans-unit>
<trans-unit id="time-until" datatype="html"> <trans-unit id="time-until" datatype="html">
<source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source> <source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
<target>U ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></target> <target>Za ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context> <context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">188</context> <context context-type="linenumber">188</context>

View File

@@ -510,7 +510,7 @@
</trans-unit> </trans-unit>
<trans-unit id="e4b2d9e6a2ab9e6ca34027ec03beaac42b7badd4" datatype="html"> <trans-unit id="e4b2d9e6a2ab9e6ca34027ec03beaac42b7badd4" datatype="html">
<source>sats</source> <source>sats</source>
<target>sats</target> <target>sat</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">57</context> <context context-type="linenumber">57</context>
@@ -881,7 +881,7 @@
</trans-unit> </trans-unit>
<trans-unit id="65fd4251d8ddfe4017d4d83f8cec6f5a80d89289" datatype="html"> <trans-unit id="65fd4251d8ddfe4017d4d83f8cec6f5a80d89289" datatype="html">
<source>Pay</source> <source>Pay</source>
<target>Betale</target> <target>Betal</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context> <context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">378</context> <context context-type="linenumber">378</context>
@@ -4846,7 +4846,7 @@
</trans-unit> </trans-unit>
<trans-unit id="615ba6c4511a36f93c225c725935fdbf16f162a5" datatype="html"> <trans-unit id="615ba6c4511a36f93c225c725935fdbf16f162a5" datatype="html">
<source>Amount (sats)</source> <source>Amount (sats)</source>
<target>Beløp (sats)</target> <target>Beløp (sat)</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/faucet/faucet.component.html</context> <context context-type="sourcefile">src/app/components/faucet/faucet.component.html</context>
<context context-type="linenumber">51</context> <context context-type="linenumber">51</context>
@@ -6442,7 +6442,7 @@
</trans-unit> </trans-unit>
<trans-unit id="31443c29cb161e8aa661eb5035f675746ef95b45" datatype="html"> <trans-unit id="31443c29cb161e8aa661eb5035f675746ef95b45" datatype="html">
<source>sats/tx</source> <source>sats/tx</source>
<target>sats/tx</target> <target>sat/tx</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context> <context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
<context context-type="linenumber">33</context> <context context-type="linenumber">33</context>
@@ -8145,7 +8145,7 @@
</trans-unit> </trans-unit>
<trans-unit id="6acd06bd5a3af583cd46c6d9f7954d7a2b44095e" datatype="html"> <trans-unit id="6acd06bd5a3af583cd46c6d9f7954d7a2b44095e" datatype="html">
<source>mSats</source> <source>mSats</source>
<target>mSats</target> <target>mSat</target>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context> <context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
<context context-type="linenumber">35</context> <context context-type="linenumber">35</context>

View File

@@ -64,6 +64,9 @@
location /api/ { location /api/ {
proxy_pass http://127.0.0.1:8999/api/v1/; proxy_pass http://127.0.0.1:8999/api/v1/;
} }
location /api/v2 {
proxy_pass http://127.0.0.1:8999/api/v2;
}
# mainnet API # mainnet API
location /ws { location /ws {

View File

@@ -40,7 +40,7 @@ update_repo()
git fetch origin || exit 1 git fetch origin || exit 1
for remote in origin;do for remote in origin;do
git remote add "${remote}" "https://github.com/${remote}/mempool" >/dev/null 2>&1 git remote add "${remote}" "https://github.com/${remote}/mempool" >/dev/null 2>&1
git fetch "${remote}" || exit 1 git fetch "${remote}" --tags || exit 1
done done
if [ $(git tag -l "${REF}") ];then if [ $(git tag -l "${REF}") ];then

View File

@@ -7,6 +7,7 @@
"MINED_BLOCKS_CACHE": 144, "MINED_BLOCKS_CACHE": 144,
"SPAWN_CLUSTER_PROCS": 0, "SPAWN_CLUSTER_PROCS": 0,
"API_URL_PREFIX": "/api/v1/", "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/",
"POLL_RATE_MS": 1000, "POLL_RATE_MS": 1000,
"DISK_CACHE_BLOCK_INTERVAL": 1 "DISK_CACHE_BLOCK_INTERVAL": 1
}, },

View File

@@ -7,6 +7,7 @@
"MINED_BLOCKS_CACHE": 144, "MINED_BLOCKS_CACHE": 144,
"SPAWN_CLUSTER_PROCS": 0, "SPAWN_CLUSTER_PROCS": 0,
"API_URL_PREFIX": "/api/v1/", "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/",
"POLL_RATE_MS": 1000, "POLL_RATE_MS": 1000,
"DISK_CACHE_BLOCK_INTERVAL": 1 "DISK_CACHE_BLOCK_INTERVAL": 1
}, },

View File

@@ -6,7 +6,8 @@
"BACKEND": "esplora", "BACKEND": "esplora",
"HTTP_PORT": 8993, "HTTP_PORT": 8993,
"INDEXING_BLOCKS_AMOUNT": 0, "INDEXING_BLOCKS_AMOUNT": 0,
"API_URL_PREFIX": "/api/v1/" "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/"
}, },
"SYSLOG": { "SYSLOG": {
"MIN_PRIORITY": "debug" "MIN_PRIORITY": "debug"

View File

@@ -8,6 +8,7 @@
"MINED_BLOCKS_CACHE": 144, "MINED_BLOCKS_CACHE": 144,
"SPAWN_CLUSTER_PROCS": 0, "SPAWN_CLUSTER_PROCS": 0,
"API_URL_PREFIX": "/api/v1/", "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/",
"CLEAR_PROTECTION_MINUTES": 5, "CLEAR_PROTECTION_MINUTES": 5,
"POLL_RATE_MS": 1000, "POLL_RATE_MS": 1000,
"INDEXING_BLOCKS_AMOUNT": -1, "INDEXING_BLOCKS_AMOUNT": -1,

View File

@@ -6,7 +6,8 @@
"BACKEND": "esplora", "BACKEND": "esplora",
"HTTP_PORT": 8991, "HTTP_PORT": 8991,
"INDEXING_BLOCKS_AMOUNT": 0, "INDEXING_BLOCKS_AMOUNT": 0,
"API_URL_PREFIX": "/api/v1/" "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/"
}, },
"SYSLOG": { "SYSLOG": {
"MIN_PRIORITY": "debug" "MIN_PRIORITY": "debug"

View File

@@ -7,6 +7,7 @@
"MINED_BLOCKS_CACHE": 144, "MINED_BLOCKS_CACHE": 144,
"SPAWN_CLUSTER_PROCS": 0, "SPAWN_CLUSTER_PROCS": 0,
"API_URL_PREFIX": "/api/v1/", "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/",
"INDEXING_BLOCKS_AMOUNT": -1, "INDEXING_BLOCKS_AMOUNT": -1,
"AUTOMATIC_POOLS_UPDATE": true, "AUTOMATIC_POOLS_UPDATE": true,
"AUDIT": true, "AUDIT": true,

View File

@@ -6,7 +6,8 @@
"BACKEND": "esplora", "BACKEND": "esplora",
"HTTP_PORT": 8992, "HTTP_PORT": 8992,
"INDEXING_BLOCKS_AMOUNT": 0, "INDEXING_BLOCKS_AMOUNT": 0,
"API_URL_PREFIX": "/api/v1/" "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/"
}, },
"SYSLOG": { "SYSLOG": {
"MIN_PRIORITY": "debug" "MIN_PRIORITY": "debug"

View File

@@ -7,6 +7,7 @@
"MINED_BLOCKS_CACHE": 144, "MINED_BLOCKS_CACHE": 144,
"SPAWN_CLUSTER_PROCS": 0, "SPAWN_CLUSTER_PROCS": 0,
"API_URL_PREFIX": "/api/v1/", "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/",
"INDEXING_BLOCKS_AMOUNT": -1, "INDEXING_BLOCKS_AMOUNT": -1,
"AUTOMATIC_POOLS_UPDATE": true, "AUTOMATIC_POOLS_UPDATE": true,
"AUDIT": true, "AUDIT": true,

View File

@@ -7,6 +7,7 @@
"MINED_BLOCKS_CACHE": 144, "MINED_BLOCKS_CACHE": 144,
"SPAWN_CLUSTER_PROCS": 0, "SPAWN_CLUSTER_PROCS": 0,
"API_URL_PREFIX": "/api/v1/", "API_URL_PREFIX": "/api/v1/",
"API_V2_URL_PREFIX": "/api/v2/",
"INDEXING_BLOCKS_AMOUNT": -1, "INDEXING_BLOCKS_AMOUNT": -1,
"AUTOMATIC_POOLS_UPDATE": true, "AUTOMATIC_POOLS_UPDATE": true,
"AUDIT": true, "AUDIT": true,