Fix broken tx diagram for non-lBTC liquid assets
This commit is contained in:
		
							parent
							
								
									5977251a20
								
							
						
					
					
						commit
						14e0d80042
					
				@ -29,7 +29,7 @@
 | 
			
		||||
  <ng-template #pegout>
 | 
			
		||||
    <ng-container *ngIf="line.pegout; else normal">
 | 
			
		||||
      <p *ngIf="!isConnector">Peg Out</p>
 | 
			
		||||
      <p *ngIf="line.value != null"><app-amount [satoshis]="line.value"></app-amount></p>
 | 
			
		||||
      <p *ngIf="line.displayValue != null"><app-amount [satoshis]="line.displayValue"></app-amount></p>
 | 
			
		||||
      <p class="address">
 | 
			
		||||
        <app-truncate [text]="line.pegout"></app-truncate>
 | 
			
		||||
      </p>
 | 
			
		||||
@ -55,18 +55,18 @@
 | 
			
		||||
            <p *ngSwitchCase="'output'"><span i18n="transaction.input">Input</span>  #{{ line.vin + 1 }}</p>
 | 
			
		||||
          </ng-container>
 | 
			
		||||
      </ng-container>
 | 
			
		||||
      <p *ngIf="line.value == null && line.confidential" i18n="shared.confidential">Confidential</p>
 | 
			
		||||
      <p *ngIf="line.value != null">
 | 
			
		||||
      <p *ngIf="line.displayValue == null && line.confidential" i18n="shared.confidential">Confidential</p>
 | 
			
		||||
      <p *ngIf="line.displayValue != null">
 | 
			
		||||
        <ng-template [ngIf]="line.asset && line.asset !== nativeAssetId" [ngIfElse]="defaultOutput">
 | 
			
		||||
          <div *ngIf="assetsMinimal && assetsMinimal[line.asset] else assetNotFound">
 | 
			
		||||
            <ng-container *ngTemplateOutlet="assetBox; context:{ $implicit: line }"></ng-container>
 | 
			
		||||
          </div>
 | 
			
		||||
          <ng-template #assetNotFound>
 | 
			
		||||
            {{ line.value }} <span class="symbol">{{ line.asset | slice : 0 : 7 }}</span>
 | 
			
		||||
            {{ line.displayValue }} <span class="symbol">{{ line.asset | slice : 0 : 7 }}</span>
 | 
			
		||||
          </ng-template>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
        <ng-template #defaultOutput>
 | 
			
		||||
          <app-amount [blockConversion]="blockConversion" [satoshis]="line.value"></app-amount>
 | 
			
		||||
          <app-amount [blockConversion]="blockConversion" [satoshis]="line.displayValue"></app-amount>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
      </p>
 | 
			
		||||
      <p *ngIf="line.type !== 'fee' && line.address" class="address">
 | 
			
		||||
@ -76,5 +76,5 @@
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<ng-template #assetBox let-item>
 | 
			
		||||
  {{ item.value / pow(10, assetsMinimal[item.asset][3]) | number: '1.' + assetsMinimal[item.asset][3] + '-' + assetsMinimal[item.asset][3] }} <span class="symbol">{{ assetsMinimal[item.asset][1] }}</span>
 | 
			
		||||
  {{ item.displayValue / pow(10, assetsMinimal[item.asset][3]) | number: '1.' + assetsMinimal[item.asset][3] + '-' + assetsMinimal[item.asset][3] }} <span class="symbol">{{ assetsMinimal[item.asset][1] }}</span>
 | 
			
		||||
</ng-template>
 | 
			
		||||
@ -7,6 +7,7 @@ import { environment } from '../../../environments/environment';
 | 
			
		||||
interface Xput {
 | 
			
		||||
  type: 'input' | 'output' | 'fee';
 | 
			
		||||
  value?: number;
 | 
			
		||||
  displayValue?: number;
 | 
			
		||||
  index?: number;
 | 
			
		||||
  txid?: string;
 | 
			
		||||
  vin?: number;
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,13 @@
 | 
			
		||||
import { Component, OnInit, Input, OnChanges, HostListener, Inject, LOCALE_ID } from '@angular/core';
 | 
			
		||||
import { StateService } from '../../services/state.service';
 | 
			
		||||
import { Outspend, Transaction } from '../../interfaces/electrs.interface';
 | 
			
		||||
import { Outspend, Transaction, Vin, Vout } from '../../interfaces/electrs.interface';
 | 
			
		||||
import { Router } from '@angular/router';
 | 
			
		||||
import { ReplaySubject, merge, Subscription, of } from 'rxjs';
 | 
			
		||||
import { tap, switchMap } from 'rxjs/operators';
 | 
			
		||||
import { ApiService } from '../../services/api.service';
 | 
			
		||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
 | 
			
		||||
import { AssetsService } from '../../services/assets.service';
 | 
			
		||||
import { environment } from '../../../environments/environment';
 | 
			
		||||
 | 
			
		||||
interface SvgLine {
 | 
			
		||||
  path: string;
 | 
			
