diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index c444929b5..1582929aa 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -39,6 +39,13 @@ "USERNAME": "mempool", "PASSWORD": "mempool" }, + "SYSLOG": { + "ENABLED": true, + "HOST": "127.0.0.1", + "PORT": 514, + "MIN_PRIORITY": "info", + "FACILITY": "local7" + }, "STATISTICS": { "ENABLED": true, "TX_PER_SECOND_SAMPLE_PERIOD": 150 diff --git a/backend/package.json b/backend/package.json index b1dae4dca..c955793e1 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "mempool-backend", - "version": "2.0.0", + "version": "2.2.0-dev", "description": "Bitcoin mempool visualizer and blockchain explorer backend", "license": "GNU Affero General Public License v3.0", "homepage": "https://mempool.space", diff --git a/backend/src/api/backend-info.ts b/backend/src/api/backend-info.ts index eb3f1f664..7c6456522 100644 --- a/backend/src/api/backend-info.ts +++ b/backend/src/api/backend-info.ts @@ -1,20 +1,24 @@ import * as fs from 'fs'; import * as os from 'os'; import logger from '../logger'; +import { IBackendInfo } from '../mempool.interfaces'; class BackendInfo { - gitCommitHash = ''; - hostname = ''; + private gitCommitHash = ''; + private hostname = ''; + private version = ''; constructor() { this.setLatestCommitHash(); + this.setVersion(); this.hostname = os.hostname(); } - public getBackendInfo() { + public getBackendInfo(): IBackendInfo { return { - 'hostname': this.hostname, - 'git-commit': this.gitCommitHash, + hostname: this.hostname, + gitCommit: this.gitCommitHash, + version: this.version, }; } @@ -29,6 +33,15 @@ class BackendInfo { logger.err('Could not load git commit info: ' + e.message || e); } } + + private setVersion(): void { + try { + const packageJson = fs.readFileSync('package.json').toString(); + this.version = JSON.parse(packageJson).version; + } catch (e) { + throw new Error(e); + } + } } export default new BackendInfo(); diff --git a/backend/src/api/mempool.ts b/backend/src/api/mempool.ts index 4f8638c3e..81330a3ce 100644 --- a/backend/src/api/mempool.ts +++ b/backend/src/api/mempool.ts @@ -169,7 +169,7 @@ class Mempool { if (!this.inSync && transactions.length === Object.keys(this.mempoolCache).length) { this.inSync = true; - logger.info('The mempool is now in sync!'); + logger.notice('The mempool is now in sync!'); loadingIndicators.setProgress('mempool', 100); } diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts index fab55119b..74a06a588 100644 --- a/backend/src/api/websocket-handler.ts +++ b/backend/src/api/websocket-handler.ts @@ -167,8 +167,7 @@ class WebsocketHandler { 'conversions': fiatConversion.getConversionRates(), 'mempool-blocks': mempoolBlocks.getMempoolBlocks(), 'transactions': memPool.getLatestTransactions(), - 'git-commit': backendInfo.gitCommitHash, - 'hostname': backendInfo.hostname, + 'backendInfo': backendInfo.getBackendInfo(), 'loadingIndicators': loadingIndicators.getLoadingIndicators(), ...this.extraInitProperties }; diff --git a/backend/src/config.ts b/backend/src/config.ts index ace63394c..d5828f922 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -41,6 +41,13 @@ interface IConfig { USERNAME: string; PASSWORD: string; }; + SYSLOG: { + ENABLED: boolean; + HOST: string; + PORT: number; + MIN_PRIORITY: 'emerg' | 'alert' | 'crit' | 'err' |'warn' | 'notice' | 'info' | 'debug'; + FACILITY: string; + }; STATISTICS: { ENABLED: boolean; TX_PER_SECOND_SAMPLE_PERIOD: number; @@ -96,6 +103,13 @@ const defaults: IConfig = { 'USERNAME': 'mempool', 'PASSWORD': 'mempool' }, + 'SYSLOG': { + 'ENABLED': true, + 'HOST': '127.0.0.1', + 'PORT': 514, + 'MIN_PRIORITY': 'info', + 'FACILITY': 'local7' + }, 'STATISTICS': { 'ENABLED': true, 'TX_PER_SECOND_SAMPLE_PERIOD': 150 @@ -117,6 +131,7 @@ class Config implements IConfig { CORE_RPC: IConfig['CORE_RPC']; CORE_RPC_MINFEE: IConfig['CORE_RPC_MINFEE']; DATABASE: IConfig['DATABASE']; + SYSLOG: IConfig['SYSLOG']; STATISTICS: IConfig['STATISTICS']; BISQ_BLOCKS: IConfig['BISQ_BLOCKS']; BISQ_MARKETS: IConfig['BISQ_MARKETS']; @@ -129,6 +144,7 @@ class Config implements IConfig { this.CORE_RPC = configs.CORE_RPC; this.CORE_RPC_MINFEE = configs.CORE_RPC_MINFEE; this.DATABASE = configs.DATABASE; + this.SYSLOG = configs.SYSLOG; this.STATISTICS = configs.STATISTICS; this.BISQ_BLOCKS = configs.BISQ_BLOCKS; this.BISQ_MARKETS = configs.BISQ_MARKETS; diff --git a/backend/src/index.ts b/backend/src/index.ts index f99cc4132..54cf383d3 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -81,7 +81,7 @@ class Server { await checkDbConnection(); } - if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED) { + if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED && cluster.isMaster) { statistics.startStatistics(); } diff --git a/backend/src/logger.ts b/backend/src/logger.ts index 41aaf5c8f..f14af0104 100644 --- a/backend/src/logger.ts +++ b/backend/src/logger.ts @@ -50,17 +50,11 @@ class Logger { public debug: ((msg: string) => void); private name = 'mempool'; - private fac: any; - private loghost: string; - private logport: number; private client: dgram.Socket; private network: string; - constructor(fac) { + constructor() { let prio; - this.fac = fac != null ? fac : Logger.facilities.local0; - this.loghost = '127.0.0.1'; - this.logport = 514; for (prio in Logger.priorities) { if (true) { this.addprio(prio); @@ -97,10 +91,12 @@ class Logger { } const network = this.network ? ' <' + this.network + '>' : ''; prionum = Logger.priorities[priority] || Logger.priorities.info; - syslogmsg = `<${(this.fac * 8 + prionum)}> ${this.name}[${process.pid}]: ${priority.toUpperCase()}${network} ${msg}`; consolemsg = `${this.ts()} [${process.pid}] ${priority.toUpperCase()}:${network} ${msg}`; - this.syslog(syslogmsg); + if (config.SYSLOG.ENABLED && Logger.priorities[priority] <= Logger.priorities[config.SYSLOG.MIN_PRIORITY]) { + syslogmsg = `<${(Logger.facilities[config.SYSLOG.FACILITY] * 8 + prionum)}> ${this.name}[${process.pid}]: ${priority.toUpperCase()}${network} ${msg}`; + this.syslog(syslogmsg); + } if (priority === 'warning') { priority = 'warn'; } @@ -116,7 +112,7 @@ class Logger { private syslog(msg) { let msgbuf; msgbuf = Buffer.from(msg); - this.client.send(msgbuf, 0, msgbuf.length, this.logport, this.loghost, function(err, bytes) { + this.client.send(msgbuf, 0, msgbuf.length, config.SYSLOG.PORT, config.SYSLOG.HOST, function(err, bytes) { if (err) { console.log(err); } @@ -146,4 +142,4 @@ class Logger { } } -export default new Logger(Logger.facilities.local7); +export default new Logger(); diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index d2a6d2818..fae78ef9b 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -161,3 +161,9 @@ interface RequiredParams { export interface ILoadingIndicators { [name: string]: number; } export interface IConversionRates { [currency: string]: number; } + +export interface IBackendInfo { + hostname: string; + gitCommit: string; + version: string; +} diff --git a/frontend/generate-config.js b/frontend/generate-config.js index 5b26fb41b..6540ccf56 100644 --- a/frontend/generate-config.js +++ b/frontend/generate-config.js @@ -5,6 +5,8 @@ const GENERATED_CONFIG_FILE_NAME = 'generated-config.js'; let settings = []; let configContent = {}; +let gitCommitHash = ''; +let packetJsonVersion = ''; try { const rawConfig = fs.readFileSync(CONFIG_FILE_NAME); @@ -15,6 +17,13 @@ try { } } +try { + const packageJson = fs.readFileSync('package.json'); + packetJsonVersion = JSON.parse(packageJson).version; +} catch (e) { + throw new Error(e); +} + for (setting in configContent) { settings.push({ key: setting, @@ -22,9 +31,17 @@ for (setting in configContent) { }); } +try { + gitCommitHash = fs.readFileSync('../.git/refs/heads/master').toString().trim(); +} catch (e) { + console.log('Could not load git commit info: ' + e.message || e); +} + const code = `(function (window) { window.__env = window.__env || {};${settings.reduce((str, obj) => `${str} window.__env.${obj.key} = ${ typeof obj.value === 'string' ? `'${obj.value}'` : obj.value };`, '')} + window.__env.GIT_COMMIT_HASH = '${gitCommitHash}'; + window.__env.PACKAGE_JSON_VERSION = '${packetJsonVersion}'; }(global || this));`; try { diff --git a/frontend/package.json b/frontend/package.json index 8e0be0b94..1b39c6435 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "mempool-frontend", - "version": "2.0.0", + "version": "2.2.0-dev", "description": "Bitcoin mempool visualizer and blockchain explorer backend", "license": "GNU Affero General Public License v3.0", "homepage": "https://mempool.space", @@ -25,12 +25,14 @@ "i18n-extract-from-source": "./node_modules/@angular/cli/bin/ng xi18n --ivy --out-file ./src/locale/messages.xlf", "i18n-pull-from-transifex": "tx pull -a --parallel --minimum-perc 1 --force", "serve": "ng serve --proxy-config proxy.conf.json", + "serve:stg": "ng serve --host 0.0.0.0 --disable-host-check --proxy-config proxy.stg.conf.json --verbose", "start": "npm run generate-config && npm run sync-assets-dev && ng serve --proxy-config proxy.conf.json", - "build": "npm run generate-config && ng build --prod --localize && npm run sync-assets && npm run build-mempool-js", + "start:stg": "npm run generate-config && npm run sync-assets-dev && ng serve --host 0.0.0.0 --disable-host-check --proxy-config proxy.stg.conf.json", + "build": "npm run generate-config && ng build --prod --localize && npm run sync-assets && npm run build-mempool.js", "sync-assets": "node sync-assets.js && rsync -av ./dist/mempool/browser/en-US/resources ./dist/mempool/browser/resources", "sync-assets-dev": "node sync-assets.js dev", "generate-config": "node generate-config.js", - "build-mempool-js": "tsc | browserify -p tinyify ./node_modules/@mempool/mempool-js/lib/index.js --standalone mempoolJS > ./dist/mempool/browser/en-US/mempool.js", + "build-mempool.js": "tsc | browserify -p tinyify ./node_modules/@mempool/mempool.js/lib/index.js --standalone mempoolJS > ./dist/mempool/browser/en-US/mempool.js", "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", @@ -55,7 +57,7 @@ "@fortawesome/fontawesome-svg-core": "^1.2.35", "@fortawesome/free-solid-svg-icons": "^5.15.3", "@mempool/chartist": "^0.11.4", - "@mempool/mempool-js": "^2.2.1", + "@mempool/mempool.js": "^2.2.0", "@ng-bootstrap/ng-bootstrap": "^7.0.0", "@nguniversal/express-engine": "11.2.1", "@types/qrcode": "^1.3.4", diff --git a/frontend/proxy.conf.json b/frontend/proxy.conf.json index bc184bc05..3f989d565 100644 --- a/frontend/proxy.conf.json +++ b/frontend/proxy.conf.json @@ -1,8 +1,4 @@ { - "/api/v1/donations": { - "target": "http://localhost:9000/", - "secure": false - }, "/api/v1": { "target": "http://localhost:8999/", "secure": false diff --git a/frontend/proxy.stg.conf.json b/frontend/proxy.stg.conf.json new file mode 100644 index 000000000..18b26b602 --- /dev/null +++ b/frontend/proxy.stg.conf.json @@ -0,0 +1,68 @@ +{ + "/api/v1/ws": { + "target": "https://mempool.ninja", + "secure": false, + "ws": true + }, + "/api/*": { + "target": "https://mempool.ninja", + "secure": false, + "changeOrigin": true, + "logLevel": "debug", + "pathRewrite": { + "^/api": "https://mempool.ninja/api" + }, + "timeout": 3600000 + }, + "/testnet/api/v1/ws": { + "target": "https://mempool.ninja/testnet", + "secure": false, + "ws": true, + "pathRewrite": { + "^/testnet/api": "/api/v1/ws" + } + }, + "/testnet/api/v1/*": { + "target": "https://mempool.ninja/testnet", + "secure": false, + "changeOrigin": true, + "pathRewrite": { + "^/testnet/api/v1": "/api/v1" + }, + "timeout": 3600000 + }, + "/bisq/api/v1/ws": { + "target": "https://mempool.ninja/bisq", + "secure": false, + "ws": true, + "pathRewrite": { + "^/bisq/api": "/api/v1/ws" + } + }, + "/bisq/api/*": { + "target": "https://mempool.ninja/bisq", + "secure": false, + "changeOrigin": true, + "pathRewrite": { + "^/bisq/api/": "/api/v1/bisq/" + }, + "timeout": 3600000 + }, + "/liquid/api/v1/ws": { + "target": "https://mempool.ninja/liquid", + "secure": false, + "ws": true, + "pathRewrite": { + "^/liquid/api": "/api/v1/ws" + } + }, + "/liquid/api/*": { + "target": "https://mempool.ninja/liquid", + "secure": false, + "changeOrigin": true, + "pathRewrite": { + "^/liquid/api/": "/api/v1/liquid/" + }, + "timeout": 3600000 + } +} diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index 3a98c904b..3466c275e 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -5,7 +5,7 @@
- v2.2-dev ({{ gitCommit$ | async }}) + v{{ packetJsonVersion }} [{{ frontendGitCommitHash }}]

@@ -48,7 +48,7 @@
- + Square
@@ -60,6 +60,13 @@ + +
+ + Exodus +
+
+



@@ -392,4 +399,10 @@ Terms of Service +
+ +
+ {{ (backendInfo$ | async)?.hostname }} (v{{ (backendInfo$ | async )?.version }}) [{{ (backendInfo$ | async )?.gitCommit | slice:0:8 }}] +
+ diff --git a/frontend/src/app/components/about/about.component.ts b/frontend/src/app/components/about/about.component.ts index 59e941465..158a00d47 100644 --- a/frontend/src/app/components/about/about.component.ts +++ b/frontend/src/app/components/about/about.component.ts @@ -6,7 +6,8 @@ import { Observable, Subscription } from 'rxjs'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { ApiService } from 'src/app/services/api.service'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; -import { delay, map, retryWhen, switchMap, tap } from 'rxjs/operators'; +import { delay, retryWhen, switchMap, tap } from 'rxjs/operators'; +import { IBackendInfo } from 'src/app/interfaces/websocket.interface'; @Component({ selector: 'app-about', @@ -14,7 +15,7 @@ import { delay, map, retryWhen, switchMap, tap } from 'rxjs/operators'; styleUrls: ['./about.component.scss'], }) export class AboutComponent implements OnInit, OnDestroy { - gitCommit$: Observable; + backendInfo$: Observable; donationForm: FormGroup; paymentForm: FormGroup; donationStatus = 1; @@ -22,6 +23,9 @@ export class AboutComponent implements OnInit, OnDestroy { contributors$: Observable; donationObj: any; sponsorsEnabled = this.stateService.env.OFFICIAL_MEMPOOL_SPACE; + frontendGitCommitHash = this.stateService.env.GIT_COMMIT_HASH.substr(0, 8); + packetJsonVersion = this.stateService.env.PACKAGE_JSON_VERSION; + officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE; sponsors = null; contributors = null; requestSubscription: Subscription | undefined; @@ -36,7 +40,7 @@ export class AboutComponent implements OnInit, OnDestroy { ) { } ngOnInit() { - this.gitCommit$ = this.stateService.gitCommit$.pipe(map((str) => str.substr(0, 8))); + this.backendInfo$ = this.stateService.backendInfo$; this.seoService.setTitle($localize`:@@004b222ff9ef9dd4771b777950ca1d0e4cd4348a:About`); this.websocketService.want(['blocks']); diff --git a/frontend/src/app/components/latest-blocks/latest-blocks.component.html b/frontend/src/app/components/latest-blocks/latest-blocks.component.html index 7b57a92de..59239d55d 100644 --- a/frontend/src/app/components/latest-blocks/latest-blocks.component.html +++ b/frontend/src/app/components/latest-blocks/latest-blocks.component.html @@ -4,7 +4,7 @@
- +
diff --git a/frontend/src/app/components/master-page/master-page.component.html b/frontend/src/app/components/master-page/master-page.component.html index 89a92b44a..42de6b17a 100644 --- a/frontend/src/app/components/master-page/master-page.component.html +++ b/frontend/src/app/components/master-page/master-page.component.html @@ -26,7 +26,7 @@ diff --git a/frontend/src/app/components/master-page/master-page.component.scss b/frontend/src/app/components/master-page/master-page.component.scss index 3c0e31490..cac4681d7 100644 --- a/frontend/src/app/components/master-page/master-page.component.scss +++ b/frontend/src/app/components/master-page/master-page.component.scss @@ -8,14 +8,16 @@ fa-icon { .navbar { z-index: 100; + min-height: 64px; } li.nav-item { + margin: auto 10px; padding-left: 10px; padding-right: 10px; } -@media (min-width: 768px) { +@media (min-width: 992px) { .navbar { padding: 0rem 2rem; } @@ -26,17 +28,50 @@ li.nav-item { margin-right: 16px; } li.nav-item { + margin: auto 0px; padding: 10px; } } -li.nav-item a { - color: #ffffff; +.navbar-nav { + background: #212121; + bottom: 0; + box-shadow: 0px 0px 15px 0px #000; + flex-direction: row; + left: 0; + justify-content: center; + position: fixed; + width: 100%; } -.navbar-nav { - flex-direction: row; - justify-content: center; +@media (min-width: 992px) { + .navbar-nav { + background: transparent; + box-shadow: none; + position: relative; + width: auto; + } +} + +.navbar-collapse { + flex-basis: auto; + justify-content: flex-end; +} + +@media (min-width: 992px) { + .navbar-collapse { + justify-content: space-between; + } +} + +.navbar-brand { + width: 60%; +} + +@media (min-width: 576px) { + .navbar-brand { + width: 140px; + } } nav { @@ -81,5 +116,16 @@ nav { .dropdown-item { display: flex; - align-items:center; + align-items: center; } + +@media (min-width: 992px) { + .search-form-container { + width: 100%; + max-width: 500px; + padding-left: 15px; + } +} +.navbar-dark .navbar-nav .nav-link { + color: #f1f1f1; +} \ No newline at end of file diff --git a/frontend/src/app/components/search-form/search-form.component.scss b/frontend/src/app/components/search-form/search-form.component.scss index d80a0bb16..b6aa14d04 100644 --- a/frontend/src/app/components/search-form/search-form.component.scss +++ b/frontend/src/app/components/search-form/search-form.component.scss @@ -5,12 +5,53 @@ text-overflow: ellipsis; } +form { + margin-top: 5px; +} + +@media (min-width: 576px) { + form { + margin-top: 0px; + margin-left: 8px; + } +} + +@media (min-width: 992px) { + form { + width: 100%; + } +} + +.btn-block { + width: 58.55px; +} + .search-box-container { width: 100%; } -@media (min-width: 992px) { +.search-box-container input { + border: 0px; +} + +.search-box-container .btn { + width: 100px; +} + +@media (min-width: 768px) { .search-box-container { - width: 350px; + min-width: 400px; + } +} + +@media (min-width: 992px) { + .search-box-container { + min-width: 260px; + } +} + +@media (min-width: 1200px) { + .search-box-container { + min-width: 300px; } } diff --git a/frontend/src/app/components/statistics/statistics.component.html b/frontend/src/app/components/statistics/statistics.component.html index e876f41fa..e0b1ec90a 100644 --- a/frontend/src/app/components/statistics/statistics.component.html +++ b/frontend/src/app/components/statistics/statistics.component.html @@ -15,7 +15,7 @@
Mempool by vBytes (sat/vByte) -
+
-
+
Height Timestamp
diff --git a/frontend/src/app/dashboard/dashboard.component.html b/frontend/src/app/dashboard/dashboard.component.html index 60e419795..d789ed074 100644 --- a/frontend/src/app/dashboard/dashboard.component.html +++ b/frontend/src/app/dashboard/dashboard.component.html @@ -1,5 +1,5 @@ -
+
diff --git a/frontend/src/app/dashboard/dashboard.component.scss b/frontend/src/app/dashboard/dashboard.component.scss index 931483668..c58ce1bb4 100644 --- a/frontend/src/app/dashboard/dashboard.component.scss +++ b/frontend/src/app/dashboard/dashboard.component.scss @@ -1,3 +1,12 @@ +.dashboard-container { + padding-bottom: 60px; +} +@media (min-width: 992px) { + .dashboard-container { + padding-bottom: 0px; + } +} + .card { background-color: #1d1f31; } diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts index f11cf7059..2138ad8dc 100644 --- a/frontend/src/app/interfaces/websocket.interface.ts +++ b/frontend/src/app/interfaces/websocket.interface.ts @@ -16,6 +16,7 @@ export interface WebsocketResponse { rbfTransaction?: Transaction; transactions?: TransactionStripped[]; loadingIndicators?: ILoadingIndicators; + backendInfo?: IBackendInfo; 'track-tx'?: string; 'track-address'?: string; 'track-asset'?: string; @@ -50,3 +51,8 @@ export interface TransactionStripped { value: number; } +export interface IBackendInfo { + hostname: string; + gitCommit: string; + version: string; +} diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts index 30b4fd65c..bd5acf91c 100644 --- a/frontend/src/app/services/state.service.ts +++ b/frontend/src/app/services/state.service.ts @@ -1,7 +1,7 @@ import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable } from 'rxjs'; import { Block, Transaction } from '../interfaces/electrs.interface'; -import { MempoolBlock, MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface'; +import { IBackendInfo, MempoolBlock, MempoolInfo, TransactionStripped } from '../interfaces/websocket.interface'; import { OptimizedMempoolStats } from '../interfaces/node-api.interface'; import { Router, NavigationStart } from '@angular/router'; import { isPlatformBrowser } from '@angular/common'; @@ -28,6 +28,8 @@ export interface Env { NGINX_PROTOCOL?: string; NGINX_HOSTNAME?: string; NGINX_PORT?: string; + GIT_COMMIT_HASH: string; + PACKAGE_JSON_VERSION: string; } const defaultEnv: Env = { @@ -43,6 +45,8 @@ const defaultEnv: Env = { 'NGINX_PROTOCOL': 'http', 'NGINX_HOSTNAME': '127.0.0.1', 'NGINX_PORT': '80', + 'GIT_COMMIT_HASH': '', + 'PACKAGE_JSON_VERSION': '', }; @Injectable({ @@ -67,7 +71,7 @@ export class StateService { isLoadingWebSocket$ = new ReplaySubject(1); vbytesPerSecond$ = new ReplaySubject(1); lastDifficultyAdjustment$ = new ReplaySubject(1); - gitCommit$ = new ReplaySubject(1); + backendInfo$ = new ReplaySubject(1); loadingIndicators$ = new ReplaySubject(1); live2Chart$ = new Subject(); diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts index 3602a3d83..f36c85b39 100644 --- a/frontend/src/app/services/websocket.service.ts +++ b/frontend/src/app/services/websocket.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { webSocket, WebSocketSubject } from 'rxjs/webSocket'; -import { WebsocketResponse } from '../interfaces/websocket.interface'; +import { WebsocketResponse, IBackendInfo } from '../interfaces/websocket.interface'; import { StateService } from './state.service'; import { Block, Transaction } from '../interfaces/electrs.interface'; import { Subscription } from 'rxjs'; @@ -244,13 +244,13 @@ export class WebsocketService { this.stateService.bsqPrice$.next(response['bsq-price']); } - if (response['git-commit']) { - this.stateService.gitCommit$.next(response['git-commit']); + if (response.backendInfo) { + this.stateService.backendInfo$.next(response.backendInfo); if (!this.latestGitCommit) { - this.latestGitCommit = response['git-commit']; + this.latestGitCommit = response.backendInfo.gitCommit; } else { - if (this.latestGitCommit !== response['git-commit']) { + if (this.latestGitCommit !== response.backendInfo.gitCommit) { setTimeout(() => { window.location.reload(); }, Math.floor(Math.random() * 60000) + 60000); @@ -291,7 +291,7 @@ export class WebsocketService { } if (response['git-commit']) { - this.stateService.gitCommit$.next(response['git-commit']); + this.stateService.backendInfo$.next(response['git-commit']); } } } diff --git a/frontend/src/resources/profile/exodus.svg b/frontend/src/resources/profile/exodus.svg new file mode 100644 index 000000000..082cba7a5 --- /dev/null +++ b/frontend/src/resources/profile/exodus.svg @@ -0,0 +1,16 @@ + + + Exodus_logo + + + + + + + + diff --git a/frontend/src/resources/profile/sqcrypto.svg b/frontend/src/resources/profile/sqcrypto.svg new file mode 100644 index 000000000..fae138e84 --- /dev/null +++ b/frontend/src/resources/profile/sqcrypto.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index aad6a9f35..6262ebeed 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -50,11 +50,11 @@ $dropdown-link-active-bg: #11131f; html, body { height: 100%; - overflow-x: hidden; } body { background-color: #11131f; + min-width: 320px; } .container { diff --git a/production/mempool-config.mainnet.json b/production/mempool-config.mainnet.json index 6b7027143..6d6a94f48 100644 --- a/production/mempool-config.mainnet.json +++ b/production/mempool-config.mainnet.json @@ -6,6 +6,7 @@ "MINED_BLOCKS_CACHE": 144, "SPAWN_CLUSTER_PROCS": 0, "API_URL_PREFIX": "/api/v1/", + "CLEAR_PROTECTION_MINUTES": 5, "POLL_RATE_MS": 2000 }, "CORE_RPC": { diff --git a/production/sysctl.conf b/production/sysctl.conf new file mode 100644 index 000000000..8d1fd9c96 --- /dev/null +++ b/production/sysctl.conf @@ -0,0 +1,2 @@ +net.inet.tcp.fast_finwait2_recycle=1 +kern.ipc.soacceptqueue=1024