2020-06-07 12:30:32 +02:00
|
|
|
import { Express, Request, Response, NextFunction } from 'express';
|
2019-07-21 16:59:47 +02:00
|
|
|
import * as express from 'express';
|
|
|
|
import * as http from 'http';
|
|
|
|
import * as WebSocket from 'ws';
|
2020-09-21 22:52:54 +02:00
|
|
|
import * as cluster from 'cluster';
|
2020-11-15 08:22:47 +01:00
|
|
|
import axios from 'axios';
|
2019-07-21 16:59:47 +02:00
|
|
|
|
2020-07-22 19:04:29 +02:00
|
|
|
import { checkDbConnection } from './database';
|
2020-10-19 06:57:02 +02:00
|
|
|
import config from './config';
|
2020-02-16 16:15:07 +01:00
|
|
|
import routes from './routes';
|
2019-07-21 16:59:47 +02:00
|
|
|
import blocks from './api/blocks';
|
2020-02-16 16:15:07 +01:00
|
|
|
import memPool from './api/mempool';
|
|
|
|
import diskCache from './api/disk-cache';
|
2019-07-21 16:59:47 +02:00
|
|
|
import statistics from './api/statistics';
|
2020-02-26 11:49:53 +01:00
|
|
|
import websocketHandler from './api/websocket-handler';
|
2019-07-21 16:59:47 +02:00
|
|
|
import fiatConversion from './api/fiat-conversion';
|
2020-09-10 09:46:23 +02:00
|
|
|
import bisq from './api/bisq/bisq';
|
|
|
|
import bisqMarkets from './api/bisq/markets';
|
2020-10-13 10:27:52 +02:00
|
|
|
import logger from './logger';
|
2020-10-13 12:48:43 +02:00
|
|
|
import backendInfo from './api/backend-info';
|
2021-01-05 12:57:06 +01:00
|
|
|
import loadingIndicators from './api/loading-indicators';
|
2021-01-20 11:16:43 +01:00
|
|
|
import mempool from './api/mempool';
|
2021-09-18 11:37:25 +02:00
|
|
|
import elementsParser from './api/liquid/elements-parser';
|
2021-12-11 01:27:58 +01:00
|
|
|
import databaseMigration from './api/database-migration';
|
2022-01-19 10:50:52 +01:00
|
|
|
import poolsParser from './api/pools-parser';
|
2021-12-20 23:00:50 +01:00
|
|
|
import syncAssets from './sync-assets';
|
|
|
|
import icons from './api/liquid/icons';
|
2021-12-30 23:28:40 +01:00
|
|
|
import { Common } from './api/common';
|
2022-02-19 12:45:02 +01:00
|
|
|
import mining from './api/mining';
|
2022-02-24 12:20:18 +01:00
|
|
|
import HashratesRepository from './repositories/HashratesRepository';
|
2019-07-21 16:59:47 +02:00
|
|
|
|
2020-02-16 16:15:07 +01:00
|
|
|
class Server {
|
2020-09-21 22:52:54 +02:00
|
|
|
private wss: WebSocket.Server | undefined;
|
2021-02-06 20:20:07 +01:00
|
|
|
private server: http.Server | undefined;
|
2020-09-21 22:52:54 +02:00
|
|
|
private app: Express;
|
2021-01-06 16:49:28 +01:00
|
|
|
private currentBackendRetryInterval = 5;
|
2019-07-21 16:59:47 +02:00
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.app = express();
|
2020-02-16 16:15:07 +01:00
|
|
|
|
2020-10-19 06:57:02 +02:00
|
|
|
if (!config.MEMPOOL.SPAWN_CLUSTER_PROCS) {
|
2020-09-21 22:52:54 +02:00
|
|
|
this.startServer();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cluster.isMaster) {
|
2020-10-19 06:57:02 +02:00
|
|
|
logger.notice(`Mempool Server (Master) is running on port ${config.MEMPOOL.HTTP_PORT} (${backendInfo.getShortCommitHash()})`);
|
2020-09-21 22:52:54 +02:00
|
|
|
|
2020-10-19 06:57:02 +02:00
|
|
|
const numCPUs = config.MEMPOOL.SPAWN_CLUSTER_PROCS;
|
2020-09-21 22:52:54 +02:00
|
|
|
for (let i = 0; i < numCPUs; i++) {
|
2020-09-29 19:25:43 +02:00
|
|
|
const env = { workerId: i };
|
|
|
|
const worker = cluster.fork(env);
|
|
|
|
worker.process['env'] = env;
|
2020-09-21 22:52:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cluster.on('exit', (worker, code, signal) => {
|
2020-09-29 19:25:43 +02:00
|
|
|
const workerId = worker.process['env'].workerId;
|
2020-10-13 11:43:09 +02:00
|
|
|
logger.warn(`Mempool Worker PID #${worker.process.pid} workerId: ${workerId} died. Restarting in 10 seconds... ${signal || code}`);
|
2020-09-29 19:25:43 +02:00
|
|
|
setTimeout(() => {
|
|
|
|
const env = { workerId: workerId };
|
|
|
|
const newWorker = cluster.fork(env);
|
|
|
|
newWorker.process['env'] = env;
|
|
|
|
}, 10000);
|
2020-09-21 22:52:54 +02:00
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.startServer(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-30 15:09:30 +01:00
|
|
|
async startServer(worker = false) {
|
2021-01-19 19:34:21 +01:00
|
|
|
logger.debug(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`);
|
|
|
|
|
2019-07-21 16:59:47 +02:00
|
|
|
this.app
|
2020-06-07 12:30:32 +02:00
|
|
|
.use((req: Request, res: Response, next: NextFunction) => {
|
2019-07-21 16:59:47 +02:00
|
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
|
|
next();
|
|
|
|
})
|
2020-10-07 15:15:42 +02:00
|
|
|
.use(express.urlencoded({ extended: true }))
|
2021-10-19 13:37:45 +02:00
|
|
|
.use(express.text())
|
|
|
|
;
|
2020-02-16 16:15:07 +01:00
|
|
|
|
2020-10-19 06:57:02 +02:00
|
|
|
this.server = http.createServer(this.app);
|
|
|
|
this.wss = new WebSocket.Server({ server: this.server });
|
2019-07-21 16:59:47 +02:00
|
|
|
|
2021-03-18 17:47:40 +01:00
|
|
|
this.setUpWebsocketHandling();
|
|
|
|
|
2021-12-20 23:00:50 +01:00
|
|
|
await syncAssets.syncAssets();
|
2021-01-19 19:34:21 +01:00
|
|
|
diskCache.loadMempoolCache();
|
|
|
|
|
2020-10-19 06:57:02 +02:00
|
|
|
if (config.DATABASE.ENABLED) {
|
2021-01-30 15:09:30 +01:00
|
|
|
await checkDbConnection();
|
2021-12-11 01:27:58 +01:00
|
|
|
try {
|
2022-02-21 08:38:18 +01:00
|
|
|
if (process.env.npm_config_reindex != undefined) { // Re-index requests
|
|
|
|
const tables = process.env.npm_config_reindex.split(',');
|
|
|
|
logger.warn(`Indexed data for "${process.env.npm_config_reindex}" tables will be erased in 5 seconds from now (using '--reindex') ...`);
|
|
|
|
await Common.sleep(5000);
|
|
|
|
await databaseMigration.$truncateIndexedData(tables);
|
|
|
|
}
|
2022-02-24 12:20:18 +01:00
|
|
|
await this.$resetHashratesIndexingState();
|
2021-12-11 01:27:58 +01:00
|
|
|
await databaseMigration.$initializeOrMigrateDatabase();
|
2022-01-28 06:31:33 +01:00
|
|
|
await poolsParser.migratePoolsJson();
|
2021-12-11 01:27:58 +01:00
|
|
|
} catch (e) {
|
|
|
|
throw new Error(e instanceof Error ? e.message : 'Error');
|
|
|
|
}
|
2020-10-19 06:57:02 +02:00
|
|
|
}
|
|
|
|
|
2021-04-19 19:39:30 +02:00
|
|
|
if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED && cluster.isMaster) {
|
2020-07-22 19:04:29 +02:00
|
|
|
statistics.startStatistics();
|
|
|
|
}
|
|
|
|
|
2021-12-30 23:28:40 +01:00
|
|
|
if (Common.isLiquid()) {
|
2021-12-20 23:00:50 +01:00
|
|
|
icons.loadIcons();
|
|
|
|
}
|
|
|
|
|
2021-01-30 16:12:22 +01:00
|
|
|
fiatConversion.startService();
|
|
|
|
|
2020-02-26 11:49:53 +01:00
|
|
|
this.setUpHttpApiRoutes();
|
2020-10-23 11:27:02 +02:00
|
|
|
this.runMainUpdateLoop();
|
2019-07-21 16:59:47 +02:00
|
|
|
|
2021-04-25 00:38:46 +02:00
|
|
|
if (config.BISQ.ENABLED) {
|
2020-07-03 18:45:19 +02:00
|
|
|
bisq.startBisqService();
|
2020-07-14 16:26:02 +02:00
|
|
|
bisq.setPriceCallbackFunction((price) => websocketHandler.setExtraInitProperties('bsq-price', price));
|
2020-09-27 12:21:18 +02:00
|
|
|
blocks.setNewBlockCallback(bisq.handleNewBitcoinBlock.bind(bisq));
|
2020-09-10 09:46:23 +02:00
|
|
|
bisqMarkets.startBisqService();
|
|
|
|
}
|
|
|
|
|
2020-10-19 06:57:02 +02:00
|
|
|
this.server.listen(config.MEMPOOL.HTTP_PORT, () => {
|
2020-09-21 22:52:54 +02:00
|
|
|
if (worker) {
|
2020-10-13 10:27:52 +02:00
|
|
|
logger.info(`Mempool Server worker #${process.pid} started`);
|
2020-09-21 22:52:54 +02:00
|
|
|
} else {
|
2021-01-19 19:34:21 +01:00
|
|
|
logger.notice(`Mempool Server is running on port ${config.MEMPOOL.HTTP_PORT}`);
|
2020-09-21 22:52:54 +02:00
|
|
|
}
|
2019-07-21 16:59:47 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-10-23 11:27:02 +02:00
|
|
|
async runMainUpdateLoop() {
|
2020-10-18 16:47:47 +02:00
|
|
|
try {
|
2021-04-02 09:47:13 +02:00
|
|
|
try {
|
|
|
|
await memPool.$updateMemPoolInfo();
|
|
|
|
} catch (e) {
|
2021-08-31 14:09:33 +02:00
|
|
|
const msg = `updateMempoolInfo: ${(e instanceof Error ? e.message : e)}`;
|
2021-09-19 00:40:16 +02:00
|
|
|
if (config.MEMPOOL.USE_SECOND_NODE_FOR_MINFEE) {
|
2021-04-02 09:47:13 +02:00
|
|
|
logger.warn(msg);
|
|
|
|
} else {
|
|
|
|
logger.debug(msg);
|
|
|
|
}
|
|
|
|
}
|
2020-10-18 16:47:47 +02:00
|
|
|
await blocks.$updateBlocks();
|
|
|
|
await memPool.$updateMempool();
|
2022-02-24 12:20:18 +01:00
|
|
|
this.$runIndexingWhenReady();
|
2022-01-05 07:41:14 +01:00
|
|
|
|
2021-01-06 16:49:28 +01:00
|
|
|
setTimeout(this.runMainUpdateLoop.bind(this), config.MEMPOOL.POLL_RATE_MS);
|
|
|
|
this.currentBackendRetryInterval = 5;
|
2020-10-18 16:47:47 +02:00
|
|
|
} catch (e) {
|
2021-08-31 14:09:33 +02:00
|
|
|
const loggerMsg = `runMainLoop error: ${(e instanceof Error ? e.message : e)}. Retrying in ${this.currentBackendRetryInterval} sec.`;
|
2021-01-06 16:49:28 +01:00
|
|
|
if (this.currentBackendRetryInterval > 5) {
|
2020-10-23 11:27:02 +02:00
|
|
|
logger.warn(loggerMsg);
|
2021-01-20 11:16:43 +01:00
|
|
|
mempool.setOutOfSync();
|
2020-10-23 11:27:02 +02:00
|
|
|
} else {
|
|
|
|
logger.debug(loggerMsg);
|
|
|
|
}
|
2021-01-01 22:40:10 +01:00
|
|
|
logger.debug(JSON.stringify(e));
|
2021-01-06 16:49:28 +01:00
|
|
|
setTimeout(this.runMainUpdateLoop.bind(this), 1000 * this.currentBackendRetryInterval);
|
|
|
|
this.currentBackendRetryInterval *= 2;
|
|
|
|
this.currentBackendRetryInterval = Math.min(this.currentBackendRetryInterval, 60);
|
2020-10-18 16:47:47 +02:00
|
|
|
}
|
2019-07-21 16:59:47 +02:00
|
|
|
}
|
|
|
|
|
2022-02-24 12:20:18 +01:00
|
|
|
async $resetHashratesIndexingState() {
|
|
|
|
return await HashratesRepository.$setLatestRunTimestamp(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
async $runIndexingWhenReady() {
|
2022-02-19 12:45:02 +01:00
|
|
|
if (!Common.indexingEnabled() || mempool.hasPriority()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-02-21 15:46:25 +01:00
|
|
|
|
|
|
|
try {
|
|
|
|
await blocks.$generateBlockDatabase();
|
|
|
|
await mining.$generateNetworkHashrateHistory();
|
|
|
|
} catch (e) {
|
2022-02-21 15:57:44 +01:00
|
|
|
logger.err(`Unable to run indexing right now, trying again later. ` + e);
|
2022-02-21 15:46:25 +01:00
|
|
|
}
|
2022-02-19 12:45:02 +01:00
|
|
|
}
|
|
|
|
|
2020-02-26 11:49:53 +01:00
|
|
|
setUpWebsocketHandling() {
|
2020-09-21 22:52:54 +02:00
|
|
|
if (this.wss) {
|
|
|
|
websocketHandler.setWebsocketServer(this.wss);
|
|
|
|
}
|
2021-12-30 23:28:40 +01:00
|
|
|
if (Common.isLiquid() && config.DATABASE.ENABLED) {
|
2021-09-18 11:37:25 +02:00
|
|
|
blocks.setNewBlockCallback(async () => {
|
|
|
|
try {
|
|
|
|
await elementsParser.$parse();
|
|
|
|
} catch (e) {
|
|
|
|
logger.warn('Elements parsing error: ' + (e instanceof Error ? e.message : e));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2020-02-26 11:49:53 +01:00
|
|
|
websocketHandler.setupConnectionHandling();
|
|
|
|
statistics.setNewStatisticsEntryCallback(websocketHandler.handleNewStatistic.bind(websocketHandler));
|
|
|
|
blocks.setNewBlockCallback(websocketHandler.handleNewBlock.bind(websocketHandler));
|
|
|
|
memPool.setMempoolChangedCallback(websocketHandler.handleMempoolChange.bind(websocketHandler));
|
2021-01-06 17:31:33 +01:00
|
|
|
fiatConversion.setProgressChangedCallback(websocketHandler.handleNewConversionRates.bind(websocketHandler));
|
2021-01-05 12:57:06 +01:00
|
|
|
loadingIndicators.setProgressChangedCallback(websocketHandler.handleLoadingChanged.bind(websocketHandler));
|
2019-07-21 16:59:47 +02:00
|
|
|
}
|
|
|
|
|
2020-02-26 11:49:53 +01:00
|
|
|
setUpHttpApiRoutes() {
|
2019-07-21 16:59:47 +02:00
|
|
|
this.app
|
2020-10-19 06:57:02 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'transaction-times', routes.getTransactionTimes)
|
2021-03-18 17:47:40 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'cpfp/:txId', routes.getCpfpInfo)
|
2021-07-18 23:50:09 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'difficulty-adjustment', routes.getDifficultyChange)
|
2020-10-19 06:57:02 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'fees/recommended', routes.getRecommendedFees)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'fees/mempool-blocks', routes.getMempoolBlocks)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'backend-info', routes.getBackendInfo)
|
2020-11-22 20:38:56 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'init-data', routes.getInitData)
|
2021-09-07 11:13:29 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'validate-address/:address', routes.validateAddress)
|
2021-10-20 21:55:36 +02:00
|
|
|
.post(config.MEMPOOL.API_URL_PREFIX + 'tx/push', routes.$postTransactionForm)
|
2021-02-06 20:20:07 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'donations', async (req, res) => {
|
|
|
|
try {
|
2021-02-06 21:00:02 +01:00
|
|
|
const response = await axios.get('https://mempool.space/api/v1/donations', { responseType: 'stream', timeout: 10000 });
|
2021-02-06 20:20:07 +01:00
|
|
|
response.data.pipe(res);
|
|
|
|
} catch (e) {
|
|
|
|
res.status(500).end();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'donations/images/:id', async (req, res) => {
|
|
|
|
try {
|
2021-02-06 21:00:02 +01:00
|
|
|
const response = await axios.get('https://mempool.space/api/v1/donations/images/' + req.params.id, {
|
2021-02-06 20:20:07 +01:00
|
|
|
responseType: 'stream', timeout: 10000
|
|
|
|
});
|
|
|
|
response.data.pipe(res);
|
|
|
|
} catch (e) {
|
|
|
|
res.status(500).end();
|
|
|
|
}
|
|
|
|
})
|
2021-04-10 09:33:01 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'contributors', async (req, res) => {
|
|
|
|
try {
|
|
|
|
const response = await axios.get('https://mempool.space/api/v1/contributors', { responseType: 'stream', timeout: 10000 });
|
|
|
|
response.data.pipe(res);
|
|
|
|
} catch (e) {
|
|
|
|
res.status(500).end();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'contributors/images/:id', async (req, res) => {
|
|
|
|
try {
|
|
|
|
const response = await axios.get('https://mempool.space/api/v1/contributors/images/' + req.params.id, {
|
|
|
|
responseType: 'stream', timeout: 10000
|
|
|
|
});
|
|
|
|
response.data.pipe(res);
|
|
|
|
} catch (e) {
|
|
|
|
res.status(500).end();
|
|
|
|
}
|
|
|
|
})
|
2022-01-13 00:58:12 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'translators', async (req, res) => {
|
|
|
|
try {
|
|
|
|
const response = await axios.get('https://mempool.space/api/v1/translators', { responseType: 'stream', timeout: 10000 });
|
|
|
|
response.data.pipe(res);
|
|
|
|
} catch (e) {
|
|
|
|
res.status(500).end();
|
|
|
|
}
|
|
|
|
})
|
2022-01-15 01:19:50 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'translators/images/:id', async (req, res) => {
|
|
|
|
try {
|
|
|
|
const response = await axios.get('https://mempool.space/api/v1/translators/images/' + req.params.id, {
|
|
|
|
responseType: 'stream', timeout: 10000
|
|
|
|
});
|
|
|
|
response.data.pipe(res);
|
|
|
|
} catch (e) {
|
|
|
|
res.status(500).end();
|
|
|
|
}
|
|
|
|
})
|
2020-02-26 11:49:53 +01:00
|
|
|
;
|
2020-07-03 18:45:19 +02:00
|
|
|
|
2020-10-19 13:47:10 +02:00
|
|
|
if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED) {
|
|
|
|
this.app
|
2022-01-12 17:57:25 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/2h', routes.$getStatisticsByTime.bind(routes, '2h'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/24h', routes.$getStatisticsByTime.bind(routes, '24h'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/1w', routes.$getStatisticsByTime.bind(routes, '1w'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/1m', routes.$getStatisticsByTime.bind(routes, '1m'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/3m', routes.$getStatisticsByTime.bind(routes, '3m'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/6m', routes.$getStatisticsByTime.bind(routes, '6m'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/1y', routes.$getStatisticsByTime.bind(routes, '1y'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/2y', routes.$getStatisticsByTime.bind(routes, '2y'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'statistics/3y', routes.$getStatisticsByTime.bind(routes, '3y'))
|
2022-02-08 10:28:53 +01:00
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2022-02-16 13:20:28 +01:00
|
|
|
if (Common.indexingEnabled()) {
|
2022-02-08 10:28:53 +01:00
|
|
|
this.app
|
2022-02-02 11:03:07 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/24h', routes.$getPools.bind(routes, '24h'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3d', routes.$getPools.bind(routes, '3d'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1w', routes.$getPools.bind(routes, '1w'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1m', routes.$getPools.bind(routes, '1m'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3m', routes.$getPools.bind(routes, '3m'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/6m', routes.$getPools.bind(routes, '6m'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1y', routes.$getPools.bind(routes, '1y'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/2y', routes.$getPools.bind(routes, '2y'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3y', routes.$getPools.bind(routes, '3y'))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/all', routes.$getPools.bind(routes, 'all'))
|
2022-02-14 05:58:40 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId/blocks', routes.$getPoolBlocks)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId/blocks/:height', routes.$getPoolBlocks)
|
2022-02-08 10:28:53 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId', routes.$getPool)
|
2022-02-16 13:20:28 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:poolId/:interval', routes.$getPool)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty', routes.$getHistoricalDifficulty)
|
2022-02-19 14:09:35 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty/:interval', routes.$getHistoricalDifficulty)
|
2022-02-24 08:55:18 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools', routes.$getPoolsHistoricalHashrate)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools/:interval', routes.$getPoolsHistoricalHashrate)
|
2022-02-19 14:09:35 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate', routes.$getHistoricalHashrate)
|
2022-02-24 08:55:18 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/:interval', routes.$getHistoricalHashrate)
|
|
|
|
;
|
2020-10-19 13:47:10 +02:00
|
|
|
}
|
|
|
|
|
2021-04-25 00:38:46 +02:00
|
|
|
if (config.BISQ.ENABLED) {
|
2020-07-03 18:45:19 +02:00
|
|
|
this.app
|
2020-10-19 06:57:02 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/stats', routes.getBisqStats)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/tx/:txId', routes.getBisqTransaction)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/block/:hash', routes.getBisqBlock)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/blocks/tip/height', routes.getBisqTip)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/blocks/:index/:length', routes.getBisqBlocks)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/address/:address', routes.getBisqAddress)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/txs/:index/:length', routes.getBisqTransactions)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/currencies', routes.getBisqMarketCurrencies.bind(routes))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/depth', routes.getBisqMarketDepth.bind(routes))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/hloc', routes.getBisqMarketHloc.bind(routes))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/markets', routes.getBisqMarketMarkets.bind(routes))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/offers', routes.getBisqMarketOffers.bind(routes))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/ticker', routes.getBisqMarketTicker.bind(routes))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/trades', routes.getBisqMarketTrades.bind(routes))
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/volumes', routes.getBisqMarketVolumes.bind(routes))
|
2021-03-10 17:02:55 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'bisq/markets/volumes/7d', routes.getBisqMarketVolumes7d.bind(routes))
|
2020-09-10 09:46:23 +02:00
|
|
|
;
|
|
|
|
}
|
2020-10-07 15:15:42 +02:00
|
|
|
|
2022-02-08 07:47:43 +01:00
|
|
|
this.app
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks-extras', routes.getBlocksExtras)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks-extras/:height', routes.getBlocksExtras);
|
|
|
|
|
2020-12-27 22:47:22 +01:00
|
|
|
if (config.MEMPOOL.BACKEND !== 'esplora') {
|
2020-12-21 17:08:34 +01:00
|
|
|
this.app
|
2021-01-24 19:09:42 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mempool', routes.getMempool)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mempool/txids', routes.getMempoolTxIds)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'mempool/recent', routes.getRecentMempoolTransactions)
|
2020-12-21 17:08:34 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId', routes.getTransaction)
|
2021-09-26 20:18:44 +02:00
|
|
|
.post(config.MEMPOOL.API_URL_PREFIX + 'tx', routes.$postTransaction)
|
2021-08-03 17:15:33 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/hex', routes.getRawTransaction)
|
2021-01-24 19:09:42 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/status', routes.getTransactionStatus)
|
2020-12-21 17:08:34 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/outspends', routes.getTransactionOutspends)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash', routes.getBlock)
|
2021-07-19 01:26:16 +02:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/header', routes.getBlockHeader)
|
2021-01-26 18:33:16 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks', routes.getBlocks)
|
2021-01-24 19:09:42 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks/:height', routes.getBlocks)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'blocks/tip/height', routes.getBlockTipHeight)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/txs', routes.getBlockTransactions)
|
2020-12-21 17:08:34 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/txs/:index', routes.getBlockTransactions)
|
2021-01-24 19:09:42 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/txids', routes.getTxIdsForBlock)
|
2020-12-21 17:08:34 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'block-height/:height', routes.getBlockHeight)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'address/:address', routes.getAddress)
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'address/:address/txs', routes.getAddressTransactions)
|
2020-12-27 22:47:22 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'address/:address/txs/chain/:txId', routes.getAddressTransactions)
|
2020-12-21 17:08:34 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'address-prefix/:prefix', routes.getAddressPrefix)
|
|
|
|
;
|
|
|
|
}
|
2021-09-18 11:37:25 +02:00
|
|
|
|
2021-12-30 23:28:40 +01:00
|
|
|
if (Common.isLiquid()) {
|
2021-12-14 13:06:03 +01:00
|
|
|
this.app
|
2021-12-20 01:01:04 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'assets/icons', routes.getAllLiquidIcon)
|
2022-02-05 22:20:26 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'assets/featured', routes.$getAllFeaturedLiquidAssets)
|
2021-12-20 01:01:04 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'asset/:assetId/icon', routes.getLiquidIcon)
|
2022-02-06 16:43:57 +01:00
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'assets/group/:id', routes.$getAssetGroup)
|
2021-12-14 13:06:03 +01:00
|
|
|
;
|
|
|
|
}
|
|
|
|
|
2021-12-30 23:28:40 +01:00
|
|
|
if (Common.isLiquid() && config.DATABASE.ENABLED) {
|
2021-09-18 11:37:25 +02:00
|
|
|
this.app
|
|
|
|
.get(config.MEMPOOL.API_URL_PREFIX + 'liquid/pegs/month', routes.$getElementsPegsByMonth)
|
|
|
|
;
|
|
|
|
}
|
2020-02-26 11:49:53 +01:00
|
|
|
}
|
2020-02-16 16:15:07 +01:00
|
|
|
}
|
2019-11-06 08:35:02 +01:00
|
|
|
|
2020-02-16 16:15:07 +01:00
|
|
|
const server = new Server();
|