Files
Heyue_test/frontend/src/hooks/useTransactionHistory.ts

118 lines
3.8 KiB
TypeScript
Raw Normal View History

import { useState, useEffect } from 'react'
export type TransactionType = 'mint' | 'burn' | 'buy' | 'sell' | 'approve' | 'create_vault' | 'update_price' | 'test' | 'addLiquidity' | 'removeLiquidity' | 'swap'
export interface TransactionRecord {
id: string
type: TransactionType
hash: string
timestamp: number
status: 'pending' | 'success' | 'failed'
amount?: string
token?: string
vault?: string
error?: string
}
const STORAGE_KEY = 'yt_asset_tx_history'
const MAX_RECORDS = 50
export function useTransactionHistory() {
const [transactions, setTransactions] = useState<TransactionRecord[]>([])
// 从 localStorage 加载历史记录
useEffect(() => {
try {
const stored = localStorage.getItem(STORAGE_KEY)
if (stored) {
const parsed = JSON.parse(stored)
// 过滤并修复损坏的记录
const valid = Array.isArray(parsed)
? parsed
.filter((tx: any) => tx && typeof tx === 'object' && tx.id && typeof tx.id === 'string')
.map((tx: any) => ({
...tx,
// 确保所有字段都是正确类型
id: String(tx.id),
type: String(tx.type || 'test'),
hash: (typeof tx.hash === 'string' && tx.hash.startsWith('0x')) ? tx.hash : '',
timestamp: Number(tx.timestamp) || Date.now(),
status: ['pending', 'success', 'failed'].includes(tx.status) ? tx.status : 'failed',
amount: tx.amount ? String(tx.amount) : undefined,
token: tx.token ? String(tx.token) : undefined,
vault: tx.vault ? String(tx.vault) : undefined,
error: tx.error ? (typeof tx.error === 'string' ? tx.error : JSON.stringify(tx.error)) : undefined,
}))
: []
setTransactions(valid)
}
} catch (e) {
console.error('Failed to load transaction history:', e)
// 清除损坏的数据
localStorage.removeItem(STORAGE_KEY)
}
}, [])
// 保存到 localStorage
const saveToStorage = (records: TransactionRecord[]) => {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(records.slice(0, MAX_RECORDS)))
} catch (e) {
console.error('Failed to save transaction history:', e)
}
}
// 添加新交易
const addTransaction = (tx: Omit<TransactionRecord, 'id' | 'timestamp'>) => {
const newTx: TransactionRecord = {
type: tx.type,
hash: (typeof tx.hash === 'string' && tx.hash.startsWith('0x')) ? tx.hash : '',
status: tx.status,
amount: tx.amount ? String(tx.amount) : undefined,
token: tx.token ? String(tx.token) : undefined,
vault: tx.vault ? String(tx.vault) : undefined,
error: tx.error ? (typeof tx.error === 'string' ? tx.error : JSON.stringify(tx.error)) : undefined,
id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
timestamp: Date.now(),
}
setTransactions(prev => {
const updated = [newTx, ...prev].slice(0, MAX_RECORDS)
saveToStorage(updated)
return updated
})
return newTx.id
}
// 更新交易状态
const updateTransaction = (id: string, updates: Partial<TransactionRecord>) => {
// 确保 hash 是字符串
if (updates.hash && typeof updates.hash !== 'string') {
updates.hash = ''
}
// 确保 error 是字符串
if (updates.error && typeof updates.error !== 'string') {
updates.error = JSON.stringify(updates.error)
}
setTransactions(prev => {
const updated = prev.map(tx =>
tx.id === id ? { ...tx, ...updates } : tx
)
saveToStorage(updated)
return updated
})
}
// 清空历史记录
const clearHistory = () => {
setTransactions([])
localStorage.removeItem(STORAGE_KEY)
}
return {
transactions,
addTransaction,
updateTransaction,
clearHistory,
}
}