parent
							
								
									ffbd6da1e0
								
							
						
					
					
						commit
						4932d6f706
					
				@ -72,6 +72,14 @@ class WebsocketHandler {
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (parsedMessage && parsedMessage['track-asset']) {
 | 
			
		||||
            if (/^[a-fA-F0-9]{64}$/.test(parsedMessage['track-asset'])) {
 | 
			
		||||
              client['track-asset'] = parsedMessage['track-asset'];
 | 
			
		||||
            } else {
 | 
			
		||||
              client['track-asset'] = null;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (parsedMessage.action === 'init') {
 | 
			
		||||
            const _blocks = blocks.getBlocks();
 | 
			
		||||
            if (!_blocks) {
 | 
			
		||||
@ -155,24 +163,24 @@ class WebsocketHandler {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Send all new incoming transactions related to tracked address
 | 
			
		||||
      if (client['track-address']) {
 | 
			
		||||
      // Send all new incoming transactions related to tracked asset
 | 
			
		||||
      if (client['track-asset']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
        newTransactions.forEach((tx) => {
 | 
			
		||||
          const someVin = tx.vin.some((vin) => !!vin.prevout && vin.prevout.scriptpubkey_address === client['track-address']);
 | 
			
		||||
          const someVin = tx.vin.some((vin) => !!vin.issuance && vin.issuance.asset_id === client['track-asset']);
 | 
			
		||||
          if (someVin) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          const someVout = tx.vout.some((vout) => vout.scriptpubkey_address === client['track-address']);
 | 
			
		||||
          const someVout = tx.vout.some((vout) => !!vout.asset && vout.asset === client['track-asset']);
 | 
			
		||||
          if (someVout) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (foundTransactions.length) {
 | 
			
		||||
          response['address-transactions'] = foundTransactions;
 | 
			
		||||
          response['asset-transactions'] = foundTransactions;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -213,7 +221,34 @@ class WebsocketHandler {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          if (tx.vout && tx.vout.some((vout) => vout.scriptpubkey_address === client['track-address'])) {
 | 
			
		||||
          if (tx.vout && tx.vout.some((vout) => !!vout.asset && vout.asset === client['track-asset'])) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (foundTransactions.length) {
 | 
			
		||||
          foundTransactions.forEach((tx) => {
 | 
			
		||||
            tx.status = {
 | 
			
		||||
              confirmed: true,
 | 
			
		||||
              block_height: block.height,
 | 
			
		||||
              block_hash: block.id,
 | 
			
		||||
              block_time: block.timestamp,
 | 
			
		||||
            };
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          response['asset-block-transactions'] = foundTransactions;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-asset']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
        transactions.forEach((tx) => {
 | 
			
		||||
          if (tx.vin && tx.vin.some((vin) => !!vin.issuance && vin.issuance.asset_id === client['track-asset'])) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          if (tx.vout && tx.vout.some((vout) => !!vout.asset && vout.asset === client['track-asset'])) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@ -56,6 +56,20 @@ export interface Vin {
 | 
			
		||||
  sequence: any;
 | 
			
		||||
  witness?: string[];
 | 
			
		||||
  inner_witnessscript_asm?: string;
 | 
			
		||||
 | 
			
		||||
  issuance?: Issuance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Issuance {
 | 
			
		||||
  asset_id: string;
 | 
			
		||||
  is_reissuance: string;
 | 
			
		||||
  asset_blinding_nonce: string;
 | 
			
		||||
  asset_entropy: string;
 | 
			
		||||
  contract_hash: string;
 | 
			
		||||
  assetamount?: number;
 | 
			
		||||
  assetamountcommitment?: string;
 | 
			
		||||
  tokenamount?: number;
 | 
			
		||||
  tokenamountcommitment?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Vout {
 | 
			
		||||
@ -64,6 +78,8 @@ export interface Vout {
 | 
			
		||||
  scriptpubkey_type: string;
 | 
			
		||||
  scriptpubkey_address: string;
 | 
			
		||||
  value: number;
 | 
			
		||||
 | 
			
		||||
  asset?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Status {
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,7 @@
 | 
			
		||||
  <ng-template [ngIf]="!isLoading && !error">
 | 
			
		||||
    <table class="table table-borderless table-striped">
 | 
			
		||||
      <thead>
 | 
			
		||||
        <th style="td-name">Name</th>
 | 
			
		||||
        <th class="td-name">Name</th>
 | 
			
		||||
        <th>Ticker</th>
 | 
			
		||||
        <th class="d-none d-md-block">Issuer domain</th>
 | 
			
		||||
        <th>Asset ID</th>
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,11 @@ export class AssetsComponent implements OnInit {
 | 
			
		||||
  ) { }
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    this.assetsService.getAssetsJson$()
 | 
			
		||||
    setTimeout(() => this.getAssets());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getAssets() {
 | 
			
		||||
    this.assetsService.getAssetsJson$
 | 
			
		||||
      .subscribe((assets) => {
 | 
			
		||||
        this.assets = Object.values(assets);
 | 
			
		||||
        this.assets.push({
 | 
			
		||||
@ -36,6 +40,6 @@ export class AssetsComponent implements OnInit {
 | 
			
		||||
        this.error = error;
 | 
			
		||||
        this.isLoading = false;
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,7 +15,7 @@
 | 
			
		||||
      <div class="row">
 | 
			
		||||
        <div class="col">
 | 
			
		||||
          <table class="table table-borderless table-striped">
 | 
			
		||||
            <tbody>
 | 
			
		||||
            <tbody *ngIf="network !== 'liquid'">
 | 
			
		||||
              <tr>
 | 
			
		||||
                <td>Total received</td>
 | 
			
		||||
                <td>{{ receieved / 100000000 | number: '1.8-8' }} <ng-template [ngIf]="network === 'liquid'">L-</ng-template>BTC</td>
 | 
			
		||||
@ -29,6 +29,20 @@
 | 
			
		||||
                <td>{{ (receieved - sent) / 100000000 | number: '1.8-8' }} <ng-template [ngIf]="network === 'liquid'">L-</ng-template>BTC (<app-fiat [value]="receieved - sent"></app-fiat>)</td>
 | 
			
		||||
              </tr>
 | 
			
		||||
            </tbody>
 | 
			
		||||
            <tbody *ngIf="network === 'liquid'">
 | 
			
		||||
              <tr>
 | 
			
		||||
                <td>Total received</td>
 | 
			
		||||
                <td>Confidential</td>
 | 
			
		||||
              </tr>
 | 
			
		||||
              <tr>
 | 
			
		||||
                <td>Total sent</td>
 | 
			
		||||
                <td>Confidential</td>
 | 
			
		||||
              </tr>
 | 
			
		||||
              <tr>
 | 
			
		||||
                <td>Balance</td>
 | 
			
		||||
                <td>Confidential</td>
 | 
			
		||||
              </tr>
 | 
			
		||||
            </tbody>
 | 
			
		||||
          </table>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col qrcode-col">
 | 
			
		||||
 | 
			
		||||
@ -84,7 +84,7 @@ export class AssetComponent implements OnInit, OnDestroy {
 | 
			
		||||
                    console.log(err);
 | 
			
		||||
                    return of(null);
 | 
			
		||||
                  })
 | 
			
		||||
                ), this.assetsService.assetsMinimal$])
 | 
			
		||||
                ), this.assetsService.getAssetsMinimalJson$])
 | 
			
		||||
              .pipe(
 | 
			
		||||
                take(1)
 | 
			
		||||
              );
 | 
			
		||||
@ -141,7 +141,7 @@ export class AssetComponent implements OnInit, OnDestroy {
 | 
			
		||||
        this.isLoadingAsset = false;
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    this.stateService.mempoolTransactions$
 | 
			
		||||
    this.stateService.assetTransactions$
 | 
			
		||||
      .subscribe((transaction) => {
 | 
			
		||||
        if (this.transactions.some((t) => t.txid === transaction.txid)) {
 | 
			
		||||
          return;
 | 
			
		||||
@ -151,22 +151,7 @@ export class AssetComponent implements OnInit, OnDestroy {
 | 
			
		||||
        this.transactions = this.transactions.slice();
 | 
			
		||||
        this.txCount++;
 | 
			
		||||
 | 
			
		||||
        // if (transaction.vout.some((vout) => vout.scriptpubkey_asset === this.asset.asset)) {
 | 
			
		||||
        //   this.audioService.playSound('cha-ching');
 | 
			
		||||
        // } else {
 | 
			
		||||
        //   this.audioService.playSound('chime');
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        // transaction.vin.forEach((vin) => {
 | 
			
		||||
        //   if (vin.prevout.scriptpubkey_asset === this.asset.asset) {
 | 
			
		||||
        //     this.sent += vin.prevout.value;
 | 
			
		||||
        //   }
 | 
			
		||||
        // });
 | 
			
		||||
        // transaction.vout.forEach((vout) => {
 | 
			
		||||
        //   if (vout.scriptpubkey_asset === this.asset.asset) {
 | 
			
		||||
        //     this.receieved += vout.value;
 | 
			
		||||
        //   }
 | 
			
		||||
        // });
 | 
			
		||||
        this.audioService.playSound('chime');
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    this.stateService.blockTransactions$
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
<span #buttonWrapper [attr.data-tlite]="'Copied!'" style="position: relative;">
 | 
			
		||||
  <button #btn class="btn btn-sm btn-link pt-0" style="line-height: 1;" [attr.data-clipboard-text]="text"> 
 | 
			
		||||
  <button #btn class="btn btn-sm btn-link pt-0" style="line-height: 0.9;" [attr.data-clipboard-text]="text"> 
 | 
			
		||||
    <img src="./resources/clippy.svg" width="13">
 | 
			
		||||
  </button>
 | 
			
		||||
</span>
 | 
			
		||||
@ -31,10 +31,12 @@ export class SearchFormComponent implements OnInit {
 | 
			
		||||
    this.searchForm = this.formBuilder.group({
 | 
			
		||||
      searchText: ['', Validators.required],
 | 
			
		||||
    });
 | 
			
		||||
    this.assetsService.assetsMinimal$
 | 
			
		||||
      .subscribe((assets) => {
 | 
			
		||||
        this.assets = assets;
 | 
			
		||||
      });
 | 
			
		||||
    if (this.network === 'liquid') {
 | 
			
		||||
      this.assetsService.getAssetsMinimalJson$
 | 
			
		||||
        .subscribe((assets) => {
 | 
			
		||||
          this.assets = assets;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  search() {
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@
 | 
			
		||||
              </td>
 | 
			
		||||
              <td>
 | 
			
		||||
                <div [ngSwitch]="true">
 | 
			
		||||
                  <ng-container *ngSwitchCase="vin.is_coinbase">Coinbase (Newly Generated Coins)</ng-container>
 | 
			
		||||
                  <ng-container *ngSwitchCase="vin.is_coinbase">Coinbase<ng-template [ngIf]="network !== 'liquid'"> (Newly Generated Coins)</ng-template></ng-container>
 | 
			
		||||
                  <ng-container *ngSwitchCase="vin.is_pegin">PEG IN</ng-container>
 | 
			
		||||
                  <ng-container *ngSwitchDefault>
 | 
			
		||||
                    <a [routerLink]="['/address/', vin.prevout.scriptpubkey_address]" title="{{ vin.prevout.scriptpubkey_address }}">
 | 
			
		||||
 | 
			
		||||
@ -35,9 +35,11 @@ export class TransactionsListComponent implements OnInit, OnChanges {
 | 
			
		||||
 | 
			
		||||
  ngOnInit() {
 | 
			
		||||
    this.latestBlock$ = this.stateService.blocks$;
 | 
			
		||||
    this.assetsService.assetsMinimal$.subscribe((assets) => {
 | 
			
		||||
      this.assetsMinimal = assets;
 | 
			
		||||
    });
 | 
			
		||||
    if (this.network === 'liquid') {
 | 
			
		||||
      this.assetsService.getAssetsMinimalJson$.subscribe((assets) => {
 | 
			
		||||
        this.assetsMinimal = assets;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnChanges() {
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,19 @@ export interface Vin {
 | 
			
		||||
  witness?: string[];
 | 
			
		||||
  inner_witnessscript_asm?: string;
 | 
			
		||||
  is_pegin?: boolean;
 | 
			
		||||
  issuance?: Issuance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface Issuance {
 | 
			
		||||
  asset_id: string;
 | 
			
		||||
  is_reissuance: string;
 | 
			
		||||
  asset_blinding_nonce: string;
 | 
			
		||||
  asset_entropy: string;
 | 
			
		||||
  contract_hash: string;
 | 
			
		||||
  assetamount?: number;
 | 
			
		||||
  assetamountcommitment?: string;
 | 
			
		||||
  tokenamount?: number;
 | 
			
		||||
  tokenamountcommitment?: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Vout {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,8 @@
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { HttpClient } from '@angular/common/http';
 | 
			
		||||
import { ReplaySubject } from 'rxjs';
 | 
			
		||||
import { ReplaySubject, Observable } from 'rxjs';
 | 
			
		||||
import { environment } from 'src/environments/environment';
 | 
			
		||||
import { shareReplay } from 'rxjs/operators';
 | 
			
		||||
 | 
			
		||||
@Injectable({
 | 
			
		||||
  providedIn: 'root'
 | 
			
		||||
@ -9,24 +10,13 @@ import { environment } from 'src/environments/environment';
 | 
			
		||||
export class AssetsService {
 | 
			
		||||
  network = environment.network;
 | 
			
		||||
 | 
			
		||||
  assetsMinimal$ = new ReplaySubject<any>(1);
 | 
			
		||||
  getAssetsJson$: Observable<any>;
 | 
			
		||||
  getAssetsMinimalJson$: Observable<any>;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    private httpClient: HttpClient,
 | 
			
		||||
  ) {
 | 
			
		||||
    if (this.network === 'liquid') {
 | 
			
		||||
      this.getAssetsMinimalJson$();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getAssetsMinimalJson$() {
 | 
			
		||||
    this.httpClient.get('/resources/assets.minimal.json')
 | 
			
		||||
    .subscribe((data) => {
 | 
			
		||||
      this.assetsMinimal$.next(data);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getAssetsJson$() {
 | 
			
		||||
    return this.httpClient.get('/resources/assets.json');
 | 
			
		||||
    this.getAssetsJson$ = this.httpClient.get('/resources/assets.json').pipe(shareReplay());
 | 
			
		||||
    this.getAssetsMinimalJson$ = this.httpClient.get('/resources/assets.minimal.json').pipe(shareReplay());
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ export class StateService {
 | 
			
		||||
  mempoolBlocks$ = new ReplaySubject<MempoolBlock[]>(1);
 | 
			
		||||
  txConfirmed$ = new Subject<Block>();
 | 
			
		||||
  mempoolTransactions$ = new Subject<Transaction>();
 | 
			
		||||
  assetTransactions$ = new Subject<Transaction>();
 | 
			
		||||
  blockTransactions$ = new Subject<Transaction>();
 | 
			
		||||
 | 
			
		||||
  live2Chart$ = new Subject<OptimizedMempoolStats>();
 | 
			
		||||
 | 
			
		||||
@ -96,6 +96,18 @@ export class WebsocketService {
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (response['asset-transactions']) {
 | 
			
		||||
          response['asset-transactions'].forEach((assetTransaction: Transaction) => {
 | 
			
		||||
            this.stateService.assetTransactions$.next(assetTransaction);
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (response['asset-block-transactions']) {
 | 
			
		||||
          response['asset-block-transactions'].forEach((addressTransaction: Transaction) => {
 | 
			
		||||
            this.stateService.blockTransactions$.next(addressTransaction);
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (response['live-2h-chart']) {
 | 
			
		||||
          this.stateService.live2Chart$.next(response['live-2h-chart']);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user