Merge pull request #669 from mempool/simon/configurable-main-module
Make base module and index.html file configurable with BASE_MODULE. A…
@ -8,7 +8,10 @@
|
||||
"POLL_RATE_MS": 2000,
|
||||
"CACHE_DIR": "./cache",
|
||||
"CLEAR_PROTECTION_MINUTES": 20,
|
||||
"RECOMMENDED_FEE_PERCENTILE": 50
|
||||
"RECOMMENDED_FEE_PERCENTILE": 50,
|
||||
"BLOCK_WEIGHT_UNITS": 4000000,
|
||||
"INITIAL_BLOCKS_AMOUNT": 8,
|
||||
"MEMPOOL_BLOCKS_AMOUNT": 8
|
||||
},
|
||||
"CORE_RPC": {
|
||||
"HOST": "127.0.0.1",
|
||||
|
@ -9,7 +9,6 @@ import transactionUtils from './transaction-utils';
|
||||
import bitcoinBaseApi from './bitcoin/bitcoin-base.api';
|
||||
|
||||
class Blocks {
|
||||
private static INITIAL_BLOCK_AMOUNT = 8;
|
||||
private blocks: BlockExtended[] = [];
|
||||
private currentBlockHeight = 0;
|
||||
private currentDifficulty = 0;
|
||||
@ -35,14 +34,14 @@ class Blocks {
|
||||
const blockHeightTip = await bitcoinApi.$getBlockHeightTip();
|
||||
|
||||
if (this.blocks.length === 0) {
|
||||
this.currentBlockHeight = blockHeightTip - Blocks.INITIAL_BLOCK_AMOUNT;
|
||||
this.currentBlockHeight = blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT;
|
||||
} else {
|
||||
this.currentBlockHeight = this.blocks[this.blocks.length - 1].height;
|
||||
}
|
||||
|
||||
if (blockHeightTip - this.currentBlockHeight > Blocks.INITIAL_BLOCK_AMOUNT * 2) {
|
||||
logger.info(`${blockHeightTip - this.currentBlockHeight} blocks since tip. Fast forwarding to the ${Blocks.INITIAL_BLOCK_AMOUNT} recent blocks`);
|
||||
this.currentBlockHeight = blockHeightTip - Blocks.INITIAL_BLOCK_AMOUNT;
|
||||
if (blockHeightTip - this.currentBlockHeight > config.MEMPOOL.INITIAL_BLOCKS_AMOUNT * 2) {
|
||||
logger.info(`${blockHeightTip - this.currentBlockHeight} blocks since tip. Fast forwarding to the ${config.MEMPOOL.INITIAL_BLOCKS_AMOUNT} recent blocks`);
|
||||
this.currentBlockHeight = blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT;
|
||||
}
|
||||
|
||||
if (!this.lastDifficultyAdjustmentTime) {
|
||||
@ -111,8 +110,8 @@ class Blocks {
|
||||
blockExtended.coinbaseTx = transactionUtils.stripCoinbaseTransaction(transactions[0]);
|
||||
transactions.shift();
|
||||
transactions.sort((a, b) => b.effectiveFeePerVsize - a.effectiveFeePerVsize);
|
||||
blockExtended.medianFee = transactions.length > 1 ? Common.median(transactions.map((tx) => tx.effectiveFeePerVsize)) : 0;
|
||||
blockExtended.feeRange = transactions.length > 1 ? Common.getFeesInRange(transactions, 8) : [0, 0];
|
||||
blockExtended.medianFee = transactions.length > 0 ? Common.median(transactions.map((tx) => tx.effectiveFeePerVsize)) : 0;
|
||||
blockExtended.feeRange = transactions.length > 0 ? Common.getFeesInRange(transactions, 8) : [0, 0];
|
||||
|
||||
if (block.height % 2016 === 0) {
|
||||
this.previousDifficultyRetarget = (block.difficulty - this.currentDifficulty) / this.currentDifficulty * 100;
|
||||
@ -121,8 +120,8 @@ class Blocks {
|
||||
}
|
||||
|
||||
this.blocks.push(blockExtended);
|
||||
if (this.blocks.length > Blocks.INITIAL_BLOCK_AMOUNT * 4) {
|
||||
this.blocks = this.blocks.slice(-Blocks.INITIAL_BLOCK_AMOUNT * 4);
|
||||
if (this.blocks.length > config.MEMPOOL.INITIAL_BLOCKS_AMOUNT * 4) {
|
||||
this.blocks = this.blocks.slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT * 4);
|
||||
}
|
||||
|
||||
if (this.newBlockCallbacks.length) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { CpfpInfo, TransactionExtended, TransactionStripped } from '../mempool.interfaces';
|
||||
|
||||
import config from '../config';
|
||||
export class Common {
|
||||
static median(numbers: number[]) {
|
||||
let medianNr = 0;
|
||||
@ -105,7 +105,7 @@ export class Common {
|
||||
totalFees += tx.bestDescendant.fee;
|
||||
}
|
||||
|
||||
tx.effectiveFeePerVsize = Math.max(1, totalFees / (totalWeight / 4));
|
||||
tx.effectiveFeePerVsize = Math.max(config.MEMPOOL.NETWORK === 'liquid' ? 0.1 : 1, totalFees / (totalWeight / 4));
|
||||
tx.cpfpChecked = true;
|
||||
|
||||
return {
|
||||
|
@ -4,7 +4,6 @@ import { Common } from './common';
|
||||
import config from '../config';
|
||||
|
||||
class MempoolBlocks {
|
||||
private static DEFAULT_PROJECTED_BLOCKS_AMOUNT = 8;
|
||||
private mempoolBlocks: MempoolBlockWithTransactions[] = [];
|
||||
|
||||
constructor() {}
|
||||
@ -76,7 +75,7 @@ class MempoolBlocks {
|
||||
let blockSize = 0;
|
||||
let transactions: TransactionExtended[] = [];
|
||||
transactionsSorted.forEach((tx) => {
|
||||
if (blockVSize + tx.vsize <= 1000000 || mempoolBlocks.length === MempoolBlocks.DEFAULT_PROJECTED_BLOCKS_AMOUNT - 1) {
|
||||
if (blockVSize + tx.weight <= config.MEMPOOL.BLOCK_WEIGHT_UNITS || mempoolBlocks.length === config.MEMPOOL.MEMPOOL_BLOCKS_AMOUNT) {
|
||||
blockVSize += tx.vsize;
|
||||
blockSize += tx.size;
|
||||
transactions.push(tx);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import bitcoinApi from './bitcoin/bitcoin-api-factory';
|
||||
import logger from '../logger';
|
||||
import { TransactionExtended, TransactionMinerInfo } from '../mempool.interfaces';
|
||||
import { IEsploraApi } from './bitcoin/esplora-api.interface';
|
||||
import config from '../config';
|
||||
|
||||
class TransactionUtils {
|
||||
constructor() { }
|
||||
@ -31,7 +31,7 @@ class TransactionUtils {
|
||||
// @ts-ignore
|
||||
return transaction;
|
||||
}
|
||||
const feePerVbytes = Math.max(1, (transaction.fee || 0) / (transaction.weight / 4));
|
||||
const feePerVbytes = Math.max(config.MEMPOOL.NETWORK === 'liquid' ? 0.1 : 1, (transaction.fee || 0) / (transaction.weight / 4));
|
||||
const transactionExtended: TransactionExtended = Object.assign({
|
||||
vsize: Math.round(transaction.weight / 4),
|
||||
feePerVsize: feePerVbytes,
|
||||
|
@ -97,7 +97,7 @@ class WebsocketHandler {
|
||||
}
|
||||
|
||||
if (parsedMessage.action === 'init') {
|
||||
const _blocks = blocks.getBlocks().slice(-8);
|
||||
const _blocks = blocks.getBlocks().slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT);
|
||||
if (!_blocks) {
|
||||
return;
|
||||
}
|
||||
@ -173,7 +173,7 @@ class WebsocketHandler {
|
||||
|
||||
getInitData(_blocks?: BlockExtended[]) {
|
||||
if (!_blocks) {
|
||||
_blocks = blocks.getBlocks().slice(-8);
|
||||
_blocks = blocks.getBlocks().slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT);
|
||||
}
|
||||
return {
|
||||
'mempoolInfo': memPool.getMempoolInfo(),
|
||||
|
@ -11,6 +11,9 @@ interface IConfig {
|
||||
CACHE_DIR: string;
|
||||
CLEAR_PROTECTION_MINUTES: number;
|
||||
RECOMMENDED_FEE_PERCENTILE: number;
|
||||
BLOCK_WEIGHT_UNITS: number;
|
||||
INITIAL_BLOCKS_AMOUNT: number;
|
||||
MEMPOOL_BLOCKS_AMOUNT: number;
|
||||
};
|
||||
ESPLORA: {
|
||||
REST_API_URL: string;
|
||||
@ -69,6 +72,9 @@ const defaults: IConfig = {
|
||||
'CACHE_DIR': './cache',
|
||||
'CLEAR_PROTECTION_MINUTES': 20,
|
||||
'RECOMMENDED_FEE_PERCENTILE': 50,
|
||||
'BLOCK_WEIGHT_UNITS': 4000000,
|
||||
'INITIAL_BLOCKS_AMOUNT': 8,
|
||||
'MEMPOOL_BLOCKS_AMOUNT': 8,
|
||||
},
|
||||
'ESPLORA': {
|
||||
'REST_API_URL': 'http://127.0.0.1:3000',
|
||||
|
3
frontend/.gitignore
vendored
@ -59,3 +59,6 @@ generated-config.js
|
||||
cypress/videos
|
||||
cypress/screenshots
|
||||
|
||||
# Base index
|
||||
src/index.html
|
||||
|
||||
|
@ -75,17 +75,7 @@ describe('Liquid', () => {
|
||||
cy.waitForSkeletonGone();
|
||||
cy.get('li:nth-of-type(5) > a').click().then(() => {
|
||||
cy.get('.container-xl input').click().type('Liquid CAD').then(() => {
|
||||
cy.get('table tr td:nth-of-type(4) a').click();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('shows a specific asset issuance TX', () => {
|
||||
cy.visit('/liquid');
|
||||
cy.waitForSkeletonGone();
|
||||
cy.get('li:nth-of-type(5) > a').click().then(() => {
|
||||
cy.get('.container-xl input').click().type('Liquid CAD').then(() => {
|
||||
cy.get('table tr td:nth-of-type(5) a').click();
|
||||
cy.get('table tr td:nth-of-type(1) a').click();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -21,6 +21,16 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
const indexFilePath = configContent.BASE_MODULE ? 'src/index.' + configContent.BASE_MODULE + '.html' : 'src/index.mempool.html';
|
||||
|
||||
try {
|
||||
fs.copyFileSync(indexFilePath, 'src/index.html');
|
||||
console.log('Copied ' + indexFilePath + ' to src/index.html');
|
||||
} catch (e) {
|
||||
console.log('Error copying the index file');
|
||||
throw new Error(e);
|
||||
}
|
||||
|
||||
try {
|
||||
const packageJson = fs.readFileSync('package.json');
|
||||
packetJsonVersion = JSON.parse(packageJson).version;
|
||||
|
@ -8,5 +8,8 @@
|
||||
"KEEP_BLOCKS_AMOUNT": 8,
|
||||
"NGINX_PROTOCOL": "http",
|
||||
"NGINX_HOSTNAME": "127.0.0.1",
|
||||
"NGINX_PORT": "80"
|
||||
"NGINX_PORT": "80",
|
||||
"MEMPOOL_BLOCKS_AMOUNT": 8,
|
||||
"BLOCK_WEIGHT_UNITS": 4000000,
|
||||
"BASE_MODULE": "mempool"
|
||||
}
|
||||
|
@ -67,11 +67,18 @@
|
||||
"^/liquid/api": "/api/v1/ws"
|
||||
}
|
||||
},
|
||||
"/liquid/api/": {
|
||||
"target": "http://localhost:50001/",
|
||||
"/liquid/api/v1/": {
|
||||
"target": "http://localhost:8999/",
|
||||
"secure": false,
|
||||
"pathRewrite": {
|
||||
"^/liquid/api/": ""
|
||||
"^/liquid/api/": "/api/"
|
||||
}
|
||||
},
|
||||
"/liquid/api/": {
|
||||
"target": "http://localhost:8999/",
|
||||
"secure": false,
|
||||
"pathRewrite": {
|
||||
"^/liquid/api/": "/api/v1/"
|
||||
}
|
||||
},
|
||||
"/bisq/api/": {
|
||||
|
@ -20,6 +20,7 @@ import { PrivacyPolicyComponent } from './components/privacy-policy/privacy-poli
|
||||
import { TrademarkPolicyComponent } from './components/trademark-policy/trademark-policy.component';
|
||||
import { BisqMasterPageComponent } from './components/bisq-master-page/bisq-master-page.component';
|
||||
import { SponsorComponent } from './components/sponsor/sponsor.component';
|
||||
import { LiquidMasterPageComponent } from './components/liquid-master-page/liquid-master-page.component';
|
||||
|
||||
let routes: Routes = [
|
||||
{
|
||||
@ -303,7 +304,7 @@ const browserWindow = window || {};
|
||||
// @ts-ignore
|
||||
const browserWindowEnv = browserWindow.__env || {};
|
||||
|
||||
if (browserWindowEnv && browserWindowEnv.OFFICIAL_BISQ_MARKETS) {
|
||||
if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'bisq') {
|
||||
routes = [{
|
||||
path: '',
|
||||
component: BisqMasterPageComponent,
|
||||
@ -311,6 +312,93 @@ if (browserWindowEnv && browserWindowEnv.OFFICIAL_BISQ_MARKETS) {
|
||||
}];
|
||||
}
|
||||
|
||||
if (browserWindowEnv && browserWindowEnv.BASE_MODULE === 'liquid') {
|
||||
routes = [{
|
||||
path: '',
|
||||
component: LiquidMasterPageComponent,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: StartComponent,
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: DashboardComponent
|
||||
},
|
||||
{
|
||||
path: 'tx/:id',
|
||||
component: TransactionComponent
|
||||
},
|
||||
{
|
||||
path: 'block/:id',
|
||||
component: BlockComponent
|
||||
},
|
||||
{
|
||||
path: 'mempool-block/:id',
|
||||
component: MempoolBlockComponent
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'blocks',
|
||||
component: LatestBlocksComponent,
|
||||
},
|
||||
{
|
||||
path: 'graphs',
|
||||
component: StatisticsComponent,
|
||||
},
|
||||
{
|
||||
path: 'address/:id',
|
||||
component: AddressComponent
|
||||
},
|
||||
{
|
||||
path: 'asset/:id',
|
||||
component: AssetComponent
|
||||
},
|
||||
{
|
||||
path: 'assets',
|
||||
component: AssetsComponent,
|
||||
},
|
||||
{
|
||||
path: 'api',
|
||||
component: ApiDocsComponent,
|
||||
},
|
||||
{
|
||||
path: 'about',
|
||||
component: AboutComponent,
|
||||
},
|
||||
{
|
||||
path: 'terms-of-service',
|
||||
component: TermsOfServiceComponent
|
||||
},
|
||||
{
|
||||
path: 'privacy-policy',
|
||||
component: PrivacyPolicyComponent
|
||||
},
|
||||
{
|
||||
path: 'trademark-policy',
|
||||
component: TrademarkPolicyComponent
|
||||
},
|
||||
{
|
||||
path: 'sponsor',
|
||||
component: SponsorComponent,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: 'tv',
|
||||
component: TelevisionComponent
|
||||
},
|
||||
{
|
||||
path: 'status',
|
||||
component: StatusViewComponent
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
redirectTo: ''
|
||||
}];
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [RouterModule.forRoot(routes, {
|
||||
initialNavigation: 'enabled',
|
||||
|
@ -22,6 +22,7 @@ import { AddressLabelsComponent } from './components/address-labels/address-labe
|
||||
import { MempoolBlocksComponent } from './components/mempool-blocks/mempool-blocks.component';
|
||||
import { MasterPageComponent } from './components/master-page/master-page.component';
|
||||
import { BisqMasterPageComponent } from './components/bisq-master-page/bisq-master-page.component';
|
||||
import { LiquidMasterPageComponent } from './components/liquid-master-page/liquid-master-page.component';
|
||||
import { AboutComponent } from './components/about/about.component';
|
||||
import { TelevisionComponent } from './components/television/television.component';
|
||||
import { StatisticsComponent } from './components/statistics/statistics.component';
|
||||
@ -61,6 +62,7 @@ import { SponsorComponent } from './components/sponsor/sponsor.component';
|
||||
AboutComponent,
|
||||
MasterPageComponent,
|
||||
BisqMasterPageComponent,
|
||||
LiquidMasterPageComponent,
|
||||
TelevisionComponent,
|
||||
BlockchainComponent,
|
||||
StartComponent,
|
||||
|
@ -20,15 +20,13 @@
|
||||
<th i18n="Asset ticker header">Ticker</th>
|
||||
<th class="d-none d-md-block" i18n="Asset Issuer Domain header">Issuer domain</th>
|
||||
<th i18n="Asset ID header">Asset ID</th>
|
||||
<th class="d-none d-lg-block" i18n="Asset issuance transaction header">Issuance TX</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let asset of filteredAssets; trackBy: trackByAsset">
|
||||
<td class="td-name">{{ asset.name }}</td>
|
||||
<td class="td-name"><a [routerLink]="['/asset/' | relativeUrl, asset.asset_id]">{{ asset.name }}</a></td>
|
||||
<td>{{ asset.ticker }}</td>
|
||||
<td class="d-none d-md-block"><a *ngIf="asset.entity" target="_blank" href="{{ 'http://' + asset.entity.domain }}">{{ asset.entity.domain }}</a></td>
|
||||
<td class="d-none d-md-block">{{ asset.entity && asset.entity.domain }}</td>
|
||||
<td><a [routerLink]="['/asset/' | relativeUrl, asset.asset_id]">{{ asset.asset_id | shortenString : 13 }}</a> <app-clipboard class="d-none d-sm-inline-block" [text]="asset.asset_id"></app-clipboard></td>
|
||||
<td class="d-none d-lg-block"><ng-template [ngIf]="asset.issuance_txin"><a [routerLink]="['/tx/' | relativeUrl, asset.issuance_txin.txid]">{{ asset.issuance_txin.txid | shortenString : 13 }}</a> <app-clipboard class="d-none d-sm-inline-block" [text]="asset.issuance_txin.txid"></app-clipboard></ng-template></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -47,15 +45,13 @@
|
||||
<th i18n="Asset ticker header">Ticker</th>
|
||||
<th i18n="Asset Issuer Domain header">Issuer domain</th>
|
||||
<th i18n="Asset ID header">Asset ID</th>
|
||||
<th i18n="Asset issuance transaction header">Issuance TX</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let dummy of [0,0,0]">
|
||||
<tr *ngFor="let dummy of [0,0,0,0,0,0,0,0,0,0]">
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
<td class="d-none d-md-block"><span class="skeleton-loader"></span></td>
|
||||
<td><span class="skeleton-loader"></span></td>
|
||||
<td class="d-none d-lg-block"><span class="skeleton-loader"></span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -107,7 +107,7 @@ export class AssetsComponent implements OnInit {
|
||||
const start = (this.page - 1) * this.itemsPerPage;
|
||||
if (searchText.length ) {
|
||||
const filteredAssets = this.assetsCache.filter((asset) => asset.name.toLowerCase().indexOf(searchText.toLowerCase()) > -1
|
||||
|| asset.ticker.toLowerCase().indexOf(searchText.toLowerCase()) > -1);
|
||||
|| (asset.ticker || '').toLowerCase().indexOf(searchText.toLowerCase()) > -1);
|
||||
this.assets = filteredAssets;
|
||||
return filteredAssets.slice(start, this.itemsPerPage + start);
|
||||
} else {
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
<div class="container-info">
|
||||
<h1>
|
||||
<ng-template [ngIf]="stateService.env.OFFICIAL_BISQ_MARKETS" [ngIfElse]="nonOfficialMarkets" i18n="Bisq All Markets">Markets</ng-template>
|
||||
<ng-template [ngIf]="stateService.env.BASE_MODULE === 'bisq'" [ngIfElse]="nonOfficialMarkets" i18n="Bisq All Markets">Markets</ng-template>
|
||||
<ng-template #nonOfficialMarkets i18n="Bisq Bitcoin Markets">Bitcoin Markets</ng-template>
|
||||
</h1>
|
||||
<ng-container *ngIf="{ value: (tickers$ | async) } as tickers">
|
||||
|
@ -69,7 +69,7 @@ export class BisqDashboardComponent implements OnInit {
|
||||
const newTickers = [];
|
||||
for (const t in tickers) {
|
||||
|
||||
if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) {
|
||||
if (this.stateService.env.BASE_MODULE !== 'bisq') {
|
||||
const pair = t.split('_');
|
||||
if (pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1) {
|
||||
continue;
|
||||
@ -106,7 +106,7 @@ export class BisqDashboardComponent implements OnInit {
|
||||
])
|
||||
.pipe(
|
||||
map(([trades, markets]) => {
|
||||
if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) {
|
||||
if (this.stateService.env.BASE_MODULE !== 'bisq') {
|
||||
trades = trades.filter((trade) => {
|
||||
const pair = trade.market.split('_');
|
||||
return !(pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1);
|
||||
|
@ -63,7 +63,7 @@
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title text-center">
|
||||
<ng-template [ngIf]="stateService.env.OFFICIAL_BISQ_MARKETS" [ngIfElse]="nonOfficialMarkets" i18n="Bisq All Markets">Markets</ng-template>
|
||||
<ng-template [ngIf]="stateService.env.BASE_MODULE === 'bisq'" [ngIfElse]="nonOfficialMarkets" i18n="Bisq All Markets">Markets</ng-template>
|
||||
<ng-template #nonOfficialMarkets i18n="Bisq Bitcoin Markets">Bitcoin Markets</ng-template>
|
||||
</h5>
|
||||
|
||||
@ -105,7 +105,7 @@
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<app-language-selector *ngIf="!stateService.env.OFFICIAL_BISQ_MARKETS"></app-language-selector>
|
||||
<app-language-selector *ngIf="stateService.env.BASE_MODULE !== 'bisq'"></app-language-selector>
|
||||
|
||||
<div class="text-small text-center mt-3">
|
||||
<a [routerLink]="['/terms-of-service']" i18n="shared.terms-of-service|Terms of Service">Terms of Service</a>
|
||||
|
@ -77,7 +77,7 @@ export class BisqMainDashboardComponent implements OnInit {
|
||||
const newTickers = [];
|
||||
for (const t in tickers) {
|
||||
|
||||
if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) {
|
||||
if (this.stateService.env.BASE_MODULE !== 'bisq') {
|
||||
const pair = t.split('_');
|
||||
if (pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1) {
|
||||
continue;
|
||||
@ -114,7 +114,7 @@ export class BisqMainDashboardComponent implements OnInit {
|
||||
])
|
||||
.pipe(
|
||||
map(([trades, markets]) => {
|
||||
if (!this.stateService.env.OFFICIAL_BISQ_MARKETS) {
|
||||
if (this.stateService.env.BASE_MODULE !== 'bisq') {
|
||||
trades = trades.filter((trade) => {
|
||||
const pair = trade.market.split('_');
|
||||
return !(pair[1] === 'btc' && this.allowCryptoCoins.indexOf(pair[0]) === -1);
|
||||
|
@ -8,10 +8,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="about-text">
|
||||
<div class="about-text" *ngIf="stateService.env.BASE_MODULE === 'mempool'; else marginBox">
|
||||
<h5><ng-container i18n="about.about-the-project">The Mempool Open Source Project</ng-container><ng-template [ngIf]="locale.substr(0, 2) === 'en'"> ™</ng-template></h5>
|
||||
<p i18n>Building a mempool and blockchain explorer for the Bitcoin community, focusing on the transaction fee market and multi-layer ecosystem, without any advertising, altcoins, or third-party trackers.</p>
|
||||
</div>
|
||||
<ng-template #marginBox>
|
||||
<div class="no-about-margin"></div>
|
||||
</ng-template>
|
||||
|
||||
<div class="social-icons">
|
||||
<a target="_blank" href="https://github.com/mempool/mempool">
|
||||
|
@ -176,4 +176,8 @@
|
||||
.footer-version {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.no-about-margin {
|
||||
height: 10px;
|
||||
}
|
@ -25,7 +25,7 @@ export class AboutComponent implements OnInit {
|
||||
constructor(
|
||||
private websocketService: WebsocketService,
|
||||
private seoService: SeoService,
|
||||
private stateService: StateService,
|
||||
public stateService: StateService,
|
||||
private apiService: ApiService,
|
||||
private router: Router,
|
||||
@Inject(LOCALE_ID) public locale: string,
|
||||
|
@ -12,7 +12,7 @@
|
||||
<ng-template ngbNavContent>
|
||||
<div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapCommonJS(code.codeSample.commonJS)"></app-clipboard></div>
|
||||
<div class="links">
|
||||
<a href="https://github.com/mempool/mempool.js" target="_blank">github repository</a>
|
||||
<a [href]="npmGithubLink()" target="_blank">github repository</a>
|
||||
</div>
|
||||
<pre><code [innerText]="wrapCommonJS(code.codeSample.commonJS)"></code></pre>
|
||||
</ng-template>
|
||||
@ -20,12 +20,12 @@
|
||||
<li ngbNavItem>
|
||||
<a ngbNavLink>ES Module</a>
|
||||
<ng-template ngbNavContent>
|
||||
<div class="subtitle"><ng-container i18n="API Docs install lib">Install Package</ng-container> <app-clipboard [text]="esModuleInstall"></app-clipboard></div>
|
||||
<div class="subtitle"><ng-container i18n="API Docs install lib">Install Package</ng-container> <app-clipboard [text]="wrapImportTemplate()"></app-clipboard></div>
|
||||
<div class="links">
|
||||
<a href="https://github.com/mempool/mempool.js" target="_blank">github repository</a>
|
||||
<a href="https://www.npmjs.org/package/@mempool/mempool.js" target="_blank">npm package</a>
|
||||
<a [href]="npmGithubLink()" target="_blank">github repository</a>
|
||||
<a [href]="npmModuleLink()" target="_blank">npm package</a>
|
||||
</div>
|
||||
<pre><code [innerText]="esModuleInstall"></code></pre>
|
||||
<pre><code [innerText]="wrapImportTemplate()"></code></pre>
|
||||
<div class="subtitle"><ng-container i18n="API Docs code example">Code Example</ng-container> <app-clipboard [text]="wrapESmodule(code.codeSample.esModule)"></app-clipboard></div>
|
||||
<pre><code [innerText]="wrapESmodule(code.codeSample.esModule)"></code></pre>
|
||||
</ng-template>
|
||||
|
@ -7,6 +7,7 @@ import { Component, Input } from '@angular/core';
|
||||
})
|
||||
export class CodeTemplateComponent {
|
||||
@Input() network: string;
|
||||
@Input() layer: string;
|
||||
@Input() code: {
|
||||
codeSample: {
|
||||
esModule: string;
|
||||
@ -16,15 +17,32 @@ export class CodeTemplateComponent {
|
||||
responseSample: string;
|
||||
};
|
||||
hostname = document.location.hostname;
|
||||
esModuleInstall = `# npm
|
||||
npm install @mempool/mempool.js --save
|
||||
|
||||
# yarn
|
||||
yarn add @mempool/mempool.js`;
|
||||
|
||||
constructor(
|
||||
) { }
|
||||
|
||||
npmGithubLink(){
|
||||
let npmLink = `https://github.com/mempool/mempool.js`;
|
||||
if (this.layer === 'bisq') {
|
||||
npmLink = `https://github.com/mempool/mempool.js/tree/main/npm-bisq-js`;
|
||||
}
|
||||
if (this.layer === 'liquid') {
|
||||
npmLink = `https://github.com/mempool/mempool.js/tree/main/npm-liquid-js`;
|
||||
}
|
||||
return npmLink;
|
||||
}
|
||||
|
||||
npmModuleLink() {
|
||||
let npmLink = `https://www.npmjs.org/package/@mempool/mempool.js`;
|
||||
if (this.layer === 'bisq') {
|
||||
npmLink = `https://www.npmjs.org/package/@mempool/bisq.js`;
|
||||
}
|
||||
if (this.layer === 'liquid') {
|
||||
npmLink = `https://www.npmjs.org/package/@mempool/liquid.js`;
|
||||
}
|
||||
return npmLink;
|
||||
}
|
||||
|
||||
normalizeCodeHostname(code: string) {
|
||||
let codeText: string;
|
||||
if (this.network === 'bisq' || this.network === 'liquid'){
|
||||
@ -44,7 +62,15 @@ yarn add @mempool/mempool.js`;
|
||||
});` );
|
||||
}
|
||||
|
||||
return `import mempoolJS from "@mempool/mempool.js";
|
||||
let importText = `import mempoolJS from "@mempool/mempool.js";`;
|
||||
if (this.layer === 'bisq') {
|
||||
importText = `import bisqJS from "@mempool/bisq.js";`;
|
||||
}
|
||||
if (this.layer === 'liquid') {
|
||||
importText = `import liquidJS from "@mempool/liquid.js";`;
|
||||
}
|
||||
|
||||
return `${importText}
|
||||
|
||||
const init = async () => {
|
||||
${codeText}
|
||||
@ -60,10 +86,18 @@ init();`;
|
||||
hostname: '${this.hostname}/${this.network}'
|
||||
});` );
|
||||
}
|
||||
|
||||
let importText = `<script src="https://mempool.space/mempool.js"></script>`;
|
||||
if (this.layer === 'bisq') {
|
||||
importText = `<script src="https://bisq.markets/bisq.js"></script>`;
|
||||
}
|
||||
if (this.layer === 'liquid') {
|
||||
importText = `<script src="https://liquid.network/liquid.js"></script>`;
|
||||
}
|
||||
return `<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="https://mempool.space/mempool.js"></script>
|
||||
${importText}
|
||||
<script>
|
||||
const init = async () => {
|
||||
${codeText}
|
||||
@ -81,4 +115,31 @@ init();`;
|
||||
return code;
|
||||
}
|
||||
|
||||
wrapImportTemplate() {
|
||||
|
||||
let importTemplate = `# npm
|
||||
npm install @mempool/mempool.js --save
|
||||
|
||||
# yarn
|
||||
yarn add @mempool/mempool.js`;
|
||||
|
||||
if (this.layer === 'bisq') {
|
||||
importTemplate = `# npm
|
||||
npm install @mempool/bisq.js --save
|
||||
|
||||
# yarn
|
||||
yarn add @mempool/bisq.js`;
|
||||
}
|
||||
|
||||
if (this.layer === 'liquid') {
|
||||
importTemplate = `# npm
|
||||
npm install @mempool/liquid.js --save
|
||||
|
||||
# yarn
|
||||
yarn add @mempool/liquid.js`;
|
||||
}
|
||||
|
||||
return importTemplate;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
||||
<a class="navbar-brand" [routerLink]="['/' | relativeUrl]" style="position: relative;">
|
||||
<ng-container *ngIf="{ val: connectionState$ | async } as connectionState">
|
||||
<img [src]="'./resources/bisq-markets.svg'" height="35" width="180" class="logo" [ngStyle]="{'opacity': connectionState.val === 2 ? 1 : 0.5 }">
|
||||
<img src="./resources/bisq/bisq-markets-logo.png" height="35" width="140" class="logo" [ngStyle]="{'opacity': connectionState.val === 2 ? 1 : 0.5 }">
|
||||
<div class="connection-badge">
|
||||
<div class="badge badge-warning" *ngIf="connectionState.val === 0" i18n="master-page.offline">Offline</div>
|
||||
<div class="badge badge-warning" *ngIf="connectionState.val === 1" i18n="master-page.reconnecting">Reconnecting...</div>
|
||||
@ -10,6 +10,20 @@
|
||||
</ng-container>
|
||||
</a>
|
||||
|
||||
<div ngbDropdown display="dynamic" class="dropdown-container" *ngIf="env.TESTNET_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.BISQ_ENABLED">
|
||||
<button ngbDropdownToggle type="button" class="btn btn-secondary dropdown-toggle-split" aria-haspopup="true">
|
||||
<img src="./resources/bisq-logo.png" style="width: 25px; height: 25px;" class="mr-1">
|
||||
</button>
|
||||
<div ngbDropdownMenu>
|
||||
<a href="https://mempool.space" ngbDropdownItem class="mainnet"><img src="./resources/bitcoin-logo.png" style="width: 30px;" class="mr-1"> Mainnet</a>
|
||||
<a href="https://mempool.space/signet" ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet"><img src="./resources/signet-logo.png" style="width: 30px;" class="mr-1"> Signet</a>
|
||||
<a href="https://mempool.space/testnet" ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet"><img src="./resources/testnet-logo.png" style="width: 30px;" class="mr-1"> Testnet</a>
|
||||
<h6 class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
|
||||
<button ngbDropdownItem class="mainnet active" routerLink="/"><img src="./resources/bisq-logo.png" style="width: 30px;" class="mr-1"> Bisq</button>
|
||||
<a href="https://liquid.network" ngbDropdownItem *ngIf="env.LIQUID_ENABLED" class="liquid"><img src="./resources/liquid-logo.png" style="width: 30px;" class="mr-1"> Liquid</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="navbar-collapse" id="navbarCollapse">
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
|
||||
@ -18,6 +32,9 @@
|
||||
<li class="nav-item mr-2" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/api' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'cogs']" [fixedWidth]="true" i18n-title="master-page.api" title="API"></fa-icon></a>
|
||||
</li>
|
||||
<li class="nav-item" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/about']" (click)="collapse()"><fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true" i18n-title="master-page.about" title="About"></fa-icon></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
@ -83,3 +83,7 @@ nav {
|
||||
display: flex;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
margin-right: 5px;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { Env, StateService } from '../../services/state.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
@ -10,12 +10,14 @@ import { Observable } from 'rxjs';
|
||||
export class BisqMasterPageComponent implements OnInit {
|
||||
connectionState$: Observable<number>;
|
||||
navCollapsed = false;
|
||||
env: Env;
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.env = this.stateService.env;
|
||||
this.connectionState$ = this.stateService.connectionState$;
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,10 @@
|
||||
</div>
|
||||
<div class="block-body">
|
||||
<div class="fees">
|
||||
~{{ block.medianFee | number:'1.0-0' }} <ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
~{{ block.medianFee | number:feeRounding }} <ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
</div>
|
||||
<div class="fee-span">
|
||||
{{ block.feeRange[1] | number:'1.0-0' }} - {{ block.feeRange[block.feeRange.length - 1] | number:'1.0-0' }} <ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
{{ block.feeRange[1] | number:feeRounding }} - {{ block.feeRange[block.feeRange.length - 1] | number:feeRounding }} <ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||
</div>
|
||||
<div class="block-size" [innerHTML]="block.size | bytes: 2">‎</div>
|
||||
<div class="transaction-count">
|
||||
|
@ -25,7 +25,7 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
|
||||
emptyBlockStyles = [];
|
||||
interval: any;
|
||||
tabHidden = false;
|
||||
|
||||
feeRounding = '1.0-0';
|
||||
arrowVisible = false;
|
||||
arrowLeftPx = 30;
|
||||
blocksFilled = false;
|
||||
@ -46,6 +46,9 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
if (this.stateService.network === 'liquid') {
|
||||
this.feeRounding = '1.0-1';
|
||||
}
|
||||
this.emptyBlocks.forEach((b) => this.emptyBlockStyles.push(this.getStyleForEmptyBlock(b)));
|
||||
this.loadingBlocks$ = this.stateService.isLoadingWebSocket$;
|
||||
this.networkSubscription = this.stateService.networkChanged$.subscribe((network) => this.network = network);
|
||||
@ -62,7 +65,7 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
this.blocks.unshift(block);
|
||||
this.blocks = this.blocks.slice(0, 8);
|
||||
this.blocks = this.blocks.slice(0, this.stateService.env.KEEP_BLOCKS_AMOUNT);
|
||||
|
||||
if (this.blocksFilled && !this.tabHidden) {
|
||||
block.stage = block.matchRate >= 66 ? 1 : 2;
|
||||
@ -165,7 +168,7 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
getStyleForBlock(block: Block) {
|
||||
const greenBackgroundHeight = 100 - (block.weight / 4000000) * 100;
|
||||
const greenBackgroundHeight = 100 - (block.weight / this.stateService.env.BLOCK_WEIGHT_UNITS) * 100;
|
||||
let addLeft = 0;
|
||||
|
||||
if (block.stage === 1) {
|
||||
@ -200,7 +203,7 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
|
||||
|
||||
mountEmptyBlocks() {
|
||||
const emptyBlocks = [];
|
||||
for (let i = 0; i < 8; i++) {
|
||||
for (let i = 0; i < this.stateService.env.KEEP_BLOCKS_AMOUNT; i++) {
|
||||
emptyBlocks.push({
|
||||
id: '',
|
||||
height: 0,
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="text-center" class="blockchain-wrapper">
|
||||
<div class="position-container">
|
||||
<div class="position-container {{ network }}">
|
||||
<span>
|
||||
<app-mempool-blocks></app-mempool-blocks>
|
||||
<app-blockchain-blocks></app-blockchain-blocks>
|
||||
|
@ -26,10 +26,17 @@
|
||||
top: 75px;
|
||||
}
|
||||
|
||||
.position-container.liquid {
|
||||
left: 420px;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.position-container {
|
||||
left: 95%;
|
||||
}
|
||||
.position-container.liquid {
|
||||
left: 50%;
|
||||
}
|
||||
.position-container.loading {
|
||||
left: 50%;
|
||||
}
|
||||
|
@ -1,11 +1,20 @@
|
||||
import { Component, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-blockchain',
|
||||
templateUrl: './blockchain.component.html',
|
||||
styleUrls: ['./blockchain.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BlockchainComponent {
|
||||
export class BlockchainComponent implements OnInit {
|
||||
network: string;
|
||||
|
||||
constructor() { }
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.network = this.stateService.network;
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ export class FooterComponent implements OnInit {
|
||||
|
||||
return {
|
||||
size: size,
|
||||
blocks: Math.ceil(vsize / 1000000)
|
||||
blocks: Math.ceil(vsize / this.stateService.blockVSize)
|
||||
};
|
||||
})
|
||||
);
|
||||
|
@ -43,6 +43,11 @@ export class LanguageSelectorComponent implements OnInit {
|
||||
try {
|
||||
document.cookie = `lang=${language}; expires=Thu, 18 Dec 2050 12:00:00 UTC; path=/`;
|
||||
} catch (e) { }
|
||||
this.document.location.href = `/${language}/${this.stateService.network}`;
|
||||
|
||||
if (this.stateService.env.BASE_MODULE === 'mempool') {
|
||||
this.document.location.href = `/${language}/${this.stateService.network}`;
|
||||
} else {
|
||||
this.document.location.href = `/${language}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
<td class="d-none d-lg-block">{{ block.tx_count | number }}</td>
|
||||
<td>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-mempool {{ network$ | async }}" role="progressbar" [ngStyle]="{'width': (block.weight / 4000000)*100 + '%' }"></div>
|
||||
<div class="progress-bar progress-mempool {{ network$ | async }}" role="progressbar" [ngStyle]="{'width': (block.weight / stateService.env.BLOCK_WEIGHT_UNITS)*100 + '%' }"></div>
|
||||
<div class="progress-text" [innerHTML]="block.size | bytes: 2"></div>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -29,7 +29,7 @@ export class LatestBlocksComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private electrsApiService: ElectrsApiService,
|
||||
private stateService: StateService,
|
||||
public stateService: StateService,
|
||||
private seoService: SeoService,
|
||||
private websocketService: WebsocketService,
|
||||
private cd: ChangeDetectorRef,
|
||||
|
@ -0,0 +1,62 @@
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
||||
<a class="navbar-brand" [routerLink]="['/' | relativeUrl]" style="position: relative;">
|
||||
<ng-container *ngIf="{ val: connectionState$ | async } as connectionState">
|
||||
<img src="./resources/liquid/liquid-network-logo.png" height="35" width="140" class="logo" [ngStyle]="{'opacity': connectionState.val === 2 ? 1 : 0.5 }">
|
||||
<div class="connection-badge">
|
||||
<div class="badge badge-warning" *ngIf="connectionState.val === 0" i18n="master-page.offline">Offline</div>
|
||||
<div class="badge badge-warning" *ngIf="connectionState.val === 1" i18n="master-page.reconnecting">Reconnecting...</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</a>
|
||||
|
||||
<div ngbDropdown display="dynamic" class="dropdown-container" *ngIf="env.TESTNET_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.BISQ_ENABLED">
|
||||
<button ngbDropdownToggle type="button" class="btn btn-secondary dropdown-toggle-split" aria-haspopup="true">
|
||||
<img src="./resources/liquid-logo.png" style="width: 25px; height: 25px;" class="mr-1">
|
||||
</button>
|
||||
<div ngbDropdownMenu>
|
||||
<a href="https://mempool.space" ngbDropdownItem class="mainnet"><img src="./resources/bitcoin-logo.png" style="width: 30px;" class="mr-1"> Mainnet</a>
|
||||
<a href="https://mempool.space/signet" ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet"><img src="./resources/signet-logo.png" style="width: 30px;" class="mr-1"> Signet</a>
|
||||
<a href="https://mempool.space/testnet" ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet"><img src="./resources/testnet-logo.png" style="width: 30px;" class="mr-1"> Testnet</a>
|
||||
<h6 class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
|
||||
<a href="https://bisq.markets" ngbDropdownItem class="mainnet"><img src="./resources/bisq-logo.png" style="width: 30px;" class="mr-1"> Bisq</a>
|
||||
<button ngbDropdownItem class="liquid active" routerLink="/"><img src="./resources/liquid-logo.png" style="width: 30px;" class="mr-1"> Liquid</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="navbar-collapse" id="navbarCollapse">
|
||||
<ul class="navbar-nav liquid">
|
||||
<li class="nav-item" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
|
||||
<a class="nav-link" [routerLink]="['/' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'tachometer-alt']" [fixedWidth]="true" i18n-title="master-page.dashboard" title="Dashboard"></fa-icon></a>
|
||||
</li>
|
||||
<li class="nav-item" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/blocks' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'cubes']" [fixedWidth]="true" i18n-title="master-page.blocks" title="Blocks"></fa-icon></a>
|
||||
</li>
|
||||
<li class="nav-item" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/graphs' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'chart-area']" [fixedWidth]="true" i18n-title="master-page.graphs" title="Graphs"></fa-icon></a>
|
||||
</li>
|
||||
<!--
|
||||
<li class="nav-item d-none d-lg-block" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/tv' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'tv']" [fixedWidth]="true" i18n-title="master-page.tvview" title="TV view"></fa-icon></a>
|
||||
</li>
|
||||
-->
|
||||
<li class="nav-item" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/assets']" (click)="collapse()"><fa-icon [icon]="['fas', 'database']" [fixedWidth]="true" i18n-title="master-page.assets" title="Assets"></fa-icon></a>
|
||||
</li>
|
||||
<li [hidden]="isMobile" class="nav-item mr-2" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/api' | relativeUrl]" (click)="collapse()"><fa-icon [icon]="['fas', 'cogs']" [fixedWidth]="true" i18n-title="master-page.api" title="API"></fa-icon></a>
|
||||
</li>
|
||||
<li class="nav-item" routerLinkActive="active">
|
||||
<a class="nav-link" [routerLink]="['/about']" (click)="collapse()"><fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true" i18n-title="master-page.about" title="About"></fa-icon></a>
|
||||
</li>
|
||||
</ul>
|
||||
<app-search-form class="search-form-container" location="top" (searchTriggered)="collapse()"></app-search-form>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<br />
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
<br>
|
@ -0,0 +1,135 @@
|
||||
li.nav-item.active {
|
||||
background-color: #653b9c;
|
||||
}
|
||||
|
||||
fa-icon {
|
||||
font-size: 1.66em;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
z-index: 100;
|
||||
min-height: 64px;
|
||||
}
|
||||
|
||||
li.nav-item {
|
||||
margin: auto 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.navbar {
|
||||
padding: 0rem 2rem;
|
||||
}
|
||||
fa-icon {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.dropdown-container {
|
||||
margin-right: 16px;
|
||||
}
|
||||
li.nav-item {
|
||||
margin: auto 0px;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.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%;
|
||||
@media (min-width: 992px) {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
a {
|
||||
font-size: 0.8em;
|
||||
@media (min-width: 375px) {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.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: 130px;
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
box-shadow: 0px 0px 15px 0px #000;
|
||||
}
|
||||
|
||||
.connection-badge {
|
||||
position: absolute;
|
||||
top: 13px;
|
||||
left: 0px;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
margin: 0 auto;
|
||||
display: table;
|
||||
}
|
||||
|
||||
.mainnet.active {
|
||||
background-color: #653b9c;
|
||||
}
|
||||
|
||||
.liquid.active {
|
||||
background-color: #116761;
|
||||
}
|
||||
|
||||
.testnet.active {
|
||||
background-color: #1d486f;
|
||||
}
|
||||
|
||||
.signet.active {
|
||||
background-color: #6f1d5d;
|
||||
}
|
||||
|
||||
.dropdown-divider {
|
||||
border-top: 1px solid #121420;
|
||||
}
|
||||
|
||||
.dropdown-toggle::after {
|
||||
vertical-align: 0.1em;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
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;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Env, StateService } from '../../services/state.service';
|
||||
import { Observable} from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-liquid-master-page',
|
||||
templateUrl: './liquid-master-page.component.html',
|
||||
styleUrls: ['./liquid-master-page.component.scss'],
|
||||
})
|
||||
export class LiquidMasterPageComponent implements OnInit {
|
||||
env: Env;
|
||||
connectionState$: Observable<number>;
|
||||
navCollapsed = false;
|
||||
isMobile = window.innerWidth <= 767.98;
|
||||
officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE;
|
||||
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.env = this.stateService.env;
|
||||
this.connectionState$ = this.stateService.connectionState$;
|
||||
}
|
||||
|
||||
collapse(): void {
|
||||
this.navCollapsed = !this.navCollapsed;
|
||||
}
|
||||
}
|
@ -20,8 +20,10 @@
|
||||
<button ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet" [class.active]="network.val === 'signet'" routerLink="/signet"><img src="./resources/signet-logo.png" style="width: 30px;" class="mr-1"> Signet</button>
|
||||
<button ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet" [class.active]="network.val === 'testnet'" routerLink="/testnet"><img src="./resources/testnet-logo.png" style="width: 30px;" class="mr-1"> Testnet</button>
|
||||
<h6 *ngIf="env.LIQUID_ENABLED || env.BISQ_ENABLED" class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
|
||||
<button ngbDropdownItem *ngIf="env.BISQ_ENABLED" class="bisq" [class.active]="network.val === 'bisq'" routerLink="/bisq"><img src="./resources/bisq-logo.png" style="width: 30px;" class="mr-1"> Bisq</button>
|
||||
<button ngbDropdownItem *ngIf="env.LIQUID_ENABLED" class="liquid" [class.active]="network.val === 'liquid'" routerLink="/liquid"><img src="./resources/liquid-logo.png" style="width: 30px;" class="mr-1"> Liquid</button>
|
||||
<a href="https://bisq.markets" ngbDropdownItem *ngIf="env.BISQ_ENABLED && env.OFFICIAL_MEMPOOL_SPACE" class="bisq"><img src="./resources/bisq-logo.png" style="width: 30px;" class="mr-1"> Bisq</a>
|
||||
<button ngbDropdownItem *ngIf="env.BISQ_ENABLED && !env.OFFICIAL_MEMPOOL_SPACE" class="bisq" [class.active]="network.val === 'bisq'" routerLink="/bisq"><img src="./resources/bisq-logo.png" style="width: 30px;" class="mr-1"> Bisq</button>
|
||||
<a href="https://liquid.network" ngbDropdownItem *ngIf="env.LIQUID_ENABLED && env.OFFICIAL_MEMPOOL_SPACE" class="liquid" [class.active]="network.val === 'liquid'"><img src="./resources/liquid-logo.png" style="width: 30px;" class="mr-1"> Liquid</a>
|
||||
<button ngbDropdownItem *ngIf="env.LIQUID_ENABLED && !env.OFFICIAL_MEMPOOL_SPACE" class="liquid" [class.active]="network.val === 'liquid'" routerLink="/liquid"><img src="./resources/liquid-logo.png" style="width: 30px;" class="mr-1"> Liquid</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
<td i18n="mempool-block.size">Size</td>
|
||||
<td>
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-mempool {{ (network$ | async) }}" role="progressbar" [ngStyle]="{'width': (mempoolBlock.blockVSize / 1000000) * 100 + '%' }"></div>
|
||||
<div class="progress-bar progress-mempool {{ (network$ | async) }}" role="progressbar" [ngStyle]="{'width': (mempoolBlock.blockVSize / stateService.blockVSize) * 100 + '%' }"></div>
|
||||
<div class="progress-text" [innerHTML]="mempoolBlock.blockSize | bytes: 2"></div>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -21,7 +21,7 @@ export class MempoolBlockComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private stateService: StateService,
|
||||
public stateService: StateService,
|
||||
private seoService: SeoService,
|
||||
private websocketService: WebsocketService,
|
||||
) { }
|
||||
@ -66,7 +66,7 @@ export class MempoolBlockComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
getOrdinal(mempoolBlock: MempoolBlock): string {
|
||||
const blocksInBlock = Math.ceil(mempoolBlock.blockVSize / 1000000);
|
||||
const blocksInBlock = Math.ceil(mempoolBlock.blockVSize / this.stateService.blockVSize);
|
||||
if (this.mempoolBlockIndex === 0) {
|
||||
return $localize`:@@mempool-block.next.block:Next block`;
|
||||
} else if (this.mempoolBlockIndex === this.stateService.env.KEEP_BLOCKS_AMOUNT - 1 && blocksInBlock > 1) {
|
||||
|
@ -6,10 +6,10 @@
|
||||
<a [routerLink]="['/mempool-block/' | relativeUrl, i]" class="blockLink"> </a>
|
||||
<div class="block-body">
|
||||
<div class="fees">
|
||||
~{{ projectedBlock.medianFee | number:'1.0-0' }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
~{{ projectedBlock.medianFee | number:feeRounding }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
</div>
|
||||
<div class="fee-span">
|
||||
{{ projectedBlock.feeRange[0] | number:'1.0-0' }} - {{ projectedBlock.feeRange[projectedBlock.feeRange.length - 1] | number:'1.0-0' }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
{{ projectedBlock.feeRange[0] | number:feeRounding }} - {{ projectedBlock.feeRange[projectedBlock.feeRange.length - 1] | number:feeRounding }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
|
||||
</div>
|
||||
<div class="block-size" [innerHTML]="projectedBlock.blockSize | bytes: 2">‎</div>
|
||||
<div class="transaction-count">
|
||||
@ -17,7 +17,7 @@
|
||||
<ng-template #transactionsSingular let-i i18n="shared.transaction-count.singular">{{ i }} transaction</ng-template>
|
||||
<ng-template #transactionsPlural let-i i18n="shared.transaction-count.plural">{{ i }} transactions</ng-template>
|
||||
</div>
|
||||
<div class="time-difference" *ngIf="projectedBlock.blockVSize <= 1000000; else mergedBlock">
|
||||
<div class="time-difference" *ngIf="projectedBlock.blockVSize <= stateService.blockVSize; else mergedBlock">
|
||||
<ng-template [ngIf]="network === 'liquid'" [ngIfElse]="timeDiffMainnet">
|
||||
<app-time-until [time]="(1 * i) + now + 61000" [fastRender]="false" [fixedRender]="true"></app-time-until>
|
||||
</ng-template>
|
||||
@ -27,7 +27,7 @@
|
||||
</div>
|
||||
<ng-template #mergedBlock>
|
||||
<div class="time-difference">
|
||||
<b>(<ng-container *ngTemplateOutlet="blocksPlural; context: {$implicit: projectedBlock.blockVSize / 1000000 | ceil }"></ng-container>)</b>
|
||||
<b>(<ng-container *ngTemplateOutlet="blocksPlural; context: {$implicit: projectedBlock.blockVSize / stateService.blockVSize | ceil }"></ng-container>)</b>
|
||||
<ng-template #blocksPlural let-i i18n="shared.blocks">{{ i }} <span class="shared-block">blocks</span></ng-template>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -34,6 +34,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
blockPadding = 30;
|
||||
arrowVisible = false;
|
||||
tabHidden = false;
|
||||
feeRounding = '1.0-0';
|
||||
|
||||
rightPosition = 0;
|
||||
transition = '2s';
|
||||
@ -47,11 +48,14 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private stateService: StateService,
|
||||
public stateService: StateService,
|
||||
private cd: ChangeDetectorRef,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
if (this.stateService.network === 'liquid') {
|
||||
this.feeRounding = '1.0-1';
|
||||
}
|
||||
this.mempoolEmptyBlocks.forEach((b) => {
|
||||
this.mempoolEmptyBlockStyles.push(this.getStyleForMempoolEmptyBlock(b.index));
|
||||
});
|
||||
@ -153,7 +157,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
this.router.navigate([(this.network ? '/' + this.network : '') + '/mempool-block/', this.markIndex - 1]);
|
||||
} else {
|
||||
this.stateService.blocks$
|
||||
.pipe(take(8))
|
||||
.pipe(take(this.stateService.env.MEMPOOL_BLOCKS_AMOUNT))
|
||||
.subscribe(([block]) => {
|
||||
if (this.stateService.latestBlockHeight === block.height) {
|
||||
this.router.navigate([(this.network ? '/' + this.network : '') + '/block/', block.id], { state: { data: { block } }});
|
||||
@ -211,7 +215,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
getStyleForMempoolBlock(mempoolBlock: MempoolBlock, index: number) {
|
||||
const emptyBackgroundSpacePercentage = Math.max(100 - mempoolBlock.blockVSize / 1000000 * 100, 0);
|
||||
const emptyBackgroundSpacePercentage = Math.max(100 - mempoolBlock.blockVSize / this.stateService.blockVSize * 100, 0);
|
||||
const usedBlockSpace = 100 - emptyBackgroundSpacePercentage;
|
||||
const backgroundGradients = [`repeating-linear-gradient(to right, #554b45, #554b45 ${emptyBackgroundSpacePercentage}%`];
|
||||
const gradientColors = [];
|
||||
@ -278,7 +282,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
const chunkPositionOffset = blockLocation * feeRangeChunkSize;
|
||||
const feePosition = feeRangeChunkSize * feeRangeIndex + chunkPositionOffset;
|
||||
|
||||
const blockedFilledPercentage = (block.blockVSize > 1000000 ? 1000000 : block.blockVSize) / 1000000;
|
||||
const blockedFilledPercentage = (block.blockVSize > this.stateService.blockVSize ? this.stateService.blockVSize : block.blockVSize) / this.stateService.blockVSize;
|
||||
const arrowRightPosition = txInBlockIndex * (this.blockWidth + this.blockPadding)
|
||||
+ ((1 - feePosition) * blockedFilledPercentage * this.blockWidth);
|
||||
|
||||
@ -291,8 +295,8 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
|
||||
mountEmptyBlocks() {
|
||||
const emptyBlocks = [];
|
||||
const numberOfBlocks = 8;
|
||||
for (let i = 0; i <= numberOfBlocks; i++) {
|
||||
const numberOfBlocks = this.stateService.env.MEMPOOL_BLOCKS_AMOUNT;
|
||||
for (let i = 0; i < numberOfBlocks; i++) {
|
||||
emptyBlocks.push({
|
||||
blockSize: 0,
|
||||
blockVSize: 0,
|
||||
|
@ -74,7 +74,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
|
||||
labelInterpolationFnc: (value: number): any => this.vbytesPipe.transform(value, 2, 'vB', 'MvB', true),
|
||||
offset: this.showLegend ? 160 : 60,
|
||||
},
|
||||
plugins: this.inverted ? [Chartist.plugins.ctTargetLine({ value: 1000000 })] : []
|
||||
plugins: this.inverted ? [Chartist.plugins.ctTargetLine({ value: this.stateService.blockVSize })] : []
|
||||
};
|
||||
|
||||
if (this.showLegend) {
|
||||
|
@ -56,7 +56,7 @@ export class TxFeeRatingComponent implements OnInit, OnChanges, OnDestroy {
|
||||
this.medianFeeNeeded = block.medianFee;
|
||||
|
||||
// Block not filled
|
||||
if (block.weight < 4000000 * 0.95) {
|
||||
if (block.weight < this.stateService.env.BLOCK_WEIGHT_UNITS * 0.95) {
|
||||
this.medianFeeNeeded = 1;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="container-xl dashboard-container">
|
||||
<div class="row row-cols-1 row-cols-md-2" *ngIf="{ value: (mempoolInfoData$ | async) } as mempoolInfoData">
|
||||
<ng-template [ngIf]="collapseLevel === 'three'" [ngIfElse]="expanded">
|
||||
<div class="col card-wrapper">
|
||||
<div class="col card-wrapper" *ngIf="(network$ | async) !== 'liquid'">
|
||||
<div class="main-title" i18n="fees-box.transaction-fees">Transaction Fees</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -10,7 +10,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" *ngIf="(network$ | async) !== 'liquid'; else emptyBlock">
|
||||
<div class="col" *ngIf="(network$ | async) !== 'liquid'">
|
||||
<ng-container *ngTemplateOutlet="difficultyEpoch"></ng-container>
|
||||
</div>
|
||||
<div class="col">
|
||||
@ -27,10 +27,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</ng-template>
|
||||
<ng-template #expanded>
|
||||
<div class="col card-wrapper">
|
||||
<div class="col card-wrapper" *ngIf="(network$ | async) !== 'liquid'">
|
||||
<div class="main-title" i18n="fees-box.transaction-fees">Transaction Fees</div>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@ -38,7 +37,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" *ngIf="(network$ | async) !== 'liquid'; else emptyBlock">
|
||||
<div class="col" *ngIf="(network$ | async) !== 'liquid'">
|
||||
<ng-container *ngTemplateOutlet="difficultyEpoch"></ng-container>
|
||||
</div>
|
||||
<div class="col">
|
||||
@ -89,7 +88,7 @@
|
||||
<td class="table-cell-transaction-count">{{ block.tx_count | number }}</td>
|
||||
<td class="table-cell-size">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-mempool {{ network$ | async }}" role="progressbar" [ngStyle]="{'width': (block.weight / 4000000)*100 + '%' }"> </div>
|
||||
<div class="progress-bar progress-mempool {{ network$ | async }}" role="progressbar" [ngStyle]="{'width': (block.weight / stateService.env.BLOCK_WEIGHT_UNITS)*100 + '%' }"> </div>
|
||||
<div class="progress-text" [innerHTML]="block.size | bytes: 2"></div>
|
||||
</div>
|
||||
</td>
|
||||
@ -114,7 +113,7 @@
|
||||
<tbody>
|
||||
<tr *ngFor="let transaction of transactions$ | async; let i = index;">
|
||||
<td class="table-cell-txid"><a [routerLink]="['/tx' | relativeUrl, transaction.txid]">{{ transaction.txid | shortenString : 10 }}</a></td>
|
||||
<td class="table-cell-satoshis"><app-amount [satoshis]="transaction.value" digitsInfo="1.2-4" [noFiat]="true"></app-amount></td>
|
||||
<td class="table-cell-satoshis"><app-amount *ngIf="(network$ | async) !== 'liquid'; else liquidAmount" [satoshis]="transaction.value" digitsInfo="1.2-4" [noFiat]="true"></app-amount><ng-template #liquidAmount i18n="shared.confidential">Confidential</ng-template></td>
|
||||
<td class="table-cell-fiat" *ngIf="(network$ | async) === ''" ><app-fiat [value]="transaction.value" digitsInfo="1.0-0"></app-fiat></td>
|
||||
<td class="table-cell-fees">{{ transaction.fee / transaction.vsize | number : '1.1-1' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></td>
|
||||
</tr>
|
||||
@ -166,7 +165,7 @@
|
||||
<ng-template #mempoolTable let-mempoolInfoData>
|
||||
<div class="mempool-info-data">
|
||||
<div class="item">
|
||||
<h5 *ngIf="!mempoolInfoData.value || mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.00001 else purgingText" class="card-title" i18n="dashboard.minimum-fee|Minimum mempool fee">Minimum fee</h5>
|
||||
<h5 *ngIf="!mempoolInfoData.value || mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.00001 || (stateService.env.BASE_MODULE === 'liquid' && mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.000001) else purgingText" class="card-title" i18n="dashboard.minimum-fee|Minimum mempool fee">Minimum fee</h5>
|
||||
<ng-template #purgingText><h5 class="card-title" i18n="dashboard.purging|Purgin below fee">Purging</h5></ng-template>
|
||||
<p class="card-text" *ngIf="(isLoadingWebSocket$ | async) === false && mempoolInfoData.value; else loading">
|
||||
<ng-template [ngIf]="mempoolInfoData.value.memPoolInfo.mempoolminfee > 0.00001">< </ng-template>{{ mempoolInfoData.value.memPoolInfo.mempoolminfee * 100000 | number : '1.1-1' }} <span><ng-container i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container></span>
|
||||
|
@ -66,7 +66,7 @@ export class DashboardComponent implements OnInit {
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) private locale: string,
|
||||
private stateService: StateService,
|
||||
public stateService: StateService,
|
||||
private apiService: ApiService,
|
||||
private websocketService: WebsocketService,
|
||||
private seoService: SeoService,
|
||||
@ -207,7 +207,7 @@ export class DashboardComponent implements OnInit {
|
||||
|
||||
return {
|
||||
size: size,
|
||||
blocks: Math.ceil(vsize / 1000000)
|
||||
blocks: Math.ceil(vsize / this.stateService.blockVSize)
|
||||
};
|
||||
})
|
||||
);
|
||||
|
@ -27,6 +27,10 @@ export class SeoService {
|
||||
}
|
||||
|
||||
getTitle(): string {
|
||||
if (this.network === 'liquid')
|
||||
return 'mempool - Liquid Network';
|
||||
if (this.network === 'bisq')
|
||||
return 'mempool - Bisq Markets';
|
||||
return 'mempool - ' + (this.network ? this.ucfirst(this.network) : 'Bitcoin') + ' Explorer';
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,12 @@ export interface Env {
|
||||
ITEMS_PER_PAGE: number;
|
||||
KEEP_BLOCKS_AMOUNT: number;
|
||||
OFFICIAL_MEMPOOL_SPACE: boolean;
|
||||
OFFICIAL_BISQ_MARKETS: boolean;
|
||||
BASE_MODULE: string;
|
||||
NGINX_PROTOCOL?: string;
|
||||
NGINX_HOSTNAME?: string;
|
||||
NGINX_PORT?: string;
|
||||
BLOCK_WEIGHT_UNITS: number;
|
||||
MEMPOOL_BLOCKS_AMOUNT: number;
|
||||
GIT_COMMIT_HASH: string;
|
||||
PACKAGE_JSON_VERSION: string;
|
||||
}
|
||||
@ -36,7 +38,7 @@ const defaultEnv: Env = {
|
||||
'TESTNET_ENABLED': false,
|
||||
'SIGNET_ENABLED': false,
|
||||
'LIQUID_ENABLED': false,
|
||||
'OFFICIAL_BISQ_MARKETS': false,
|
||||
'BASE_MODULE': 'mempool',
|
||||
'BISQ_ENABLED': false,
|
||||
'BISQ_SEPARATE_BACKEND': false,
|
||||
'ITEMS_PER_PAGE': 10,
|
||||
@ -45,6 +47,8 @@ const defaultEnv: Env = {
|
||||
'NGINX_PROTOCOL': 'http',
|
||||
'NGINX_HOSTNAME': '127.0.0.1',
|
||||
'NGINX_PORT': '80',
|
||||
'BLOCK_WEIGHT_UNITS': 4000000,
|
||||
'MEMPOOL_BLOCKS_AMOUNT': 8,
|
||||
'GIT_COMMIT_HASH': '',
|
||||
'PACKAGE_JSON_VERSION': '',
|
||||
};
|
||||
@ -55,6 +59,7 @@ const defaultEnv: Env = {
|
||||
export class StateService {
|
||||
isBrowser: boolean = isPlatformBrowser(this.platformId);
|
||||
network = '';
|
||||
blockVSize: number;
|
||||
env: Env;
|
||||
latestBlockHeight = 0;
|
||||
|
||||
@ -88,11 +93,10 @@ export class StateService {
|
||||
@Inject(PLATFORM_ID) private platformId: any,
|
||||
private router: Router,
|
||||
) {
|
||||
this.router.events.subscribe((event) => {
|
||||
if (event instanceof NavigationStart) {
|
||||
this.setNetworkBasedonUrl(event.url);
|
||||
}
|
||||
});
|
||||
const browserWindow = window || {};
|
||||
// @ts-ignore
|
||||
const browserWindowEnv = browserWindow.__env || {};
|
||||
this.env = Object.assign(defaultEnv, browserWindowEnv);
|
||||
|
||||
if (this.isBrowser) {
|
||||
this.setNetworkBasedonUrl(window.location.pathname);
|
||||
@ -102,15 +106,26 @@ export class StateService {
|
||||
this.isTabHidden$ = new BehaviorSubject(false);
|
||||
}
|
||||
|
||||
const browserWindow = window || {};
|
||||
// @ts-ignore
|
||||
const browserWindowEnv = browserWindow.__env || {};
|
||||
this.env = Object.assign(defaultEnv, browserWindowEnv);
|
||||
this.router.events.subscribe((event) => {
|
||||
if (event instanceof NavigationStart) {
|
||||
this.setNetworkBasedonUrl(event.url);
|
||||
}
|
||||
});
|
||||
|
||||
this.blocks$ = new ReplaySubject<[Block, boolean]>(this.env.KEEP_BLOCKS_AMOUNT);
|
||||
|
||||
if (this.env.BASE_MODULE !== 'mempool') {
|
||||
this.network = this.env.BASE_MODULE;
|
||||
this.networkChanged$.next(this.env.BASE_MODULE);
|
||||
}
|
||||
|
||||
this.blockVSize = this.env.BLOCK_WEIGHT_UNITS / 4;
|
||||
}
|
||||
|
||||
setNetworkBasedonUrl(url: string) {
|
||||
if (this.env.BASE_MODULE !== 'mempool') {
|
||||
return;
|
||||
}
|
||||
const networkMatches = url.match(/\/(bisq|testnet|liquid|signet)/);
|
||||
switch (networkMatches && networkMatches[1]) {
|
||||
case 'liquid':
|
||||
|
@ -11,6 +11,9 @@ export class RelativeUrlPipe implements PipeTransform {
|
||||
) { }
|
||||
|
||||
transform(value: string): string {
|
||||
if (this.stateService.env.BASE_MODULE !== 'mempool') {
|
||||
return '/' + value;
|
||||
}
|
||||
return (this.stateService.network ? '/' + this.stateService.network : '') + value;
|
||||
}
|
||||
|
||||
|
@ -2,33 +2,34 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bisq Markets</title>
|
||||
<title>mempool - Bisq Markets</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="description" content="Bisq is an open-source desktop application that allows you to buy and sell bitcoins in exchange for national currencies, or alternative cryptocurrencies.">
|
||||
<meta name="description" content="An open-source explorer developed for the Bisq community.">
|
||||
|
||||
<meta property="og:image" content="https://bisq.network/images/bisq-og.jpg">
|
||||
<meta property="og:image" content="https://bisq.markets/resources/bisq/bisq-markets-preview.png" />
|
||||
<meta property="og:image:type" content="image/jpeg" />
|
||||
|
||||
<meta property="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:site" content="https://bisq.markets/">
|
||||
<meta property="twitter:creator" content="@bisq_network">
|
||||
<meta property="twitter:title" content="Bisq Markets">
|
||||
<meta property="twitter:description" content="Bisq is an open-source desktop application that allows you to buy and sell bitcoins in exchange for national currencies, or alternative cryptocurrencies.">
|
||||
<meta property="twitter:image:src" content="https://bisq.network/images/bisq-og.jpg">
|
||||
<meta property="twitter:title" content="mempool - Bisq Markets">
|
||||
<meta property="twitter:description" content="An open-source explorer developed for the Bisq community.">
|
||||
<meta property="twitter:image:src" content="https://bisq.markets/resources/bisq/bisq-markets-preview.png" />
|
||||
<meta property="twitter:domain" content="bisq.markets">
|
||||
|
||||
<meta name="msapplication-TileColor" content="#000000">
|
||||
<meta name="msapplication-config" content="/resources/favicons/browserconfig.xml">
|
||||
<meta name="msapplication-config" content="/resources/bisq/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="https://bisq.network/images/apple-touch-icon.png">
|
||||
<link rel="mask-icon" href="https://bisq.network/safari-pinned-tab.svg" color="#404040">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="https://bisq.network/images/bisq-fav.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="https://bisq.network/images/bisq-fav.png">
|
||||
<link rel="icon" type="image/x-icon" href="https://bisq.network/favicon.ico" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/resources/bisq/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/resources/bisq/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/resources/bisq/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/resources/bisq/favicons/site.webmanifest">
|
||||
<link rel="mask-icon" href="/resources/bisq/favicons/safari-pinned-tab.svg" color="#5bbad5">
|
||||
<link rel="shortcut icon" href="/resources/bisq/favicons/favicon.ico">
|
||||
|
||||
<link id="canonical" rel="canonical" href="https://bisq.markets">
|
||||
|
||||
|
53
frontend/src/index.liquid.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>mempool - Liquid Network</title>
|
||||
<base href="/">
|
||||
|
||||
<meta name="description" content="An open-source explorer developed for the Liquid Network.">
|
||||
<meta property="og:image" content="https://liquid.network/resources/liquid/liquid-network-preview.png" />
|
||||
<meta property="og:image:type" content="image/png" />
|
||||
<meta property="og:image:width" content="1000" />
|
||||
<meta property="og:image:height" content="500" />
|
||||
<meta property="twitter:card" content="summary_large_image">
|
||||
<meta property="twitter:site" content="@mempool">
|
||||
<meta property="twitter:creator" content="@mempool">
|
||||
<meta property="twitter:title" content="mempool - Liquid Network">
|
||||
<meta property="twitter:description" content="An open-source explorer developed for the Liquid Network.">
|
||||
<meta property="twitter:image:src" content="https://liquid.network/resources/liquid/liquid-network-preview.png" />
|
||||
<meta property="twitter:domain" content="liquid.network">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/resources/liquid/favicons/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="48x48" href="/resources/liquid/favicons/favicon-48x48.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/resources/liquid/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="24x24" href="/resources/liquid/favicons/favicon-24x24.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/resources/liquid/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="/resources/liquid/favicons/site.webmanifest">
|
||||
<link id="canonical" rel="canonical" href="https://liquid.network">
|
||||
|
||||
<meta name="msapplication-TileColor" content="#000000">
|
||||
<meta name="msapplication-config" content="/resources/liquid/favicons/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<app-root></app-root>
|
||||
<script type="text/javascript">
|
||||
if (document.location.hostname === "liquid.network")
|
||||
{
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//stats.liquid.network/";
|
||||
_paq.push(['setTrackerUrl', u+'m.php']);
|
||||
_paq.push(['setSiteId', '8']);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.src=u+'m.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,17 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="172.649" height="33.558" viewBox="0 0 172.649 33.558">
|
||||
<g id="bisq-markets" transform="translate(-158 -373.5)">
|
||||
<g id="bisq_logo_green" transform="translate(158 376.985)">
|
||||
<g id="bisq_mark" transform="translate(0 0)">
|
||||
<path id="Combined_Shape" data-name="Combined Shape" d="M8.251,22.938A11.845,11.845,0,0,1,0,11.722,11.38,11.38,0,0,1,3.118,3.8,11.625,11.625,0,0,1,10.946,0c4.083,0,5.907,3.373,4.469,5.255-1.607,2.092-3.475,1.922-4.865,1.025,0,0-1.912-1.281-2.476-1.708-.869-.64-1.825-.64-2.172.385C5.294,6.792,4.991,7.945,4.513,9.78A12.5,12.5,0,0,0,4.166,12.6a5.734,5.734,0,0,0,2.215,4.483,23.065,23.065,0,0,0,3.084,2.305,5.649,5.649,0,0,0,2.954.9h.087a5.649,5.649,0,0,0,2.954-.9,37.207,37.207,0,0,0,4.083-2.69c1.611-1.5,3.849.178,2.286,2.187a12.238,12.238,0,0,1-9.679,4.684A12.38,12.38,0,0,1,8.251,22.938Zm3.874-4.88a.512.512,0,0,1-.334-.111c-.251-.221-.71-.664-1.128-1.034a.368.368,0,0,1-.057-.44.472.472,0,0,1,.432-.224,22.129,22.129,0,0,1,2.213,0,.446.446,0,0,1,.381.251.362.362,0,0,1-.089.413c-.417.369-.876.812-1.085,1.034a.511.511,0,0,1-.322.111Zm2.482-4.744a1.463,1.463,0,0,1,1.473-1.377c.332,0,1.368.12,1.553.561.369.8-.888,1.883-1.443,2.084a1.728,1.728,0,0,1-.575.11C14.852,14.691,14.525,14,14.607,13.314ZM8.031,14.581c-.555-.2-1.812-1.282-1.443-2.084.148-.441,1.221-.561,1.554-.561a1.463,1.463,0,0,1,1.473,1.377C9.7,14,9.37,14.691,8.606,14.691A1.728,1.728,0,0,1,8.031,14.581Zm10.457-3.794C16.284,9.8,14.689,9.1,16,7.458a16.235,16.235,0,0,1,2.164-2.219c.851-.7,1.378-1.137,2.108.328A30.626,30.626,0,0,1,21.959,9.43a1.372,1.372,0,0,1-1.431,1.894A5.117,5.117,0,0,1,18.488,10.787Z" transform="translate(0 0)" fill="#25b135"/>
|
||||
</g>
|
||||
<g id="Group" transform="translate(27.192 0.604)">
|
||||
<path id="Fill_1" data-name="Fill 1" d="M14.5,20.545H10.918V14.184a5.512,5.512,0,0,1-1.692.958,5.913,5.913,0,0,1-1.975.354,7.037,7.037,0,0,1-5.1-2.158A7.954,7.954,0,0,1,0,7.748a7.954,7.954,0,0,1,2.153-5.59A7.037,7.037,0,0,1,7.251,0c.128,0,.26,0,.4.012.1.005.507.048.524.049a7.027,7.027,0,0,1,4.171,2.1A7.939,7.939,0,0,1,14.5,7.572c0,.013,0,12.439,0,12.968v.006ZM7.146,3.486h0c-2.682.027-3.638,2.219-3.638,4.261,0,2.061.969,4.262,3.688,4.262,2.156,0,3.781-1.832,3.781-4.262,0-.081,0-.165-.006-.249v0a4.727,4.727,0,0,0-.754-2.431A3.448,3.448,0,0,0,8.073,3.592v0c-.062-.015-.128-.03-.2-.043l-.011,0-.024,0-.034-.005-.026,0a4.62,4.62,0,0,0-.636-.05Z" transform="translate(33.235 4.834)" fill="#25b135"/>
|
||||
<path id="Fill_4" data-name="Fill 4" d="M6.629,6.112,5.159,5.789c-.964-.206-1.442-.627-1.42-1.252.023-.662.766-1.15,1.726-1.135A1.817,1.817,0,0,1,7.376,4.459l2.842-1.873A5.337,5.337,0,0,0,5.585,0a6.052,6.052,0,0,0-3.6,1.1A4.308,4.308,0,0,0,.156,4.48C.076,6.743,1.579,8.46,4.279,9.19c.41.111.951.252,1.495.358,1.271.246,1.432.7,1.416,1.161-.028.8-.766,1.3-1.879,1.281a3.207,3.207,0,0,1-2.931-1.768L0,12.326a5.623,5.623,0,0,0,5.19,3.067c2.986.048,5.49-2.027,5.582-4.626.083-2.348-1.386-4-4.143-4.655" transform="translate(21.452 4.937)" fill="#25b135"/>
|
||||
<path id="Fill_6" data-name="Fill 6" d="M0,14.778H3.695V0H0Z" transform="translate(16.218 5.245)" fill="#25b135"/>
|
||||
<path id="Fill_8" data-name="Fill 8" d="M7.252,20.545h0c-.128,0-.26,0-.4-.012-.1-.005-.207-.014-.311-.023H6.529L6.451,20.5l-.127-.011v-.008a7.025,7.025,0,0,1-4.171-2.1A7.936,7.936,0,0,1,0,12.983a.036.036,0,0,0,0-.008.033.033,0,0,1,0-.011V0H3.585V6.362A5.512,5.512,0,0,1,5.276,5.4,5.913,5.913,0,0,1,7.251,5.05a7.037,7.037,0,0,1,5.1,2.158A7.952,7.952,0,0,1,14.5,12.8a7.952,7.952,0,0,1-2.153,5.59A7.037,7.037,0,0,1,7.252,20.545Zm-.823-3.6h0c.059.015.123.029.2.043l.012,0,.023,0L6.694,17l.026,0a4.527,4.527,0,0,0,.636.05c2.683-.027,3.638-2.219,3.638-4.261,0-2.061-.969-4.262-3.688-4.262-2.156,0-3.781,1.832-3.781,4.262a5.138,5.138,0,0,0,.111,1.051h-.01a4.351,4.351,0,0,0,.9,1.95,3.42,3.42,0,0,0,1.905,1.156v0Z" transform="translate(0 0)" fill="#25b135"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="Path_3" data-name="Path 3" d="M.924,0H1.98V-6.4H2L4.631,0h.7L7.964-6.4h.022V0H9.042V-7.788H7.469l-2.453,5.9H4.972L2.5-7.788H.924Zm11.8,0h1.232l.77-1.925h3.707L19.217,0h1.232L17.116-7.788h-.957ZM15.1-2.849l1.474-3.575H16.6l1.452,3.575ZM24.211,0h1.056V-3.432h1.177L28.424,0h1.32L27.533-3.553A2.088,2.088,0,0,0,29.447-5.61c0-.979-.506-2.178-2.5-2.178H24.211Zm1.056-6.864h1.386c.836,0,1.672.2,1.672,1.254s-.836,1.254-1.672,1.254H25.267ZM33.682,0h1.056V-3.894h.088L38.456,0H40L35.981-4.191l3.762-3.6H38.269L34.826-4.422h-.088V-7.788H33.682ZM43.56,0h5.225V-.99H44.616v-2.5h3.7v-.99h-3.7V-6.8h3.971v-.99H43.56Zm11.1,0h1.056V-6.8h2.508v-.99H52.151v.99h2.508Zm6.8-.88A2.99,2.99,0,0,0,63.943.2a2.46,2.46,0,0,0,2.706-2.409c0-2.8-3.839-1.628-3.839-3.6,0-.484.352-1.188,1.518-1.188a1.634,1.634,0,0,1,1.386.682l.858-.781a2.693,2.693,0,0,0-2.244-.891,2.365,2.365,0,0,0-2.64,2.178c0,3.036,3.839,1.925,3.839,3.718a1.443,1.443,0,0,1-1.551,1.3,1.943,1.943,0,0,1-1.65-.836Z" transform="translate(264 394.28)" fill="#9d9da5"/>
|
||||
<line id="Line_1" data-name="Line 1" y1="33.559" transform="translate(248.67 373.5)" fill="none" stroke="#3e3e50" stroke-width="1"/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 5.0 KiB |
BIN
frontend/src/resources/bisq/bisq-markets-logo.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
frontend/src/resources/bisq/bisq-markets-preview.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
frontend/src/resources/bisq/favicons/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
frontend/src/resources/bisq/favicons/android-chrome-384x384.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
frontend/src/resources/bisq/favicons/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
9
frontend/src/resources/bisq/favicons/browserconfig.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/resources/bisq/favicons/mstile-150x150.png"/>
|
||||
<TileColor>#000000</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
BIN
frontend/src/resources/bisq/favicons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 842 B |
BIN
frontend/src/resources/bisq/favicons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
frontend/src/resources/bisq/favicons/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
frontend/src/resources/bisq/favicons/mstile-150x150.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
18
frontend/src/resources/bisq/favicons/safari-pinned-tab.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="501.000000pt" height="501.000000pt" viewBox="0 0 501.000000 501.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,501.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M555 4997 c-132 -14 -247 -66 -345 -155 -109 -98 -171 -208 -199
|
||||
-352 -8 -39 -10 -634 -9 -2020 l3 -1965 27 -73 c77 -210 218 -343 433 -408 57
|
||||
-17 160 -18 2025 -18 1595 0 1975 2 2020 13 30 7 93 31 139 53 164 78 299 252
|
||||
333 430 19 96 17 3913 -2 4003 -51 247 -237 433 -485 485 -47 10 -461 13
|
||||
-1965 14 -1048 1 -1936 -2 -1975 -7z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 855 B |
19
frontend/src/resources/bisq/favicons/site.webmanifest
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "bisq.markets",
|
||||
"short_name": "bisq.markets",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/resources/bisq/favicons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/resources/bisq/favicons/android-chrome-384x384.png",
|
||||
"sizes": "384x384",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#000000",
|
||||
"display": "standalone"
|
||||
}
|
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 42 KiB |
BIN
frontend/src/resources/liquid/favicons/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
9
frontend/src/resources/liquid/favicons/browserconfig.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/resources/liquid/favicons/mstile-150x150.png"/>
|
||||
<TileColor>#000000</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
BIN
frontend/src/resources/liquid/favicons/favicon-16x16.png
Normal file
After Width: | Height: | Size: 799 B |
BIN
frontend/src/resources/liquid/favicons/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
frontend/src/resources/liquid/favicons/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
frontend/src/resources/liquid/favicons/mstile-150x150.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
20
frontend/src/resources/liquid/favicons/safari-pinned-tab.svg
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1001.000000pt" height="1001.000000pt" viewBox="0 0 1001.000000 1001.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,1001.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1137 9994 c-1 -1 -24 -4 -52 -8 -269 -33 -525 -162 -725 -365 -186
|
||||
-188 -294 -399 -341 -661 -18 -101 -18 -240 -16 -3995 2 -2140 6 -3906 11
|
||||
-3925 69 -307 164 -488 356 -680 171 -171 401 -296 615 -336 11 -2 43 -8 70
|
||||
-13 32 -7 1443 -10 3937 -11 3874 0 3887 0 3985 20 135 29 128 27 191 50 446
|
||||
165 745 540 817 1025 7 42 6 7681 0 7750 -7 78 -17 149 -20 155 -2 4 -7 20 -9
|
||||
37 -23 127 -137 369 -228 480 -41 50 -192 198 -233 229 -153 112 -342 196
|
||||
-524 231 -79 15 -412 16 -3959 18 -2130 0 -3874 0 -3875 -1z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.0 KiB |
19
frontend/src/resources/liquid/favicons/site.webmanifest
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "liquid.network",
|
||||
"short_name": "liquid",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/resources/liquid/favicons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/resources/liquid/favicons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#000000",
|
||||
"display": "standalone"
|
||||
}
|
BIN
frontend/src/resources/liquid/liquid-network-logo.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
frontend/src/resources/liquid/liquid-network-preview.png
Normal file
After Width: | Height: | Size: 58 KiB |
@ -1,11 +1,26 @@
|
||||
var https = require('https');
|
||||
var fs = require('fs');
|
||||
|
||||
const CONFIG_FILE_NAME = 'mempool-frontend-config.json';
|
||||
let configContent = {};
|
||||
|
||||
var PATH = 'dist/mempool/browser/en-US/resources/';
|
||||
if (process.argv[2] && process.argv[2] === 'dev') {
|
||||
PATH = 'src/resources/';
|
||||
}
|
||||
|
||||
try {
|
||||
const rawConfig = fs.readFileSync(CONFIG_FILE_NAME);
|
||||
configContent = JSON.parse(rawConfig);
|
||||
console.log(`${CONFIG_FILE_NAME} file found, using provided config`);
|
||||
} catch (e) {
|
||||
if (e.code !== 'ENOENT') {
|
||||
throw new Error(e);
|
||||
} else {
|
||||
console.log(`${CONFIG_FILE_NAME} file not found, using default config`);
|
||||
}
|
||||
}
|
||||
|
||||
function download(filename, url) {
|
||||
https.get(url, (response) => {
|
||||
if (response.statusCode < 200 || response.statusCode > 299) {
|
||||
@ -18,9 +33,18 @@ function download(filename, url) {
|
||||
});
|
||||
}
|
||||
|
||||
const poolsJsonUrl = 'https://raw.githubusercontent.com/btccom/Blockchain-Known-Pools/master/pools.json';
|
||||
let assetsJsonUrl = 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.json';
|
||||
let assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.minimal.json';
|
||||
|
||||
if (configContent.BASE_MODULE && configContent.BASE_MODULE === 'liquid') {
|
||||
assetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.json';
|
||||
assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.minimal.json';
|
||||
}
|
||||
|
||||
console.log('Downloading assets');
|
||||
download(PATH + 'assets.json', 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.json');
|
||||
download(PATH + 'assets.json', assetsJsonUrl);
|
||||
console.log('Downloading assets minimal');
|
||||
download(PATH + 'assets.minimal.json', 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.minimal.json');
|
||||
download(PATH + 'assets.minimal.json', assetsMinimalJsonUrl);
|
||||
console.log('Downloading mining pools info');
|
||||
download(PATH + 'pools.json', 'https://raw.githubusercontent.com/btccom/Blockchain-Known-Pools/master/pools.json');
|
||||
download(PATH + 'pools.json', poolsJsonUrl);
|
||||
|
@ -1,50 +1,72 @@
|
||||
#!/usr/local/bin/zsh -x
|
||||
#!/usr/local/bin/zsh
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:$HOME/bin
|
||||
LOCKFILE="${HOME}/lock"
|
||||
REPO=origin
|
||||
BRANCH=master
|
||||
HOSTNAME=$(hostname)
|
||||
|
||||
if [ -f $HOME/lock ];then
|
||||
echo "check lockfile"
|
||||
if [ -f "${LOCKFILE}" ];then
|
||||
echo "upgrade already running? check lockfile ${LOCKFILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch $HOME/lock
|
||||
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
source "$NVM_DIR/nvm.sh"
|
||||
|
||||
REPO=origin
|
||||
BRANCH=master
|
||||
trap 'rm -f "${LOCKFILE}"; exit $?' INT TERM EXIT
|
||||
touch "${LOCKFILE}"
|
||||
|
||||
TAG="${BRANCH}"
|
||||
[ ! -z "$1" ] && TAG=$1
|
||||
|
||||
echo "upgrading mempool to ${TAG}" | wall
|
||||
echo "Upgrading mempool to ${TAG}" | wall
|
||||
|
||||
cd "$HOME/mempool"
|
||||
git fetch "${REPO}"
|
||||
git reset --hard "${REPO}/${TAG}"
|
||||
cd "$HOME/"
|
||||
|
||||
for site in mainnet liquid testnet bisq signet
|
||||
do
|
||||
cd "$HOME/${site}"
|
||||
git fetch "${REPO}"
|
||||
git reset --hard "${REPO}/${TAG}"
|
||||
hash=$(git rev-parse HEAD)
|
||||
|
||||
if [ "${site}" = "mainnet" ]
|
||||
then
|
||||
cd "$HOME/${site}/frontend"
|
||||
npm install
|
||||
npm run build
|
||||
rsync -av ./dist/mempool/browser/* "${HOME}/public_html/${site}/"
|
||||
update_repo()
|
||||
{
|
||||
local site="$1"
|
||||
echo "[*] Upgrading ${site} to ${TAG}"
|
||||
cd "$HOME/${site}" || exit 1
|
||||
git fetch "${REPO}" || exit 1
|
||||
if [ $(git tag -l "${TAG}") ];then
|
||||
git reset --hard "tags/${TAG}" || exit 1
|
||||
else
|
||||
git reset --hard "${REPO}/${TAG}" || exit 1
|
||||
fi
|
||||
export HASH=$(git rev-parse HEAD)
|
||||
}
|
||||
|
||||
cd "$HOME/${site}/backend"
|
||||
npm install
|
||||
npm run build
|
||||
done
|
||||
build_frontend()
|
||||
{
|
||||
local site="$1"
|
||||
echo "[*] Building frontend for ${site}"
|
||||
[ -z "${HASH}" ] && exit 1
|
||||
cd "$HOME/${site}/frontend" || exit 1
|
||||
npm install --no-optional || exit 1
|
||||
npm run build || exit 1
|
||||
}
|
||||
|
||||
hostname=$(hostname)
|
||||
echo "${hostname} updated to \`${TAG}\` @ \`${hash}\`" | /usr/local/bin/keybase chat send --nonblock --channel ops mempool.space
|
||||
build_backend()
|
||||
{
|
||||
local site="$1"
|
||||
echo "[*] Building backend for ${site}"
|
||||
[ -z "${HASH}" ] && exit 1
|
||||
cd "$HOME/${site}/backend" || exit 1
|
||||
npm install --no-optional || exit 1
|
||||
npm run build || exit 1
|
||||
}
|
||||
|
||||
rm "$HOME/lock"
|
||||
ship_frontend()
|
||||
{
|
||||
local site="$1"
|
||||
cd "$HOME/${site}/frontend" || exit 1
|
||||
rsync -av ./dist/mempool/browser/* "${HOME}/public_html/${site}/" || exit 1
|
||||
}
|
||||
|
||||
export NVM_DIR="${HOME}/.nvm"
|
||||
source "${NVM_DIR}/nvm.sh"
|
||||
|
||||
for target in mainnet liquid bisq testnet signet;do update_repo "${target}";done
|
||||
for target in mainnet liquid bisq testnet signet;do build_backend "${target}";done
|
||||
for target in mainnet liquid bisq;do build_frontend "${target}";done
|
||||
for target in mainnet liquid bisq;do ship_frontend "${target}";done
|
||||
|
||||
echo "${HOSTNAME} updated to \`${TAG}\` @ \`${HASH}\`" | /usr/local/bin/keybase chat send --nonblock --channel ops mempool.space
|
||||
|
||||
exit 0
|
||||
|