Transaction view.
This commit is contained in:
		
							parent
							
								
									02d67e8406
								
							
						
					
					
						commit
						bd2bd478ef
					
				@ -268,6 +268,7 @@ class MempoolSpace {
 | 
			
		||||
      this.app
 | 
			
		||||
        .get(config.API_ENDPOINT + 'explorer/blocks', routes.getBlocks)
 | 
			
		||||
        .get(config.API_ENDPOINT + 'explorer/blocks/:height', routes.getBlocks)
 | 
			
		||||
        .get(config.API_ENDPOINT + 'explorer/tx/:id', routes.getRawTransaction)
 | 
			
		||||
        ;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -90,6 +90,15 @@ class Routes {
 | 
			
		||||
      res.status(500).send(e.message);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async getRawTransaction(req, res) {
 | 
			
		||||
    try {
 | 
			
		||||
      const result = await bitcoinApi.getRawTransaction(req.params.id);
 | 
			
		||||
      res.send(result);
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      res.status(500).send(e.message);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new Routes();
 | 
			
		||||
 | 
			
		||||
@ -48,6 +48,23 @@
 | 
			
		||||
              "extractLicenses": true,
 | 
			
		||||
              "vendorChunk": false,
 | 
			
		||||
              "buildOptimizer": true
 | 
			
		||||
            },
 | 
			
		||||
            "esplora": {
 | 
			
		||||
              "fileReplacements": [
 | 
			
		||||
                {
 | 
			
		||||
                  "replace": "src/environments/environment.ts",
 | 
			
		||||
                  "with": "src/environments/environment-esplora.prod.ts"
 | 
			
		||||
                }
 | 
			
		||||
              ],
 | 
			
		||||
              "optimization": true,
 | 
			
		||||
              "outputHashing": "all",
 | 
			
		||||
              "sourceMap": false,
 | 
			
		||||
              "extractCss": true,
 | 
			
		||||
              "namedChunks": false,
 | 
			
		||||
              "aot": true,
 | 
			
		||||
              "extractLicenses": true,
 | 
			
		||||
              "vendorChunk": false,
 | 
			
		||||
              "buildOptimizer": true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,8 @@
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "ng": "ng",
 | 
			
		||||
    "start": "ng serve --aot --proxy-config proxy.conf.json",
 | 
			
		||||
    "build": "ng build --prod --vendorChunk=false --build-optimizer=true",
 | 
			
		||||
    "build": "ng build --prod",
 | 
			
		||||
    "build-esplora": "ng build --prod --configuration=esplora",
 | 
			
		||||
    "test": "ng test",
 | 
			
		||||
    "lint": "ng lint",
 | 
			
		||||
    "e2e": "ng e2e"
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1 @@
 | 
			
		||||
.yellow-color { 
 | 
			
		||||
  color: #ffd800;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.green-color {
 | 
			
		||||
  color: #3bcc49;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,8 @@
 | 
			
		||||
  <div *ngFor="let block of blocks; let i = index; trackBy: trackByBlocksFn" >
 | 
			
		||||
    <div (click)="openBlockModal(block);" class="text-center bitcoin-block mined-block" id="bitcoin-block-{{ block.height }}" [ngStyle]="getStyleForBlock(block)">
 | 
			
		||||
      <div class="block-height">
 | 
			
		||||
        <a href="https://www.blockstream.info/block-height/{{ block.height }}" target="_blank">#{{ block.height }}</a>
 | 
			
		||||
        <a *ngIf="!isEsploraEnabled" href="https://www.blockstream.info/block-height/{{ block.height }}" target="_blank">#{{ block.height }}</a>
 | 
			
		||||
        <a *ngIf="isEsploraEnabled" [routerLink]="['/explorer/block/', block.hash]">#{{ block.height }}</a>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="block-body">
 | 
			
		||||
        <div class="fees">
 | 
			
		||||
@ -13,7 +14,7 @@
 | 
			
		||||
        <div class="block-size">{{ block.size | bytes: 2 }}</div>
 | 
			
		||||
        <div class="transaction-count">{{ block.nTx }} transactions</div>
 | 
			
		||||
        <br /><br />
 | 
			
		||||
        <div class="time-difference">{{ block.time | timeSince }} ago</div>
 | 
			
		||||
        <div class="time-difference">{{ block.time | timeSince : trigger }} ago</div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
@ -39,10 +39,6 @@
 | 
			
		||||
  margin-bottom: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yellow-color { 
 | 
			
		||||
  color: #ffd800;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.transaction-count {
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,6 +4,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
 | 
			
		||||
import { BlockModalComponent } from './block-modal/block-modal.component';
 | 
			
		||||
import { MemPoolService } from '../services/mem-pool.service';
 | 
			
		||||
import { Subscription } from 'rxjs';
 | 
			
		||||
import { environment } from '../../environments/environment';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-blockchain-blocks',
 | 
			
		||||
@ -13,6 +14,9 @@ import { Subscription } from 'rxjs';
 | 
			
		||||
export class BlockchainBlocksComponent implements OnInit, OnDestroy {
 | 
			
		||||
  blocks: IBlock[] = [];
 | 
			
		||||
  blocksSubscription: Subscription;
 | 
			
		||||
  interval: any;
 | 
			
		||||
  trigger = 0;
 | 
			
		||||
  isEsploraEnabled = !!environment.esplora;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private modalService: NgbModal,
 | 
			
		||||
@ -28,10 +32,13 @@ export class BlockchainBlocksComponent implements OnInit, OnDestroy {
 | 
			
		||||
        this.blocks.unshift(block);
 | 
			
		||||
        this.blocks = this.blocks.slice(0, 8);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    this.interval = setInterval(() => this.trigger++, 10 * 1000);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnDestroy() {
 | 
			
		||||
    this.blocksSubscription.unsubscribe();
 | 
			
		||||
    clearInterval(this.interval);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  trackByBlocksFn(index: number, item: IBlock) {
 | 
			
		||||
 | 
			
		||||
@ -49,10 +49,6 @@
 | 
			
		||||
  margin-bottom: 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yellow-color { 
 | 
			
		||||
  color: #ffd800;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.transaction-count {
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,7 +0,0 @@
 | 
			
		||||
.yellow-color { 
 | 
			
		||||
  color: #ffd800;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.green-color {
 | 
			
		||||
  color: #3bcc49;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								frontend/src/app/explorer/address/address.component.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								frontend/src/app/explorer/address/address.component.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
<p>address works!</p>
 | 
			
		||||
							
								
								
									
										15
									
								
								frontend/src/app/explorer/address/address.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								frontend/src/app/explorer/address/address.component.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
			
		||||
import { Component, OnInit } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-address',
 | 
			
		||||
  templateUrl: './address.component.html',
 | 
			
		||||
  styleUrls: ['./address.component.scss']
 | 
			
		||||
})
 | 
			
		||||
export class AddressComponent implements OnInit {
 | 
			
		||||
 | 
			
		||||
  constructor() { }
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -5,6 +5,7 @@ import { TransactionComponent } from './transaction/transaction.component';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { SharedModule } from '../shared/shared.module';
 | 
			
		||||
import { BlockComponent } from './block/block.component';
 | 
			
		||||
import { AddressComponent } from './address/address.component';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
  {
 | 
			
		||||
@ -19,10 +20,14 @@ const routes: Routes = [
 | 
			
		||||
    path: 'tx/:id',
 | 
			
		||||
    component: TransactionComponent,
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    path: 'address/:id',
 | 
			
		||||
    component: AddressComponent,
 | 
			
		||||
  },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
  declarations: [ExplorerComponent, TransactionComponent, BlockComponent],
 | 
			
		||||
  declarations: [ExplorerComponent, TransactionComponent, BlockComponent, AddressComponent],
 | 
			
		||||
  imports: [
 | 
			
		||||
    SharedModule,
 | 
			
		||||
    CommonModule,
 | 
			
		||||
 | 
			
		||||
@ -1 +1,143 @@
 | 
			
		||||
<p>transaction works!</p>
 | 
			
		||||
<div class="container">
 | 
			
		||||
  <h1>Transaction</h1>
 | 
			
		||||
 | 
			
		||||
  <ng-template [ngIf]="!isLoadingTx" [ngIfElse]="loadingTx">
 | 
			
		||||
 | 
			
		||||
    <table class="table table-borderless">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <tr class="header-bg">
 | 
			
		||||
          <th>
 | 
			
		||||
            {{ tx.txid }}
 | 
			
		||||
          </th>
 | 
			
		||||
        </tr>
 | 
			
		||||
      </thead>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
    <div class="row">
 | 
			
		||||
        <div class="col">
 | 
			
		||||
 | 
			
		||||
          <table class="table table-borderless smaller-text">
 | 
			
		||||
            <tbody>
 | 
			
		||||
              <tr>
 | 
			
		||||
                <td>
 | 
			
		||||
                  <div *ngFor="let vin of tx.vin">
 | 
			
		||||
                    <ng-template [ngIf]="vin.is_coinbase" [ngIfElse]="regularVin">
 | 
			
		||||
                      Coinbase
 | 
			
		||||
                    </ng-template>
 | 
			
		||||
                    <ng-template #regularVin>
 | 
			
		||||
                      <a [routerLink]="['/explorer/address/', vin.prevout.scriptpubkey_address]">{{ vin.prevout.scriptpubkey_address }}</a>
 | 
			
		||||
                      (<a [routerLink]="['/explorer/tx/', vin.txid]">tx</a>)
 | 
			
		||||
                    </ng-template>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td class="text-right">
 | 
			
		||||
                  <div *ngFor="let vin of tx.vin">
 | 
			
		||||
                    <ng-template [ngIf]="vin.prevout">
 | 
			
		||||
                      <ng-template [ngIf]="viewFiat" [ngIfElse]="viewFiatVin">
 | 
			
		||||
                        <span class="green-color">{{ conversions.USD * (vin.prevout.value / 100000000) | currency:'USD':'symbol':'1.2-2' }}</span>
 | 
			
		||||
                      </ng-template>
 | 
			
		||||
                      <ng-template #viewFiatVin>
 | 
			
		||||
                        {{ vin.prevout.value / 100000000 }} BTC
 | 
			
		||||
                      </ng-template>
 | 
			
		||||
                    </ng-template>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
            </tbody>
 | 
			
		||||
          </table>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col">
 | 
			
		||||
          <table class="table table-borderless smaller-text">
 | 
			
		||||
            <tbody>
 | 
			
		||||
              <tr>
 | 
			
		||||
              <td>
 | 
			
		||||
                <div *ngFor="let vout of tx.vout">
 | 
			
		||||
                  <a *ngIf="vout.scriptpubkey_address; else scriptpubkey_type" [routerLink]="['/explorer/address/', vout.scriptpubkey_address]">{{ vout.scriptpubkey_address }}</a>
 | 
			
		||||
                  <ng-template #scriptpubkey_type>
 | 
			
		||||
                    {{ vout.scriptpubkey_type | uppercase }}
 | 
			
		||||
                  </ng-template>
 | 
			
		||||
                </div>
 | 
			
		||||
              </td>
 | 
			
		||||
              <td class="text-right">
 | 
			
		||||
                <div *ngFor="let vout of tx.vout">
 | 
			
		||||
                  <ng-template [ngIf]="viewFiat" [ngIfElse]="viewFiatVout">
 | 
			
		||||
                    <span class="green-color">{{ conversions.USD * (vout.value / 100000000) | currency:'USD':'symbol':'1.2-2' }}</span>
 | 
			
		||||
                  </ng-template>
 | 
			
		||||
                  <ng-template #viewFiatVout>
 | 
			
		||||
                    {{ vout.value / 100000000 }} BTC
 | 
			
		||||
                  </ng-template>
 | 
			
		||||
                </div>
 | 
			
		||||
              </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <td class="text-right" colspan="4">
 | 
			
		||||
                <button *ngIf="tx.status.confirmed" type="button" class="btn btn-success">{{ latestBlockHeight - tx.status.block_height + 1 }} confirmations</button>
 | 
			
		||||
                <ng-template #unconfirmedButton>
 | 
			
		||||
                  <button type="button" class="btn btn-danger">Unconfirmed</button>
 | 
			
		||||
                </ng-template>
 | 
			
		||||
                 
 | 
			
		||||
                <button type="button" class="btn btn-primary" (click)="viewFiat = !viewFiat">
 | 
			
		||||
                  <ng-template [ngIf]="viewFiat" [ngIfElse]="viewFiatButton">
 | 
			
		||||
                    <span *ngIf="conversions">{{ conversions.USD * (totalOutput / 100000000) | currency:'USD':'symbol':'1.2-2' }}</span>
 | 
			
		||||
                  </ng-template>
 | 
			
		||||
                  <ng-template #viewFiatButton>
 | 
			
		||||
                    {{ totalOutput / 100000000 }} BTC
 | 
			
		||||
                  </ng-template>
 | 
			
		||||
                </button>
 | 
			
		||||
              </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            </tbody>
 | 
			
		||||
          </table>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
    <h2>Details</h2>
 | 
			
		||||
 | 
			
		||||
    <br>
 | 
			
		||||
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <table class="table table-borderless table-striped">
 | 
			
		||||
          <tbody>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <td>Size</td>
 | 
			
		||||
              <td>{{ tx.size | bytes }}</td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <td>Weight</td>
 | 
			
		||||
              <td>{{ tx.weight }} WU</td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr *ngIf="tx.status.confirmed">
 | 
			
		||||
              <td>Included in block</td>
 | 
			
		||||
              <td><a [routerLink]="['/explorer/block/', tx.status.block_hash]">#{{ tx.status.block_height }}</a></td>
 | 
			
		||||
            </tr>
 | 
			
		||||
          </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="col">
 | 
			
		||||
        <table class="table table-borderless table-striped"  *ngIf="tx.fee">
 | 
			
		||||
          <tbody>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <td>Fees</td>
 | 
			
		||||
              <td>{{ tx.fee }} <span *ngIf="conversions">(<span class="green-color">{{ conversions.USD * tx.fee | currency:'USD':'symbol':'1.2-2' }}</span>)</span></td>
 | 
			
		||||
            </tr>
 | 
			
		||||
            <tr>
 | 
			
		||||
              <td>Fees per vByte</td>
 | 
			
		||||
              <td>{{ (tx.fee * 100000000) / tx.vsize | number : '1.2-2' }} sat/vB</td>
 | 
			
		||||
            </tr>
 | 
			
		||||
          </tbody>
 | 
			
		||||
        </table>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
  </ng-template>
 | 
			
		||||
  <ng-template #loadingTx>
 | 
			
		||||
    <div class="text-center">
 | 
			
		||||
      <div class="spinner-border text-light"></div>
 | 
			
		||||
      <br><br>
 | 
			
		||||
    </div>
 | 
			
		||||
  </ng-template>
 | 
			
		||||
</div>
 | 
			
		||||
  
 | 
			
		||||
@ -1,4 +1,8 @@
 | 
			
		||||
import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import { ApiService } from 'src/app/services/api.service';
 | 
			
		||||
import { ActivatedRoute, ParamMap } from '@angular/router';
 | 
			
		||||
import { switchMap } from 'rxjs/operators';
 | 
			
		||||
import { MemPoolService } from 'src/app/services/mem-pool.service';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-transaction',
 | 
			
		||||
@ -6,10 +10,41 @@ import { Component, OnInit } from '@angular/core';
 | 
			
		||||
  styleUrls: ['./transaction.component.scss']
 | 
			
		||||
})
 | 
			
		||||
export class TransactionComponent implements OnInit {
 | 
			
		||||
  tx: any;
 | 
			
		||||
  isLoadingTx = true;
 | 
			
		||||
  conversions: any;
 | 
			
		||||
  totalOutput: number;
 | 
			
		||||
 | 
			
		||||
  constructor() { }
 | 
			
		||||
  viewFiat = false;
 | 
			
		||||
  latestBlockHeight: number;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private route: ActivatedRoute,
 | 
			
		||||
    private apiService: ApiService,
 | 
			
		||||
    private memPoolService: MemPoolService,
 | 
			
		||||
  ) { }
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
  }
 | 
			
		||||
    this.route.paramMap.pipe(
 | 
			
		||||
      switchMap((params: ParamMap) => {
 | 
			
		||||
        const txId: string = params.get('id') || '';
 | 
			
		||||
        return this.apiService.getTransaction$(txId);
 | 
			
		||||
      })
 | 
			
		||||
    )
 | 
			
		||||
    .subscribe((tx) => {
 | 
			
		||||
      this.tx = tx;
 | 
			
		||||
      this.totalOutput = this.tx.vout.map((v: any) => v.value || 0).reduce((a: number, b: number) => a + b);
 | 
			
		||||
      this.isLoadingTx = false;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    this.memPoolService.conversions$
 | 
			
		||||
      .subscribe((conversions) => {
 | 
			
		||||
        this.conversions = conversions;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    this.memPoolService.blocks$
 | 
			
		||||
      .subscribe((block) => {
 | 
			
		||||
        this.latestBlockHeight = block.height;
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
      <li class="nav-item" routerLinkActive="active">
 | 
			
		||||
        <a class="nav-link" routerLink="/tv" (click)="collapse()">TV view  <img src="./assets/expand.png" width="15"/></a>
 | 
			
		||||
      </li>
 | 
			
		||||
      <li class="nav-item" routerLinkActive="active">
 | 
			
		||||
      <li class="nav-item" routerLinkActive="active" *ngIf="isEsploraEnabled">
 | 
			
		||||
        <a class="nav-link" routerLink="/explorer" (click)="collapse()">Explorer</a>
 | 
			
		||||
      </li>
 | 
			
		||||
      <li class="nav-item" routerLinkActive="active">
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
 | 
			
		||||
import { MemPoolService } from '../services/mem-pool.service';
 | 
			
		||||
import { Router } from '@angular/router';
 | 
			
		||||
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
 | 
			
		||||
import { environment } from '../../environments/environment';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-master-page',
 | 
			
		||||
@ -13,6 +14,7 @@ export class MasterPageComponent implements OnInit {
 | 
			
		||||
  navCollapsed = false;
 | 
			
		||||
  isOffline = false;
 | 
			
		||||
  searchForm: FormGroup;
 | 
			
		||||
  isEsploraEnabled = !!environment.esplora;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private memPoolService: MemPoolService,
 | 
			
		||||
 | 
			
		||||
@ -166,4 +166,7 @@ export class ApiService {
 | 
			
		||||
    return this.httpClient.get<IBlockTransaction[]>(API_BASE_URL + '/explorer/blocks/' + (height || ''));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getTransaction$(txId: string): Observable<IBlockTransaction[]> {
 | 
			
		||||
    return this.httpClient.get<IBlockTransaction[]>(API_BASE_URL + '/explorer/tx/' + txId);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,10 @@
 | 
			
		||||
      <table style="width: 100%;">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="text-left"><b>Transaction hash</b></td>
 | 
			
		||||
            <td class="text-right"><a href="https://www.blockstream.info/tx/{{ tx?.txid }}" target="_blank">{{ txIdShort }}</a></td>
 | 
			
		||||
            <td class="text-right">
 | 
			
		||||
              <a *ngIf="!isEsploraEnabled" href="https://www.blockstream.info/tx/{{ tx?.txid }}" target="_blank">{{ txIdShort }}</a>
 | 
			
		||||
              <a *ngIf="isEsploraEnabled" [routerLink]="['/explorer/tx/', tx?.txid]">{{ txIdShort }}</a>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td class="text-left"><b>Fee:</b></td>
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,3 @@
 | 
			
		||||
.txBubble .arrow-top-left.txBubbleText::after {
 | 
			
		||||
  left: 20%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.green-color {
 | 
			
		||||
  color: #3bcc49;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';
 | 
			
		||||
import { ITransaction, IProjectedBlock } from '../blockchain/interfaces';
 | 
			
		||||
import { Subscription } from 'rxjs';
 | 
			
		||||
import { ITxTracking, MemPoolService } from '../services/mem-pool.service';
 | 
			
		||||
import { environment } from '../../environments/environment';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'app-tx-bubble',
 | 
			
		||||
@ -35,6 +36,8 @@ export class TxBubbleComponent implements OnInit, OnDestroy {
 | 
			
		||||
  txTrackingTx: ITransaction | null = null;
 | 
			
		||||
  txShowTxNotFound = false;
 | 
			
		||||
 | 
			
		||||
  isEsploraEnabled = !!environment.esplora;
 | 
			
		||||
 | 
			
		||||
  @HostListener('window:resize', ['$event'])
 | 
			
		||||
  onResize(event: Event) {
 | 
			
		||||
    this.moveTxBubbleToPosition();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								frontend/src/environments/environment-esplora.prod.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								frontend/src/environments/environment-esplora.prod.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
export const environment = {
 | 
			
		||||
  production: true,
 | 
			
		||||
  esplora: true,
 | 
			
		||||
};
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
export const environment = {
 | 
			
		||||
  production: true
 | 
			
		||||
  production: true,
 | 
			
		||||
  esplora: false,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,8 @@
 | 
			
		||||
// The list of file replacements can be found in `angular.json`.
 | 
			
		||||
 | 
			
		||||
export const environment = {
 | 
			
		||||
  production: false
 | 
			
		||||
  production: false,
 | 
			
		||||
  esplora: true,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
@ -132,4 +132,28 @@ html, body {
 | 
			
		||||
 | 
			
		||||
hr {
 | 
			
		||||
  border-top: 1px solid rgba(255, 255, 255, 0.1);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.green-color {
 | 
			
		||||
  color: #3bcc49;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.yellow-color { 
 | 
			
		||||
  color: #ffd800;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.table-striped tbody tr:nth-of-type(odd) {
 | 
			
		||||
  background-color: #181b2d !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.header-bg {
 | 
			
		||||
  background-color: #653b9c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.bordertop {
 | 
			
		||||
  border-top: 1px solid #4c4c4c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.smaller-text {
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user