Compare commits

...

23 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
wiz
4e581347c8 Bump version to v3.0.0-rc1 2024-08-20 12:06:11 +09:00
wiz
820777236e Merge pull request #5465 from mempool/orangesurf/update-logos-2024-08-19
Add logo images and references to logos
2024-08-20 12:01:51 +09:00
wiz
beeb5eb08c Merge pull request #5466 from mempool/mononaut/fix-about-layout
Fix about page layout
2024-08-20 10:50:04 +09:00
Mononaut
b78aca0282 Fix about page layout 2024-08-19 19:46:22 +00:00
orangesurf
9572f2d554 Add logo images and references to logos 2024-08-19 20:13:49 +02:00
softsimon
ef13596b59 Merge pull request #5449 from mempool/mononaut/non-acc-effective-fee
fix mined acceleration detection logic on tx pages
2024-08-19 17:10:46 +02:00
wiz
80da024bbb Add hr locale to angular.json 2024-08-19 14:49:36 +09:00
natsoni
f75f85f914 Hide fee delta on accelerated tx mined by participating pool with 0 bid boost 2024-08-18 19:43:38 +02:00
natsoni
b3ac107b0b clear feeDelta if a tx is mined by non-participating pool 2024-08-18 18:35:30 +02:00
softsimon
f8cedaa7a3 Merge pull request #5462 from mempool/natsoni/fix-console-error
Fix accelerated arrow not appearing
2024-08-18 15:47:02 +02:00
natsoni
72bb92dd8b Merge branch 'master' into mononaut/non-acc-effective-fee 2024-08-18 14:27:48 +02:00
natsoni
e3c4e219f3 Fix accelerated arrow not appearing 2024-08-18 14:15:56 +02:00
wiz
aa3fa4478a Merge pull request #5458 from mempool/mononaut/pool-pie-colors
update pool pie chart color scheme
2024-08-18 12:15:27 +09:00
Mononaut
26c03eee88 update pool pie chart color scheme 2024-08-14 14:21:47 +00:00
Mononaut
a31729b8b8 fix feeDelta display logic 2024-08-10 21:56:11 +00:00
Mononaut
79e494150c fix mined acceleration detection logic on tx pages 2024-08-09 14:44:51 +00:00
47 changed files with 249 additions and 80 deletions

12
LICENSE
View File

@@ -1,5 +1,5 @@
The Mempool Open Source Project® The Mempool Open Source Project®
Copyright (c) 2019-2023 Mempool Space K.K. and other shadowy super-coders Copyright (c) 2019-2024 Mempool Space K.K. and other shadowy super-coders
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free the terms of the GNU Affero General Public License as published by the Free
@@ -12,10 +12,12 @@ or any other contributor to The Mempool Open Source Project.
The Mempool Open Source Project®, Mempool Accelerator™, Mempool Enterprise®, The Mempool Open Source Project®, Mempool Accelerator™, Mempool Enterprise®,
Mempool Liquidity™, mempool.space®, Be your own explorer™, Explore the full Mempool Liquidity™, mempool.space®, Be your own explorer™, Explore the full
Bitcoin ecosystem™, Mempool Goggles™, the mempool Logo, the mempool Square logo, Bitcoin ecosystem™, Mempool Goggles™, the mempool Logo, the mempool Square Logo,
the mempool Blocks logo, the mempool Blocks 3 | 2 logo, the mempool.space Vertical the mempool block visualization Logo, the mempool Blocks Logo, the mempool
Logo, and the mempool.space Horizontal logo are registered trademarks or trademarks transaction Logo, the mempool Blocks 3 | 2 Logo, the mempool research Logo,
of Mempool Space K.K in Japan, the United States, and/or other countries. the mempool.space Vertical Logo, and the mempool.space Horizontal Logo are
registered trademarks or trademarks of Mempool Space K.K in Japan,
the United States, and/or other countries.
See our full Trademark Policy and Guidelines for more details, published on See our full Trademark Policy and Guidelines for more details, published on
<https://mempool.space/trademark-policy>. <https://mempool.space/trademark-policy>.

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

