+
We are sorry, but we could not find find enough funds in your payment address! 😿
- No UTXO has enough value to execute a transaction at the set fees.
+ No UTXO has enough value to execute a transaction at the current fees.
We recommend sending at least
diff --git a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
index cd5c5f1f1..38026f300 100644
--- a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
+++ b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
@@ -1,7 +1,7 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';
import { hex } from '@scure/base';
-import { BehaviorSubject, catchError, combineLatest, map, of, shareReplay, switchMap, take, tap } from 'rxjs';
+import { BehaviorSubject, catchError, combineLatest, map, of, shareReplay, startWith, switchMap, take, tap } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { Cat21ApiService } from '../../../services/ordinals/cat21-api.service';
@@ -41,6 +41,7 @@ export class Cat21MintComponent implements OnInit {
simulation: SimulateTransactionResult;
paymentOutput: TxnOutput;
} | undefined = undefined;
+ utxosScanned = false;
unisatShowWarningThreshold = 10 * 1000;
@@ -62,6 +63,7 @@ export class Cat21MintComponent implements OnInit {
tap(() => {
this.utxoLoading = true;
this.utxoError = '';
+ this.cd.detectChanges();
}),
switchMap(wallet => this.cat21Service.getUtxos(wallet?.paymentAddress).pipe(
// retry({ count: 3, delay: 500 }), // Ordpool has a global interceptor for this, otherwise add this line
@@ -78,6 +80,7 @@ export class Cat21MintComponent implements OnInit {
tap(({ error }) => {
this.utxoLoading = false;
this.utxoError = error ? extractErrorMessage(error) : '';
+ this.cd.detectChanges();
})
))
);
@@ -89,19 +92,23 @@ export class Cat21MintComponent implements OnInit {
of({
mintingAllowed : true,
mintingAllowedAt: new Date().toISOString(),
+ level: 'Public'
}) : this.connectedWallet$.pipe(
tap(() => {
this.checkerLoading = true;
this.checkerError = '';
+ this.cd.detectChanges();
}),
switchMap(wallet => this.cat21ApiService.getWhitelistStatus(wallet.ordinalsAddress).pipe(
tap(() => {
this.checkerLoading = false;
this.checkerError = '';
+ this.cd.detectChanges();
}),
catchError(error => {
this.checkerLoading = false;
this.checkerError = error ? extractErrorMessage(error) : '';
+ this.cd.detectChanges();
return of(undefined);
})
)));
@@ -169,7 +176,10 @@ export class Cat21MintComponent implements OnInit {
.slice(0, 10); // limit to max 10 elements
}),
// sets it to the largest available UTXO or to undefined
- tap(simulateTransactions => this.selectedPaymentOutput = simulateTransactions[0]),
+ tap(simulateTransactions => {
+ this.selectedPaymentOutput = simulateTransactions[0];
+ this.cd.detectChanges();
+ }),
shareReplay({
bufferSize: 1,
refCount: true
diff --git a/frontend/src/app/components/ordinals/cat21-mint/countdown-timer-component.ts b/frontend/src/app/components/ordinals/cat21-mint/countdown-timer-component.ts
new file mode 100644
index 000000000..e77993689
--- /dev/null
+++ b/frontend/src/app/components/ordinals/cat21-mint/countdown-timer-component.ts
@@ -0,0 +1,42 @@
+import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
+import { Observable, interval, map, startWith, takeWhile } from 'rxjs';
+
+@Component({
+ selector: 'app-countdown-timer',
+ templateUrl: './countdown-timer.component.html',
+ styleUrls: ['./countdown-timer.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class CountdownTimerComponent implements OnInit {
+
+ @Input()
+ targetDate: string | undefined;
+ countdown$: Observable
;
+
+ ngOnInit() {
+ this.countdown$ = interval(1000).pipe(
+ startWith(0),
+ map(() => {
+
+ if (!this.targetDate) {
+ return '';
+ }
+
+ const now = new Date().getTime();
+ const distance = new Date(this.targetDate).getTime() - now;
+
+ if (distance < 0) {
+ return 'GO';
+ }
+
+ const days = Math.floor(distance / (1000 * 60 * 60 * 24));
+ const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
+ const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
+ const seconds = Math.floor((distance % (1000 * 60)) / 1000);
+
+ return `${days}d ${hours}h ${minutes}m ${seconds}s`;
+ }),
+ takeWhile(countdown => countdown !== 'GO', true)
+ );
+ }
+}
diff --git a/frontend/src/app/components/ordinals/cat21-mint/countdown-timer.component.html b/frontend/src/app/components/ordinals/cat21-mint/countdown-timer.component.html
new file mode 100644
index 000000000..a0bada7ac
--- /dev/null
+++ b/frontend/src/app/components/ordinals/cat21-mint/countdown-timer.component.html
@@ -0,0 +1,13 @@
+
+
+
+
CCC (Colossal Cat Countdown)
+
{{ countdown }}
+
+
+

+
+
Don't sleep on the cats!
+
+
+
diff --git a/frontend/src/app/components/ordinals/cat21-mint/countdown-timer.component.scss b/frontend/src/app/components/ordinals/cat21-mint/countdown-timer.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index 97fad170a..20454b83b 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -125,8 +125,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
digitalArtifactsPage = 1;
getParsedDigitalArtifacts(): DigitalArtifact[] {
- // just debugging: fake cat for every txn
- // this.tx.locktime = 21;
return DigitalArtifactsParserService.parse(this.tx);
}
diff --git a/frontend/src/app/services/ordinals/cat21.service.helper.ts b/frontend/src/app/services/ordinals/cat21.service.helper.ts
index 9501ce670..abac9c9dc 100644
--- a/frontend/src/app/services/ordinals/cat21.service.helper.ts
+++ b/frontend/src/app/services/ordinals/cat21.service.helper.ts
@@ -432,7 +432,7 @@ export function createTransaction(
const network: typeof btc.NETWORK = isMainnet ? btc.NETWORK : btc.TEST_NETWORK;
- const lockTime = 21; // THIS is the most important part 😺
+ const lockTime = 21;
const tx = new btc.Transaction({
lockTime,
allowLegacyWitnessUtxo: true, // for Unisat Legacy address
diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts
index 1b5e95e96..6bdecbbdc 100644
--- a/frontend/src/app/shared/shared.module.ts
+++ b/frontend/src/app/shared/shared.module.ts
@@ -119,6 +119,7 @@ import { FeesBoxClickableComponent } from '../components/fees-box-clickable/fees
import { WalletConnectComponent } from '../components/ordinals/wallet-connect/wallet-connect.component';
import { HighlightModule } from 'ngx-highlightjs';
import { Cat21MintComponent } from '../components/ordinals/cat21-mint/cat21-mint.component';
+import { CountdownTimerComponent } from '../components/ordinals/cat21-mint/countdown-timer-component';
import { Cat21CollabComponent } from '../components/ordinals/cat21-collab/cat21-collab.component';
import { Cat21WhitelistCheckerComponent } from '../components/ordinals/cat21-whitelist-checker/cat21-whitelist-checker.component';
@@ -233,6 +234,7 @@ import { Cat21WhitelistCheckerComponent } from '../components/ordinals/cat21-whi
FeesBoxClickableComponent,
WalletConnectComponent,
Cat21MintComponent,
+ CountdownTimerComponent,
Cat21CollabComponent,
Cat21WhitelistCheckerComponent
],
From 86cc040c08431482c60e84b54c0968d6c66f75df Mon Sep 17 00:00:00 2001
From: Hans Crypto
Date: Mon, 8 Apr 2024 01:35:21 +0200
Subject: [PATCH 7/8] polling to API (10 seconds to prevent too much load)
---
.../ordinals/cat21-mint/cat21-mint.component.ts | 2 +-
.../src/app/services/ordinals/cat21-api.service.ts | 11 ++++++++++-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
index 38026f300..df49b18df 100644
--- a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
+++ b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
@@ -99,7 +99,7 @@ export class Cat21MintComponent implements OnInit {
this.checkerError = '';
this.cd.detectChanges();
}),
- switchMap(wallet => this.cat21ApiService.getWhitelistStatus(wallet.ordinalsAddress).pipe(
+ switchMap(wallet => this.cat21ApiService.getWhitelistStatusPolled(wallet.ordinalsAddress).pipe(
tap(() => {
this.checkerLoading = false;
this.checkerError = '';
diff --git a/frontend/src/app/services/ordinals/cat21-api.service.ts b/frontend/src/app/services/ordinals/cat21-api.service.ts
index 03ac49a85..9e3d32533 100644
--- a/frontend/src/app/services/ordinals/cat21-api.service.ts
+++ b/frontend/src/app/services/ordinals/cat21-api.service.ts
@@ -1,6 +1,6 @@
import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
-import { Observable } from 'rxjs';
+import { Observable, interval, startWith, switchMap, takeWhile } from 'rxjs';
import { environment } from '../../../environments/environment';
import { WalletService } from './wallet.service';
@@ -98,4 +98,13 @@ export class Cat21ApiService {
getWhitelistStatus(walletAddress: string): Observable {
return this.http.get(`${this.baseUrl}/whitelist/status/${walletAddress}`);
}
+
+ getWhitelistStatusPolled(walletAddress: string): Observable {
+ return interval(10000).pipe(
+ startWith(0),
+ switchMap(() => this.http.get(`${this.baseUrl}/whitelist/status/${walletAddress}`)),
+ // Stop polling when mintingAllowed is true!
+ takeWhile((result: WhitelistStatusResult) => !result.mintingAllowed, true)
+ );
+ }
}
From f26df9fd79631e44c698741eafc8d731da5a96e4 Mon Sep 17 00:00:00 2001
From: Hans Crypto
Date: Tue, 9 Apr 2024 01:23:33 +0200
Subject: [PATCH 8/8] this works!? yay!
---
.../cat21-mint/cat21-mint.component.html | 28 +++++++++++--------
.../cat21-mint/cat21-mint.component.ts | 7 +++++
.../services/ordinals/cat21-api.service.ts | 15 ++++++++++
.../app/services/ordinals/cat21.service.ts | 23 +++++++++++++--
4 files changed, 59 insertions(+), 14 deletions(-)
diff --git a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.html b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.html
index 988f12f22..b475db8ec 100644
--- a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.html
+++ b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.html
@@ -154,12 +154,25 @@ Mint a CAT-21 Ordinal
-
@@ -172,13 +185,6 @@
Mint a CAT-21 Ordinal
Scanning your payments address
-
-
- Minting your cat
-
-
-
-
diff --git a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
index df49b18df..72c6df253 100644
--- a/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
+++ b/frontend/src/app/components/ordinals/cat21-mint/cat21-mint.component.ts
@@ -265,6 +265,13 @@ export class Cat21MintComponent implements OnInit {
this.mintCat21Loading = false;
this.mintCat21Success = result;
this.cd.detectChanges();
+
+ // announce mint very late, and not synchronized with the main pipe
+ // if this breaks, then it breaks - YOLO
+ this.cat21ApiService.announceMintTransaction({
+ transactionId: result.txId,
+ ...result
+ }).subscribe();
},
error: (err: Error) => {
this.mintCat21Loading = false;
diff --git a/frontend/src/app/services/ordinals/cat21-api.service.ts b/frontend/src/app/services/ordinals/cat21-api.service.ts
index 9e3d32533..f74947795 100644
--- a/frontend/src/app/services/ordinals/cat21-api.service.ts
+++ b/frontend/src/app/services/ordinals/cat21-api.service.ts
@@ -55,6 +55,17 @@ export interface WhitelistStatusResult {
mintingAllowedAt: string;
}
+export interface MintTransaction {
+ transactionId: string;
+ network: string;
+ transactionHex: string;
+ paymentAddress: string;
+ recipientAddress: string;
+ createdAt: string;
+}
+
+
+
@Injectable({
providedIn: 'root'
@@ -107,4 +118,8 @@ export class Cat21ApiService {
takeWhile((result: WhitelistStatusResult) => !result.mintingAllowed, true)
);
}
+
+ announceMintTransaction(mintTransaction: MintTransaction) {
+ return this.http.post