diff --git a/backend/src/index.ts b/backend/src/index.ts index d195ff157..09d8f7669 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -336,8 +336,8 @@ class Server { } this.app - .get(config.MEMPOOL.API_URL_PREFIX + 'blocks', routes.getBlocks) - .get(config.MEMPOOL.API_URL_PREFIX + 'blocks/:height', routes.getBlocks) + .get(config.MEMPOOL.API_URL_PREFIX + 'blocks', routes.getBlocks.bind(routes)) + .get(config.MEMPOOL.API_URL_PREFIX + 'blocks/:height', routes.getBlocks.bind(routes)) .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash', routes.getBlock); if (config.MEMPOOL.BACKEND !== 'esplora') { diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index 0081bd34f..60b07da1b 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -81,7 +81,7 @@ export interface TransactionStripped { export interface BlockExtension { totalFees?: number; - medianFee?: number; // Actually the median fee rate that we compute ourself + medianFee?: number; feeRange?: number[]; reward?: number; coinbaseTx?: TransactionMinerInfo; diff --git a/backend/src/routes.ts b/backend/src/routes.ts index 5b762ff27..fa298cc22 100644 --- a/backend/src/routes.ts +++ b/backend/src/routes.ts @@ -722,14 +722,52 @@ class Routes { public async getBlocks(req: Request, res: Response) { try { - const height = req.params.height === undefined ? undefined : parseInt(req.params.height, 10); - res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); - res.json(await blocks.$getBlocks(height, 15)); + if (['mainnet', 'testnet', 'signet', 'regtest'].includes(config.MEMPOOL.NETWORK)) { // Bitcoin + const height = req.params.height === undefined ? undefined : parseInt(req.params.height, 10); + res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); + res.json(await blocks.$getBlocks(height, 15)); + } else { // Liquid, Bisq + return await this.getLegacyBlocks(req, res); + } } catch (e) { res.status(500).send(e instanceof Error ? e.message : e); } } + public async getLegacyBlocks(req: Request, res: Response) { + try { + const returnBlocks: IEsploraApi.Block[] = []; + const fromHeight = parseInt(req.params.height, 10) || blocks.getCurrentBlockHeight(); + + // Check if block height exist in local cache to skip the hash lookup + const blockByHeight = blocks.getBlocks().find((b) => b.height === fromHeight); + let startFromHash: string | null = null; + if (blockByHeight) { + startFromHash = blockByHeight.id; + } else { + startFromHash = await bitcoinApi.$getBlockHash(fromHeight); + } + + let nextHash = startFromHash; + for (let i = 0; i < 10 && nextHash; i++) { + const localBlock = blocks.getBlocks().find((b) => b.id === nextHash); + if (localBlock) { + returnBlocks.push(localBlock); + nextHash = localBlock.previousblockhash; + } else { + const block = await bitcoinApi.$getBlock(nextHash); + returnBlocks.push(block); + nextHash = block.previousblockhash; + } + } + + res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); + res.json(returnBlocks); + } catch (e) { + res.status(500).send(e instanceof Error ? e.message : e); + } + } + public async getBlockTransactions(req: Request, res: Response) { try { loadingIndicators.setProgress('blocktxs-' + req.params.hash, 0); diff --git a/backend/src/utils/blocks-utils.ts b/backend/src/utils/blocks-utils.ts index 8760a08c0..937a37448 100644 --- a/backend/src/utils/blocks-utils.ts +++ b/backend/src/utils/blocks-utils.ts @@ -15,7 +15,7 @@ export function prepareBlock(block: any): BlockExtended { weight: block.weight, previousblockhash: block.previousblockhash, extras: { - coinbaseRaw: block.coinbase_raw ?? block.extras.coinbaseRaw, + coinbaseRaw: block.coinbase_raw ?? block.extras?.coinbaseRaw, medianFee: block.medianFee ?? block.median_fee ?? block.extras?.medianFee, feeRange: block.feeRange ?? block.fee_span, reward: block.reward ?? block?.extras?.reward, diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.ts b/frontend/src/app/components/blocks-list/blocks-list.component.ts index f1f81d321..7cca2af62 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.ts +++ b/frontend/src/app/components/blocks-list/blocks-list.component.ts @@ -87,9 +87,11 @@ export class BlocksList implements OnInit { return blocks[0]; } this.blocksCount = Math.max(this.blocksCount, blocks[1][0].height) + 1; - // @ts-ignore: Need to add an extra field for the template - blocks[1][0].extras.pool.logo = `./resources/mining-pools/` + - blocks[1][0].extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg'; + if (this.stateService.env.MINING_DASHBOARD) { + // @ts-ignore: Need to add an extra field for the template + blocks[1][0].extras.pool.logo = `./resources/mining-pools/` + + blocks[1][0].extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg'; + } acc.unshift(blocks[1][0]); acc = acc.slice(0, this.widget ? 6 : 15); return acc;