		||||
@ -20,6 +21,7 @@ interface SvgLine {
 | 
			
		||||
interface Xput {
 | 
			
		||||
  type: 'input' | 'output' | 'fee';
 | 
			
		||||
  value?: number;
 | 
			
		||||
  displayValue?: number;
 | 
			
		||||
  index?: number;
 | 
			
		||||
  txid?: string;
 | 
			
		||||
  vin?: number;
 | 
			
		||||
@ -74,6 +76,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
			
		||||
  zeroValueThickness = 20;
 | 
			
		||||
  hasLine: boolean;
 | 
			
		||||
  assetsMinimal: any;
 | 
			
		||||
  nativeAssetId = this.stateService.network === 'liquidtestnet' ? environment.nativeTestAssetId : environment.nativeAssetId;
 | 
			
		||||
 | 
			
		||||
  outspendsSubscription: Subscription;
 | 
			
		||||
  refreshOutspends$: ReplaySubject<string> = new ReplaySubject();
 | 
			
		||||
@ -167,7 +170,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
			
		||||
    let voutWithFee = this.tx.vout.map((v, i) => {
 | 
			
		||||
      return {
 | 
			
		||||
        type: v.scriptpubkey_type === 'fee' ? 'fee' : 'output',
 | 
			
		||||
        value: v?.value,
 | 
			
		||||
        value: this.getOutputValue(v),
 | 
			
		||||
        displayValue: v?.value,
 | 
			
		||||
        address: v?.scriptpubkey_address || v?.scriptpubkey_type?.toUpperCase(),
 | 
			
		||||
        index: i,
 | 
			
		||||
        pegout: v?.pegout?.scriptpubkey_address,
 | 
			
		||||
@ -185,7 +189,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
			
		||||
    let truncatedInputs = this.tx.vin.map((v, i) => {
 | 
			
		||||
      return {
 | 
			
		||||
        type: 'input',
 | 
			
		||||
        value: v?.prevout?.value || (v?.is_coinbase && !totalValue ? 0 : undefined),
 | 
			
		||||
        value: (v?.is_coinbase && !totalValue ? 0 : this.getInputValue(v)),
 | 
			
		||||
        displayValue: v?.prevout?.value,
 | 
			
		||||
        txid: v.txid,
 | 
			
		||||
        vout: v.vout,
 | 
			
		||||
        address: v?.prevout?.scriptpubkey_address || v?.prevout?.scriptpubkey_type?.toUpperCase(),
 | 
			
		||||
@ -229,14 +234,14 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  calcTotalValue(tx: Transaction): number {
 | 
			
		||||
    const totalOutput = this.tx.vout.reduce((acc, v) => (v.value == null ? 0 : v.value) + acc, 0);
 | 
			
		||||
    let totalOutput = this.tx.vout.reduce((acc, v) => (this.getOutputValue(v) || 0) + acc, 0);
 | 
			
		||||
    // simple sum of outputs + fee for bitcoin
 | 
			
		||||
    if (!this.isLiquid) {
 | 
			
		||||
      return this.tx.fee ? totalOutput + this.tx.fee : totalOutput;
 | 
			
		||||
    } else {
 | 
			
		||||
      const totalInput = this.tx.vin.reduce((acc, v) => (v?.prevout?.value == null ? 0 : v.prevout.value) + acc, 0);
 | 
			
		||||
      const confidentialInputCount = this.tx.vin.reduce((acc, v) => acc + (v?.prevout?.value == null ? 1 : 0), 0);
 | 
			
		||||
      const confidentialOutputCount = this.tx.vout.reduce((acc, v) => acc + (v.value == null ? 1 : 0), 0);
 | 
			
		||||
      const totalInput = this.tx.vin.reduce((acc, v) => (this.getInputValue(v) || 0) + acc, 0);
 | 
			
		||||
      const confidentialInputCount = this.tx.vin.reduce((acc, v) => acc + (this.isUnknownInputValue(v) ? 1 : 0), 0);
 | 
			
		||||
      const confidentialOutputCount = this.tx.vout.reduce((acc, v) => acc + (this.isUnknownOutputValue(v) ? 1 : 0), 0);
 | 
			
		||||
 | 
			
		||||
      // if there are unknowns on both sides, the total is indeterminate, so we'll just fudge it
 | 
			
		||||
      if (confidentialInputCount && confidentialOutputCount) {
 | 
			
		||||
@ -456,6 +461,34 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getOutputValue(v: Vout): number | void {
 | 
			
		||||
    if (!v) {
 | 
			
		||||
      return null;
 | 
			
		||||
    } else if (this.isLiquid && v.asset !== this.nativeAssetId) {
 | 
			
		||||
      return null;
 | 
			
		||||
    } else {
 | 
			
		||||
      return v.value;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  getInputValue(v: Vin): number | void {
 | 
			
		||||
    if (!v?.prevout) {
 | 
			
		||||
      return null;
 | 
			
		||||
    } else if (this.isLiquid && v.prevout.asset !== this.nativeAssetId) {
 | 
			
		||||
      return null;
 | 
			
		||||
    } else {
 | 
			
		||||
      return v.prevout.value;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isUnknownInputValue(v: Vin): boolean {
 | 
			
		||||
    return v?.prevout?.value == null || this.isLiquid && v?.prevout?.asset !== this.nativeAssetId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  isUnknownOutputValue(v: Vout): boolean {
 | 
			
		||||
    return v?.value == null || this.isLiquid && v?.asset !== this.nativeAssetId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @HostListener('pointermove', ['$event'])
 | 
			
		||||
  onPointerMove(event) {
 | 
			
		||||
    if (this.dir === 'rtl') {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user