[accelerator] accelerate with lightning
This commit is contained in:
parent
f1572f0038
commit
66a88b8422
@ -58,12 +58,24 @@
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
}
|
||||
|
||||
@else if (step === 'checkout') {
|
||||
<!-- Show checkout page -->
|
||||
|
||||
} @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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-2 d-flex justify-content-around">
|
||||
@if (cashappEnabled) {
|
||||
<img class="paymentMethod" src="/resources/cash-app.svg" height=55 (click)="selectPaymentMethod('cashapp')">
|
||||
}
|
||||
<img class="paymentMethod" src="/resources/btcpay.svg" height=55 (click)="selectPaymentMethod('btcpay')">
|
||||
</div>
|
||||
|
||||
} @else if (step === 'checkout') {
|
||||
<!-- 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>
|
||||
</div>
|
||||
</div>
|
||||
@ -76,36 +88,40 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (!loadingCashapp) {
|
||||
@if (paymentMethod === 'cashapp') {
|
||||
@if (!loadingCashapp) {
|
||||
<div class="row text-center mt-1">
|
||||
<div class="col-sm">
|
||||
<div class="form-group w-100">
|
||||
<span><u><strong>Total additional cost</strong></u><br>
|
||||
<span style="font-size: 16px" class="d-block mt-2">
|
||||
Pay
|
||||
<strong><app-fiat [value]="cost"></app-fiat></strong>
|
||||
with
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="row text-center mt-1">
|
||||
<div class="col-sm">
|
||||
<div class="form-group w-100">
|
||||
<span><u><strong>Total additional cost</strong></u><br>
|
||||
<span style="font-size: 16px" class="d-block mt-2">
|
||||
Pay
|
||||
<strong><app-fiat [value]="cost"></app-fiat></strong>
|
||||
with
|
||||
</span>
|
||||
</span>
|
||||
<div id="cash-app-pay" class="d-inline-block" [style]="loadingCashapp ? 'opacity: 0; width: 0px; height: 0px; pointer-events: none;' : ''"></div>
|
||||
@if (loadingCashapp) {
|
||||
<div display="d-flex flex-row justify-content-center">
|
||||
<span>Loading payment method...</span>
|
||||
<div class="ml-2 spinner-border text-light" style="width: 25px; height: 25px"></div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @else if (paymentMethod === 'btcpay' && invoice?.btcpayInvoiceId) {
|
||||
<app-bitcoin-invoice [invoiceId]="invoice.btcpayInvoiceId" (completed)="closeModal(2000)"></app-bitcoin-invoice>
|
||||
}
|
||||
|
||||
<div class="row text-center mt-1">
|
||||
<div class="col-sm">
|
||||
<div class="form-group w-100">
|
||||
<div id="cash-app-pay" class="d-inline-block" [style]="loadingCashapp ? 'opacity: 0; width: 0px; height: 0px; pointer-events: none;' : ''"></div>
|
||||
@if (loadingCashapp) {
|
||||
<div display="d-flex flex-row justify-content-center">
|
||||
<span>Loading payment method...</span>
|
||||
<div class="ml-2 spinner-border text-light" style="width: 25px; height: 25px"></div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class="row mt-2 mb-2 text-center">
|
||||
<div class="col-sm d-flex flex-column">
|
||||
@ -118,7 +134,7 @@
|
||||
@else if (step === 'processing') {
|
||||
<div class="row mb-1 text-center">
|
||||
<div class="col-sm">
|
||||
<h1 style="font-size: larger;">Confirm your payment</h1>
|
||||
<h1 style="font-size: larger;">Confirming your payment</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -7,3 +7,11 @@
|
||||
.estimating {
|
||||
color: var(--green)
|
||||
}
|
||||
|
||||
.paymentMethod {
|
||||
padding: 10px;
|
||||
background-color: var(--secondary);
|
||||
border-radius: 15px;
|
||||
border: 2px solid var(--bg);
|
||||
cursor: pointer;
|
||||
}
|
@ -16,12 +16,16 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
@Input() eta: number | null = null;
|
||||
@Input() txid: string = '70c18d76cdb285a1b5bd87fdaae165880afa189809c30b4083ff7c0e69ee09ad';
|
||||
@Input() scrollEvent: boolean;
|
||||
@Input() cashappEnabled: boolean;
|
||||
@Output() close = new EventEmitter<null>();
|
||||
|
||||
calculating = true;
|
||||
choosenOption: 'wait' | 'accelerate' = 'wait';
|
||||
error = '';
|
||||
|
||||
step: 'paymentMethod' | 'cta' | 'checkout' | 'processing' = 'cta';
|
||||
paymentMethod: 'cashapp' | 'btcpay';
|
||||
|
||||
// accelerator stuff
|
||||
square: { appId: string, locationId: string};
|
||||
accelerationUUID: string;
|
||||
@ -38,7 +42,10 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
cashAppPay: any;
|
||||
cashAppSubscription: Subscription;
|
||||
conversionsSubscription: Subscription;
|
||||
step: 'cta' | 'checkout' | 'processing' = 'cta';
|
||||
|
||||
// btcpay
|
||||
loadingBtcpayInvoice = false;
|
||||
invoice = undefined;
|
||||
|
||||
constructor(
|
||||
private servicesApiService: ServicesApiServices,
|
||||
@ -77,19 +84,19 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes.scrollEvent) {
|
||||
this.scrollToPreview('acceleratePreviewAnchor', 'start');
|
||||
this.scrollToElement('acceleratePreviewAnchor', 'start');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll to element id with or without setTimeout
|
||||
*/
|
||||
scrollToPreviewWithTimeout(id: string, position: ScrollLogicalPosition) {
|
||||
scrollToElementWithTimeout(id: string, position: ScrollLogicalPosition, timeout: number = 1000) {
|
||||
setTimeout(() => {
|
||||
this.scrollToPreview(id, position);
|
||||
}, 1000);
|
||||
this.scrollToElement(id, position);
|
||||
}, timeout);
|
||||
}
|
||||
scrollToPreview(id: string, position: ScrollLogicalPosition) {
|
||||
scrollToElement(id: string, position: ScrollLogicalPosition) {
|
||||
const acceleratePreviewAnchor = document.getElementById(id);
|
||||
if (acceleratePreviewAnchor) {
|
||||
this.cd.markForCheck();
|
||||
@ -111,7 +118,6 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
this.calculating = true;
|
||||
this.estimateSubscription = this.servicesApiService.estimate$(this.txid).pipe(
|
||||
tap((response) => {
|
||||
this.calculating = false;
|
||||
if (response.status === 204) {
|
||||
this.error = `cannot_accelerate_tx`;
|
||||
} else {
|
||||
@ -126,6 +132,8 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
this.maxBidBoost = minExtraBoost * DEFAULT_BID_RATIO;
|
||||
this.cost = this.maxBidBoost + this.estimate.mempoolBaseFee + this.estimate.vsizeFee;
|
||||
this.etaInfo$ = this.etaService.getProjectedEtaObservable(this.estimate);
|
||||
this.calculating = false;
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
}),
|
||||
|
||||
@ -265,19 +273,48 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* BTCPay
|
||||
*/
|
||||
async requestBTCPayInvoice() {
|
||||
this.servicesApiService.generateBTCPayAcceleratorInvoice$(this.txid).subscribe({
|
||||
next: (response) => {
|
||||
this.invoice = response;
|
||||
this.cd.markForCheck();
|
||||
this.scrollToElementWithTimeout('acceleratePreviewAnchor', 'start', 500);
|
||||
},
|
||||
error: (response) => {
|
||||
console.log(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* UI events
|
||||
*/
|
||||
enableCheckoutPage() {
|
||||
this.step = 'paymentMethod';
|
||||
}
|
||||
selectPaymentMethod(paymentMethod: 'cashapp' | 'btcpay') {
|
||||
this.step = 'checkout';
|
||||
this.loadingCashapp = true;
|
||||
this.insertSquare();
|
||||
this.setupSquare();
|
||||
this.paymentMethod = paymentMethod;
|
||||
if (paymentMethod === 'cashapp') {
|
||||
this.loadingCashapp = true;
|
||||
this.insertSquare();
|
||||
this.setupSquare();
|
||||
} else if (paymentMethod === 'btcpay') {
|
||||
this.loadingBtcpayInvoice = true;
|
||||
this.requestBTCPayInvoice();
|
||||
}
|
||||
}
|
||||
selectedOptionChanged(event) {
|
||||
this.choosenOption = event.target.id;
|
||||
}
|
||||
closeModal(): void {
|
||||
this.close.emit();
|
||||
closeModal(timeout: number = 0): void {
|
||||
setTimeout(() => {
|
||||
this.step = 'processing';
|
||||
this.cd.markForCheck();
|
||||
this.close.emit();
|
||||
}, timeout);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,89 @@
|
||||
<div class="wrapper">
|
||||
|
||||
<span *ngIf="paymentStatus === 3" class="valid-feedback d-block mt-5">
|
||||
Payment successful. You can close this page.
|
||||
</span>
|
||||
|
||||
<span *ngIf="paymentStatus === 4" class="valid-feedback d-block mt-5">
|
||||
A transaction <a [href]="'/tx/' + invoice.cryptoInfo[0].payments[0].id.split('-')[0]">has been detected in the mempool</a> fully paying for this invoice. Waiting for on-chain confirmation.
|
||||
</span>
|
||||
|
||||
<div *ngIf="paymentStatus === 2">
|
||||
|
||||
<form [formGroup]="paymentForm">
|
||||
|
||||
<div class="form-group">
|
||||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<!-- <label *ngIf="invoice.addresses.BTC" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'chain'}">
|
||||
<input type="radio" value="chain" formControlName="method"> <fa-icon [icon]="['fas', 'link']" [fixedWidth]="true" title="Onchain"></fa-icon>
|
||||
</label> -->
|
||||
<label *ngIf="invoice.addresses.BTC_LightningLike" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'lightning'}">
|
||||
<input type="radio" value="lightning" formControlName="method"> <fa-icon [icon]="['fas', 'bolt']" [fixedWidth]="true" title="Lightning"></fa-icon>
|
||||
</label>
|
||||
<!-- <label *ngIf="invoice.addresses.LBTC" class="btn btn-primary" [ngClass]="{'active': paymentForm.get('method')?.value === 'lbtc'}">
|
||||
<input type="radio" value="lbtc" formControlName="method"> <fa-icon [icon]="['fas', 'tint']" [fixedWidth]="true" title="Liquid Bitcoin"></fa-icon>
|
||||
</label> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<ng-template [ngIf]="paymentForm.get('method')?.value === 'chain' && invoice">
|
||||
|
||||
<div class="qr-wrapper">
|
||||
<a [href]="bypassSecurityTrustUrl('bitcoin:' + invoice.addresses.BTC + '?amount=' + invoice.amount)" target="_blank">
|
||||
<app-qrcode imageUrl="/resources/bitcoin-logo.png" [size]="200" [data]="'bitcoin:' + invoice.addresses.BTC + '?amount=' + invoice.amount"></app-qrcode>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="input-group input-group-sm info-group">
|
||||
<input type="text" class="form-control input-dark" readonly [value]="invoice.addresses.BTC">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" type="button" ><app-clipboard [text]="invoice.addresses.BTC"></app-clipboard></button>
|
||||
</div>
|
||||
</div>
|
||||
<p>{{ invoice.amount }} <span class="symbol">BTC</span></p>
|
||||
|
||||
</ng-template>
|
||||
|
||||
<ng-template [ngIf]="paymentForm.get('method')?.value === 'lightning' && invoice">
|
||||
|
||||
<div class="qr-wrapper">
|
||||
<a [href]="bypassSecurityTrustUrl('lightning:' + invoice.addresses.BTC_LightningLike)" target="_blank">
|
||||
<app-qrcode imageUrl="/resources/bitcoin-logo.png" [size]="200" [data]="invoice.addresses.BTC_LightningLike.toUpperCase()"></app-qrcode>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="input-group input-group-sm info-group">
|
||||
<input type="text" class="form-control input-dark" readonly [value]="invoice.addresses.BTC_LightningLike">
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" type="button"><app-clipboard [text]="invoice.addresses.BTC_LightningLike"></app-clipboard></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>{{ invoice.amount * 100_000_000 }} <span class="symbol">sats</span></p>
|
||||
|
||||
</ng-template>
|
||||
|
||||
<ng-template [ngIf]="invoice && (paymentForm.get('method')?.value === 'lbtc' || paymentForm.get('method')?.value === 'tlbtc')">
|
||||
|
||||
<div class="qr-wrapper">
|
||||
<a [href]="bypassSecurityTrustUrl('liquidnetwork:' + invoice.addresses.LBTC + '?amount=' + invoice.amount + '&assetid=6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d')" target="_blank">
|
||||
<app-qrcode imageUrl="/resources/liquid-bitcoin.png" [size]="200" [data]="'liquidnetwork:' + invoice.addresses.LBTC + '?amount=' + invoice.amount + '&assetid=6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d'"></app-qrcode>
|
||||
</a>
|
||||
</div>
|
||||
<br>
|
||||
<div class="input-group input-group-sm info-group">
|
||||
<input type="text" class="form-control input-dark" readonly [value]="invoice.addresses.LBTC" />
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-outline-secondary" type="button" ><app-clipboard [text]="invoice.addresses.LBTC"></app-clipboard></button>
|
||||
</div>
|
||||
</div>
|
||||
<p>{{ invoice.amount }} <span class="symbol">BTC</span></p>
|
||||
|
||||
</ng-template>
|
||||
|
||||
<p>Waiting for transaction... </p>
|
||||
<div class="spinner-border text-light"></div>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,149 @@
|
||||
.form-panel {
|
||||
background-color: #292b45;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
.sponsor-page {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.qr-wrapper {
|
||||
background-color: #FFF;
|
||||
padding: 10px;
|
||||
display: inline-block;
|
||||
padding-bottom: 5px;
|
||||
margin: 20px auto 0px;
|
||||
}
|
||||
|
||||
.info-group {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.card {
|
||||
width: 240px;
|
||||
height: 220px;
|
||||
background-color: var(--bg);
|
||||
border: 2px solid var(--bg);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transition: 100ms all;
|
||||
margin: 30px 30px 20px 30px;
|
||||
@media(min-width: 476px) {
|
||||
margin: 30px 100px 20px 100px;
|
||||
}
|
||||
@media(min-width: 851px) {
|
||||
margin: 60px 20px 40px 20px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-weight: bold;
|
||||
span {
|
||||
font-weight: 100;
|
||||
}
|
||||
}
|
||||
|
||||
&.bigger {
|
||||
height: 220px;
|
||||
width: 240px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: #5058926b;
|
||||
border: 2px solid #505892;
|
||||
transform: scale(1.1) translateY(-10px);
|
||||
margin-top: 70px;
|
||||
|
||||
.card-header {
|
||||
background-color: #505892;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.donation-form {
|
||||
max-width: 280px;
|
||||
margin: auto;
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background-color: #171929;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.middle-card {
|
||||
width: 280px;
|
||||
height: 260px;
|
||||
margin-top: 40px;
|
||||
&:hover {
|
||||
margin-top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.shiny-border {
|
||||
background-color: #5058926b;
|
||||
border: 2px solid #505892;
|
||||
transform: scale(1.1) translateY(-10px);
|
||||
margin-top: 70px;
|
||||
box-shadow: 0px 0px 100px #9858ff52;
|
||||
.card-header {
|
||||
background-color: #505892;
|
||||
}
|
||||
|
||||
&.middle-card {
|
||||
margin-top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group {
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.donation-confirmed {
|
||||
h2 {
|
||||
margin-top: 50px;
|
||||
span {
|
||||
display: block;
|
||||
&:last-child {
|
||||
color: #9858ff;
|
||||
font-weight: bold;
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-details {
|
||||
margin-top: 50px;
|
||||
span {
|
||||
color: #d81b60;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-body {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.input-dark {
|
||||
background-color: var(--bg);
|
||||
border-color: var(--active-bg);
|
||||
color: white;
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output } from '@angular/core';
|
||||
import { FormBuilder, FormGroup } from '@angular/forms';
|
||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Subscription, timer } from 'rxjs';
|
||||
import { retry, switchMap, tap } from 'rxjs/operators';
|
||||
import { ServicesApiServices } from '../../services/services-api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-bitcoin-invoice',
|
||||
templateUrl: './bitcoin-invoice.component.html',
|
||||
styleUrls: ['./bitcoin-invoice.component.scss']
|
||||
})
|
||||
export class BitcoinInvoiceComponent implements OnInit, OnDestroy {
|
||||
@Input() invoiceId: string;
|
||||
@Input() redirect = true;
|
||||
@Output() completed = new EventEmitter();
|
||||
|
||||
paymentForm: FormGroup;
|
||||
requestSubscription: Subscription | undefined;
|
||||
paymentStatusSubscription: Subscription | undefined;
|
||||
invoice: any;
|
||||
paymentStatus = 1; // 1 - Waiting for invoice | 2 - Pending payment | 3 - Payment completed
|
||||
paramMapSubscription: Subscription | undefined;
|
||||
invoiceSubscription: Subscription | undefined;
|
||||
invoiceTimeout; // Wait for angular to load all the things before making a request
|
||||
|
||||
constructor(
|
||||
private formBuilder: FormBuilder,
|
||||
private apiService: ServicesApiServices,
|
||||
private sanitizer: DomSanitizer,
|
||||
private activatedRoute: ActivatedRoute
|
||||
) { }
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.requestSubscription) {
|
||||
this.requestSubscription.unsubscribe();
|
||||
}
|
||||
if (this.paramMapSubscription) {
|
||||
this.paramMapSubscription.unsubscribe();
|
||||
}
|
||||
if (this.invoiceSubscription) {
|
||||
this.invoiceSubscription.unsubscribe();
|
||||
}
|
||||
if (this.paymentStatusSubscription) {
|
||||
this.paymentStatusSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.paymentForm = this.formBuilder.group({
|
||||
'method': 'lightning'
|
||||
});
|
||||
|
||||
/**
|
||||
* If the invoice is passed in the url, fetch it and display btcpay payment
|
||||
* Otherwise get a new invoice
|
||||
*/
|
||||
this.paramMapSubscription = this.activatedRoute.paramMap
|
||||
.pipe(
|
||||
tap((paramMap) => {
|
||||
const invoiceId = paramMap.get('invoiceId') ?? this.invoiceId;
|
||||
if (invoiceId) {
|
||||
this.paymentStatusSubscription = this.apiService.retreiveInvoice$(invoiceId).pipe(
|
||||
tap((invoice: any) => {
|
||||
this.invoice = invoice;
|
||||
this.invoice.amount = invoice.btcDue ?? (invoice.cryptoInfo.length ? parseFloat(invoice.cryptoInfo[0].totalDue) : 0) ?? 0;
|
||||
|
||||
if (this.invoice.amount > 0) {
|
||||
this.paymentStatus = 2;
|
||||
} else {
|
||||
this.paymentStatus = 4;
|
||||
}
|
||||
}),
|
||||
switchMap(() => this.apiService.getPaymentStatus$(this.invoice.id)
|
||||
.pipe(
|
||||
retry({ delay: () => timer(2000)})
|
||||
)
|
||||
),
|
||||
).subscribe({
|
||||
next: ((result) => {
|
||||
this.paymentStatus = 3;
|
||||
this.completed.emit();
|
||||
}),
|
||||
});
|
||||
}
|
||||
})
|
||||
).subscribe();
|
||||
}
|
||||
|
||||
bypassSecurityTrustUrl(text: string): SafeUrl {
|
||||
return this.sanitizer.bypassSecurityTrustUrl(text);
|
||||
}
|
||||
}
|
@ -75,7 +75,7 @@
|
||||
} @else {
|
||||
<app-time kind="until" [time]="eta.time" [fastRender]="false" [fixedRender]="true"></app-time>
|
||||
}
|
||||
@if (!showAccelerationSummary && isMobile && paymentType === 'cashapp' && accelerationEligible && !tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) {
|
||||
@if (!showAccelerationSummary && isMobile && !tx.acceleration && acceleratorAvailable && accelerateCtaType === 'button' && !tx?.acceleration) {
|
||||
<a class="btn btn-sm accelerate btn-small-height" i18n="transaction.accelerate|Accelerate button label" (click)="onAccelerateClicked()">Accelerate</a>
|
||||
}
|
||||
</span>
|
||||
@ -116,7 +116,7 @@
|
||||
|
||||
<div class="bottom-panel">
|
||||
@if (showAccelerationSummary && !accelerationFlowCompleted) {
|
||||
<app-accelerate-checkout *ngIf="(da$ | async) as da;" [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>
|
||||
<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>
|
||||
} @else {
|
||||
@if (tx?.acceleration && !tx.status?.confirmed) {
|
||||
<div class="progress-icon">
|
||||
|
@ -107,7 +107,6 @@ export class TrackerComponent implements OnInit, OnDestroy {
|
||||
now = Date.now();
|
||||
da$: Observable<DifficultyAdjustment>;
|
||||
isMobile: boolean;
|
||||
paymentType: 'bitcoin' | 'cashapp' = 'bitcoin';
|
||||
|
||||
trackerStage: TrackerStage = 'waiting';
|
||||
|
||||
@ -158,9 +157,6 @@ export class TrackerComponent implements OnInit, OnDestroy {
|
||||
|
||||
this.acceleratorAvailable = this.stateService.env.OFFICIAL_MEMPOOL_SPACE && this.stateService.env.ACCELERATOR && this.stateService.network === '';
|
||||
|
||||
if (this.acceleratorAvailable && this.stateService.referrer === 'https://cash.app/') {
|
||||
this.paymentType = 'cashapp';
|
||||
}
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get('cash_request_id')) {
|
||||
this.showAccelerationSummary = true;
|
||||
@ -390,11 +386,9 @@ export class TrackerComponent implements OnInit, OnDestroy {
|
||||
this.trackerStage = 'replaced';
|
||||
}
|
||||
|
||||
this.showAccelerationSummary = true;
|
||||
if (txPosition.position?.block > 0 && this.tx.weight < 4000) {
|
||||
this.accelerationEligible = true;
|
||||
if (this.acceleratorAvailable && this.paymentType === 'cashapp') {
|
||||
this.showAccelerationSummary = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -167,4 +167,19 @@ export class ServicesApiServices {
|
||||
requestTestnet4Coins$(address: string, sats: number) {
|
||||
return this.httpClient.get<{txid: string}>(`${SERVICES_API_PREFIX}/testnet4/faucet/request?address=${address}&sats=${sats}`, { responseType: 'json' });
|
||||
}
|
||||
|
||||
generateBTCPayAcceleratorInvoice$(txid: string): Observable<any> {
|
||||
const params = {
|
||||
product: txid
|
||||
};
|
||||
return this.httpClient.post<any>(`${SERVICES_API_PREFIX}/payments/bitcoin`, params);
|
||||
}
|
||||
|
||||
retreiveInvoice$(invoiceId: string): Observable<any[]> {
|
||||
return this.httpClient.get<any[]>(`${SERVICES_API_PREFIX}/payments/bitcoin/invoice?id=${invoiceId}`);
|
||||
}
|
||||
|
||||
getPaymentStatus$(orderId: string): Observable<any[]> {
|
||||
return this.httpClient.get<any[]>(`${SERVICES_API_PREFIX}/payments/bitcoin/check?order_id=${orderId}`);
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ import { HttpErrorComponent } from '../shared/components/http-error/http-error.c
|
||||
import { TwitterWidgetComponent } from '../components/twitter-widget/twitter-widget.component';
|
||||
import { FaucetComponent } from '../components/faucet/faucet.component';
|
||||
import { TwitterLogin } from '../components/twitter-login/twitter-login.component';
|
||||
import { BitcoinInvoiceComponent } from '../components/bitcoin-invoice/bitcoin-invoice.component';
|
||||
|
||||
import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-directives/weight-directives';
|
||||
|
||||
@ -230,6 +231,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
|
||||
TwitterWidgetComponent,
|
||||
FaucetComponent,
|
||||
TwitterLogin,
|
||||
BitcoinInvoiceComponent,
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
@ -359,6 +361,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
|
||||
HttpErrorComponent,
|
||||
TwitterWidgetComponent,
|
||||
TwitterLogin,
|
||||
BitcoinInvoiceComponent,
|
||||
|
||||
MempoolBlockOverviewComponent,
|
||||
ClockchainComponent,
|
||||
|
Loading…
x
Reference in New Issue
Block a user