diff --git a/src/components/WalletViewer.tsx b/src/components/WalletViewer.tsx index 148a37e..8088778 100644 --- a/src/components/WalletViewer.tsx +++ b/src/components/WalletViewer.tsx @@ -1,5 +1,16 @@ -import { useState } from "react"; -import { Wallet, Zap, RefreshCw, Copy, Check } from "lucide-react"; +import { useState, useEffect, useCallback } from "react"; +import { + Wallet, + Zap, + RefreshCw, + Copy, + Check, + ChevronDown, + ChevronRight, + ArrowUpRight, + ArrowDownLeft, + Clock, +} from "lucide-react"; import { use$ } from "applesauce-react/hooks"; import walletManager from "@/services/wallet"; import { Button } from "@/components/ui/button"; @@ -7,12 +18,17 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { toast } from "sonner"; import WalletConnectDialog from "./WalletConnectDialog"; import { npubEncode } from "applesauce-core/helpers"; +import { formatDistanceToNow } from "date-fns"; +import type { Transaction } from "applesauce-wallet-connect/helpers/methods"; export default function WalletViewer() { const walletState = use$(walletManager.state$); const [showConnect, setShowConnect] = useState(false); const [isRefreshing, setIsRefreshing] = useState(false); const [copiedPubkey, setCopiedPubkey] = useState(false); + const [transactions, setTransactions] = useState([]); + const [isLoadingTx, setIsLoadingTx] = useState(false); + const [showTransactions, setShowTransactions] = useState(false); async function handleRefresh() { setIsRefreshing(true); @@ -44,6 +60,32 @@ export default function WalletViewer() { return sats.toLocaleString(); } + const supportsTransactions = + walletState.info?.methods.includes("list_transactions"); + + const loadTransactions = useCallback(async () => { + const wallet = walletManager.getWallet(); + if (!wallet || !supportsTransactions) return; + + setIsLoadingTx(true); + try { + const result = await wallet.listTransactions({ + limit: 50, + }); + setTransactions(result.transactions || []); + } catch (_error) { + toast.error("Failed to load transactions"); + } finally { + setIsLoadingTx(false); + } + }, [supportsTransactions]); + + useEffect(() => { + if (showTransactions && transactions.length === 0) { + loadTransactions(); + } + }, [showTransactions, transactions.length, loadTransactions]); + if (!walletState.connected || !walletState.info) { return (
@@ -152,6 +194,47 @@ export default function WalletViewer() { + {/* Transactions */} + {supportsTransactions && ( + + setShowTransactions(!showTransactions)} + > +
+ + Transactions + +
+ {isLoadingTx && ( + + )} + {showTransactions ? ( + + ) : ( + + )} +
+
+
+ {showTransactions && ( + + {transactions.length === 0 ? ( +
+ {isLoadingTx ? "Loading..." : "No transactions"} +
+ ) : ( +
+ {transactions.map((tx) => ( + + ))} +
+ )} +
+ )} +
+ )} + {/* Actions */}