diff --git a/backend/package.json b/backend/package.json index b1dae4dca..883deaab8 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "mempool-backend", - "version": "2.0.0", + "version": "2.2-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/websocket-handler.ts b/backend/src/api/websocket-handler.ts index d90d523fc..2ac88fe42 100644 --- a/backend/src/api/websocket-handler.ts +++ b/backend/src/api/websocket-handler.ts @@ -159,8 +159,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/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index 8e2ed17a8..66a486f94 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -160,3 +160,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 cebb3c6f9..98d9425fe 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "mempool-frontend", - "version": "2.0.0", + "version": "2.2-dev", "description": "Bitcoin mempool visualizer and blockchain explorer backend", "license": "GNU Affero General Public License v3.0", "homepage": "https://mempool.space", 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/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index 9c861dc10..9886543b3 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -3,9 +3,13 @@

+
-
- v2.2-dev ({{ gitCommit$ | async }}) +
+ Frontend: + v{{ packetJsonVersion }} ({{ frontendGitCommitHash }}) [{{ hostname }}] +
+ Backend: v{{ (backendInfo$ | async ).version }} ({{ (backendInfo$ | async ).gitCommit | slice:0:8 }}) [{{ (backendInfo$ | async).hostname }}]

diff --git a/frontend/src/app/components/about/about.component.ts b/frontend/src/app/components/about/about.component.ts index 59e941465..9e7b79715 100644 --- a/frontend/src/app/components/about/about.component.ts +++ b/frontend/src/app/components/about/about.component.ts @@ -7,6 +7,7 @@ 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 { 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; + hostname = document.location.hostname; 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/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts index 2a753b91f..882ee72ab 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; @@ -49,3 +50,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 58eb75faf..fe58b103f 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'; @@ -27,6 +27,8 @@ export interface Env { NGINX_PROTOCOL?: string; NGINX_HOSTNAME?: string; NGINX_PORT?: string; + GIT_COMMIT_HASH: string; + PACKAGE_JSON_VERSION: string; } const defaultEnv: Env = { @@ -41,6 +43,8 @@ const defaultEnv: Env = { 'NGINX_PROTOCOL': 'http', 'NGINX_HOSTNAME': '127.0.0.1', 'NGINX_PORT': '80', + 'GIT_COMMIT_HASH': '', + 'PACKAGE_JSON_VERSION': '', }; @Injectable({ @@ -65,7 +69,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 7c35e040d..e5882e959 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'; @@ -236,13 +236,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); @@ -283,7 +283,7 @@ export class WebsocketService { } if (response['git-commit']) { - this.stateService.gitCommit$.next(response['git-commit']); + this.stateService.backendInfo$.next(response['git-commit']); } } }