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 }
}