Add testnet4 frontend support
This commit is contained in:
		
							parent
							
								
									8ec5dd70e0
								
							
						
					
					
						commit
						1e5a55917c
					
				@ -53,6 +53,44 @@ let routes: Routes = [
 | 
				
			|||||||
      },
 | 
					      },
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    path: 'testnet4',
 | 
				
			||||||
 | 
					    children: [
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: '',
 | 
				
			||||||
 | 
					        pathMatch: 'full',
 | 
				
			||||||
 | 
					        loadChildren: () => import('./bitcoin-graphs.module').then(m => m.BitcoinGraphsModule),
 | 
				
			||||||
 | 
					        data: { preload: true },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: '',
 | 
				
			||||||
 | 
					        loadChildren: () => import('./master-page.module').then(m => m.MasterPageModule),
 | 
				
			||||||
 | 
					        data: { preload: true },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: 'wallet',
 | 
				
			||||||
 | 
					        children: [],
 | 
				
			||||||
 | 
					        component: AddressGroupComponent,
 | 
				
			||||||
 | 
					        data: {
 | 
				
			||||||
 | 
					          networkSpecific: true,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: 'status',
 | 
				
			||||||
 | 
					        data: { networks: ['bitcoin', 'liquid'] },
 | 
				
			||||||
 | 
					        component: StatusViewComponent
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: '',
 | 
				
			||||||
 | 
					        loadChildren: () => import('./bitcoin-graphs.module').then(m => m.BitcoinGraphsModule),
 | 
				
			||||||
 | 
					        data: { preload: true },
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        path: '**',
 | 
				
			||||||
 | 
					        redirectTo: '/testnet4'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    path: 'signet',
 | 
					    path: 'signet',
 | 
				
			||||||
    children: [
 | 
					    children: [
 | 
				
			||||||
 | 
				
			|||||||
@ -189,22 +189,22 @@ export const specialBlocks = {
 | 
				
			|||||||
  '0': {
 | 
					  '0': {
 | 
				
			||||||
    labelEvent: 'Genesis',
 | 
					    labelEvent: 'Genesis',
 | 
				
			||||||
    labelEventCompleted: 'The Genesis of Bitcoin',
 | 
					    labelEventCompleted: 'The Genesis of Bitcoin',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '210000': {
 | 
					  '210000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 1st Halving',
 | 
					    labelEvent: 'Bitcoin\'s 1st Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 25 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 25 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '420000': {
 | 
					  '420000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 2nd Halving',
 | 
					    labelEvent: 'Bitcoin\'s 2nd Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 12.5 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 12.5 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '630000': {
 | 
					  '630000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 3rd Halving',
 | 
					    labelEvent: 'Bitcoin\'s 3rd Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 6.25 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 6.25 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '709632': {
 | 
					  '709632': {
 | 
				
			||||||
    labelEvent: 'Taproot 🌱 activation',
 | 
					    labelEvent: 'Taproot 🌱 activation',
 | 
				
			||||||
@ -214,62 +214,62 @@ export const specialBlocks = {
 | 
				
			|||||||
  '840000': {
 | 
					  '840000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 4th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 4th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 3.125 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 3.125 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '1050000': {
 | 
					  '1050000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 5th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 5th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 1.5625 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 1.5625 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '1260000': {
 | 
					  '1260000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 6th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 6th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.78125 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.78125 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '1470000': {
 | 
					  '1470000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 7th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 7th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.390625 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.390625 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '1680000': {
 | 
					  '1680000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 8th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 8th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.1953125 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.1953125 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '1890000': {
 | 
					  '1890000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 9th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 9th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.09765625 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.09765625 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '2100000': {
 | 
					  '2100000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 10th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 10th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.04882812 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.04882812 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '2310000': {
 | 
					  '2310000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 11th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 11th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.02441406 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.02441406 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '2520000': {
 | 
					  '2520000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 12th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 12th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.01220703 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.01220703 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '2730000': {
 | 
					  '2730000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 13th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 13th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.00610351 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.00610351 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '2940000': {
 | 
					  '2940000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 14th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 14th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.00305175 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.00305175 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  '3150000': {
 | 
					  '3150000': {
 | 
				
			||||||
    labelEvent: 'Bitcoin\'s 15th Halving',
 | 
					    labelEvent: 'Bitcoin\'s 15th Halving',
 | 
				
			||||||
    labelEventCompleted: 'Block Subsidy has halved to 0.00152587 BTC per block',
 | 
					    labelEventCompleted: 'Block Subsidy has halved to 0.00152587 BTC per block',
 | 
				
			||||||
    networks: ['mainnet', 'testnet'],
 | 
					    networks: ['mainnet', 'testnet', 'testnet4'],
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -266,6 +266,11 @@ const featureActivation = {
 | 
				
			|||||||
    segwit: 872730,
 | 
					    segwit: 872730,
 | 
				
			||||||
    taproot: 2032291,
 | 
					    taproot: 2032291,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  testnet4: {
 | 
				
			||||||
 | 
					    rbf: 0,
 | 
				
			||||||
 | 
					    segwit: 0,
 | 
				
			||||||
 | 
					    taproot: 0,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  signet: {
 | 
					  signet: {
 | 
				
			||||||
    rbf: 0,
 | 
					    rbf: 0,
 | 
				
			||||||
    segwit: 0,
 | 
					    segwit: 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -43,5 +43,6 @@
 | 
				
			|||||||
  <ng-template [ngIf]="network === 'liquid' && !forceBtc">L-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'liquid' && !forceBtc">L-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'testnet'">t</ng-template>
 | 
					  <ng-template [ngIf]="network === 'testnet'">t</ng-template>
 | 
				
			||||||
 | 
					  <ng-template [ngIf]="network === 'testnet4'">t</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'signet'">s</ng-template>
 | 
					  <ng-template [ngIf]="network === 'signet'">s</ng-template>
 | 
				
			||||||
</ng-template>
 | 
					</ng-template>
 | 
				
			||||||
 | 
				
			|||||||
@ -70,6 +70,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
    liquid: ['var(--liquid)', 'var(--testnet-alt)'],
 | 
					    liquid: ['var(--liquid)', 'var(--testnet-alt)'],
 | 
				
			||||||
    'liquidtestnet': ['var(--liquidtestnet)', 'var(--liquidtestnet-alt)'],
 | 
					    'liquidtestnet': ['var(--liquidtestnet)', 'var(--liquidtestnet-alt)'],
 | 
				
			||||||
    testnet: ['var(--testnet)', 'var(--testnet-alt)'],
 | 
					    testnet: ['var(--testnet)', 'var(--testnet-alt)'],
 | 
				
			||||||
 | 
					    testnet4: ['var(--testnet)', 'var(--testnet-alt)'],
 | 
				
			||||||
    signet: ['var(--signet)', 'var(--signet-alt)'],
 | 
					    signet: ['var(--signet)', 'var(--signet-alt)'],
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,7 @@ export class ClockComponent implements OnInit {
 | 
				
			|||||||
    liquid: ['#116761', '#183550'],
 | 
					    liquid: ['#116761', '#183550'],
 | 
				
			||||||
    'liquidtestnet': ['#494a4a', '#272e46'],
 | 
					    'liquidtestnet': ['#494a4a', '#272e46'],
 | 
				
			||||||
    testnet: ['#1d486f', '#183550'],
 | 
					    testnet: ['#1d486f', '#183550'],
 | 
				
			||||||
 | 
					    testnet4: ['#1d486f', '#183550'],
 | 
				
			||||||
    signet: ['#6f1d5d', '#471850'],
 | 
					    signet: ['#6f1d5d', '#471850'],
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -51,7 +51,8 @@
 | 
				
			|||||||
    <div ngbDropdownMenu [ngClass]="{'dropdown-menu-right' : isMobile}">
 | 
					    <div ngbDropdownMenu [ngClass]="{'dropdown-menu-right' : isMobile}">
 | 
				
			||||||
      <a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['mainnet'] || '')" ngbDropdownItem class="mainnet"><app-svg-images name="bitcoin" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Mainnet</a>
 | 
					      <a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['mainnet'] || '')" ngbDropdownItem class="mainnet"><app-svg-images name="bitcoin" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Mainnet</a>
 | 
				
			||||||
      <a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['signet'] || '/signet')" ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
 | 
					      <a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['signet'] || '/signet')" ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
 | 
				
			||||||
      <a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet'] || '/testnet')" ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet</a>
 | 
					      <a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet'] || '/testnet')" ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
 | 
				
			||||||
 | 
					      <a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet4'] || '/testnet4')" ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
 | 
				
			||||||
      <h6 class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
 | 
					      <h6 class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
 | 
				
			||||||
      <a ngbDropdownItem class="liquid mr-1" [class.active]="network.val === 'liquid'" [routerLink]="networkPaths['liquid'] || '/'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
 | 
					      <a ngbDropdownItem class="liquid mr-1" [class.active]="network.val === 'liquid'" [routerLink]="networkPaths['liquid'] || '/'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
 | 
				
			||||||
      <a ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquidtestnet'" [routerLink]="networkPaths['liquidtestnet'] || '/testnet'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
 | 
					      <a ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquidtestnet'" [routerLink]="networkPaths['liquidtestnet'] || '/testnet'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
 | 
				
			||||||
 | 
				
			|||||||
@ -15,7 +15,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <div [ngSwitch]="network.val">
 | 
					    <div [ngSwitch]="network.val">
 | 
				
			||||||
      <span *ngSwitchCase="'signet'" class="network signet"><app-svg-images name="signet" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Signet</span>
 | 
					      <span *ngSwitchCase="'signet'" class="network signet"><app-svg-images name="signet" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Signet</span>
 | 
				
			||||||
      <span *ngSwitchCase="'testnet'" class="network testnet"><app-svg-images name="testnet" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Testnet</span>
 | 
					      <span *ngSwitchCase="'testnet'" class="network testnet"><app-svg-images name="testnet" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Testnet3</span>
 | 
				
			||||||
 | 
					      <span *ngSwitchCase="'testnet4'" class="network testnet"><app-svg-images name="testnet4" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Testnet4</span>
 | 
				
			||||||
      <span *ngSwitchCase="'liquid'" class="network liquid"><app-svg-images name="liquid" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Mainnet</span>
 | 
					      <span *ngSwitchCase="'liquid'" class="network liquid"><app-svg-images name="liquid" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Mainnet</span>
 | 
				
			||||||
      <span *ngSwitchCase="'liquidtestnet'" class="network liquidtestnet"><app-svg-images name="liquidtestnet" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Testnet</span>
 | 
					      <span *ngSwitchCase="'liquidtestnet'" class="network liquidtestnet"><app-svg-images name="liquidtestnet" width="35" height="35" viewBox="0 0 125 125" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Testnet</span>
 | 
				
			||||||
      <span *ngSwitchDefault class="network mainnet"><app-svg-images name="bitcoin" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Mainnet</span>
 | 
					      <span *ngSwitchDefault class="network mainnet"><app-svg-images name="bitcoin" width="35" height="35" viewBox="0 0 65 65" style="width: 40px; height: 48px;" class="mainnet mr-1"></app-svg-images> Mainnet</span>
 | 
				
			||||||
 | 
				
			|||||||
@ -58,14 +58,15 @@
 | 
				
			|||||||
    </ng-container>
 | 
					    </ng-container>
 | 
				
			||||||
  </a>
 | 
					  </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div (window:resize)="onResize()" ngbDropdown class="dropdown-container" *ngIf="env.TESTNET_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED">
 | 
					  <div (window:resize)="onResize()" ngbDropdown class="dropdown-container" *ngIf="env.TESTNET_ENABLED || env.TESTNET4_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED">
 | 
				
			||||||
    <button ngbDropdownToggle type="button" class="btn btn-secondary dropdown-toggle-split d-flex justify-content-center align-items-center" aria-haspopup="true">
 | 
					    <button ngbDropdownToggle type="button" class="btn btn-secondary dropdown-toggle-split d-flex justify-content-center align-items-center" aria-haspopup="true">
 | 
				
			||||||
      <app-svg-images class="d-flex justify-content-center align-items-center current-network-svg" [name]="network.val === '' ? 'bitcoin' : network.val" width="20" height="20" viewBox="0 0 65 65"></app-svg-images>
 | 
					      <app-svg-images class="d-flex justify-content-center align-items-center current-network-svg" [name]="network.val === '' ? 'bitcoin' : network.val" width="20" height="20" viewBox="0 0 65 65"></app-svg-images>
 | 
				
			||||||
    </button>
 | 
					    </button>
 | 
				
			||||||
    <div ngbDropdownMenu [ngClass]="{'dropdown-menu-right' : isMobile}">
 | 
					    <div ngbDropdownMenu [ngClass]="{'dropdown-menu-right' : isMobile}">
 | 
				
			||||||
      <a ngbDropdownItem class="mainnet" [routerLink]="networkPaths['mainnet'] || '/'"><app-svg-images name="bitcoin" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Mainnet</a>
 | 
					      <a ngbDropdownItem class="mainnet" [routerLink]="networkPaths['mainnet'] || '/'"><app-svg-images name="bitcoin" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Mainnet</a>
 | 
				
			||||||
      <a ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet" [class.active]="network.val === 'signet'" [routerLink]="networkPaths['signet'] || '/signet'"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
 | 
					      <a ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet" [class.active]="network.val === 'signet'" [routerLink]="networkPaths['signet'] || '/signet'"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
 | 
				
			||||||
      <a ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet" [class.active]="network.val === 'testnet'" [routerLink]="networkPaths['testnet'] || '/testnet'"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet</a>
 | 
					      <a ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet" [class.active]="network.val === 'testnet'" [routerLink]="networkPaths['testnet'] || '/testnet'"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
 | 
				
			||||||
 | 
					      <a ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet" [class.active]="network.val === 'testnet4'" [routerLink]="networkPaths['testnet4'] || '/testnet4'"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
 | 
				
			||||||
      <h6 *ngIf="env.LIQUID_ENABLED" class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
 | 
					      <h6 *ngIf="env.LIQUID_ENABLED" class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
 | 
				
			||||||
      <a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquid'] || '')" ngbDropdownItem *ngIf="env.LIQUID_ENABLED" class="liquid" [class.active]="network.val === 'liquid'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
 | 
					      <a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquid'] || '')" ngbDropdownItem *ngIf="env.LIQUID_ENABLED" class="liquid" [class.active]="network.val === 'liquid'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
 | 
				
			||||||
      <a [href]="env.LIQUID_WEBSITE_URL + urlLanguage  + (networkPaths['liquidtestnet'] || '/testnet')" ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquid'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
 | 
					      <a [href]="env.LIQUID_WEBSITE_URL + urlLanguage  + (networkPaths['liquidtestnet'] || '/testnet')" ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquid'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
 | 
				
			||||||
@ -114,7 +115,7 @@
 | 
				
			|||||||
  <div class="empty-sidenav"><!-- empty sidenav needed to push footer down the screen --></div>
 | 
					  <div class="empty-sidenav"><!-- empty sidenav needed to push footer down the screen --></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div class="flex-grow-1 d-flex flex-column">
 | 
					  <div class="flex-grow-1 d-flex flex-column">
 | 
				
			||||||
    <app-testnet-alert *ngIf="network.val === 'testnet' || network.val === 'signet'"></app-testnet-alert>
 | 
					    <app-testnet-alert *ngIf="network.val === 'testnet' || network.val === 'testnet4' || network.val === 'signet'"></app-testnet-alert>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <main style="min-width: 375px; max-width: 100vw">
 | 
					    <main style="min-width: 375px; max-width: 100vw">
 | 
				
			||||||
      <router-outlet></router-outlet>
 | 
					      <router-outlet></router-outlet>
 | 
				
			||||||
 | 
				
			|||||||
@ -179,7 +179,7 @@ export class SearchFormComponent implements OnInit {
 | 
				
			|||||||
          const lightningResults = result[1];
 | 
					          const lightningResults = result[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // Do not show date and timestamp results for liquid
 | 
					          // Do not show date and timestamp results for liquid
 | 
				
			||||||
          const isNetworkBitcoin = this.network === '' || this.network === 'testnet' || this.network === 'signet';
 | 
					          const isNetworkBitcoin = this.network === '' || this.network === 'testnet' || this.network === 'testnet4' || this.network === 'signet';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          const matchesBlockHeight = this.regexBlockheight.test(searchText) && parseInt(searchText) <= this.stateService.latestBlockHeight;
 | 
					          const matchesBlockHeight = this.regexBlockheight.test(searchText) && parseInt(searchText) <= this.stateService.latestBlockHeight;
 | 
				
			||||||
          const matchesDateTime = this.regexDate.test(searchText) && new Date(searchText).toString() !== 'Invalid Date' && new Date(searchText).getTime() <= Date.now() && isNetworkBitcoin;
 | 
					          const matchesDateTime = this.regexDate.test(searchText) && new Date(searchText).toString() !== 'Invalid Date' && new Date(searchText).getTime() <= Date.now() && isNetworkBitcoin;
 | 
				
			||||||
 | 
				
			|||||||
@ -60,6 +60,9 @@
 | 
				
			|||||||
  <ng-container *ngSwitchCase="'testnet'">
 | 
					  <ng-container *ngSwitchCase="'testnet'">
 | 
				
			||||||
    <ng-component *ngTemplateOutlet="bitcoinLogo; context: {$implicit: '#5fd15c', width, height, viewBox}"></ng-component>
 | 
					    <ng-component *ngTemplateOutlet="bitcoinLogo; context: {$implicit: '#5fd15c', width, height, viewBox}"></ng-component>
 | 
				
			||||||
  </ng-container>
 | 
					  </ng-container>
 | 
				
			||||||
 | 
					  <ng-container *ngSwitchCase="'testnet4'">
 | 
				
			||||||
 | 
					    <ng-component *ngTemplateOutlet="bitcoinLogo; context: {$implicit: '#5fd15c', width, height, viewBox}"></ng-component>
 | 
				
			||||||
 | 
					  </ng-container>
 | 
				
			||||||
  <ng-container *ngSwitchCase="'liquid'">
 | 
					  <ng-container *ngSwitchCase="'liquid'">
 | 
				
			||||||
    <ng-component *ngTemplateOutlet="liquidLogo; context: {$implicit: '', width, height, viewBox, color1: '#2cccbf', color2: '#9ef2ed'}"></ng-component>
 | 
					    <ng-component *ngTemplateOutlet="liquidLogo; context: {$implicit: '', width, height, viewBox, color1: '#2cccbf', color2: '#9ef2ed'}"></ng-component>
 | 
				
			||||||
  </ng-container>
 | 
					  </ng-container>
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,8 @@
 | 
				
			|||||||
          <app-svg-images name="officialMempoolSpace" style="width: 144px; height: 36px" width="500" height="126" viewBox="0 0 500 126"></app-svg-images>
 | 
					          <app-svg-images name="officialMempoolSpace" style="width: 144px; height: 36px" width="500" height="126" viewBox="0 0 500 126"></app-svg-images>
 | 
				
			||||||
          <div [ngSwitch]="network" class="network-label">
 | 
					          <div [ngSwitch]="network" class="network-label">
 | 
				
			||||||
            <span *ngSwitchCase="'signet'" class="network signet"><span class="name">Bitcoin Signet</span><app-svg-images name="signet" width="35" height="35" viewBox="0 0 65 65" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
					            <span *ngSwitchCase="'signet'" class="network signet"><span class="name">Bitcoin Signet</span><app-svg-images name="signet" width="35" height="35" viewBox="0 0 65 65" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
				
			||||||
            <span *ngSwitchCase="'testnet'" class="network testnet"><span class="name">Bitcoin Testnet</span><app-svg-images name="testnet" width="35" height="35" viewBox="0 0 65 65" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
					            <span *ngSwitchCase="'testnet'" class="network testnet"><span class="name">Bitcoin Testnet3</span><app-svg-images name="testnet" width="35" height="35" viewBox="0 0 65 65" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
				
			||||||
 | 
					            <span *ngSwitchCase="'testnet4'" class="network testnet"><span class="name">Bitcoin Testnet4</span><app-svg-images name="testnet4" width="35" height="35" viewBox="0 0 65 65" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
				
			||||||
            <span *ngSwitchCase="'liquid'" class="network liquid"><span class="name">Liquid</span><app-svg-images name="liquid" width="35" height="35" viewBox="0 0 125 125" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
					            <span *ngSwitchCase="'liquid'" class="network liquid"><span class="name">Liquid</span><app-svg-images name="liquid" width="35" height="35" viewBox="0 0 125 125" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
				
			||||||
            <span *ngSwitchCase="'liquidtestnet'" class="network liquidtestnet"><span class="name">Liquid Testnet</span><app-svg-images name="liquidtestnet" width="35" height="35" viewBox="0 0 125 125" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
					            <span *ngSwitchCase="'liquidtestnet'" class="network liquidtestnet"><span class="name">Liquid Testnet</span><app-svg-images name="liquidtestnet" width="35" height="35" viewBox="0 0 125 125" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
				
			||||||
            <span *ngSwitchDefault class="network mainnet"><span class="name">Bitcoin</span><app-svg-images name="bitcoin" width="35" height="35" viewBox="0 0 65 65" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
					            <span *ngSwitchDefault class="network mainnet"><span class="name">Bitcoin</span><app-svg-images name="bitcoin" width="35" height="35" viewBox="0 0 65 65" style="display: inline-block" class="mainnet ml-2"></app-svg-images></span>
 | 
				
			||||||
 | 
				
			|||||||
@ -91,6 +91,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
				
			|||||||
    'liquidtestnet': ['#d2d2d2', '#979797', '#d2d2d200'],
 | 
					    'liquidtestnet': ['#d2d2d2', '#979797', '#d2d2d200'],
 | 
				
			||||||
    // testnet: ['#1d486f', '#183550'],
 | 
					    // testnet: ['#1d486f', '#183550'],
 | 
				
			||||||
    testnet: ['#4edf77', '#10a0af', '#4edf7700'],
 | 
					    testnet: ['#4edf77', '#10a0af', '#4edf7700'],
 | 
				
			||||||
 | 
					    testnet4: ['#4edf77', '#10a0af', '#4edf7700'],
 | 
				
			||||||
    // signet: ['#6f1d5d', '#471850'],
 | 
					    // signet: ['#6f1d5d', '#471850'],
 | 
				
			||||||
    signet: ['#d24fc8', '#a84fd2', '#d24fc800'],
 | 
					    signet: ['#d24fc8', '#a84fd2', '#d24fc800'],
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
				
			|||||||
@ -41,6 +41,7 @@ export class EnterpriseService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  disableSubnetworks(): void {
 | 
					  disableSubnetworks(): void {
 | 
				
			||||||
    this.stateService.env.TESTNET_ENABLED = false;
 | 
					    this.stateService.env.TESTNET_ENABLED = false;
 | 
				
			||||||
 | 
					    this.stateService.env.TESTNET4_ENABLED = false;
 | 
				
			||||||
    this.stateService.env.LIQUID_ENABLED = false;
 | 
					    this.stateService.env.LIQUID_ENABLED = false;
 | 
				
			||||||
    this.stateService.env.LIQUID_TESTNET_ENABLED = false;
 | 
					    this.stateService.env.LIQUID_TESTNET_ENABLED = false;
 | 
				
			||||||
    this.stateService.env.SIGNET_ENABLED = false;
 | 
					    this.stateService.env.SIGNET_ENABLED = false;
 | 
				
			||||||
 | 
				
			|||||||
@ -58,7 +58,7 @@ export class MiningService {
 | 
				
			|||||||
    // I think it's fine to hardcode this since we don't have x1000 hashrate jump everyday
 | 
					    // I think it's fine to hardcode this since we don't have x1000 hashrate jump everyday
 | 
				
			||||||
    // If we want to support the mining dashboard for testnet, we can hardcode it too
 | 
					    // If we want to support the mining dashboard for testnet, we can hardcode it too
 | 
				
			||||||
    let selectedPower = 18;
 | 
					    let selectedPower = 18;
 | 
				
			||||||
    if (this.stateService.network === 'testnet') {
 | 
					    if (this.stateService.network === 'testnet' || this.stateService.network === 'testnet4') {
 | 
				
			||||||
      selectedPower = 12;
 | 
					      selectedPower = 12;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ const networkModules = {
 | 
				
			|||||||
    subnets: [
 | 
					    subnets: [
 | 
				
			||||||
      { name: 'mainnet', path: '' },
 | 
					      { name: 'mainnet', path: '' },
 | 
				
			||||||
      { name: 'testnet', path: '/testnet' },
 | 
					      { name: 'testnet', path: '/testnet' },
 | 
				
			||||||
 | 
					      { name: 'testnet4', path: '/testnet4' },
 | 
				
			||||||
      { name: 'signet', path: '/signet' },
 | 
					      { name: 'signet', path: '/signet' },
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@ -68,7 +69,7 @@ export class NavigationService {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      if (route.url?.length) {
 | 
					      if (route.url?.length) {
 | 
				
			||||||
        path = [path, ...route.url.map(segment => segment.path).filter(path => {
 | 
					        path = [path, ...route.url.map(segment => segment.path).filter(path => {
 | 
				
			||||||
          return path.length && !['testnet', 'signet'].includes(path);
 | 
					          return path.length && !['testnet', 'testnet4', 'signet'].includes(path);
 | 
				
			||||||
        })].join('/');
 | 
					        })].join('/');
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      route = route.firstChild;
 | 
					      route = route.firstChild;
 | 
				
			||||||
 | 
				
			|||||||
@ -81,7 +81,9 @@ export class SeoService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  getTitle(): string {
 | 
					  getTitle(): string {
 | 
				
			||||||
    if (this.network === 'testnet')
 | 
					    if (this.network === 'testnet')
 | 
				
			||||||
      return this.baseTitle + ' - Bitcoin Testnet';
 | 
					      return this.baseTitle + ' - Bitcoin Testnet3';
 | 
				
			||||||
 | 
					    if (this.network === 'testnet4')
 | 
				
			||||||
 | 
					      return this.baseTitle + ' - Bitcoin Testnet4';
 | 
				
			||||||
    if (this.network === 'signet')
 | 
					    if (this.network === 'signet')
 | 
				
			||||||
      return this.baseTitle + ' - Bitcoin Signet';
 | 
					      return this.baseTitle + ' - Bitcoin Signet';
 | 
				
			||||||
    if (this.network === 'liquid')
 | 
					    if (this.network === 'liquid')
 | 
				
			||||||
@ -92,7 +94,7 @@ export class SeoService {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getDescription(): string {
 | 
					  getDescription(): string {
 | 
				
			||||||
    if ( (this.network === 'testnet') || (this.network === 'signet') || (this.network === '') || (this.network == 'mainnet') )
 | 
					    if ( (this.network === 'testnet') || (this.network === 'testnet4') || (this.network === 'signet') || (this.network === '') || (this.network == 'mainnet') )
 | 
				
			||||||
      return this.baseDescription + ' See the real-time status of your transactions, browse network stats, and more.';
 | 
					      return this.baseDescription + ' See the real-time status of your transactions, browse network stats, and more.';
 | 
				
			||||||
    if ( (this.network === 'liquid') || (this.network === 'liquidtestnet') )
 | 
					    if ( (this.network === 'liquid') || (this.network === 'liquidtestnet') )
 | 
				
			||||||
      return this.baseDescription + ' See Liquid transactions & assets, get network info, and more.';
 | 
					      return this.baseDescription + ' See Liquid transactions & assets, get network info, and more.';
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,7 @@ export interface Customization {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export interface Env {
 | 
					export interface Env {
 | 
				
			||||||
  TESTNET_ENABLED: boolean;
 | 
					  TESTNET_ENABLED: boolean;
 | 
				
			||||||
 | 
					  TESTNET4_ENABLED: boolean;
 | 
				
			||||||
  SIGNET_ENABLED: boolean;
 | 
					  SIGNET_ENABLED: boolean;
 | 
				
			||||||
  LIQUID_ENABLED: boolean;
 | 
					  LIQUID_ENABLED: boolean;
 | 
				
			||||||
  LIQUID_TESTNET_ENABLED: boolean;
 | 
					  LIQUID_TESTNET_ENABLED: boolean;
 | 
				
			||||||
@ -73,6 +74,7 @@ export interface Env {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const defaultEnv: Env = {
 | 
					const defaultEnv: Env = {
 | 
				
			||||||
  'TESTNET_ENABLED': false,
 | 
					  'TESTNET_ENABLED': false,
 | 
				
			||||||
 | 
					  'TESTNET4_ENABLED': false,
 | 
				
			||||||
  'SIGNET_ENABLED': false,
 | 
					  'SIGNET_ENABLED': false,
 | 
				
			||||||
  'LIQUID_ENABLED': false,
 | 
					  'LIQUID_ENABLED': false,
 | 
				
			||||||
  'LIQUID_TESTNET_ENABLED': false,
 | 
					  'LIQUID_TESTNET_ENABLED': false,
 | 
				
			||||||
@ -298,7 +300,7 @@ export class StateService {
 | 
				
			|||||||
    // (?:preview\/)?                               optional "preview" prefix (non-capturing)
 | 
					    // (?:preview\/)?                               optional "preview" prefix (non-capturing)
 | 
				
			||||||
    // (testnet|signet)/                            network string (captured as networkMatches[1])
 | 
					    // (testnet|signet)/                            network string (captured as networkMatches[1])
 | 
				
			||||||
    // ($|\/)                                       network string must end or end with a slash
 | 
					    // ($|\/)                                       network string must end or end with a slash
 | 
				
			||||||
    const networkMatches = url.match(/^\/(?:[a-z]{2}(?:-[A-Z]{2})?\/)?(?:preview\/)?(testnet|signet)($|\/)/);
 | 
					    const networkMatches = url.match(/^\/(?:[a-z]{2}(?:-[A-Z]{2})?\/)?(?:preview\/)?(testnet4?|signet)($|\/)/);
 | 
				
			||||||
    switch (networkMatches && networkMatches[1]) {
 | 
					    switch (networkMatches && networkMatches[1]) {
 | 
				
			||||||
      case 'signet':
 | 
					      case 'signet':
 | 
				
			||||||
        if (this.network !== 'signet') {
 | 
					        if (this.network !== 'signet') {
 | 
				
			||||||
@ -317,6 +319,12 @@ export class StateService {
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					      case 'testnet4':
 | 
				
			||||||
 | 
					        if (this.network !== 'testnet4') {
 | 
				
			||||||
 | 
					          this.network = 'testnet4';
 | 
				
			||||||
 | 
					          this.networkChanged$.next('testnet4');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
      default:
 | 
					      default:
 | 
				
			||||||
        if (this.env.BASE_MODULE !== 'mempool') {
 | 
					        if (this.env.BASE_MODULE !== 'mempool') {
 | 
				
			||||||
          if (this.network !== this.env.BASE_MODULE) {
 | 
					          if (this.network !== this.env.BASE_MODULE) {
 | 
				
			||||||
@ -365,7 +373,7 @@ export class StateService {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isAnyTestnet(): boolean {
 | 
					  isAnyTestnet(): boolean {
 | 
				
			||||||
    return ['testnet', 'signet', 'liquidtestnet'].includes(this.network);
 | 
					    return ['testnet', 'testnet4', 'signet', 'liquidtestnet'].includes(this.network);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resetChainTip() {
 | 
					  resetChainTip() {
 | 
				
			||||||
 | 
				
			|||||||
@ -151,7 +151,7 @@ export function nextRoundNumber(num: number): number {
 | 
				
			|||||||
export function seoDescriptionNetwork(network: string): string {
 | 
					export function seoDescriptionNetwork(network: string): string {
 | 
				
			||||||
  if( network === 'liquidtestnet' || network === 'testnet' ) {
 | 
					  if( network === 'liquidtestnet' || network === 'testnet' ) {
 | 
				
			||||||
    return ' Testnet';
 | 
					    return ' Testnet';
 | 
				
			||||||
  } else if( network === 'signet' || network === 'testnet' ) {
 | 
					  } else if( network === 'signet' || network === 'testnet' || network === 'testnet4') {
 | 
				
			||||||
    return ' ' + network.charAt(0).toUpperCase() + network.slice(1);
 | 
					    return ' ' + network.charAt(0).toUpperCase() + network.slice(1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return '';
 | 
					  return '';
 | 
				
			||||||
 | 
				
			|||||||
@ -4,5 +4,6 @@
 | 
				
			|||||||
  <ng-template [ngIf]="network === 'liquid'">L-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'liquid'">L-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'testnet'">t-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'testnet'">t-</ng-template>
 | 
				
			||||||
 | 
					  <ng-template [ngIf]="network === 'testnet4'">t-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'signet'">s-</ng-template>{{ unit }}
 | 
					  <ng-template [ngIf]="network === 'signet'">s-</ng-template>{{ unit }}
 | 
				
			||||||
</span>
 | 
					</span>
 | 
				
			||||||
@ -62,10 +62,11 @@
 | 
				
			|||||||
          <p><a [routerLink]="['/docs/faq' | relativeUrl]" i18n="faq.more-faq">More FAQs »</a></p>
 | 
					          <p><a [routerLink]="['/docs/faq' | relativeUrl]" i18n="faq.more-faq">More FAQs »</a></p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="links" *ngIf="officialMempoolSpace || env.TESTNET_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED else toolBox" >
 | 
					        <div class="links" *ngIf="officialMempoolSpace || env.TESTNET_ENABLED || env.TESTNET4_ENABLED || env.SIGNET_ENABLED || env.LIQUID_ENABLED || env.LIQUID_TESTNET_ENABLED else toolBox" >
 | 
				
			||||||
          <p class="category" i18n="footer.networks">Networks</p>
 | 
					          <p class="category" i18n="footer.networks">Networks</p>
 | 
				
			||||||
          <p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== '') && (currentNetwork !== 'mainnet')"><a [href]="networkLink('mainnet')" i18n="footer.mainnet-explorer">Mainnet Explorer</a></p>
 | 
					          <p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== '') && (currentNetwork !== 'mainnet')"><a [href]="networkLink('mainnet')" i18n="footer.mainnet-explorer">Mainnet Explorer</a></p>
 | 
				
			||||||
          <p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet') && env.TESTNET_ENABLED"><a [href]="networkLink('testnet')" i18n="footer.testnet-explorer">Testnet Explorer</a></p>
 | 
					          <p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet') && env.TESTNET_ENABLED"><a [href]="networkLink('testnet')" i18n="footer.testnet3-explorer">Testnet3 Explorer</a></p>
 | 
				
			||||||
 | 
					          <p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet4') && env.TESTNET4_ENABLED"><a [href]="networkLink('testnet4')" i18n="footer.testnet4-explorer">Testnet4 Explorer</a></p>
 | 
				
			||||||
          <p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'signet') && env.SIGNET_ENABLED"><a [href]="networkLink('signet')" i18n="footer.signet-explorer">Signet Explorer</a></p>
 | 
					          <p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'signet') && env.SIGNET_ENABLED"><a [href]="networkLink('signet')" i18n="footer.signet-explorer">Signet Explorer</a></p>
 | 
				
			||||||
          <p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquidtestnet')"><a [href]="networkLink('liquidtestnet')" i18n="footer.liquid-testnet-explorer">Liquid Testnet Explorer</a></p>
 | 
					          <p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquidtestnet')"><a [href]="networkLink('liquidtestnet')" i18n="footer.liquid-testnet-explorer">Liquid Testnet Explorer</a></p>
 | 
				
			||||||
          <p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquid')"><a [href]="networkLink('liquid')" i18n="footer.liquid-explorer">Liquid Explorer</a></p>
 | 
					          <p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquid')"><a [href]="networkLink('liquid')" i18n="footer.liquid-explorer">Liquid Explorer</a></p>
 | 
				
			||||||
 | 
				
			|||||||
@ -76,7 +76,7 @@ export class GlobalFooterComponent implements OnInit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  networkLink(network) {
 | 
					  networkLink(network) {
 | 
				
			||||||
    const thisNetwork = network || 'mainnet';
 | 
					    const thisNetwork = network || 'mainnet';
 | 
				
			||||||
    if( network === '' || network === 'mainnet' || network === 'testnet' || network === 'signet' ) {
 | 
					    if( network === '' || network === 'mainnet' || network === 'testnet' || network === 'testnet4' || network === 'signet' ) {
 | 
				
			||||||
      return (this.env.BASE_MODULE === 'mempool' ? '' : this.env.MEMPOOL_WEBSITE_URL + this.urlLanguage) + this.networkPaths[thisNetwork] || '/';
 | 
					      return (this.env.BASE_MODULE === 'mempool' ? '' : this.env.MEMPOOL_WEBSITE_URL + this.urlLanguage) + this.networkPaths[thisNetwork] || '/';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if( network === 'liquid' || network === 'liquidtestnet' ) {
 | 
					    if( network === 'liquid' || network === 'liquidtestnet' ) {
 | 
				
			||||||
 | 
				
			|||||||
@ -4,5 +4,6 @@
 | 
				
			|||||||
  <ng-template [ngIf]="network === 'liquid'">L-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'liquid'">L-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'liquidtestnet'">tL-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'testnet'">t-</ng-template>
 | 
					  <ng-template [ngIf]="network === 'testnet'">t-</ng-template>
 | 
				
			||||||
 | 
					  <ng-template [ngIf]="network === 'testnet4'">t-</ng-template>
 | 
				
			||||||
  <ng-template [ngIf]="network === 'signet'">s-</ng-template>sats
 | 
					  <ng-template [ngIf]="network === 'signet'">s-</ng-template>sats
 | 
				
			||||||
</span>
 | 
					</span>
 | 
				
			||||||
@ -62,6 +62,20 @@ const ADDRESS_CHARS: {
 | 
				
			|||||||
        + `{20,100}`
 | 
					        + `{20,100}`
 | 
				
			||||||
      + `)`,
 | 
					      + `)`,
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  testnet4: {
 | 
				
			||||||
 | 
					    base58: `[mn2]` // Starts with a single m, n, or 2 (P2PKH is m or n, 2 is P2SH)
 | 
				
			||||||
 | 
					      + BASE58_CHARS
 | 
				
			||||||
 | 
					      + `{33,34}`, // m|n is 34 length, 2 is 35 length (We match the first letter separately)
 | 
				
			||||||
 | 
					    bech32: `(?:`
 | 
				
			||||||
 | 
					        + `tb1` // Starts with tb1
 | 
				
			||||||
 | 
					        + BECH32_CHARS_LW
 | 
				
			||||||
 | 
					        + `{20,100}` // As per bech32, 6 char checksum is minimum
 | 
				
			||||||
 | 
					      + `|`
 | 
				
			||||||
 | 
					        + `TB1` // All upper case version
 | 
				
			||||||
 | 
					        + BECH32_CHARS_UP
 | 
				
			||||||
 | 
					        + `{20,100}`
 | 
				
			||||||
 | 
					      + `)`,
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  signet: {
 | 
					  signet: {
 | 
				
			||||||
    base58: `[mn2]`
 | 
					    base58: `[mn2]`
 | 
				
			||||||
      + BASE58_CHARS
 | 
					      + BASE58_CHARS
 | 
				
			||||||
@ -128,7 +142,7 @@ const ADDRESS_CHARS: {
 | 
				
			|||||||
type RegexTypeNoAddrNoBlockHash = | `transaction` | `blockheight` | `date` | `timestamp`;
 | 
					type RegexTypeNoAddrNoBlockHash = | `transaction` | `blockheight` | `date` | `timestamp`;
 | 
				
			||||||
export type RegexType = `address` | `blockhash` | RegexTypeNoAddrNoBlockHash;
 | 
					export type RegexType = `address` | `blockhash` | RegexTypeNoAddrNoBlockHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const NETWORKS = [`testnet`, `signet`, `liquid`, `liquidtestnet`, `mainnet`] as const;
 | 
					export const NETWORKS = [`testnet`, `testnet4`, `signet`, `liquid`, `liquidtestnet`, `mainnet`] as const;
 | 
				
			||||||
export type Network = typeof NETWORKS[number]; // Turn const array into union type
 | 
					export type Network = typeof NETWORKS[number]; // Turn const array into union type
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ADDRESS_REGEXES: [RegExp, Network][] = NETWORKS
 | 
					export const ADDRESS_REGEXES: [RegExp, Network][] = NETWORKS
 | 
				
			||||||
@ -144,6 +158,8 @@ function isNetworkAvailable(network: Network, env: Env): boolean {
 | 
				
			|||||||
  switch (network) {
 | 
					  switch (network) {
 | 
				
			||||||
    case 'testnet':
 | 
					    case 'testnet':
 | 
				
			||||||
      return env.TESTNET_ENABLED === true;
 | 
					      return env.TESTNET_ENABLED === true;
 | 
				
			||||||
 | 
					    case 'testnet4':
 | 
				
			||||||
 | 
					      return env.TESTNET4_ENABLED === true;
 | 
				
			||||||
    case 'signet':
 | 
					    case 'signet':
 | 
				
			||||||
      return env.SIGNET_ENABLED === true;
 | 
					      return env.SIGNET_ENABLED === true;
 | 
				
			||||||
    case 'liquid':
 | 
					    case 'liquid':
 | 
				
			||||||
@ -160,7 +176,7 @@ function isNetworkAvailable(network: Network, env: Env): boolean {
 | 
				
			|||||||
export function needBaseModuleChange(fromBaseModule: 'mempool' | 'liquid', toNetwork: Network): boolean {
 | 
					export function needBaseModuleChange(fromBaseModule: 'mempool' | 'liquid', toNetwork: Network): boolean {
 | 
				
			||||||
  if (!toNetwork) return false; // No target network means no change needed
 | 
					  if (!toNetwork) return false; // No target network means no change needed
 | 
				
			||||||
  if (fromBaseModule === 'mempool') {
 | 
					  if (fromBaseModule === 'mempool') {
 | 
				
			||||||
    return toNetwork !== 'mainnet' && toNetwork !== 'testnet' && toNetwork !== 'signet';
 | 
					    return toNetwork !== 'mainnet' && toNetwork !== 'testnet' && toNetwork !== 'testnet4' && toNetwork !== 'signet';
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (fromBaseModule === 'liquid') {
 | 
					  if (fromBaseModule === 'liquid') {
 | 
				
			||||||
    return toNetwork !== 'liquid' && toNetwork !== 'liquidtestnet';
 | 
					    return toNetwork !== 'liquid' && toNetwork !== 'liquidtestnet';
 | 
				
			||||||
@ -175,7 +191,7 @@ export function getTargetUrl(toNetwork: Network, address: string, env: Env): str
 | 
				
			|||||||
    targetUrl += '/address/';
 | 
					    targetUrl += '/address/';
 | 
				
			||||||
    targetUrl += address;
 | 
					    targetUrl += address;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (toNetwork === 'mainnet' || toNetwork === 'testnet' || toNetwork === 'signet') {
 | 
					  if (toNetwork === 'mainnet' || toNetwork === 'testnet' || toNetwork === 'testnet4' || toNetwork === 'signet') {
 | 
				
			||||||
    targetUrl = env.MEMPOOL_WEBSITE_URL;
 | 
					    targetUrl = env.MEMPOOL_WEBSITE_URL;
 | 
				
			||||||
    targetUrl += (toNetwork === 'mainnet' ? '' : `/${toNetwork}`);
 | 
					    targetUrl += (toNetwork === 'mainnet' ? '' : `/${toNetwork}`);
 | 
				
			||||||
    targetUrl += '/address/';
 | 
					    targetUrl += '/address/';
 | 
				
			||||||
@ -209,6 +225,9 @@ export function getRegex(type: RegexType, network?: Network): RegExp {
 | 
				
			|||||||
        case `testnet`:
 | 
					        case `testnet`:
 | 
				
			||||||
          leadingZeroes = 8; // Assumes at least 32 bits of difficulty
 | 
					          leadingZeroes = 8; // Assumes at least 32 bits of difficulty
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
 | 
					        case `testnet4`:
 | 
				
			||||||
 | 
					          leadingZeroes = 8; // Assumes at least 32 bits of difficulty
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
        case `signet`:
 | 
					        case `signet`:
 | 
				
			||||||
          leadingZeroes = 5;
 | 
					          leadingZeroes = 5;
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
@ -261,6 +280,15 @@ export function getRegex(type: RegexType, network?: Network): RegExp {
 | 
				
			|||||||
          regex += `|`; // OR
 | 
					          regex += `|`; // OR
 | 
				
			||||||
          regex += `(?:02|03)${HEX_CHARS}{64}`; // Compressed pubkey
 | 
					          regex += `(?:02|03)${HEX_CHARS}{64}`; // Compressed pubkey
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
 | 
					        case `testnet4`:
 | 
				
			||||||
 | 
					          regex += ADDRESS_CHARS.testnet.base58;
 | 
				
			||||||
 | 
					          regex += `|`; // OR
 | 
				
			||||||
 | 
					          regex += ADDRESS_CHARS.testnet.bech32;
 | 
				
			||||||
 | 
					          regex += `|`; // OR
 | 
				
			||||||
 | 
					          regex += `04${HEX_CHARS}{128}`; // Uncompressed pubkey
 | 
				
			||||||
 | 
					          regex += `|`; // OR
 | 
				
			||||||
 | 
					          regex += `(?:02|03)${HEX_CHARS}{64}`; // Compressed pubkey
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
        case `signet`:
 | 
					        case `signet`:
 | 
				
			||||||
          regex += ADDRESS_CHARS.signet.base58;
 | 
					          regex += ADDRESS_CHARS.signet.base58;
 | 
				
			||||||
          regex += `|`; // OR
 | 
					          regex += `|`; // OR
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user