Merge pull request #5472 from mempool/mononaut/json-errors
respect json Accept header in API error responses
This commit is contained in:
		
						commit
						8717051a06
					
				@ -20,6 +20,7 @@ import difficultyAdjustment from '../difficulty-adjustment';
 | 
			
		||||
import transactionRepository from '../../repositories/TransactionRepository';
 | 
			
		||||
import rbfCache from '../rbf-cache';
 | 
			
		||||
import { calculateMempoolTxCpfp } from '../cpfp';
 | 
			
		||||
import { handleError } from '../../utils/api';
 | 
			
		||||
 | 
			
		||||
class BitcoinRoutes {
 | 
			
		||||
  public initRoutes(app: Application) {
 | 
			
		||||
@ -86,7 +87,7 @@ class BitcoinRoutes {
 | 
			
		||||
      res.set('Content-Type', 'application/json');
 | 
			
		||||
      res.send(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -105,13 +106,13 @@ class BitcoinRoutes {
 | 
			
		||||
      const result = mempoolBlocks.getMempoolBlocks();
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getTransactionTimes(req: Request, res: Response) {
 | 
			
		||||
    if (!Array.isArray(req.query.txId)) {
 | 
			
		||||
      res.status(500).send('Not an array');
 | 
			
		||||
      handleError(req, res, 500, 'Not an array');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    const txIds: string[] = [];
 | 
			
		||||
@ -128,12 +129,12 @@ class BitcoinRoutes {
 | 
			
		||||
  private async $getBatchedOutspends(req: Request, res: Response): Promise<IEsploraApi.Outspend[][] | void> {
 | 
			
		||||
    const txids_csv = req.query.txids;
 | 
			
		||||
    if (!txids_csv || typeof txids_csv !== 'string') {
 | 
			
		||||
      res.status(500).send('Invalid txids format');
 | 
			
		||||
      handleError(req, res, 500, 'Invalid txids format');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    const txids = txids_csv.split(',');
 | 
			
		||||
    if (txids.length > 50) {
 | 
			
		||||
      res.status(400).send('Too many txids requested');
 | 
			
		||||
      handleError(req, res, 400, 'Too many txids requested');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -141,13 +142,13 @@ class BitcoinRoutes {
 | 
			
		||||
      const batchedOutspends = await bitcoinApi.$getBatchedOutspends(txids);
 | 
			
		||||
      res.json(batchedOutspends);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async $getCpfpInfo(req: Request, res: Response) {
 | 
			
		||||
    if (!/^[a-fA-F0-9]{64}$/.test(req.params.txId)) {
 | 
			
		||||
      res.status(501).send(`Invalid transaction ID.`);
 | 
			
		||||
      handleError(req, res, 501, `Invalid transaction ID.`);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -180,7 +181,7 @@ class BitcoinRoutes {
 | 
			
		||||
        try {
 | 
			
		||||
          cpfpInfo = await transactionRepository.$getCpfpInfo(req.params.txId);
 | 
			
		||||
        } catch (e) {
 | 
			
		||||
          res.status(500).send('failed to get CPFP info');
 | 
			
		||||
          handleError(req, res, 500, 'failed to get CPFP info');
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
@ -209,7 +210,7 @@ class BitcoinRoutes {
 | 
			
		||||
      if (e instanceof Error && e instanceof Error && e.message && e.message.indexOf('No such mempool or blockchain transaction') > -1) {
 | 
			
		||||
        statusCode = 404;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(statusCode).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, statusCode, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -223,7 +224,7 @@ class BitcoinRoutes {
 | 
			
		||||
      if (e instanceof Error && e.message && e.message.indexOf('No such mempool or blockchain transaction') > -1) {
 | 
			
		||||
        statusCode = 404;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(statusCode).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, statusCode, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -284,13 +285,13 @@ class BitcoinRoutes {
 | 
			
		||||
        // Not modified
 | 
			
		||||
        // 422 Unprocessable Entity
 | 
			
		||||
        // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/422
 | 
			
		||||
        res.status(422).send(`Psbt had no missing nonWitnessUtxos.`);
 | 
			
		||||
        handleError(req, res, 422, `Psbt had no missing nonWitnessUtxos.`);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
      if (e instanceof Error && new RegExp(notFoundError).test(e.message)) {
 | 
			
		||||
        res.status(404).send(e.message);
 | 
			
		||||
        handleError(req, res, 404, e.message);
 | 
			
		||||
      } else {
 | 
			
		||||
        res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -304,7 +305,7 @@ class BitcoinRoutes {
 | 
			
		||||
      if (e instanceof Error && e.message && e.message.indexOf('No such mempool or blockchain transaction') > -1) {
 | 
			
		||||
        statusCode = 404;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(statusCode).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, statusCode, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -314,7 +315,7 @@ class BitcoinRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24 * 30).toUTCString());
 | 
			
		||||
      res.json(transactions);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -336,7 +337,7 @@ class BitcoinRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * cacheDuration).toUTCString());
 | 
			
		||||
      res.json(block);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -346,7 +347,7 @@ class BitcoinRoutes {
 | 
			
		||||
      res.setHeader('content-type', 'text/plain');
 | 
			
		||||
      res.send(blockHeader);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -357,10 +358,11 @@ class BitcoinRoutes {
 | 
			
		||||
        res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24 * 30).toUTCString());
 | 
			
		||||
        res.json(auditSummary);
 | 
			
		||||
      } else {
 | 
			
		||||
        return res.status(404).send(`audit not available`);
 | 
			
		||||
        handleError(req, res, 404, `audit not available`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -371,7 +373,8 @@ class BitcoinRoutes {
 | 
			
		||||
        res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24 * 30).toUTCString());
 | 
			
		||||
        res.json(auditSummary);
 | 
			
		||||
      } else {
 | 
			
		||||
        return res.status(404).send(`transaction audit not available`);
 | 
			
		||||
        handleError(req, res, 404, `transaction audit not available`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
@ -388,42 +391,49 @@ class BitcoinRoutes {
 | 
			
		||||
        return await this.getLegacyBlocks(req, res);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async getBlocksByBulk(req: Request, res: Response) {
 | 
			
		||||
    try {
 | 
			
		||||
      if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false) { // Liquid - Not implemented
 | 
			
		||||
        return res.status(404).send(`This API is only available for Bitcoin networks`);
 | 
			
		||||
        handleError(req, res, 404, `This API is only available for Bitcoin networks`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (config.MEMPOOL.MAX_BLOCKS_BULK_QUERY <= 0) {
 | 
			
		||||
        return res.status(404).send(`This API is disabled. Set config.MEMPOOL.MAX_BLOCKS_BULK_QUERY to a positive number to enable it.`);
 | 
			
		||||
        handleError(req, res, 404, `This API is disabled. Set config.MEMPOOL.MAX_BLOCKS_BULK_QUERY to a positive number to enable it.`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (!Common.indexingEnabled()) {
 | 
			
		||||
        return res.status(404).send(`Indexing is required for this API`);
 | 
			
		||||
        handleError(req, res, 404, `Indexing is required for this API`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const from = parseInt(req.params.from, 10);
 | 
			
		||||
      if (!req.params.from || from < 0) {
 | 
			
		||||
        return res.status(400).send(`Parameter 'from' must be a block height (integer)`);
 | 
			
		||||
        handleError(req, res, 400, `Parameter 'from' must be a block height (integer)`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      const to = req.params.to === undefined ? await bitcoinApi.$getBlockHeightTip() : parseInt(req.params.to, 10);
 | 
			
		||||
      if (to < 0) {
 | 
			
		||||
        return res.status(400).send(`Parameter 'to' must be a block height (integer)`);
 | 
			
		||||
        handleError(req, res, 400, `Parameter 'to' must be a block height (integer)`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (from > to) {
 | 
			
		||||
        return res.status(400).send(`Parameter 'to' must be a higher block height than 'from'`);
 | 
			
		||||
        handleError(req, res, 400, `Parameter 'to' must be a higher block height than 'from'`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if ((to - from + 1) > config.MEMPOOL.MAX_BLOCKS_BULK_QUERY) {
 | 
			
		||||
        return res.status(400).send(`You can only query ${config.MEMPOOL.MAX_BLOCKS_BULK_QUERY} blocks at once.`);
 | 
			
		||||
        handleError(req, res, 400, `You can only query ${config.MEMPOOL.MAX_BLOCKS_BULK_QUERY} blocks at once.`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(await blocks.$getBlocksBetweenHeight(from, to));
 | 
			
		||||
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -458,7 +468,7 @@ class BitcoinRoutes {
 | 
			
		||||
      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);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -483,7 +493,7 @@ class BitcoinRoutes {
 | 
			
		||||
      res.json(transactions);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      loadingIndicators.setProgress('blocktxs-' + req.params.hash, 100);
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -492,13 +502,13 @@ class BitcoinRoutes {
 | 
			
		||||
      const blockHash = await bitcoinApi.$getBlockHash(parseInt(req.params.height, 10));
 | 
			
		||||
      res.send(blockHash);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async getAddress(req: Request, res: Response) {
 | 
			
		||||
    if (config.MEMPOOL.BACKEND === 'none') {
 | 
			
		||||
      res.status(405).send('Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      handleError(req, res, 405, 'Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -507,15 +517,16 @@ class BitcoinRoutes {
 | 
			
		||||
      res.json(addressData);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) {
 | 
			
		||||
        return res.status(413).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 413, e instanceof Error ? e.message : e);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async getAddressTransactions(req: Request, res: Response): Promise<void> {
 | 
			
		||||
    if (config.MEMPOOL.BACKEND === 'none') {
 | 
			
		||||
      res.status(405).send('Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      handleError(req, res, 405, 'Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -528,23 +539,23 @@ class BitcoinRoutes {
 | 
			
		||||
      res.json(transactions);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) {
 | 
			
		||||
        res.status(413).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 413, e instanceof Error ? e.message : e);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async getAddressTransactionSummary(req: Request, res: Response): Promise<void> {
 | 
			
		||||
    if (config.MEMPOOL.BACKEND !== 'esplora') {
 | 
			
		||||
      res.status(405).send('Address summary lookups require mempool/electrs backend.');
 | 
			
		||||
      handleError(req, res, 405, 'Address summary lookups require mempool/electrs backend.');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async getScriptHash(req: Request, res: Response) {
 | 
			
		||||
    if (config.MEMPOOL.BACKEND === 'none') {
 | 
			
		||||
      res.status(405).send('Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      handleError(req, res, 405, 'Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -555,15 +566,16 @@ class BitcoinRoutes {
 | 
			
		||||
      res.json(addressData);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) {
 | 
			
		||||
        return res.status(413).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 413, e instanceof Error ? e.message : e);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async getScriptHashTransactions(req: Request, res: Response): Promise<void> {
 | 
			
		||||
    if (config.MEMPOOL.BACKEND === 'none') {
 | 
			
		||||
      res.status(405).send('Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      handleError(req, res, 405, 'Address lookups cannot be used with bitcoind as backend.');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -578,16 +590,16 @@ class BitcoinRoutes {
 | 
			
		||||
      res.json(transactions);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof Error && e.message && (e.message.indexOf('too long') > 0 || e.message.indexOf('confirmed status') > 0)) {
 | 
			
		||||
        res.status(413).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 413, e instanceof Error ? e.message : e);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async getScriptHashTransactionSummary(req: Request, res: Response): Promise<void> {
 | 
			
		||||
    if (config.MEMPOOL.BACKEND !== 'esplora') {
 | 
			
		||||
      res.status(405).send('Scripthash summary lookups require mempool/electrs backend.');
 | 
			
		||||
      handleError(req, res, 405, 'Scripthash summary lookups require mempool/electrs backend.');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -597,7 +609,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const blockHash = await bitcoinApi.$getAddressPrefix(req.params.prefix);
 | 
			
		||||
      res.send(blockHash);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -624,7 +636,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const rawMempool = await bitcoinApi.$getRawMempool();
 | 
			
		||||
      res.send(rawMempool);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -632,12 +644,13 @@ class BitcoinRoutes {
 | 
			
		||||
    try {
 | 
			
		||||
      const result = blocks.getCurrentBlockHeight();
 | 
			
		||||
      if (!result) {
 | 
			
		||||
        return res.status(503).send(`Service Temporarily Unavailable`);
 | 
			
		||||
        handleError(req, res, 503, `Service Temporarily Unavailable`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.setHeader('content-type', 'text/plain');
 | 
			
		||||
      res.send(result.toString());
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -647,7 +660,7 @@ class BitcoinRoutes {
 | 
			
		||||
      res.setHeader('content-type', 'text/plain');
 | 
			
		||||
      res.send(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -657,7 +670,7 @@ class BitcoinRoutes {
 | 
			
		||||
      res.setHeader('content-type', 'application/octet-stream');
 | 
			
		||||
      res.send(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -666,7 +679,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const result = await bitcoinApi.$getTxIdsForBlock(req.params.hash);
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -675,7 +688,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const result = await bitcoinClient.validateAddress(req.params.address);
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -688,7 +701,7 @@ class BitcoinRoutes {
 | 
			
		||||
        replaces
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -697,7 +710,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const result = rbfCache.getRbfTrees(false);
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -706,7 +719,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const result = rbfCache.getRbfTrees(true);
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -719,7 +732,7 @@ class BitcoinRoutes {
 | 
			
		||||
        res.status(204).send();
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -728,7 +741,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const result = await bitcoinApi.$getOutspends(req.params.txId);
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -738,10 +751,10 @@ class BitcoinRoutes {
 | 
			
		||||
      if (da) {
 | 
			
		||||
        res.json(da);
 | 
			
		||||
      } else {
 | 
			
		||||
        res.status(503).send(`Service Temporarily Unavailable`);
 | 
			
		||||
        handleError(req, res, 503, `Service Temporarily Unavailable`);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -752,7 +765,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const txIdResult = await bitcoinApi.$sendRawTransaction(rawTx);
 | 
			
		||||
      res.send(txIdResult);
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
      res.status(400).send(e.message && e.code ? 'sendrawtransaction RPC error: ' + JSON.stringify({ code: e.code, message: e.message })
 | 
			
		||||
      handleError(req, res, 400, e.message && e.code ? 'sendrawtransaction RPC error: ' + JSON.stringify({ code: e.code, message: e.message })
 | 
			
		||||
        : (e.message || 'Error'));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -764,7 +777,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const txIdResult = await bitcoinClient.sendRawTransaction(txHex);
 | 
			
		||||
      res.send(txIdResult);
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
      res.status(400).send(e.message && e.code ? 'sendrawtransaction RPC error: ' + JSON.stringify({ code: e.code, message: e.message })
 | 
			
		||||
      handleError(req, res, 400, e.message && e.code ? 'sendrawtransaction RPC error: ' + JSON.stringify({ code: e.code, message: e.message })
 | 
			
		||||
        : (e.message || 'Error'));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -776,8 +789,7 @@ class BitcoinRoutes {
 | 
			
		||||
      const result = await bitcoinApi.$testMempoolAccept(rawTxs, maxfeerate);
 | 
			
		||||
      res.send(result);
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
      res.setHeader('content-type', 'text/plain');
 | 
			
		||||
      res.status(400).send(e.message && e.code ? 'testmempoolaccept RPC error: ' + JSON.stringify({ code: e.code, message: e.message })
 | 
			
		||||
      handleError(req, res, 400, e.message && e.code ? 'testmempoolaccept RPC error: ' + JSON.stringify({ code: e.code, message: e.message })
 | 
			
		||||
        : (e.message || 'Error'));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import config from '../../config';
 | 
			
		||||
import { Application, Request, Response } from 'express';
 | 
			
		||||
import channelsApi from './channels.api';
 | 
			
		||||
import { handleError } from '../../utils/api';
 | 
			
		||||
 | 
			
		||||
class ChannelsRoutes {
 | 
			
		||||
  constructor() { }
 | 
			
		||||
@ -22,7 +23,7 @@ class ChannelsRoutes {
 | 
			
		||||
      const channels = await channelsApi.$searchChannelsById(req.params.search);
 | 
			
		||||
      res.json(channels);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -38,7 +39,7 @@ class ChannelsRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(channel);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -53,11 +54,11 @@ class ChannelsRoutes {
 | 
			
		||||
      const status: string = typeof req.query.status === 'string' ? req.query.status : '';
 | 
			
		||||
 | 
			
		||||
      if (index < -1) {
 | 
			
		||||
        res.status(400).send('Invalid index');
 | 
			
		||||
        handleError(req, res, 400, 'Invalid index');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      if (['open', 'active', 'closed'].includes(status) === false) {
 | 
			
		||||
        res.status(400).send('Invalid status');
 | 
			
		||||
        handleError(req, res, 400, 'Invalid status');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -69,14 +70,14 @@ class ChannelsRoutes {
 | 
			
		||||
      res.header('X-Total-Count', channelsCount.toString());
 | 
			
		||||
      res.json(channels);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async $getChannelsByTransactionIds(req: Request, res: Response): Promise<void> {
 | 
			
		||||
    try {
 | 
			
		||||
      if (!Array.isArray(req.query.txId)) {
 | 
			
		||||
        res.status(400).send('Not an array');
 | 
			
		||||
        handleError(req, res, 400, 'Not an array');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      const txIds: string[] = [];
 | 
			
		||||
@ -107,7 +108,7 @@ class ChannelsRoutes {
 | 
			
		||||
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -119,7 +120,7 @@ class ChannelsRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(channels);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -132,7 +133,7 @@ class ChannelsRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(channels);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,8 @@ import { Application, Request, Response } from 'express';
 | 
			
		||||
import nodesApi from './nodes.api';
 | 
			
		||||
import channelsApi from './channels.api';
 | 
			
		||||
import statisticsApi from './statistics.api';
 | 
			
		||||
import { handleError } from '../../utils/api';
 | 
			
		||||
 | 
			
		||||
class GeneralLightningRoutes {
 | 
			
		||||
  constructor() { }
 | 
			
		||||
 | 
			
		||||
@ -27,7 +29,7 @@ class GeneralLightningRoutes {
 | 
			
		||||
        channels: channels,
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -41,7 +43,7 @@ class GeneralLightningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(statistics);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -50,7 +52,7 @@ class GeneralLightningRoutes {
 | 
			
		||||
      const statistics = await statisticsApi.$getLatestStatistics();
 | 
			
		||||
      res.json(statistics);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ import { Application, Request, Response } from 'express';
 | 
			
		||||
import nodesApi from './nodes.api';
 | 
			
		||||
import DB from '../../database';
 | 
			
		||||
import { INodesRanking } from '../../mempool.interfaces';
 | 
			
		||||
import { handleError } from '../../utils/api';
 | 
			
		||||
 | 
			
		||||
class NodesRoutes {
 | 
			
		||||
  constructor() { }
 | 
			
		||||
@ -31,7 +32,7 @@ class NodesRoutes {
 | 
			
		||||
      const nodes = await nodesApi.$searchNodeByPublicKeyOrAlias(req.params.search);
 | 
			
		||||
      res.json(nodes);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -187,7 +188,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(nodes);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -195,7 +196,7 @@ class NodesRoutes {
 | 
			
		||||
    try {
 | 
			
		||||
      const node = await nodesApi.$getNode(req.params.public_key);
 | 
			
		||||
      if (!node) {
 | 
			
		||||
        res.status(404).send('Node not found');
 | 
			
		||||
        handleError(req, res, 404, 'Node not found');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.header('Pragma', 'public');
 | 
			
		||||
@ -203,7 +204,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(node);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -215,7 +216,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(statistics);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -223,7 +224,7 @@ class NodesRoutes {
 | 
			
		||||
    try {
 | 
			
		||||
      const node = await nodesApi.$getFeeHistogram(req.params.public_key);
 | 
			
		||||
      if (!node) {
 | 
			
		||||
        res.status(404).send('Node not found');
 | 
			
		||||
        handleError(req, res, 404, 'Node not found');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.header('Pragma', 'public');
 | 
			
		||||
@ -231,7 +232,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(node);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -247,7 +248,7 @@ class NodesRoutes {
 | 
			
		||||
        topByChannels: topChannelsNodes,
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -259,7 +260,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(topCapacityNodes);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -271,7 +272,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(topCapacityNodes);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -283,7 +284,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(topCapacityNodes);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -295,7 +296,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 600).toUTCString());
 | 
			
		||||
      res.json(nodesPerAs);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -307,7 +308,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 600).toUTCString());
 | 
			
		||||
      res.json(worldNodes);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -322,7 +323,7 @@ class NodesRoutes {
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      if (country.length === 0) {
 | 
			
		||||
        res.status(404).send(`This country does not exist or does not host any lightning nodes on clearnet`);
 | 
			
		||||
        handleError(req, res, 404, `This country does not exist or does not host any lightning nodes on clearnet`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -335,7 +336,7 @@ class NodesRoutes {
 | 
			
		||||
        nodes: nodes,
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -349,7 +350,7 @@ class NodesRoutes {
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      if (isp.length === 0) {
 | 
			
		||||
        res.status(404).send(`This ISP does not exist or does not host any lightning nodes on clearnet`);
 | 
			
		||||
        handleError(req, res, 404, `This ISP does not exist or does not host any lightning nodes on clearnet`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -362,7 +363,7 @@ class NodesRoutes {
 | 
			
		||||
        nodes: nodes,
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -374,7 +375,7 @@ class NodesRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 600).toUTCString());
 | 
			
		||||
      res.json(nodesPerAs);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ import { Application, Request, Response } from 'express';
 | 
			
		||||
import config from '../../config';
 | 
			
		||||
import elementsParser from './elements-parser';
 | 
			
		||||
import icons from './icons';
 | 
			
		||||
import { handleError } from '../../utils/api';
 | 
			
		||||
 | 
			
		||||
class LiquidRoutes {
 | 
			
		||||
  public initRoutes(app: Application) {
 | 
			
		||||
@ -42,7 +43,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('content-length', result.length);
 | 
			
		||||
      res.send(result);
 | 
			
		||||
    } else {
 | 
			
		||||
      res.status(404).send('Asset icon not found');
 | 
			
		||||
      handleError(req, res, 404, 'Asset icon not found');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -51,7 +52,7 @@ class LiquidRoutes {
 | 
			
		||||
    if (result) {
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } else {
 | 
			
		||||
      res.status(404).send('Asset icons not found');
 | 
			
		||||
      handleError(req, res, 404, 'Asset icons not found');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -82,7 +83,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60 * 60).toUTCString());
 | 
			
		||||
      res.json(pegs);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -94,7 +95,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60 * 60).toUTCString());
 | 
			
		||||
      res.json(reserves);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -106,7 +107,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(currentSupply);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -118,7 +119,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(currentReserves);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -130,7 +131,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(auditStatus);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -142,7 +143,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(federationAddresses);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -154,7 +155,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(federationAddresses);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -166,7 +167,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(federationUtxos);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -178,7 +179,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(expiredUtxos);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -190,7 +191,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(federationUtxos);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -202,7 +203,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(emergencySpentUtxos);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -214,7 +215,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(emergencySpentUtxos);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -226,7 +227,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(recentPegs);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -238,7 +239,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(pegsVolume);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -250,7 +251,7 @@ class LiquidRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 30).toUTCString());
 | 
			
		||||
      res.json(pegsCount);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ import mining from "./mining";
 | 
			
		||||
import PricesRepository from '../../repositories/PricesRepository';
 | 
			
		||||
import AccelerationRepository from '../../repositories/AccelerationRepository';
 | 
			
		||||
import accelerationApi from '../services/acceleration';
 | 
			
		||||
import { handleError } from '../../utils/api';
 | 
			
		||||
 | 
			
		||||
class MiningRoutes {
 | 
			
		||||
  public initRoutes(app: Application) {
 | 
			
		||||
@ -53,7 +54,7 @@ class MiningRoutes {
 | 
			
		||||
      res.header('Cache-control', 'public');
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
 | 
			
		||||
      if (['testnet', 'signet', 'liquidtestnet'].includes(config.MEMPOOL.NETWORK)) {
 | 
			
		||||
        res.status(400).send('Prices are not available on testnets.');
 | 
			
		||||
        handleError(req, res, 400, 'Prices are not available on testnets.');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      const timestamp = parseInt(req.query.timestamp as string, 10) || 0;
 | 
			
		||||
@ -71,7 +72,7 @@ class MiningRoutes {
 | 
			
		||||
      }
 | 
			
		||||
      res.status(200).send(response);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -84,9 +85,9 @@ class MiningRoutes {
 | 
			
		||||
      res.json(stats);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof Error && e.message.indexOf('This mining pool does not exist') > -1) {
 | 
			
		||||
        res.status(404).send(e.message);
 | 
			
		||||
        handleError(req, res, 404, e.message);
 | 
			
		||||
      } else {
 | 
			
		||||
        res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -103,9 +104,9 @@ class MiningRoutes {
 | 
			
		||||
      res.json(poolBlocks);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof Error && e.message.indexOf('This mining pool does not exist') > -1) {
 | 
			
		||||
        res.status(404).send(e.message);
 | 
			
		||||
        handleError(req, res, 404, e.message);
 | 
			
		||||
      } else {
 | 
			
		||||
        res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -129,7 +130,7 @@ class MiningRoutes {
 | 
			
		||||
        res.json(pools);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -143,7 +144,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(stats);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -157,7 +158,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
 | 
			
		||||
      res.json(hashrates);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -172,9 +173,9 @@ class MiningRoutes {
 | 
			
		||||
      res.json(hashrates);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      if (e instanceof Error && e.message.indexOf('This mining pool does not exist') > -1) {
 | 
			
		||||
        res.status(404).send(e.message);
 | 
			
		||||
        handleError(req, res, 404, e.message);
 | 
			
		||||
      } else {
 | 
			
		||||
        res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
        handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -203,7 +204,7 @@ class MiningRoutes {
 | 
			
		||||
        currentDifficulty: currentDifficulty,
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -217,7 +218,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(blockFees);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -235,7 +236,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(blockFees);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -249,7 +250,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(blockRewards);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -263,7 +264,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(blockFeeRates);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -281,7 +282,7 @@ class MiningRoutes {
 | 
			
		||||
        weights: blockWeights
 | 
			
		||||
      });
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -293,7 +294,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
 | 
			
		||||
      res.json(difficulty.map(adj => [adj.time, adj.height, adj.difficulty, adj.adjustment]));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -317,7 +318,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(blocksHealth.map(health => [health.time, health.height, health.match_rate]));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -326,7 +327,7 @@ class MiningRoutes {
 | 
			
		||||
      const audit = await BlocksAuditsRepository.$getBlockAudit(req.params.hash);
 | 
			
		||||
 | 
			
		||||
      if (!audit) {
 | 
			
		||||
        res.status(204).send(`This block has not been audited.`);
 | 
			
		||||
        handleError(req, res, 204, `This block has not been audited.`);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -335,7 +336,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24).toUTCString());
 | 
			
		||||
      res.json(audit);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -358,7 +359,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
 | 
			
		||||
      res.json(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -371,7 +372,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      res.json(await BlocksAuditsRepository.$getBlockAuditScores(height, height - 15));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -384,7 +385,7 @@ class MiningRoutes {
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24).toUTCString());
 | 
			
		||||
      res.json(audit || 'null');
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -394,12 +395,12 @@ class MiningRoutes {
 | 
			
		||||
      res.header('Cache-control', 'public');
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
 | 
			
		||||
        res.status(400).send('Acceleration data is not available.');
 | 
			
		||||
        handleError(req, res, 400, 'Acceleration data is not available.');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(200).send(await AccelerationRepository.$getAccelerationInfo(req.params.slug));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -409,13 +410,13 @@ class MiningRoutes {
 | 
			
		||||
      res.header('Cache-control', 'public');
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 3600 * 24).toUTCString());
 | 
			
		||||
      if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
 | 
			
		||||
        res.status(400).send('Acceleration data is not available.');
 | 
			
		||||
        handleError(req, res, 400, 'Acceleration data is not available.');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      const height = req.params.height === undefined ? undefined : parseInt(req.params.height, 10);
 | 
			
		||||
      res.status(200).send(await AccelerationRepository.$getAccelerationInfo(null, height));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -425,12 +426,12 @@ class MiningRoutes {
 | 
			
		||||
      res.header('Cache-control', 'public');
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
 | 
			
		||||
        res.status(400).send('Acceleration data is not available.');
 | 
			
		||||
        handleError(req, res, 400, 'Acceleration data is not available.');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(200).send(await AccelerationRepository.$getAccelerationInfo(null, null, req.params.interval));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -440,12 +441,12 @@ class MiningRoutes {
 | 
			
		||||
      res.header('Cache-control', 'public');
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
 | 
			
		||||
        res.status(400).send('Acceleration data is not available.');
 | 
			
		||||
        handleError(req, res, 400, 'Acceleration data is not available.');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(200).send(await AccelerationRepository.$getAccelerationTotals(<string>req.query.pool, <string>req.query.interval));
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -455,12 +456,12 @@ class MiningRoutes {
 | 
			
		||||
      res.header('Cache-control', 'public');
 | 
			
		||||
      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
			
		||||
      if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
 | 
			
		||||
        res.status(400).send('Acceleration data is not available.');
 | 
			
		||||
        handleError(req, res, 400, 'Acceleration data is not available.');
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      res.status(200).send(accelerationApi.accelerations || []);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -472,7 +473,7 @@ class MiningRoutes {
 | 
			
		||||
      accelerationApi.accelerationRequested(req.params.txid);
 | 
			
		||||
      res.status(200).send();
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
			
		||||
      handleError(req, res, 500, e instanceof Error ? e.message : e);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										9
									
								
								backend/src/utils/api.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								backend/src/utils/api.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
			
		||||
import { Request, Response } from 'express';
 | 
			
		||||
 | 
			
		||||
export function handleError(req: Request, res: Response, statusCode: number, errorMessage: string | unknown): void {
 | 
			
		||||
  if (req.accepts('json')) {
 | 
			
		||||
    res.status(statusCode).json({ error: errorMessage });
 | 
			
		||||
  } else {
 | 
			
		||||
    res.status(statusCode).send(errorMessage);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user