[accelerator] check for input replaceability
This commit is contained in:
		
							parent
							
								
									c71a0afe1f
								
							
						
					
					
						commit
						e35ac6e1a2
					
				| @ -122,7 +122,7 @@ | ||||
|         <span class="explainer"> </span> | ||||
|       } @else if (showAccelerationSummary) { | ||||
|         <ng-container *ngIf="(ETA$ | async) as eta;"> | ||||
|           <app-accelerate-checkout *ngIf="(da$ | async) as da;" [cashappEnabled]="accelerationEligible" [advancedEnabled]="false" [forceMobile]="true" [tx]="tx" [miningStats]="miningStats" [eta]="eta" [scrollEvent]="scrollIntoAccelPreview" class="h-100 w-100"></app-accelerate-checkout> | ||||
|           <app-accelerate-checkout *ngIf="(da$ | async) as da;" [cashappEnabled]="cashappEligible" [advancedEnabled]="false" [forceMobile]="true" [tx]="tx" [miningStats]="miningStats" [eta]="eta" [scrollEvent]="scrollIntoAccelPreview" class="h-100 w-100"></app-accelerate-checkout> | ||||
|         </ng-container> | ||||
|       } @else { | ||||
|         @if (tx?.acceleration && !tx.status?.confirmed) { | ||||
|  | ||||
| @ -21,7 +21,7 @@ import { AudioService } from '../../services/audio.service'; | ||||
| import { ApiService } from '../../services/api.service'; | ||||
| import { SeoService } from '../../services/seo.service'; | ||||
| import { seoDescriptionNetwork } from '../../shared/common.utils'; | ||||
| import { Filter } from '../../shared/filters.utils'; | ||||
| import { Filter, TransactionFlags } from '../../shared/filters.utils'; | ||||
| import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration, AccelerationPosition } from '../../interfaces/node-api.interface'; | ||||
| import { PriceService } from '../../services/price.service'; | ||||
| import { ServicesApiServices } from '../../services/services-api.service'; | ||||
| @ -30,7 +30,7 @@ import { ZONE_SERVICE } from '../../injection-tokens'; | ||||
| import { TrackerStage } from './tracker-bar.component'; | ||||
| import { MiningService, MiningStats } from '../../services/mining.service'; | ||||
| import { ETA, EtaService } from '../../services/eta.service'; | ||||
| import { getUnacceleratedFeeRate } from '../../shared/transaction.utils'; | ||||
| import { getTransactionFlags, getUnacceleratedFeeRate } from '../../shared/transaction.utils'; | ||||
| 
 | ||||
| interface Pool { | ||||
|   id: number; | ||||
| @ -117,8 +117,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
|   hasEffectiveFeeRate: boolean; | ||||
|   accelerateCtaType: 'alert' | 'button' = 'button'; | ||||
|   acceleratorAvailable: boolean = this.stateService.env.ACCELERATOR && this.stateService.network === ''; | ||||
|   accelerationEligible: boolean = false; | ||||
|   showAccelerationSummary = false; | ||||
|   eligibleForAcceleration: boolean = false; | ||||
|   accelerationFlowCompleted = false; | ||||
|   scrollIntoAccelPreview = false; | ||||
|   auditEnabled: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true; | ||||
| @ -155,11 +154,6 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
|       this.miningStats = stats; | ||||
|     }); | ||||
| 
 | ||||
|     const urlParams = new URLSearchParams(window.location.search); | ||||
|     if (urlParams.get('cash_request_id')) { | ||||
|       this.showAccelerationSummary = true; | ||||
|     } | ||||
| 
 | ||||
|     this.enterpriseService.page(); | ||||
| 
 | ||||
