Add simple mode checkout to main transaction page
This commit is contained in:
parent
790e76ab26
commit
4445fe408b
@ -1,4 +1,4 @@
|
||||
<div class="container-md card w-100" style="padding: 1em; background: var(--box-bg)" id=acceleratePreviewAnchor>
|
||||
<div class="box card w-100" style="padding: 1em; background: var(--box-bg)" id=acceleratePreviewAnchor>
|
||||
|
||||
@if (error) {
|
||||
<div class="mt-2">
|
||||
@ -10,18 +10,33 @@
|
||||
<!-- Show A/B CTAs -->
|
||||
<div class="row mb-1">
|
||||
<div class="col-sm">
|
||||
<h1 style="font-size: larger;">Accelerate your Bitcoin transaction?</h1>
|
||||
<h1 style="font-size: larger;"><ng-content select="[slot='cta-title']"></ng-content><span class="default-slot">Accelerate your Bitcoin transaction?</span></h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form>
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="row" *ngIf="(etaInfo$ | async) as etaInfo">
|
||||
<div class="col-md">
|
||||
<div class="form-group form-check mb-2">
|
||||
<input type="radio" class="form-check-input" id="wait" name="accelerate" (change)="selectedOptionChanged($event)">
|
||||
<label class="form-check-label d-flex flex-column" for="wait">
|
||||
<span class="font-weight-bold">Wait</span>
|
||||
@if (eta.blocks < 7) {
|
||||
<span style="color: rgb(186, 186, 186); font-size: 14px;">Confirmation expected <app-time kind="within" [time]="eta.time" [fastRender]="false" [fixedRender]="true"></app-time></span>
|
||||
} @else {
|
||||
<span style="color: rgb(186, 186, 186); font-size: 14px;">
|
||||
<span>Confirmation expected within several hours</span>
|
||||
</span>
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md">
|
||||
<div class="form-group form-check mb-2">
|
||||
<input type="radio" class="form-check-input" id="accelerate" name="accelerate" (change)="selectedOptionChanged($event)">
|
||||
<label class="form-check-label d-flex flex-column" for="accelerate">
|
||||
<span class="font-weight-bold">Accelerate</span>
|
||||
<span style="color: rgb(186, 186, 186); font-size: 14px;" *ngIf="(etaInfo$ | async) as etaInfo">Confirmation expected <app-time kind="within" [time]="etaInfo.acceleratedETA" [fastRender]="false" [fixedRender]="true"></app-time><br>
|
||||
<span style="color: rgb(186, 186, 186); font-size: 14px;">Confirmation expected <app-time kind="within" [time]="etaInfo.acceleratedETA" [fastRender]="false" [fixedRender]="true"></app-time><br>
|
||||
@if (!calculating) {
|
||||
<app-fiat [value]="cost"></app-fiat>fee (<span><small style="font-family: monospace;">{{ cost | number }}</small> <span class="symbol" i18n="shared.sats">sats</span></span>)
|
||||
} @else {
|
||||
@ -31,22 +46,9 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="form-group form-check mb-2">
|
||||
<input type="radio" class="form-check-input" id="wait" name="accelerate" (change)="selectedOptionChanged($event)">
|
||||
<label class="form-check-label d-flex flex-column" for="wait">
|
||||
<span class="font-weight-bold">Wait</span>
|
||||
@if (eta) {
|
||||
<span style="color: rgb(186, 186, 186); font-size: 14px;">Confirmation expected <app-time kind="within" [time]="eta" [fastRender]="false" [fixedRender]="true"></app-time></span>
|
||||
} @else {
|
||||
<span style="color: rgb(186, 186, 186); font-size: 14px;">
|
||||
<span>Settlement expected within several hours</span>
|
||||
</span>
|
||||
}
|
||||
</label>
|
||||
</div>
|
||||
<div class="col-md pie d-none d-lg-flex" *ngIf="estimate && !isTracker">
|
||||
<small class="form-text text-muted mb-2" i18n="accelerator.hashrate-percentage-description">Your transaction will be prioritized by up to {{ etaInfo.hashratePercentage | number : '1.1-1' }}% of miners.</small>
|
||||
<app-active-acceleration-box [miningStats]="miningStats" [pools]="estimate.pools" [chartOnly]="true"></app-active-acceleration-box>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2 mb-2" [style]="(choosenOption === 'wait' || calculating) ? 'opacity: 0.25; pointer-events: none' : ''">
|
||||
@ -62,7 +64,7 @@
|
||||
} @else if (step === 'paymentMethod') {
|
||||
<div class="row mb-md-1 text-center">
|
||||
<div class="col-sm">
|
||||
<h1 style="font-size: larger;">Select your payment method</h1>
|
||||
<h1 style="font-size: larger;"><ng-content select="[slot='payment-title']"></ng-content><span class="default-slot">Select your payment method</span></h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-2 d-flex justify-content-around">
|
||||
@ -76,14 +78,14 @@
|
||||
<!-- Show checkout page -->
|
||||
<div class="row mb-md-1 text-center">
|
||||
<div class="col-sm" id="confirm-payment-title">
|
||||
<h1 style="font-size: larger;">Confirm your payment</h1>
|
||||
<h1 style="font-size: larger;"><ng-content select="[slot='checkout-title']"></ng-content><span class="default-slot">Confirm your payment</span></h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row text-center">
|
||||
<div class="col-sm">
|
||||
<div class="form-group w-100" style="font-size: 14px">
|
||||
Payment to mempool.space for acceleration of txid <a [routerLink]="'/tx/' + txid" target="_blank">{{ txid.substr(0, 10) }}..{{ txid.substr(-10) }}</a>
|
||||
Payment to mempool.space for acceleration of txid <a [routerLink]="'/tx/' + tx.txid" target="_blank">{{ tx.txid.substr(0, 10) }}..{{ tx.txid.substr(-10) }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -134,7 +136,7 @@
|
||||
@else if (step === 'processing') {
|
||||
<div class="row mb-1 text-center">
|
||||
<div class="col-sm">
|
||||
<h1 style="font-size: larger;">Confirming your payment</h1>
|
||||
<h1 style="font-size: larger;"><ng-content select="[slot='processing-title']"></ng-content><span class="default-slot">Confirming your payment</span></h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -14,4 +14,14 @@
|
||||
border-radius: 15px;
|
||||
border: 2px solid var(--bg);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.default-slot:not(:only-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.pie {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 330px;
|
||||
}
|
@ -5,7 +5,9 @@ import { nextRoundNumber } from '../../shared/common.utils';
|
||||
import { StateService } from '../../services/state.service';
|
||||
import { AudioService } from '../../services/audio.service';
|
||||
import { AccelerationEstimate } from '../accelerate-preview/accelerate-preview.component';
|
||||
import { EtaService } from '../../services/eta.service';
|
||||
import { ETA, EtaService } from '../../services/eta.service';
|
||||
import { Transaction } from '../../interfaces/electrs.interface';
|
||||
import { MiningStats } from '../../services/mining.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-accelerate-checkout',
|
||||
@ -13,10 +15,12 @@ import { EtaService } from '../../services/eta.service';
|
||||
styleUrls: ['./accelerate-checkout.component.scss']
|
||||
})
|
||||
export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
@Input() eta: number | null = null;
|
||||
@Input() txid: string = '70c18d76cdb285a1b5bd87fdaae165880afa189809c30b4083ff7c0e69ee09ad';
|
||||
@Input() tx: Transaction;
|
||||
@Input() miningStats: MiningStats;
|
||||
@Input() eta: ETA;
|
||||
@Input() scrollEvent: boolean;
|
||||
@Input() cashappEnabled: boolean;
|
||||
@Input() isTracker: boolean = false;
|
||||
@Output() close = new EventEmitter<null>();
|
||||
|
||||
calculating = true;
|
||||
@ -116,7 +120,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
this.estimateSubscription.unsubscribe();
|
||||
}
|
||||
this.calculating = true;
|
||||
this.estimateSubscription = this.servicesApiService.estimate$(this.txid).pipe(
|
||||
this.estimateSubscription = this.servicesApiService.estimate$(this.tx.txid).pipe(
|
||||
tap((response) => {
|
||||
if (response.status === 204) {
|
||||
this.error = `cannot_accelerate_tx`;
|
||||
@ -213,13 +217,13 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
amount: costUSD.toString(),
|
||||
label: 'Total',
|
||||
pending: true,
|
||||
productUrl: `${redirectHostname}/tracker/${this.txid}`,
|
||||
productUrl: `${redirectHostname}/tracker/${this.tx.txid}`,
|
||||
},
|
||||
button: { shape: 'semiround', size: 'small', theme: 'light'}
|
||||
});
|
||||
this.cashAppPay = await this.payments.cashAppPay(paymentRequest, {
|
||||
redirectURL: `${redirectHostname}/tracker/${this.txid}`,
|
||||
referenceId: `accelerator-${this.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`,
|
||||
redirectURL: `${redirectHostname}/tracker/${this.tx.txid}`,
|
||||
referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`,
|
||||
button: { shape: 'semiround', size: 'small', theme: 'light'}
|
||||
});
|
||||
|
||||
@ -235,7 +239,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
this.error = error;
|
||||
} else if (tokenResult.status === 'OK') {
|
||||
that.servicesApiService.accelerateWithCashApp$(
|
||||
that.txid,
|
||||
that.tx.txid,
|
||||
tokenResult.token,
|
||||
tokenResult.details.cashAppPay.cashtag,
|
||||
tokenResult.details.cashAppPay.referenceId,
|
||||
@ -277,7 +281,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
* BTCPay
|
||||
*/
|
||||
async requestBTCPayInvoice() {
|
||||
this.servicesApiService.generateBTCPayAcceleratorInvoice$(this.txid).subscribe({
|
||||
this.servicesApiService.generateBTCPayAcceleratorInvoice$(this.tx.txid).subscribe({
|
||||
next: (response) => {
|
||||
this.invoice = response;
|
||||
this.cd.markForCheck();
|
||||
|
@ -116,7 +116,9 @@
|
||||
|
||||
<div class="bottom-panel">
|
||||
@if (showAccelerationSummary && !accelerationFlowCompleted) {
|
||||
<app-accelerate-checkout *ngIf="(da$ | async) as da;" [cashappEnabled]="accelerationEligible" [txid]="tx.txid" [eta]="mempoolPosition?.block >= 7 ? null : da.adjustedTimeAvg * (mempoolPosition.block + 1) + now + da.timeOffset" (close)="accelerationFlowCompleted = true" [scrollEvent]="scrollIntoAccelPreview" class="h-100 w-100"></app-accelerate-checkout>
|
||||
<ng-container *ngIf="(ETA$ | async) as eta;">
|
||||
<app-accelerate-checkout *ngIf="(da$ | async) as da;" [cashappEnabled]="accelerationEligible" [tx]="tx" [miningStats]="miningStats" [eta]="eta" [isTracker]="true" (close)="accelerationFlowCompleted = true" [scrollEvent]="scrollIntoAccelPreview" class="h-100 w-100"></app-accelerate-checkout>
|
||||
</ng-container>
|
||||
} @else {
|
||||
@if (tx?.acceleration && !tx.status?.confirmed) {
|
||||
<div class="progress-icon">
|
||||
|
@ -84,9 +84,17 @@
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<div class="box">
|
||||
<app-accelerate-preview [tx]="tx" [miningStats]="miningStats" [scrollEvent]="scrollIntoAccelPreview" [showDetails]="showAccelerationDetails"></app-accelerate-preview>
|
||||
</div>
|
||||
@if (isLoggedIn()) {
|
||||
<div class="box">
|
||||
<app-accelerate-preview [tx]="tx" [miningStats]="miningStats" [scrollEvent]="scrollIntoAccelPreview" [showDetails]="showAccelerationDetails"></app-accelerate-preview>
|
||||
</div>
|
||||
} @else {
|
||||
<ng-container *ngIf="(ETA$ | async) as eta;">
|
||||
<app-accelerate-checkout *ngIf="(da$ | async) as da;" [cashappEnabled]="accelerationEligible" [tx]="tx" [eta]="eta" [miningStats]="miningStats" (close)="showAccelerationSummary = false" [scrollEvent]="scrollIntoAccelPreview" class="h-100 w-100">
|
||||
<span slot="cta-title">Urgent transaction? Get it confirmed faster.</span>
|
||||
</app-accelerate-checkout>
|
||||
</ng-container>
|
||||
}
|
||||
</ng-container>
|
||||
|
||||
<ng-template [ngIf]="showCpfpDetails">
|
||||
|
@ -140,6 +140,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
showAccelerationSummary = false;
|
||||
showAccelerationDetails = false;
|
||||
scrollIntoAccelPreview = false;
|
||||
accelerationEligible = false;
|
||||
auditEnabled: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true;
|
||||
|
||||
@ViewChild('graphContainer')
|
||||
@ -397,6 +398,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
} else if ((this.tx?.acceleration && txPosition.position.acceleratedBy)) {
|
||||
this.tx.acceleratedBy = txPosition.position.acceleratedBy;
|
||||
}
|
||||
this.accelerationEligible = txPosition?.position?.block > 0 && this.tx?.weight < 4000;
|
||||
}
|
||||
} else {
|
||||
this.mempoolPosition = null;
|
||||
@ -910,6 +912,11 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
isLoggedIn(): boolean {
|
||||
const auth = this.storageService.getAuth();
|
||||
return auth !== null;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.subscription.unsubscribe();
|
||||
this.fetchCpfpSubscription.unsubscribe();
|
||||
|
@ -6,7 +6,10 @@ import { SharedModule } from '../../shared/shared.module';
|
||||
import { TxBowtieModule } from '../tx-bowtie-graph/tx-bowtie.module';
|
||||
import { GraphsModule } from '../../graphs/graphs.module';
|
||||
import { AcceleratePreviewComponent } from '../accelerate-preview/accelerate-preview.component';
|
||||
import { AccelerateCheckout } from '../accelerate-checkout/accelerate-checkout.component';
|
||||
import { AccelerateFeeGraphComponent } from '../accelerate-preview/accelerate-fee-graph.component';
|
||||
import { TrackerComponent } from '../tracker/tracker.component';
|
||||
import { TrackerBarComponent } from '../tracker/tracker-bar.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -38,7 +41,10 @@ export class TransactionRoutingModule { }
|
||||
],
|
||||
declarations: [
|
||||
TransactionComponent,
|
||||
TrackerComponent,
|
||||
TrackerBarComponent,
|
||||
AcceleratePreviewComponent,
|
||||
AccelerateCheckout,
|
||||
AccelerateFeeGraphComponent,
|
||||
]
|
||||
})
|
||||
|
@ -50,8 +50,6 @@ import { BlockOverviewGraphComponent } from '../components/block-overview-graph/
|
||||
import { BlockOverviewTooltipComponent } from '../components/block-overview-tooltip/block-overview-tooltip.component';
|
||||
import { BlockFiltersComponent } from '../components/block-filters/block-filters.component';
|
||||
import { AddressGroupComponent } from '../components/address-group/address-group.component';
|
||||
import { TrackerComponent } from '../components/tracker/tracker.component';
|
||||
import { TrackerBarComponent } from '../components/tracker/tracker-bar.component';
|
||||
import { SearchFormComponent } from '../components/search-form/search-form.component';
|
||||
import { AddressLabelsComponent } from '../components/address-labels/address-labels.component';
|
||||
import { FooterComponent } from '../components/footer/footer.component';
|
||||
@ -100,7 +98,6 @@ import { MempoolErrorComponent } from './components/mempool-error/mempool-error.
|
||||
import { AccelerationsListComponent } from '../components/acceleration/accelerations-list/accelerations-list.component';
|
||||
import { PendingStatsComponent } from '../components/acceleration/pending-stats/pending-stats.component';
|
||||
import { AccelerationStatsComponent } from '../components/acceleration/acceleration-stats/acceleration-stats.component';
|
||||
import { AccelerateCheckout } from '../components/accelerate-checkout/accelerate-checkout.component';
|
||||
|
||||
import { BlockViewComponent } from '../components/block-view/block-view.component';
|
||||
import { EightBlocksComponent } from '../components/eight-blocks/eight-blocks.component';
|
||||
@ -165,8 +162,6 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
|
||||
BlockFiltersComponent,
|
||||
TransactionsListComponent,
|
||||
AddressGroupComponent,
|
||||
TrackerComponent,
|
||||
TrackerBarComponent,
|
||||
SearchFormComponent,
|
||||
AddressLabelsComponent,
|
||||
FooterComponent,
|
||||
@ -225,7 +220,6 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
|
||||
MempoolErrorComponent,
|
||||
AccelerationsListComponent,
|
||||
AccelerationStatsComponent,
|
||||
AccelerateCheckout,
|
||||
PendingStatsComponent,
|
||||
HttpErrorComponent,
|
||||
TwitterWidgetComponent,
|
||||
@ -307,8 +301,6 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
|
||||
BlockFiltersComponent,
|
||||
TransactionsListComponent,
|
||||
AddressGroupComponent,
|
||||
TrackerComponent,
|
||||
TrackerBarComponent,
|
||||
SearchFormComponent,
|
||||
AddressLabelsComponent,
|
||||
FooterComponent,
|
||||
@ -356,7 +348,6 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
|
||||
MempoolErrorComponent,
|
||||
AccelerationsListComponent,
|
||||
AccelerationStatsComponent,
|
||||
AccelerateCheckout,
|
||||
PendingStatsComponent,
|
||||
HttpErrorComponent,
|
||||
TwitterWidgetComponent,
|
||||
|
Loading…
x
Reference in New Issue
Block a user