add GET /bee/stats — JWT-guarded read-only bee node stats

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Felix FaerberandClaude Opus 4.7 committed 2026-05-27 15:12:25 +03:00
1 parent 3244848ae0
commit 3618f5baf6
2 files changed
+66

No files matched your search

+2
View File
@@ -8,6 +8,7 @@ import { usersRoutes } from './users/routes';
import { accountsRoutes } from './accounts/routes';
import { apiKeysRoutes } from './apiKeys/routes';
import { gatewayRoutes } from './gateway/routes';
import { beeRoutes } from './bee/routes';
import { getGatewayContext } from './gateway/context';
const app = new Elysia()
@@ -25,6 +26,7 @@ const app = new Elysia()
.use(usersRoutes)
.use(accountsRoutes)
.use(apiKeysRoutes)
.use(beeRoutes)
.use(gatewayRoutes);
// Start the HTTP server immediately so auth / accounts / api-keys routes are
+64
View File
@@ -0,0 +1,64 @@
import Elysia from 'elysia';
import { Bee } from '@ethersphere/bee-js';
import { jwtGuard } from '../auth/jwt';
import { env } from '../env';
import { logger } from '../logger';
const bee = new Bee(env.BEE_API_URL);
function settled<T, U>(p: Promise<T>, map: (v: T) => U): Promise<U | null> {
return p.then(map).catch((err) => {
logger.warn({ err: (err as Error).message }, 'bee stats field failed');
return null;
});
}
export const beeRoutes = new Elysia({ prefix: '/bee' })
.use(jwtGuard)
.get('/stats', async () => {
const [health, addresses, topology, wallet, stamps, chain] = await Promise.all([
settled(bee.getHealth(), (h) => ({
status: h.status,
version: h.version,
apiVersion: h.apiVersion,
})),
settled(bee.getNodeAddresses(), (a) => ({
overlay: a.overlay.toString(),
ethereum: a.ethereum.toString(),
publicKey: a.publicKey.toString(),
pssPublicKey: a.pssPublicKey.toString(),
underlay: a.underlay,
})),
settled(bee.getTopology(), (t) => ({
connected: t.connected,
population: t.population,
depth: t.depth,
reachability: t.reachability,
networkAvailability: t.networkAvailability,
})),
settled(bee.getWalletBalance(), (w) => ({
bzz: w.bzzBalance.toDecimalString(),
xdai: w.nativeTokenBalance.toDecimalString(),
walletAddress: w.walletAddress,
chainID: w.chainID,
})),
settled(bee.getAllPostageBatch(), (batches) =>
batches.map((b) => ({
batchID: b.batchID.toString(),
label: b.label,
depth: b.depth,
amount: b.amount,
usable: b.usable,
usageText: b.usageText,
durationDays: b.duration.toDays(),
})),
),
settled(bee.getChainState(), (c) => ({
block: c.block,
chainTip: c.chainTip,
currentPrice: c.currentPrice,
})),
]);
return { health, addresses, topology, wallet, stamps, chain };
});