138 lines
4.7 KiB
TypeScript
138 lines
4.7 KiB
TypeScript
import { useState, useEffect } from 'react';
|
|
import { ethers } from 'ethers';
|
|
import { useWalletStore } from '@/lib/wallet-store';
|
|
import { USER_TRUST_CONTRACT_ADDRESS, USER_TRUST_CONTRACT_ABI } from '@/lib/constants';
|
|
|
|
export function useTrustData() {
|
|
const { walletConnected, walletAddress, isVerified, trustScore: storeTrustScore, dailyLimit: storeDailyLimit, updateTrustScore, updateDailyLimit } = useWalletStore();
|
|
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
|
|
|
|
// Trust-earning actions mapping
|
|
const trustActions = [
|
|
{ action: "Submit an unflagged perspective", points: 1 },
|
|
{ action: "Receive an upvote from a verified user", points: 5 },
|
|
{ action: "Have your perspective included in a consensus", points: 10 },
|
|
{ action: "Consistent participation (30 days)", points: 15 },
|
|
{ action: "Have zero flagged content", points: 5 }
|
|
];
|
|
|
|
// Fetch trust data from API or blockchain
|
|
const fetchTrustData = async () => {
|
|
if (!walletConnected || !walletAddress) return;
|
|
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
// Try to get data from our API first (which may use blockchain in production)
|
|
const response = await fetch(`/api/trust?address=${walletAddress}`);
|
|
|
|
if (!response.ok) {
|
|
throw new Error('API request failed');
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// Update local state with data from API
|
|
updateTrustScore(data.trustScore);
|
|
updateDailyLimit(data.dailyLimit);
|
|
|
|
setLastUpdated(new Date(data.lastUpdated));
|
|
} catch (err) {
|
|
console.error('Error fetching trust data:', err);
|
|
|
|
// Fallback to blockchain directly if API fails
|
|
try {
|
|
if (window.ethereum) {
|
|
const provider = new ethers.providers.Web3Provider(
|
|
window.ethereum as ethers.providers.ExternalProvider
|
|
);
|
|
const contract = new ethers.Contract(
|
|
USER_TRUST_CONTRACT_ADDRESS,
|
|
USER_TRUST_CONTRACT_ABI,
|
|
provider
|
|
);
|
|
|
|
const userData = await contract.getUserTrustData(walletAddress);
|
|
|
|
// Update local state with data from blockchain
|
|
updateTrustScore(userData.trustScore.toNumber());
|
|
updateDailyLimit(userData.dailyLimit.toNumber());
|
|
|
|
setLastUpdated(new Date());
|
|
} else {
|
|
// Just use the store values if no API and no wallet
|
|
setError('Failed to fetch trust data');
|
|
}
|
|
} catch (fallbackErr) {
|
|
console.error('Fallback error:', fallbackErr);
|
|
setError('Failed to fetch trust data from blockchain');
|
|
}
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
// Update trust score via API
|
|
const updateUserTrust = async (action: string, amount: number = 1) => {
|
|
if (!walletConnected || !walletAddress) return;
|
|
|
|
setIsLoading(true);
|
|
setError(null);
|
|
|
|
try {
|
|
const response = await fetch('/api/trust', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
walletAddress,
|
|
action,
|
|
amount,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error('API request failed');
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// Update local state with data from API
|
|
updateTrustScore(data.trustScore);
|
|
updateDailyLimit(data.dailyLimit);
|
|
|
|
setLastUpdated(new Date(data.lastUpdated));
|
|
return data;
|
|
} catch (err) {
|
|
console.error('Error updating trust score:', err);
|
|
setError('Failed to update trust score');
|
|
throw err;
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
// Initial fetch on component mount
|
|
useEffect(() => {
|
|
if (walletConnected && walletAddress) {
|
|
fetchTrustData();
|
|
}
|
|
}, [walletConnected, walletAddress]);
|
|
|
|
return {
|
|
isVerified,
|
|
trustScore: storeTrustScore,
|
|
dailyLimit: storeDailyLimit,
|
|
isLoading,
|
|
error,
|
|
lastUpdated,
|
|
fetchTrustData,
|
|
updateUserTrust,
|
|
trustActions
|
|
};
|
|
}
|