diff --git a/src/app/components/vault/components/vault-progress-bar.tsx b/src/app/components/vault/components/vault-progress-bar.tsx
index 5c730861..a3375457 100644
--- a/src/app/components/vault/components/vault-progress-bar.tsx
+++ b/src/app/components/vault/components/vault-progress-bar.tsx
@@ -1,15 +1,28 @@
import { Box, Progress, Text, VStack } from "@chakra-ui/react";
+import { VaultState } from "@models/vault";
interface VaultProgressBarProps {
confirmedBlocks: number;
+ vaultState: VaultState;
}
export function VaultProgressBar({
confirmedBlocks,
-}: VaultProgressBarProps): React.JSX.Element {
+ vaultState,
+}: VaultProgressBarProps): React.JSX.Element | boolean {
+ const shouldBeIndeterminate = confirmedBlocks > 6;
+
+ if (vaultState === VaultState.CLOSED && confirmedBlocks > 6) return false;
return (
-
+
- WAITING FOR CONFIRMATIONS: {confirmedBlocks}/6
+ {shouldBeIndeterminate
+ ? "PROCESSING"
+ : `WAITING FOR CONFIRMATIONS: ${confirmedBlocks}/6`}
diff --git a/src/app/components/vault/vault-card.tsx b/src/app/components/vault/vault-card.tsx
index e2e3b7e2..7334447f 100644
--- a/src/app/components/vault/vault-card.tsx
+++ b/src/app/components/vault/vault-card.tsx
@@ -1,6 +1,7 @@
import React, { useState } from "react";
import { CustomSkeleton } from "@components/custom-skeleton/custom-skeleton";
+import { useConfirmationChecker } from "@hooks/use-confirmation-checker";
import { Vault, VaultState } from "@models/vault";
import { VaultCardLayout } from "./components/vault-card.layout";
@@ -21,7 +22,11 @@ export function VaultCard({
isSelectable = false,
handleSelect,
}: VaultBoxProps): React.JSX.Element {
- const confirmedBlocks = 3;
+ const confirmations = useConfirmationChecker(
+ vault?.state === VaultState.FUNDING ? vault?.fundingTX : vault?.closingTX,
+ vault?.state,
+ );
+
const [isExpanded, setIsExpanded] = useState(isSelected ? true : false);
if (!vault) return ;
@@ -48,8 +53,11 @@ export function VaultCard({
isExpanded={isExpanded}
/>
)}
- {[VaultState.FUNDING, VaultState.CLOSING].includes(vault.state) && (
-
+ {[VaultState.FUNDING, VaultState.CLOSED].includes(vault.state) && (
+
)}
);
diff --git a/src/app/hooks/use-confirmation-checker.ts b/src/app/hooks/use-confirmation-checker.ts
new file mode 100644
index 00000000..b1d78417
--- /dev/null
+++ b/src/app/hooks/use-confirmation-checker.ts
@@ -0,0 +1,74 @@
+import { useEffect, useMemo, useRef, useState } from "react";
+
+import { VaultState } from "@models/vault";
+
+export function useConfirmationChecker(
+ txID: string | undefined,
+ vaultState: VaultState | undefined,
+): number {
+ const bitcoinExplorerTXURL = `https://devnet.dlc.link/electrs/tx/${txID}`;
+ const bitcoinExplorerHeightURL = `https://devnet.dlc.link/electrs/blocks/tip/height`;
+ const fetchInterval = useRef(undefined);
+
+ const [transactionProgress, setTransactionProgress] = useState(0);
+
+ const memoizedTransactionProgress = useMemo(
+ () => transactionProgress,
+ [transactionProgress],
+ );
+
+ const fetchTransactionDetails = async () => {
+ if (
+ !txID ||
+ (vaultState &&
+ ![VaultState.FUNDING, VaultState.CLOSED].includes(vaultState))
+ ) {
+ clearInterval(fetchInterval.current);
+ return;
+ }
+
+ let bitcoinCurrentBlockHeight;
+ try {
+ const response = await fetch(bitcoinExplorerHeightURL, {
+ headers: { Accept: "application/json" },
+ });
+ bitcoinCurrentBlockHeight = await response.json();
+ } catch (error) {
+ console.error(error);
+ }
+
+ let bitcoinTransactionBlockHeight;
+
+ try {
+ const response = await fetch(bitcoinExplorerTXURL, {
+ headers: { Accept: "application/json" },
+ });
+ const bitcoinTransactionDetails = await response.json();
+ bitcoinTransactionBlockHeight =
+ bitcoinTransactionDetails.status.block_height;
+ } catch (error) {
+ console.error(error);
+ }
+
+ const difference =
+ bitcoinCurrentBlockHeight - bitcoinTransactionBlockHeight;
+
+ setTransactionProgress(difference);
+
+ if (difference > 6) {
+ clearInterval(fetchInterval.current);
+ }
+ };
+
+ fetchTransactionDetails();
+
+ useEffect(() => {
+ fetchInterval.current = setInterval(
+ fetchTransactionDetails,
+ 10000,
+ ) as unknown as number; // Cleanup the interval when the component unmounts
+ return () => clearInterval(fetchInterval.current);
+ }, []);
+
+ return memoizedTransactionProgress;
+}