import { CopyIcon, CreditCardIcon, ExternalLinkIcon, RefreshCwIcon, } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import AppHeader from "src/components/AppHeader"; import { FixedFloatButton } from "src/components/FixedFloatButton"; import { FormattedBitcoinAmount } from "src/components/FormattedBitcoinAmount"; import FormattedFiatAmount from "src/components/FormattedFiatAmount"; import Loading from "src/components/Loading"; import LottieLoading from "src/components/LottieLoading"; import LottieSuccess from "src/components/LottieSuccess"; import { MempoolAlert } from "src/components/MempoolAlert"; import OnchainAddressDisplay from "src/components/OnchainAddressDisplay"; import QRCode from "src/components/QRCode"; import ResponsiveLinkButton from "src/components/ResponsiveLinkButton"; import { Button } from "src/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle, } from "src/components/ui/card"; import { ExternalLinkButton } from "src/components/ui/custom/external-link-button"; import { LinkButton } from "src/components/ui/custom/link-button"; import { LoadingButton } from "src/components/ui/custom/loading-button"; import { Separator } from "src/components/ui/separator"; import { useInfo } from "src/hooks/useInfo"; import { useMempoolApi } from "src/hooks/useMempoolApi"; import { useOnchainAddress } from "src/hooks/useOnchainAddress"; import { useSyncWallet } from "src/hooks/useSyncWallet"; import { copyToClipboard } from "src/lib/clipboard"; import { MempoolUtxo } from "src/types"; export default function DepositBitcoin() { useSyncWallet(); const { data: onchainAddress, getNewAddress, loadingAddress, } = useOnchainAddress(); const { data: mempoolAddressUtxos } = useMempoolApi( onchainAddress ? `/address/${onchainAddress}/utxo` : undefined, 3000 ); const [txId, setTxId] = useState(""); const [confirmedAmountSat, setConfirmedAmountSat] = useState( null ); const [pendingAmountSat, setPendingAmountSat] = useState(null); const startTimeRef = useRef(0); useEffect(() => { if (startTimeRef.current === 0) { startTimeRef.current = Math.floor(Date.now() / 1000); } }, []); useEffect(() => { if ( !mempoolAddressUtxos || mempoolAddressUtxos.length === 0 || startTimeRef.current === 0 ) { return; } if (txId) { const utxo = mempoolAddressUtxos.find((utxo) => utxo.txid === txId); if (utxo?.status.confirmed) { setConfirmedAmountSat(utxo.value); setPendingAmountSat(null); } } else { const unconfirmed = mempoolAddressUtxos.find( (utxo) => !utxo.status.confirmed ); if (unconfirmed) { setTxId(unconfirmed.txid); setPendingAmountSat(unconfirmed.value); return; } const confirmed = mempoolAddressUtxos.find( (utxo) => utxo.status.confirmed && !!utxo.status.block_time && utxo.status.block_time >= startTimeRef.current ); if (confirmed) { setTxId(confirmed.txid); setConfirmedAmountSat(confirmed.value); setPendingAmountSat(null); } } }, [mempoolAddressUtxos, txId]); if (!onchainAddress) { return ; } return (
} />
{confirmedAmountSat ? ( ) : txId ? ( ) : (
{!loadingAddress && } Change
Top Up with Crypto
)}
); } function DepositPending({ amountSat, txId, }: { amountSat: number | null; txId: string; }) { const { data: info } = useInfo(); return ( Awaiting Confirmation {amountSat && (

)}
View on Mempool
); } function DepositSuccess({ amountSat, txId, }: { amountSat: number; txId: string; }) { const { data: info } = useInfo(); return ( <> Payment Received!

View on Mempool
Back To Node ); }