|     this.enterpriseInfo$ = this.enterpriseService.info$.subscribe(info => { | ||||
| @ -267,6 +261,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
| 
 | ||||
|       if (!this.tx) { | ||||
|         this.tx = tx; | ||||
|         this.checkAccelerationEligibility(); | ||||
|         this.isCached = true; | ||||
|         if (tx.fee === undefined) { | ||||
|           this.tx.fee = 0; | ||||
| @ -385,20 +380,9 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
|             this.trackerStage = 'replaced'; | ||||
|           } | ||||
| 
 | ||||
|           if (!this.mempoolPosition.accelerated) { | ||||
|             if (!this.accelerationFlowCompleted && !this.showAccelerationSummary && this.mempoolPosition.block > 0) { | ||||
|               this.showAccelerationSummary = true; | ||||
|               this.miningService.getMiningStats('1w').subscribe(stats => { | ||||
|                 this.miningStats = stats; | ||||
|               }); | ||||
|             } | ||||
|             if (txPosition.position?.block > 0) { | ||||
|               this.accelerationEligible = true; | ||||
|             } | ||||
|           } else if (this.showAccelerationSummary) { | ||||
|           if (this.mempoolPosition.accelerated && this.showAccelerationSummary) { | ||||
|             setTimeout(() => { | ||||
|               this.accelerationFlowCompleted = true; | ||||
|               this.showAccelerationSummary = false; | ||||
|             }, 2000); | ||||
|           } | ||||
|         } | ||||
| @ -462,6 +446,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
|           this.seoService.clearSoft404(); | ||||
| 
 | ||||
|           this.tx = tx; | ||||
|           this.checkAccelerationEligibility(); | ||||
|           this.isCached = false; | ||||
|           if (tx.fee === undefined) { | ||||
|             this.tx.fee = 0; | ||||
| @ -744,8 +729,9 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
|     } | ||||
|     this.enterpriseService.goal(8); | ||||
|     this.accelerationFlowCompleted = false; | ||||
|     this.showAccelerationSummary = true && this.acceleratorAvailable; | ||||
|     if (this.showAccelerationSummary) { | ||||
|       this.scrollIntoAccelPreview = true; | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
| @ -753,6 +739,30 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
|     return this.isLoadingTx || this.loadingCachedTx || this.loadingPosition; | ||||
|   } | ||||
| 
 | ||||
|   checkAccelerationEligibility() { | ||||
|     if (this.tx) { | ||||
|       this.tx.flags = getTransactionFlags(this.tx); | ||||
|       const replaceableInputs = (this.tx.flags & (TransactionFlags.sighash_none | TransactionFlags.sighash_acp)) > 0n; | ||||
|       this.eligibleForAcceleration = !replaceableInputs; | ||||
|     } else { | ||||
|       this.eligibleForAcceleration = false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   get cashappEligible(): boolean { | ||||
|     return this.mempoolPosition?.block > 0; | ||||
|   } | ||||
| 
 | ||||
|   get showAccelerationSummary(): boolean { | ||||
|     return ( | ||||
|       this.tx | ||||
|       && !this.tx.acceleration | ||||
|       && this.acceleratorAvailable | ||||
|       && this.eligibleForAcceleration | ||||
|       && !this.accelerationFlowCompleted | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   resetTransaction() { | ||||
|     this.error = undefined; | ||||
|     this.tx = null; | ||||
| @ -778,7 +788,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | ||||
|     this.pool = null; | ||||
|     this.auditStatus = null; | ||||
|     this.accelerationPositions = null; | ||||
|     this.accelerationEligible = false; | ||||
|     this.eligibleForAcceleration = false; | ||||
|     this.trackerStage = 'waiting'; | ||||
|     document.body.scrollTo(0, 0); | ||||
|     this.leaveTransaction(); | ||||
|  | ||||
| @ -147,7 +147,7 @@ | ||||
|       <ng-container *ngIf="(ETA$ | async) as eta;"> | ||||
|         <app-accelerate-checkout | ||||
|           *ngIf="(da$ | async) as da;" | ||||
|           [cashappEnabled]="accelerationEligible" | ||||
|           [cashappEnabled]="cashappEligible" | ||||
|           [advancedEnabled]="true" | ||||
|           [tx]="tx" | ||||
|           [eta]="eta" | ||||
|  | ||||
| @ -24,8 +24,8 @@ import { SeoService } from '../../services/seo.service'; | ||||
| import { StorageService } from '../../services/storage.service'; | ||||
| import { seoDescriptionNetwork } from '../../shared/common.utils'; | ||||
| import { getTransactionFlags, getUnacceleratedFeeRate } from '../../shared/transaction.utils'; | ||||
| import { Filter, toFilters } from '../../shared/filters.utils'; | ||||
| import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration, AccelerationPosition, SinglePoolStats } from '../../interfaces/node-api.interface'; | ||||
| import { Filter, TransactionFlags, toFilters } from '../../shared/filters.utils'; | ||||
| import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration, AccelerationPosition } from '../../interfaces/node-api.interface'; | ||||
| import { LiquidUnblinding } from './liquid-ublinding'; | ||||
| import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; | ||||
| import { PriceService } from '../../services/price.service'; | ||||
| @ -137,13 +137,14 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | ||||
|   hasEffectiveFeeRate: boolean; | ||||
|   accelerateCtaType: 'alert' | 'button' = 'button'; | ||||
|   acceleratorAvailable: boolean = this.stateService.env.ACCELERATOR && this.stateService.network === ''; | ||||
|   eligibleForAcceleration: boolean = false; | ||||
|   forceAccelerationSummary = false; | ||||
|   hideAccelerationSummary = false; | ||||
|   accelerationFlowCompleted = false; | ||||
|   showAccelerationDetails = false; | ||||
|   hasAccelerationDetails = false; | ||||
|   scrollIntoAccelPreview = false; | ||||
|   accelerationEligible = false; | ||||
|   cashappEligible = false; | ||||
|   auditEnabled: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true; | ||||
| 
 | ||||
|   @ViewChild('graphContainer') | ||||
| @ -421,7 +422,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | ||||
|                 }); | ||||
|               } | ||||
|               if (txPosition.position?.block > 0 && this.tx.weight < 4000) { | ||||
|                 this.accelerationEligible = true; | ||||
|                 this.cashappEligible = true; | ||||
|               } | ||||
|             } else if (this.showAccelerationSummary) { | ||||
|               setTimeout(() => { | ||||
| @ -819,6 +820,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | ||||
|       this.rbfEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'rbf'); | ||||
|       this.tx.flags = getTransactionFlags(this.tx); | ||||
|       this.filters = this.tx.flags ? toFilters(this.tx.flags).filter(f => f.txPage) : []; | ||||
|       this.checkAccelerationEligibility(); | ||||
|     } else { | ||||
|       this.segwitEnabled = false; | ||||
|       this.taprootEnabled = false; | ||||
| @ -827,6 +829,15 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | ||||
|     this.featuresEnabled = this.segwitEnabled || this.taprootEnabled || this.rbfEnabled; | ||||
|   } | ||||
| 
 | ||||
|   checkAccelerationEligibility() { | ||||
|     if (this.tx && this.tx.flags) { | ||||
|       const replaceableInputs = (this.tx.flags & (TransactionFlags.sighash_none | TransactionFlags.sighash_acp)) > 0n; | ||||
|       this.eligibleForAcceleration = !replaceableInputs; | ||||
|     } else { | ||||
|       this.eligibleForAcceleration = false; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   isAuditAvailable(blockHeight: number): boolean { | ||||
|     if (!this.auditEnabled) { | ||||
|       return false; | ||||
| @ -871,7 +882,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | ||||
|     this.showCpfpDetails = false; | ||||
|     this.showAccelerationDetails = false; | ||||
|     this.accelerationInfo = null; | ||||
|     this.accelerationEligible = false; | ||||
|     this.cashappEligible = false; | ||||
|     this.txInBlockIndex = null; | ||||
|     this.mempoolPosition = null; | ||||
|     this.pool = null; | ||||
| @ -880,6 +891,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | ||||
|     document.body.scrollTo(0, 0); | ||||
|     this.isAcceleration = false; | ||||
|     this.isAccelerated$.next(this.isAcceleration); | ||||
|     this.eligibleForAcceleration = false; | ||||
|     this.leaveTransaction(); | ||||
|   } | ||||
| 
 | ||||
| @ -974,6 +986,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | ||||
|       this.tx | ||||
|       && !this.tx.acceleration | ||||
|       && this.acceleratorAvailable | ||||
|       && this.eligibleForAcceleration | ||||
|       && ( | ||||
|         (!this.hideAccelerationSummary && !this.accelerationFlowCompleted) | ||||
|         || this.forceAccelerationSummary | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user