mirror of
https://github.com/Retropex/umbrel-bitcoin.git
synced 2025-05-12 03:00:49 +02:00
Add widget endpoints
This commit is contained in:
parent
f92f060ca4
commit
2e416f9573
2
app.js
2
app.js
@ -18,6 +18,7 @@ const logger = require('utils/logger.js');
|
||||
const bitcoind = require('routes/v1/bitcoind/info.js');
|
||||
const charts = require('routes/v1/bitcoind/charts.js');
|
||||
const system = require('routes/v1/bitcoind/system.js');
|
||||
const widgets = require('routes/v1/bitcoind/widgets.js');
|
||||
const ping = require('routes/ping.js');
|
||||
const app = express();
|
||||
|
||||
@ -37,6 +38,7 @@ app.use('/', express.static('./ui/dist'));
|
||||
app.use('/v1/bitcoind/info', bitcoind);
|
||||
app.use('/v1/bitcoind/info', charts);
|
||||
app.use('/v1/bitcoind/system', system);
|
||||
app.use('/v1/bitcoind/widgets', widgets);
|
||||
app.use('/ping', ping);
|
||||
|
||||
app.use(errorHandleMiddleware);
|
||||
|
96
logic/widgets.js
Normal file
96
logic/widgets.js
Normal file
@ -0,0 +1,96 @@
|
||||
const bitcoind = require('logic/bitcoind.js');
|
||||
|
||||
async function getBitcoinStatsWidgetData() {
|
||||
const stats = await bitcoind.nodeStatusSummary();
|
||||
// bitcoind.nodeStatusSummary() returns the following format:
|
||||
// {
|
||||
// "difficulty": 70343519904866.8,
|
||||
// "size": 619737765556,
|
||||
// "mempool": 264944224,
|
||||
// "connections": 11,
|
||||
// "networkhashps": 516082722091118500000
|
||||
// }
|
||||
|
||||
const [hashRateValue, hashRateUnits] = abbreviateHashRate(stats.networkhashps);
|
||||
const [blockchainSizeValue, blockchainSizeUnits] = abbreviateSize(stats.size);
|
||||
const [mempoolValue, mempoolUnits] = abbreviateSize(stats.mempool);
|
||||
|
||||
const widgetData = {
|
||||
type: 'four-stats',
|
||||
refresh: '5s',
|
||||
link: '',
|
||||
items: [
|
||||
{title: 'Connections', text: stats.connections, subtext: 'peers'},
|
||||
{title: 'Mempool', text: mempoolValue, subtext: mempoolUnits},
|
||||
{title: 'Hashrate', text: hashRateValue, subtext: hashRateUnits},
|
||||
{title: 'Blockchain size', text: blockchainSizeValue, subtext: blockchainSizeUnits}
|
||||
]
|
||||
};
|
||||
|
||||
return widgetData;
|
||||
}
|
||||
|
||||
async function getBitcoinSyncWidgetData() {
|
||||
const sync = await bitcoind.getSyncStatus();
|
||||
// bitcoind.getSyncStatus() returns the following format:
|
||||
// {
|
||||
// "chain": "main",
|
||||
// "percent": 0.9999993962382976,
|
||||
// "currentBlock": 828436,
|
||||
// "headerCount": 828436,
|
||||
// "pruned": false
|
||||
// }
|
||||
|
||||
|
||||
// sync.percent is `verificationprogress` from the getblockchaininfo RPC, which can't reach 1 when the most recent block is in the past.
|
||||
// To ensure accurate percentage display during sync:
|
||||
// - When no headers have been downloaded, we set the progress to 0% (this is because sync.percent = 1 when no headers have been downloaded).
|
||||
// - When current block matches header count (indicating sync completion), we set the progress to 100%.
|
||||
// - For other cases, we use the value of `verificationprogress` with 2 decimal places and floor it such that the value is in the range 0% to 99.99%.
|
||||
// This allows us to show accurate percentage during initial sync by using the `verificationprogress` value, while also
|
||||
// not relying on prematurely rounding to 100% before the sync is actually complete
|
||||
let syncPercent = Math.floor(sync.percent * 10000) / 100;
|
||||
// If we're synced to the tip, always show 100
|
||||
if (sync.currentBlock === sync.headerCount) syncPercent = 100;
|
||||
// If no headers have been downloaded, show 0. sync.percent = 1 when no headers have been downloaded.
|
||||
if (sync.headerCount === 0) syncPercent = 0;
|
||||
|
||||
|
||||
const widgetData = {
|
||||
type: 'text-with-progress',
|
||||
refresh: '2s',
|
||||
link: '',
|
||||
title: 'Blockchain sync',
|
||||
text: `${syncPercent}%`,
|
||||
progressLabel: syncPercent === 100 ? 'Synced' : 'In progress',
|
||||
progress: syncPercent / 100
|
||||
};
|
||||
|
||||
return widgetData;
|
||||
}
|
||||
|
||||
// consider breaking out into a utility and using in both frontend and backend
|
||||
function abbreviateHashRate(n) {
|
||||
if (n < 1e3) return [Number(n.toFixed(1)), 'H/s'];
|
||||
if (n >= 1e3 && n < 1e6) return [Number((n / 1e3).toFixed(1)), 'kH/s'];
|
||||
if (n >= 1e6 && n < 1e9) return [Number((n / 1e6).toFixed(1)), 'MH/s'];
|
||||
if (n >= 1e9 && n < 1e12) return [Number((n / 1e9).toFixed(1)), 'GH/s'];
|
||||
if (n >= 1e12 && n < 1e15) return [Number((n / 1e12).toFixed(1)), 'TH/s'];
|
||||
if (n >= 1e15 && n < 1e18) return [Number((n / 1e15).toFixed(1)), 'PH/s'];
|
||||
if (n >= 1e18 && n < 1e21) return [Number((n / 1e18).toFixed(1)), 'EH/s'];
|
||||
if (n >= 1e21) return [Number(+(n / 1e21).toFixed(1)), 'ZH/s'];
|
||||
}
|
||||
|
||||
function abbreviateSize(n) {
|
||||
if (n < 1e3) return [Number(n.toFixed(1)), 'Bytes'];
|
||||
if (n >= 1e3 && n < 1e6) return [Number((n / 1e3).toFixed(1)), 'KB'];
|
||||
if (n >= 1e6 && n < 1e9) return [Number((n / 1e6).toFixed(1)), 'MB'];
|
||||
if (n >= 1e9 && n < 1e12) return [Number((n / 1e9).toFixed(1)), 'GB'];
|
||||
if (n >= 1e12 && n < 1e15) return [Number((n / 1e12).toFixed(1)), 'TB'];
|
||||
if (n >= 1e15) return [Number(+(n / 1e15).toFixed(1)), 'PB'];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getBitcoinStatsWidgetData,
|
||||
getBitcoinSyncWidgetData
|
||||
};
|
17
routes/v1/bitcoind/widgets.js
Normal file
17
routes/v1/bitcoind/widgets.js
Normal file
@ -0,0 +1,17 @@
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
|
||||
const widgetLogic = require('logic/widgets.js');
|
||||
const safeHandler = require('utils/safeHandler');
|
||||
|
||||
router.get('/stats', safeHandler(async(req, res) => {
|
||||
const widgetData = await widgetLogic.getBitcoinStatsWidgetData();
|
||||
res.json(widgetData);
|
||||
}));
|
||||
|
||||
router.get('/sync', safeHandler(async(req, res) => {
|
||||
const widgetData = await widgetLogic.getBitcoinSyncWidgetData();
|
||||
res.json(widgetData);
|
||||
}));
|
||||
|
||||
module.exports = router;
|
Loading…
Reference in New Issue
Block a user