@@ -1,12 +1,12 @@
{ {
"name": "mempool-backend", "name": "mempool-backend",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "mempool-backend", "name": "mempool-backend",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"hasInstallScript": true, "hasInstallScript": true,
"license": "GNU Affero General Public License v3.0", "license": "GNU Affero General Public License v3.0",
"dependencies": { "dependencies": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "mempool-backend", "name": "mempool-backend",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"description": "Bitcoin mempool visualizer and blockchain explorer backend", "description": "Bitcoin mempool visualizer and blockchain explorer backend",
"license": "GNU Affero General Public License v3.0", "license": "GNU Affero General Public License v3.0",
"homepage": "https://mempool.space", "homepage": "https://mempool.space",

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

@@ -54,6 +54,10 @@
"translation": "src/locale/messages.fr.xlf", "translation": "src/locale/messages.fr.xlf",
"baseHref": "/fr/" "baseHref": "/fr/"
}, },
"hr": {
"translation": "src/locale/messages.hr.xlf",
"baseHref": "/hr/"
},
"ja": { "ja": {
"translation": "src/locale/messages.ja.xlf", "translation": "src/locale/messages.ja.xlf",
"baseHref": "/ja/" "baseHref": "/ja/"

View File

@@ -750,7 +750,7 @@
}, },
"backendInfo": { "backendInfo": {
"hostname": "node205.tk7.mempool.space", "hostname": "node205.tk7.mempool.space",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"gitCommit": "abbc8a134", "gitCommit": "abbc8a134",
"lightning": false "lightning": false
}, },

View File

@@ -1,12 +1,12 @@
{ {
"name": "mempool-frontend", "name": "mempool-frontend",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "mempool-frontend", "name": "mempool-frontend",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"license": "GNU Affero General Public License v3.0", "license": "GNU Affero General Public License v3.0",
"dependencies": { "dependencies": {
"@angular-devkit/build-angular": "^17.3.1", "@angular-devkit/build-angular": "^17.3.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "mempool-frontend", "name": "mempool-frontend",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"description": "Bitcoin mempool visualizer and blockchain explorer backend", "description": "Bitcoin mempool visualizer and blockchain explorer backend",
"license": "GNU Affero General Public License v3.0", "license": "GNU Affero General Public License v3.0",
"homepage": "https://mempool.space", "homepage": "https://mempool.space",

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

@@ -53,7 +53,7 @@
<span>Spiral</span> <span>Spiral</span>
</a> </a>
<a href="https://foundrydigital.com/" target="_blank" title="Foundry"> <a href="https://foundrydigital.com/" target="_blank" title="Foundry">
<svg xmlns="http://www.w3.org/2000/svg" id="b" data-name="Layer 2" style="zoom: 1;" width="32" height="76" viewBox="0 0 32 76"> <svg xmlns="http://www.w3.org/2000/svg" id="b" data-name="Layer 2" style="zoom: 1;" width="32" height="76" viewBox="0 0 32 76" class="image">
<defs> <defs>
<style> <style>
.d { .d {
@@ -125,7 +125,9 @@
<span>Blockstream</span> <span>Blockstream</span>
</a> </a>
<a href="https://unchained.com/" target="_blank" title="Unchained"> <a href="https://unchained.com/" target="_blank" title="Unchained">
<svg id="Layer_1" width="78" height="78" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156.68 156.68"><defs><style>.cls-unchained-1{fill:#fff;}</style></defs><path class="cls-unchained-1" d="m78.34,0C35.07,0,0,35.07,0,78.34s35.07,78.34,78.34,78.34,78.34-35.07,78.34-78.34S121.6,0,78.34,0ZM20.23,109.5c-4.99-9.28-7.81-19.89-7.81-31.16C12.42,41.93,41.93,12.42,78.34,12.42c33.15,0,60.58,24.46,65.23,56.32h-37.48c-45.29,0-71.19,20.05-85.85,40.76Zm58.11,34.76c-12.42,0-24.04-3.44-33.96-9.41,3.94-8.85,9.11-18.7,15.84-28.9,20.99-31.8,52.2-31.19,76.49-31.19h7.45c.06,1.18.1,2.38.1,3.58,0,36.41-29.51,65.92-65.92,65.92Z"/><path class="cls-unchained-1" d="m91.98,42.4l-3.62-1.18c-3.94-1.29-7.03-4.38-8.32-8.32l-1.18-3.63c-.13-.39-.68-.39-.81,0l-1.18,3.63c-1.29,3.94-4.38,7.03-8.32,8.32l-3.62,1.18c-.39.13-.39.68,0,.81l3.62,1.18c3.94,1.29,7.03,4.38,8.32,8.32l1.18,3.63c.13.39.68.39.81,0l1.18-3.63c1.29-3.94,4.38-7.03,8.32-8.32l3.62-1.18c.39-.13.39-.68,0-.81Z"/></svg> <svg id="Layer_1" width="78" height="78" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156.68 156.68" class="image">
<defs><style>.cls-unchained-1{fill:#fff;}</style></defs><path class="cls-unchained-1" d="m78.34,0C35.07,0,0,35.07,0,78.34s35.07,78.34,78.34,78.34,78.34-35.07,78.34-78.34S121.6,0,78.34,0ZM20.23,109.5c-4.99-9.28-7.81-19.89-7.81-31.16C12.42,41.93,41.93,12.42,78.34,12.42c33.15,0,60.58,24.46,65.23,56.32h-37.48c-45.29,0-71.19,20.05-85.85,40.76Zm58.11,34.76c-12.42,0-24.04-3.44-33.96-9.41,3.94-8.85,9.11-18.7,15.84-28.9,20.99-31.8,52.2-31.19,76.49-31.19h7.45c.06,1.18.1,2.38.1,3.58,0,36.41-29.51,65.92-65.92,65.92Z"/><path class="cls-unchained-1" d="m91.98,42.4l-3.62-1.18c-3.94-1.29-7.03-4.38-8.32-8.32l-1.18-3.63c-.13-.39-.68-.39-.81,0l-1.18,3.63c-1.29,3.94-4.38,7.03-8.32,8.32l-3.62,1.18c-.39.13-.39.68,0,.81l3.62,1.18c3.94,1.29,7.03,4.38,8.32,8.32l1.18,3.63c.13.39.68.39.81,0l1.18-3.63c1.29-3.94,4.38-7.03,8.32-8.32l3.62-1.18c.39-.13.39-.68,0-.81Z"/>
</svg>
<span>Unchained</span> <span>Unchained</span>
</a> </a>
<a href="https://gemini.com/" target="_blank" title="Gemini"> <a href="https://gemini.com/" target="_blank" title="Gemini">
@@ -150,7 +152,7 @@
<span>Bull Bitcoin</span> <span>Bull Bitcoin</span>
</a> </a>
<a href="https://exodus.com/" target="_blank" title="Exodus"> <a href="https://exodus.com/" target="_blank" title="Exodus">
<svg width="80" height="80" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="80" height="80" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg" class="image">
<circle cx="250" cy="250" r="250" fill="#1F2033"/> <circle cx="250" cy="250" r="250" fill="#1F2033"/>
<g clip-path="url(#clip0_2_14)"> <g clip-path="url(#clip0_2_14)">
<path d="M411.042 178.303L271.79 87V138.048L361.121 196.097L350.612 229.351H271.79V271.648H350.612L361.121 304.903L271.79 362.952V414L411.042 322.989L388.271 250.646L411.042 178.303Z" fill="url(#paint0_linear_2_14)"/> <path d="M411.042 178.303L271.79 87V138.048L361.121 196.097L350.612 229.351H271.79V271.648H350.612L361.121 304.903L271.79 362.952V414L411.042 322.989L388.271 250.646L411.042 178.303Z" fill="url(#paint0_linear_2_14)"/>
@@ -435,7 +437,7 @@
Trademark Notice<br> Trademark Notice<br>
</div> </div>
<p> <p>
The Mempool Open Source Project&reg;, Mempool Accelerator&trade;, Mempool Enterprise&reg;, Mempool Liquidity&trade;, mempool.space&reg;, Be your own explorer&trade;, Explore the full Bitcoin ecosystem&reg;, Mempool Goggles&trade;, the mempool logo, the mempool Square logo, the mempool Blocks logo, the mempool Blocks 3 | 2 logo, the mempool.space Vertical Logo, and the mempool.space Horizontal logo are either registered trademarks or trademarks of Mempool Space K.K in Japan, the United States, and/or other countries. The Mempool Open Source Project&reg;, Mempool Accelerator&trade;, Mempool Enterprise&reg;, Mempool Liquidity&trade;, mempool.space&reg;, Be your own explorer&trade;, Explore the full Bitcoin ecosystem&reg;, Mempool Goggles&trade;, the mempool Logo, the mempool Square Logo, the mempool block visualization Logo, the mempool Blocks Logo, the mempool transaction Logo, the mempool Blocks 3 | 2 Logo, the mempool research Logo, the mempool.space Vertical Logo, and the mempool.space Horizontal Logo are either registered trademarks or trademarks of Mempool Space K.K in Japan, the United States, and/or other countries.
</p> </p>
<p> <p>
While our software is available under an open source software license, the copyright license does not include an implied right or license to use our trademarks. See our <a href="https://mempool.space/trademark-policy">Trademark Policy and Guidelines</a> for more details, published on &lt;https://mempool.space/trademark-policy&gt;. While our software is available under an open source software license, the copyright license does not include an implied right or license to use our trademarks. See our <a href="https://mempool.space/trademark-policy">Trademark Policy and Guidelines</a> for more details, published on &lt;https://mempool.space/trademark-policy&gt;.

View File

@@ -13,8 +13,6 @@
.image.not-rounded { .image.not-rounded {
border-radius: 0; border-radius: 0;
width: 60px;
height: 60px;
} }
.intro { .intro {
@@ -158,9 +156,8 @@
margin: 40px 29px 10px; margin: 40px 29px 10px;
&.image.coldcard { &.image.coldcard {
border-radius: 0; border-radius: 0;
width: auto; height: auto;
max-height: 50px; margin: 20px 29px 20px;
margin: 40px 29px 14px 29px;
} }
} }
} }

View File

@@ -67,13 +67,17 @@ export class ActiveAccelerationBox implements OnChanges {
const acceleratingPools = (poolList || []).filter(id => pools[id]).sort((a,b) => pools[a].lastEstimatedHashrate - pools[b].lastEstimatedHashrate); const acceleratingPools = (poolList || []).filter(id => pools[id]).sort((a,b) => pools[a].lastEstimatedHashrate - pools[b].lastEstimatedHashrate);
const totalAcceleratedHashrate = acceleratingPools.reduce((total, pool) => total + pools[pool].lastEstimatedHashrate, 0); const totalAcceleratedHashrate = acceleratingPools.reduce((total, pool) => total + pools[pool].lastEstimatedHashrate, 0);
const lightenStep = acceleratingPools.length ? (0.48 / acceleratingPools.length) : 0; // Find the first pool with at least 1% of the total network hashrate
const firstSignificantPool = acceleratingPools.findIndex(pool => pools[pool].lastEstimatedHashrate > this.miningStats.lastEstimatedHashrate / 100);
const numSignificantPools = acceleratingPools.length - firstSignificantPool;
acceleratingPools.forEach((poolId, index) => { acceleratingPools.forEach((poolId, index) => {
const pool = pools[poolId]; const pool = pools[poolId];
const poolShare = ((pool.lastEstimatedHashrate / this.miningStats.lastEstimatedHashrate) * 100).toFixed(1); const poolShare = ((pool.lastEstimatedHashrate / this.miningStats.lastEstimatedHashrate) * 100).toFixed(1);
data.push(getDataItem( data.push(getDataItem(
pool.lastEstimatedHashrate, pool.lastEstimatedHashrate,
toRGB(lighten({ r: 147, g: 57, b: 244 }, index * lightenStep)), index >= firstSignificantPool
? toRGB(lighten({ r: 147, g: 57, b: 244 }, 1 - (index - firstSignificantPool) / (numSignificantPools - 1)))
: 'white',
`<b style="color: white">${pool.name} (${poolShare}%)</b>`, `<b style="color: white">${pool.name} (${poolShare}%)</b>`,
true, true,
) as PieSeriesOption); ) as PieSeriesOption);

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

@@ -213,7 +213,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
} }
if (state.mempoolPosition) { if (state.mempoolPosition) {
this.txPosition = state.mempoolPosition; this.txPosition = state.mempoolPosition;
if (this.txPosition.accelerated && !oldTxPosition.accelerated) { if (this.txPosition.accelerated && !oldTxPosition?.accelerated) {
this.acceleratingArrow = true; this.acceleratingArrow = true;
setTimeout(() => { setTimeout(() => {
this.acceleratingArrow = false; this.acceleratingArrow = false;

View File

@@ -293,7 +293,7 @@ export class TrackerComponent implements OnInit, OnDestroy {
}) })
).subscribe((accelerationHistory) => { ).subscribe((accelerationHistory) => {
for (const acceleration of accelerationHistory) { for (const acceleration of accelerationHistory) {
if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional')) { if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional') && acceleration.pools.includes(acceleration.minedByPoolUniqueId)) {
const boostCost = acceleration.boostCost || acceleration.bidBoost; const boostCost = acceleration.boostCost || acceleration.bidBoost;
acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize; acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize;
acceleration.boost = boostCost; acceleration.boost = boostCost;

View File

@@ -8,7 +8,7 @@
<div *ngIf="officialMempoolSpace"> <div *ngIf="officialMempoolSpace">
<h2>Trademark Policy and Guidelines</h2> <h2>Trademark Policy and Guidelines</h2>
<h5>The Mempool Open Source Project &reg;</h5> <h5>The Mempool Open Source Project &reg;</h5>
<h6>Updated: July 3, 2024</h6> <h6>Updated: August 19, 2024</h6>
<br> <br>
<div class="text-left"> <div class="text-left">
@@ -100,11 +100,26 @@
<p>The Mempool Accelerator Logo</p> <p>The Mempool Accelerator Logo</p>
<br><br> <br><br>
<img src="/resources/mempool-research.png" style="width: 500px; max-width: 80%">
<br><br>
<p>The mempool research Logo</p>
<br><br>
<app-svg-images name="goggles" height="96px"></app-svg-images> <app-svg-images name="goggles" height="96px"></app-svg-images>
<br><br> <br><br>
<p>The Mempool Goggles Logo</p> <p>The Mempool Goggles Logo</p>
<br><br> <br><br>
<img src="/resources/mempool-transaction.png" style="width: 500px; max-width: 80%">
<br><br>
<p>The mempool transaction Logo</p>
<br><br>
<img src="/resources/mempool-block-visualization.png" style="width: 500px; max-width: 80%">
<br><br>
<p>The mempool block visualization Logo</p>
<br><br>
<img src="/resources/mempool-blocks-2-3-logo.jpeg" style="width: 500px; max-width: 80%"> <img src="/resources/mempool-blocks-2-3-logo.jpeg" style="width: 500px; max-width: 80%">
<br><br> <br><br>
<p>The mempool Blocks Logo</p> <p>The mempool Blocks Logo</p>

View File

@@ -606,16 +606,11 @@
@if (!isLoadingTx) { @if (!isLoadingTx) {
<tr> <tr>
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td> <td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
<td class="text-wrap">{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <td class="text-wrap">{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span>
@if (accelerationInfo?.bidBoost) { @if (accelerationInfo?.bidBoost ?? tx.feeDelta > 0) {
<span class="oobFees" i18n-ngbTooltip="Acceleration Fees" ngbTooltip="Acceleration fees paid out-of-band"> +{{ accelerationInfo.bidBoost | number }} </span><span class="symbol" i18n="shared.sat|sat">sat</span> <span class="oobFees" i18n-ngbTooltip="Acceleration Fees" ngbTooltip="Acceleration fees paid out-of-band"> +{{ accelerationInfo?.bidBoost ?? tx.feeDelta | number }} </span><span class="symbol" i18n="shared.sat|sat">sat</span>
<span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee + accelerationInfo.bidBoost"></app-fiat></span> }
} @else if (tx.feeDelta && !accelerationInfo) { <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee + ((accelerationInfo?.bidBoost ?? tx.feeDelta) || 0)"></app-fiat></span>
<span class="oobFees" i18n-ngbTooltip="Acceleration Fees" ngbTooltip="Acceleration fees paid out-of-band"> +{{ tx.feeDelta | number }} </span><span class="symbol" i18n="shared.sat|sat">sat</span>
<span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee + tx.feeDelta"></app-fiat></span>
} @else {
<span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span>
}
</td> </td>
</tr> </tr>
} @else { } @else {

View File

@@ -358,12 +358,18 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}), }),
).subscribe((accelerationHistory) => { ).subscribe((accelerationHistory) => {
for (const acceleration of accelerationHistory) { for (const acceleration of accelerationHistory) {
if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional')) { if (acceleration.txid === this.txId) {
const boostCost = acceleration.boostCost || acceleration.bidBoost; if (acceleration.status === 'completed' || acceleration.status === 'completed_provisional') {
acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize; if (acceleration.pools.includes(acceleration.minedByPoolUniqueId)) {
acceleration.boost = boostCost; const boostCost = acceleration.boostCost || acceleration.bidBoost;
this.tx.acceleratedAt = acceleration.added; acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize;
this.accelerationInfo = acceleration; acceleration.boost = boostCost;
this.tx.acceleratedAt = acceleration.added;
this.accelerationInfo = acceleration;
} else {
this.tx.feeDelta = undefined;
}
}
this.waitingForAccelerationInfo = false; this.waitingForAccelerationInfo = false;
this.setIsAccelerated(); this.setIsAccelerated();
} }

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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

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,

View File

@@ -1,12 +1,12 @@
{ {
"name": "mempool-unfurl", "name": "mempool-unfurl",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "mempool-unfurl", "name": "mempool-unfurl",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"dependencies": { "dependencies": {
"@types/node": "^16.11.41", "@types/node": "^16.11.41",
"ejs": "^3.1.10", "ejs": "^3.1.10",

View File

@@ -1,6 +1,6 @@
{ {
"name": "mempool-unfurl", "name": "mempool-unfurl",
"version": "3.0.0-beta", "version": "3.0.0-rc1",
"description": "Renderer for mempool open graph link preview images", "description": "Renderer for mempool open graph link preview images",
"repository": { "repository": {
"type": "git", "type": "git",