import { useState, useEffect } from 'react' import type { Address } from 'viem' import { getTransactionStore } from '../../storage/transaction-store.js' import type { StoredTransaction } from '../../types/transaction.js' import { TransactionStatus } from '../../types/transaction.js' /** * Hook for accessing all transactions in Ink components. * Provides the complete list of stored transactions. * * @example * ```tsx * function TransactionListScreen() { * const { transactions, loading, error } = useTransactions() * * if (loading) return * if (error) return {error} * * return ( * } * /> * ) * } * ``` */ export function useTransactions() { const [transactions, setTransactions] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { try { const txStore = getTransactionStore() const allTxs = txStore.getAllTransactions() setTransactions(allTxs) setLoading(false) } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load transactions') setLoading(false) } }, []) return { transactions, loading, error } } /** * Hook for accessing a specific transaction by Safe transaction hash. * * @param safeTxHash - The Safe transaction hash * * @example * ```tsx * function TransactionDetails({ safeTxHash }) { * const { transaction, loading, error } = useTransaction(safeTxHash) * * if (loading) return * if (error) return {error} * if (!transaction) return Transaction not found * * return ( * *
* * * ) * } * ``` */ export function useTransaction(safeTxHash: string) { const [transaction, setTransaction] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { try { const txStore = getTransactionStore() const foundTx = txStore.getTransaction(safeTxHash) setTransaction(foundTx || null) setLoading(false) } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load transaction') setLoading(false) } }, [safeTxHash]) return { transaction, loading, error } } /** * Hook for accessing transactions for a specific Safe account. * Optionally filter by chain ID. * * @param safeAddress - The Safe account address * @param chainId - Optional chain ID to filter by * * @example * ```tsx * function SafeTransactionsScreen({ safeAddress, chainId }) { * const { transactions, loading, error } = useTransactionsBySafe(safeAddress, chainId) * * if (loading) return * * return ( * *
* ( * * {tx.safeTxHash.slice(0, 10)}... * Status: {tx.status} * * )} * emptyMessage="No transactions found" * /> * * ) * } * ``` */ export function useTransactionsBySafe(safeAddress: Address, chainId?: string) { const [transactions, setTransactions] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { try { const txStore = getTransactionStore() const safeTxs = txStore.getTransactionsBySafe(safeAddress, chainId) setTransactions(safeTxs) setLoading(false) } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load transactions') setLoading(false) } }, [safeAddress, chainId]) return { transactions, loading, error } } /** * Hook for accessing transactions filtered by status. * Useful for showing pending, signed, or executed transactions. * * @param status - The transaction status to filter by * * @example * ```tsx * function PendingTransactionsScreen() { * const { transactions, loading } = useTransactionsByStatus(TransactionStatus.PENDING) * * return ( * *
* } * emptyMessage="No pending transactions" * /> * * ) * } * ``` */ export function useTransactionsByStatus(status: TransactionStatus) { const [transactions, setTransactions] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { try { const txStore = getTransactionStore() const allTxs = txStore.getAllTransactions() const filteredTxs = allTxs.filter((tx) => tx.status === status) setTransactions(filteredTxs) setLoading(false) } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load transactions') setLoading(false) } }, [status]) return { transactions, loading, error } } /** * Hook for getting transaction statistics. * Returns counts by status and other useful metrics. * * @example * ```tsx * function TransactionStatsScreen() { * const { stats, loading } = useTransactionStats() * * if (loading) return * * return ( * * ) * } * ``` */ export function useTransactionStats() { const [stats, setStats] = useState({ total: 0, pending: 0, signed: 0, executed: 0, rejected: 0, }) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) useEffect(() => { try { const txStore = getTransactionStore() const allTxs = txStore.getAllTransactions() const newStats = { total: allTxs.length, pending: allTxs.filter((tx) => tx.status === TransactionStatus.PENDING).length, signed: allTxs.filter((tx) => tx.status === TransactionStatus.SIGNED).length, executed: allTxs.filter((tx) => tx.status === TransactionStatus.EXECUTED).length, rejected: allTxs.filter((tx) => tx.status === TransactionStatus.REJECTED).length, } setStats(newStats) setLoading(false) } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load transaction stats') setLoading(false) } }, []) return { stats, loading, error } }